From: <dos...@us...> - 2012-04-15 14:13:32
|
Revision: 4481 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=4481&view=rev Author: doskabouter Date: 2012-04-15 14:13:24 +0000 (Sun, 15 Apr 2012) Log Message: ----------- - removed reference to htmlagilitypack - cleanup code - added ParentNode to GeckoNode Modified Paths: -------------- trunk/plugins/BrowseTheWeb/Source/BrowseTheWeb/BrowseTheWeb.csproj trunk/plugins/BrowseTheWeb/Source/BrowseTheWeb/GUIPlugin.cs trunk/plugins/BrowseTheWeb/Source/Skybound.Gecko/GeckoDom.cs Modified: trunk/plugins/BrowseTheWeb/Source/BrowseTheWeb/BrowseTheWeb.csproj =================================================================== --- trunk/plugins/BrowseTheWeb/Source/BrowseTheWeb/BrowseTheWeb.csproj 2012-04-15 14:08:54 UTC (rev 4480) +++ trunk/plugins/BrowseTheWeb/Source/BrowseTheWeb/BrowseTheWeb.csproj 2012-04-15 14:13:24 UTC (rev 4481) @@ -66,9 +66,6 @@ <Reference Include="Dialogs"> <HintPath>C:\Program Files\Team MediaPortal\MediaPortal\plugins\Windows\Dialogs.dll</HintPath> </Reference> - <Reference Include="HtmlAgilityPack"> - <HintPath>C:\Program Files\Team MediaPortal\MediaPortal\plugins\Windows\HtmlAgilityPack.dll</HintPath> - </Reference> <Reference Include="Ionic.Zip"> <HintPath>C:\Program Files\Team MediaPortal\MediaPortal\Ionic.Zip.dll</HintPath> </Reference> Modified: trunk/plugins/BrowseTheWeb/Source/BrowseTheWeb/GUIPlugin.cs =================================================================== --- trunk/plugins/BrowseTheWeb/Source/BrowseTheWeb/GUIPlugin.cs 2012-04-15 14:08:54 UTC (rev 4480) +++ trunk/plugins/BrowseTheWeb/Source/BrowseTheWeb/GUIPlugin.cs 2012-04-15 14:13:24 UTC (rev 4481) @@ -48,13 +48,14 @@ private const int MOUSEEVENTF_LEFTUP = 0x04; private const int MOUSEEVENTF_RIGHTDOWN = 0x08; private const int MOUSEEVENTF_RIGHTUP = 0x10; + private const bool logHtml = false; #region Links private Dictionary<int, HtmlLinkNumber> _htmlLinkNumbers = new Dictionary<int, HtmlLinkNumber>(); #endregion #region Constants - private const string _span = "<span style=\"font-family: arial,sans-serif; font-size: 12px ! important; line-height: 130% ! important; border-width: 1px ! important; border-style: solid ! important; -moz-border-radius: 2px 2px 2px 2px ! important; padding: 0px 2px ! important; margin-left: 2px; max-width: 20px; max-height: 10px ! important; overflow: visible ! important; float: none ! important; display: inline;\" gecko_id=\"{0}\" gecko_action=\"{1}\" gecko_type=\"{2}\" class=\"{3}\">{0}</span>"; + private const string _spanstyle = "font-family: arial,sans-serif; font-size: 12px ! important; line-height: 130% ! important; border-width: 1px ! important; border-style: solid ! important; -moz-border-radius: 2px 2px 2px 2px ! important; padding: 0px 2px ! important; margin-left: 2px; max-width: 20px; max-height: 10px ! important; overflow: visible ! important; float: none ! important; display: inline;"; #endregion #region declare vars @@ -859,9 +860,44 @@ GUIPropertyManager.SetProperty("#btWeb.status", str); } } + + private void AddElements(List<GeckoElement> list, GeckoNode parent, string elName) + { + if (parent is GeckoElement && ((GeckoElement)parent).TagName.ToLowerInvariant() == elName) + list.Add((GeckoElement)parent); + foreach (GeckoNode child in parent.ChildNodes) + AddElements(list, child, elName); + } + + private List<GeckoElement> getElements(GeckoNode parent, string elName) + { + List<GeckoElement> res = new List<GeckoElement>(); + AddElements(res, parent, elName); + return res; + } + + private GeckoElement insertSpan(int geckoId, string geckoAction, string geckoType, string className, GeckoNode after) + { + if (after == null) + throw new ArgumentNullException("after"); + GeckoElement newChild = after.OwnerDocument.CreateElement("span"); + newChild.SetAttribute("style", _spanstyle); + newChild.SetAttribute("gecko_id", geckoId.ToString()); + newChild.SetAttribute("gecko_action", geckoAction); + newChild.SetAttribute("gecko_type", geckoType); + newChild.InnerHtml = geckoId.ToString(); + if (!String.IsNullOrEmpty(className)) + newChild.SetAttribute("class", className); + if (after.NextSibling != null) + after.ParentNode.InsertBefore(newChild, after.NextSibling); + else + after.ParentNode.AppendChild(newChild); + return newChild; + } + private void webBrowser_DocumentCompleted(object sender, EventArgs e) { - MyLog.debug("page completetd : " + webBrowser.Url.ToString()); + MyLog.debug("page completed : " + webBrowser.Url.ToString()); try { @@ -900,7 +936,8 @@ }; if (!element.InnerHtml.Contains("gecko_id")) { - element.InnerHtml += string.Format(_span, i, "", "LINK", lastSpan.ClassName); + insertSpan(i, String.Empty, "LINK", lastSpan.ClassName, + element.LastChild == null ? element : element.LastChild); } string gb = element.GetAttribute("gb"); @@ -921,86 +958,79 @@ } GeckoElementCollection forms = webBrowser.Document.GetElementsByTagName("form"); - HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); MyLog.debug("page forms cnt : " + forms.Count); foreach (GeckoElement element in forms) { + List<GeckoElement> inps = getElements(element, "input"); string action = element.GetAttribute("action"); - doc.LoadHtml(element.InnerHtml); - foreach (HtmlAgilityPack.HtmlNode link in doc.DocumentNode.SelectNodes("//*")) + foreach (GeckoElement link in inps) { - if (link.OriginalName == "input") + string linkType = link.GetAttribute("type"); + if (!String.IsNullOrEmpty(linkType)) { - if (link.Attributes["type"] != null) + if (linkType != "hidden") { - if (link.Attributes["type"].Value != "hidden") - { - string gb = link.GetAttributeValue("gb", ""); - string id = link.GetAttributeValue("id", ""); - string name = link.GetAttributeValue("name", ""); - string outerHtml = link.OuterHtml; - if (string.IsNullOrEmpty(gb)) - { - link.SetAttributeValue("gb", "gecko_link" + i); - } - if (string.IsNullOrEmpty(id)) - { - link.SetAttributeValue("id", "gb" + i); - id = "gb" + i; - } - - if (!element.InnerHtml.Contains("gecko_id=\"" + i + "\"")) - { - string newLink = link.OuterHtml + string.Format(_span, i, action, "INPUT", ""); - element.InnerHtml = element.InnerHtml.Replace(outerHtml, newLink); - } - if (link.Attributes["type"].Value == "submit" || - link.Attributes["type"].Value == "reset" || - link.Attributes["type"].Value == "radio" || - link.Attributes["type"].Value == "image" || - link.Attributes["type"].Value == "checkbox") - { - _htmlLinkNumbers.Add(i, new HtmlLinkNumber(i, id, name, action, HtmlInputType.Action)); - } - else - { - if (link.Attributes["type"].Value == "password") - _htmlLinkNumbers.Add(i, new HtmlLinkNumber(i, id, name, action, HtmlInputType.InputPassword)); - else - _htmlLinkNumbers.Add(i, new HtmlLinkNumber(i, id, name, action, HtmlInputType.Input)); - } - i++; - } - } - else - { - string gb = link.GetAttributeValue("gb", ""); - string id = link.GetAttributeValue("id", ""); - string name = link.GetAttributeValue("name", ""); - string outerHtml = link.OuterHtml; + string gb = link.GetAttribute("gb"); + string id = link.GetAttribute("id"); + string name = link.GetAttribute("name"); if (string.IsNullOrEmpty(gb)) { - link.SetAttributeValue("gb", "gecko_link" + i); + link.SetAttribute("gb", "gecko_link" + i); } if (string.IsNullOrEmpty(id)) { - link.SetAttributeValue("id", "gb" + i); + link.SetAttribute("id", "gb" + i); id = "gb" + i; } if (!element.InnerHtml.Contains("gecko_id=\"" + i + "\"")) { - string newLink = link.OuterHtml + string.Format(_span, i, action, "INPUT", ""); - element.InnerHtml = element.InnerHtml.Replace(outerHtml, newLink); + insertSpan(i, action, "INPUT", null, link); } - - _htmlLinkNumbers.Add(i, new HtmlLinkNumber(i, id, name, action, HtmlInputType.Input)); + if (linkType == "submit" || + linkType == "reset" || + linkType == "radio" || + linkType == "image" || + linkType == "checkbox") + { + _htmlLinkNumbers.Add(i, new HtmlLinkNumber(i, id, name, action, HtmlInputType.Action)); + } + else + { + if (linkType == "password") + _htmlLinkNumbers.Add(i, new HtmlLinkNumber(i, id, name, action, HtmlInputType.InputPassword)); + else + _htmlLinkNumbers.Add(i, new HtmlLinkNumber(i, id, name, action, HtmlInputType.Input)); + } i++; } } + else + { + string gb = link.GetAttribute("gb"); + string id = link.GetAttribute("id"); + string name = link.GetAttribute("name"); + if (string.IsNullOrEmpty(gb)) + { + link.SetAttribute("gb", "gecko_link" + i); + } + if (string.IsNullOrEmpty(id)) + { + link.SetAttribute("id", "gb" + i); + id = "gb" + i; + } + + if (!element.InnerHtml.Contains("gecko_id=\"" + i + "\"")) + { + insertSpan(i, action, "INPUT", null, link); + } + + _htmlLinkNumbers.Add(i, new HtmlLinkNumber(i, id, name, action, HtmlInputType.Input)); + i++; + } } } #endregion @@ -1026,6 +1056,13 @@ lastDomain = webBrowser.Document.Domain; } #endregion + if (logHtml) + { + using (System.IO.StreamWriter tw = new System.IO.StreamWriter(@"e:\last.html")) + { + tw.WriteLine(webBrowser.Document.DocumentElement.InnerHtml); + } + } } catch (Exception ex) { @@ -1105,27 +1142,27 @@ string result = string.Empty; if (ShowKeyboard(ref result, id.Type == HtmlInputType.InputPassword) == DialogResult.OK) { - SetInputFieldText(id.Number, result); + SetInputElementValue(webBrowser.Document, id.Number, result); } webBrowser.Visible = true; } - public void SetInputFieldText(int id, string text) + + private bool SetInputElementValue(GeckoNode parent, int geckoId, string text) { - HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); - doc.LoadHtml(webBrowser.Document.Body.InnerHtml); - - foreach (HtmlAgilityPack.HtmlNode element in doc.DocumentNode.SelectNodes("//input")) + GeckoElement el = parent as GeckoElement; + if (el != null && el.TagName.ToLowerInvariant() == "input" && el.GetAttribute("gb") == "gecko_link" + geckoId) { - string name = element.GetAttributeValue("gb", ""); - if (!string.IsNullOrEmpty(name)) + el.SetAttribute("value", text); + return true; + } + else + { + foreach (GeckoNode child in parent.ChildNodes) { - if (name == "gecko_link" + id) - { - element.SetAttributeValue("value", text); - webBrowser.Document.Body.InnerHtml = doc.DocumentNode.InnerHtml; - break; - } + if (SetInputElementValue(child, geckoId, text)) + return true; } + return false; } } Modified: trunk/plugins/BrowseTheWeb/Source/Skybound.Gecko/GeckoDom.cs =================================================================== --- trunk/plugins/BrowseTheWeb/Source/Skybound.Gecko/GeckoDom.cs 2012-04-15 14:08:54 UTC (rev 4480) +++ trunk/plugins/BrowseTheWeb/Source/Skybound.Gecko/GeckoDom.cs 2012-04-15 14:13:24 UTC (rev 4481) @@ -40,1033 +40,1038 @@ namespace Skybound.Gecko { - /// <summary> - /// Provides a base class for DOM nodes. - /// </summary> - public class GeckoNode - { - internal GeckoNode(nsIDOMNode domObject) - { - _DomObject = domObject; - } - - internal static GeckoNode Create(nsIDOMNode domObject) - { - if (domObject == null) - return null; - - nsIDOMHTMLElement element = Xpcom.QueryInterface<nsIDOMHTMLElement>(domObject); - if (element != null) - return GeckoElement.Create(element); - - nsIDOMAttr attr = Xpcom.QueryInterface<nsIDOMAttr>(domObject); - if (attr != null) - return GeckoAttribute.Create(attr); - - return new GeckoNode(domObject); - } - - /// <summary> - /// Gets the underlying XPCOM object. - /// </summary> - public object DomObject - { - get { return _DomObject; } - } - nsIDOMNode _DomObject; - - public override bool Equals(object obj) - { - if (this == obj) - return true; - else if (obj is GeckoNode) - return this.GetHashCode() == (obj as GeckoNode).GetHashCode(); - - return base.Equals(obj); - } - - public override int GetHashCode() - { - IntPtr pUnk = Marshal.GetIUnknownForObject(this._DomObject); - try - { - return pUnk.GetHashCode(); - } - finally - { - if (pUnk != IntPtr.Zero) - Marshal.Release(pUnk); - } - } - - /// <summary> - /// Gets the text contents of the node. - /// </summary> - public string TextContent - { - get { return nsString.Get(((nsIDOM3Node)_DomObject).GetTextContent); } - set { nsString.Set(((nsIDOM3Node)_DomObject).SetTextContent, value); } - } - - /// <summary> - /// Gets or sets the value of the node. - /// </summary> - public string NodeValue - { - get { return nsString.Get(((nsIDOMNode)_DomObject).GetNodeValue); } - set { nsString.Set(((nsIDOMNode)_DomObject).SetNodeValue, value); } - } - - /// <summary> - /// Gets a collection containing all child nodes of this node. - /// </summary> - public GeckoNodeCollection ChildNodes - { - get { return new GeckoNodeCollection(_DomObject.GetChildNodes()); } - } - - public GeckoNode FirstChild { get { return GeckoNode.Create(_DomObject.GetFirstChild()); } } - public GeckoNode LastChild { get { return GeckoNode.Create(_DomObject.GetLastChild()); } } - public GeckoNode NextSibling { get { return GeckoNode.Create(_DomObject.GetNextSibling()); } } - public GeckoNode PreviousSibling { get { return GeckoNode.Create(_DomObject.GetPreviousSibling()); } } - public bool HasChildNodes { get { return _DomObject.HasChildNodes(); } } - public bool HasAttributes { get { return _DomObject.HasAttributes(); } } - - public GeckoDocument OwnerDocument { get { return GeckoDocument.Create(Xpcom.QueryInterface<nsIDOMHTMLDocument>(_DomObject.GetOwnerDocument())); } } - - public GeckoNode AppendChild(GeckoNode node) - { - if (node == null) - throw new ArgumentNullException("node"); - - _DomObject.AppendChild(node._DomObject); - return node; - } - - public GeckoNode CloneNode(bool deep) - { - return GeckoNode.Create(_DomObject.CloneNode(deep)); - } - - public GeckoNode InsertBefore(GeckoNode newChild, GeckoNode before) - { - if (newChild == null) - throw new ArgumentNullException("newChild"); - if (before == null) - throw new ArgumentNullException("before"); - - _DomObject.InsertBefore(newChild._DomObject, before._DomObject); - return newChild; - } - - public GeckoNode RemoveChild(GeckoNode node) - { - if (node == null) - throw new ArgumentNullException("node"); - - _DomObject.RemoveChild(node._DomObject); - return node; - } - - public GeckoNode ReplaceChild(GeckoNode newChild, GeckoNode oldChild) - { - if (newChild == null) - throw new ArgumentNullException("newChild"); - if (oldChild == null) - throw new ArgumentNullException("oldChild"); - - _DomObject.ReplaceChild(newChild._DomObject, oldChild._DomObject); - return newChild; - } - - public GeckoNamedNodeMap Attributes - { - get { return new GeckoNamedNodeMap(_DomObject.GetAttributes()); } - } - } - - /// <summary> - /// Represents a DOM attribute. - /// </summary> - public class GeckoAttribute : GeckoNode - { - internal GeckoAttribute(nsIDOMAttr attr) : base(attr) - { - this.DomAttr = attr; - } - nsIDOMAttr DomAttr; - - internal static GeckoAttribute Create(nsIDOMAttr attr) - { - return (attr == null) ? null : new GeckoAttribute(attr); - } - - /// <summary> - /// Gets the name of the attribute. - /// </summary> - public string Name - { - get { return nsString.Get(DomAttr.GetName); } - } - - /// <summary> - /// Gets the value of the attribute. - /// </summary> - public string Value - { - get { return nsString.Get(DomAttr.GetValue); } - set { nsString.Set(DomAttr.SetValue, value); } - } - - /// <summary> - /// Gets a value indicating whether the attribute is specified. - /// </summary> - public bool Specified - { - get { return DomAttr.GetSpecified(); } - } - - /// <summary> - /// Gets the <see cref="GeckoElement"/> which contains this attribute. - /// </summary> - public GeckoElement OwnerElement - { - get { return GeckoElement.Create((nsIDOMHTMLElement)DomAttr.GetOwnerElement()); } - } - } - - /// <summary> - /// Represents a DOM element. - /// </summary> - public class GeckoElement : GeckoNode - { - internal GeckoElement(nsIDOMHTMLElement element) : base(element) - { - this.DomElement = element; - this.DomNSElement = (nsIDOMNSElement)element; - this.DomNSHTMLElement = (nsIDOMNSHTMLElement)element; - - // since a reference is stored in the base class, we only need weak references here - Marshal.ChangeWrapperHandleStrength(DomNSElement, true); - Marshal.ChangeWrapperHandleStrength(DomNSHTMLElement, true); - } - - internal static GeckoElement Create(nsIDOMHTMLElement element) - { - return (element == null) ? null : new GeckoElement(element); - } - - nsIDOMHTMLElement DomElement; - nsIDOMNSElement DomNSElement; - nsIDOMNSHTMLElement DomNSHTMLElement; - - /// <summary> - /// Gets the parent element of this one. - /// </summary> - public GeckoElement Parent - { - get - { - // note: the parent node could also be the document - return GeckoElement.Create(Xpcom.QueryInterface<nsIDOMHTMLElement>(DomElement.GetParentNode())); - } - } - - /// <summary> - /// Gets the name of the tag. - /// </summary> - public string TagName - { - get { return nsString.Get(DomElement.GetTagName); } - } - - /// <summary> - /// Gets the value of the id attribute. - /// </summary> - public string Id - { - get { return nsString.Get(DomElement.GetId); } - set { nsString.Set(DomElement.SetId, value); } - } - - /// <summary> - /// Gets the value of the class attribute. - /// </summary> - public string ClassName - { - get { return nsString.Get(DomElement.GetClassName); } - set { nsString.Set(DomElement.SetClassName, value); } - } - - /// <summary> - /// Returns a collection containing the child elements of this element with a given tag name. - /// </summary> - /// <param name="tagName"></param> - /// <returns></returns> - public GeckoElementCollection GetElementsByTagName(string tagName) - { - if (string.IsNullOrEmpty(tagName)) - return null; - - return new GeckoElementCollection(DomElement.GetElementsByTagName(new nsAString(tagName))); - } - - /// <summary> - /// Gets the value of an attribute on this element with the specified name. - /// </summary> - /// <param name="attributeName"></param> - /// <returns></returns> - public string GetAttribute(string attributeName) - { - if (string.IsNullOrEmpty(attributeName)) - throw new ArgumentException("attributeName"); - - using (nsAString retval = new nsAString()) - { - DomElement.GetAttribute(new nsAString(attributeName), retval); - return retval.ToString(); - } - } - - /// <summary> - /// Gets the value of an attribute on this element with the specified name and namespace. - /// </summary> - /// <param name="attributeName"></param> - /// <returns></returns> - public string GetAttributeNS(string namespaceUri, string attributeName) - { - if (string.IsNullOrEmpty(namespaceUri)) - return GetAttribute(attributeName); - - if (string.IsNullOrEmpty(attributeName)) - throw new ArgumentException("attributeName"); - - using (nsAString retval = new nsAString()) - { - DomElement.GetAttributeNS(new nsAString(namespaceUri), new nsAString(attributeName), retval); - return retval.ToString(); - } - } - - /// <summary> - /// Sets the value of an attribute on this element with the specified name. - /// </summary> - /// <param name="attributeName"></param> - /// <param name="value"></param> - public void SetAttribute(string attributeName, string value) - { - if (string.IsNullOrEmpty(attributeName)) - throw new ArgumentException("attributeName"); - - DomElement.SetAttribute(new nsAString(attributeName), new nsAString(value)); - } - - /// <summary> - /// Sets the value of an attribute on this element with the specified name and namespace. - /// </summary> - /// <param name="attributeName"></param> - /// <param name="value"></param> - public void SetAttributeNS(string namespaceUri, string attributeName, string value) - { - if (string.IsNullOrEmpty(namespaceUri)) - { - SetAttribute(attributeName, value); - } - else - { - if (string.IsNullOrEmpty(attributeName)) - throw new ArgumentException("attributeName"); - - DomElement.SetAttributeNS(new nsAString(namespaceUri), new nsAString(attributeName), new nsAString(value)); - } - } - - /// <summary> - /// Removes an attribute from this element. - /// </summary> - /// <param name="attributeName"></param> - public void RemoveAttribute(string attributeName) - { - if (string.IsNullOrEmpty(attributeName)) - throw new ArgumentException("attributeName"); - - DomElement.RemoveAttribute(new nsAString(attributeName)); - } - - #if GECKO_1_9_1 - public int ScrollLeft { get { return DomNSElement.GetScrollLeft(); } set { DomNSElement.SetScrollLeft(value); } } - public int ScrollTop { get { return DomNSElement.GetScrollTop(); } set { DomNSElement.SetScrollTop(value); } } - public int ScrollWidth { get { return DomNSElement.GetScrollWidth(); } } - public int ScrollHeight { get { return DomNSElement.GetScrollHeight(); } } - public int ClientWidth { get { return DomNSElement.GetClientWidth(); } } - public int ClientHeight { get { return DomNSElement.GetClientHeight(); } } - #else + /// <summary> + /// Provides a base class for DOM nodes. + /// </summary> + public class GeckoNode + { + internal GeckoNode(nsIDOMNode domObject) + { + _DomObject = domObject; + } + + internal static GeckoNode Create(nsIDOMNode domObject) + { + if (domObject == null) + return null; + + nsIDOMHTMLElement element = Xpcom.QueryInterface<nsIDOMHTMLElement>(domObject); + if (element != null) + return GeckoElement.Create(element); + + nsIDOMAttr attr = Xpcom.QueryInterface<nsIDOMAttr>(domObject); + if (attr != null) + return GeckoAttribute.Create(attr); + + return new GeckoNode(domObject); + } + + /// <summary> + /// Gets the underlying XPCOM object. + /// </summary> + public object DomObject + { + get { return _DomObject; } + } + nsIDOMNode _DomObject; + + public override bool Equals(object obj) + { + if (this == obj) + return true; + else if (obj is GeckoNode) + return this.GetHashCode() == (obj as GeckoNode).GetHashCode(); + + return base.Equals(obj); + } + + public override int GetHashCode() + { + IntPtr pUnk = Marshal.GetIUnknownForObject(this._DomObject); + try + { + return pUnk.GetHashCode(); + } + finally + { + if (pUnk != IntPtr.Zero) + Marshal.Release(pUnk); + } + } + + /// <summary> + /// Gets the text contents of the node. + /// </summary> + public string TextContent + { + get { return nsString.Get(((nsIDOM3Node)_DomObject).GetTextContent); } + set { nsString.Set(((nsIDOM3Node)_DomObject).SetTextContent, value); } + } + + /// <summary> + /// Gets or sets the value of the node. + /// </summary> + public string NodeValue + { + get { return nsString.Get(((nsIDOMNode)_DomObject).GetNodeValue); } + set { nsString.Set(((nsIDOMNode)_DomObject).SetNodeValue, value); } + } + + /// <summary> + /// Gets a collection containing all child nodes of this node. + /// </summary> + public GeckoNodeCollection ChildNodes + { + get { return new GeckoNodeCollection(_DomObject.GetChildNodes()); } + } + + public GeckoNode ParentNode { get { return GeckoNode.Create(_DomObject.GetParentNode()); } } + public GeckoNode FirstChild { get { return GeckoNode.Create(_DomObject.GetFirstChild()); } } + public GeckoNode LastChild { get { return GeckoNode.Create(_DomObject.GetLastChild()); } } + public GeckoNode NextSibling { get { return GeckoNode.Create(_DomObject.GetNextSibling()); } } + public GeckoNode PreviousSibling { get { return GeckoNode.Create(_DomObject.GetPreviousSibling()); } } + public bool HasChildNodes { get { return _DomObject.HasChildNodes(); } } + public bool HasAttributes { get { return _DomObject.HasAttributes(); } } + + public GeckoDocument OwnerDocument { get { return GeckoDocument.Create(Xpcom.QueryInterface<nsIDOMHTMLDocument>(_DomObject.GetOwnerDocument())); } } + + public GeckoNode AppendChild(GeckoNode node) + { + if (node == null) + throw new ArgumentNullException("node"); + + _DomObject.AppendChild(node._DomObject); + return node; + } + + public GeckoNode CloneNode(bool deep) + { + return GeckoNode.Create(_DomObject.CloneNode(deep)); + } + + public GeckoNode InsertBefore(GeckoNode newChild, GeckoNode before) + { + if (newChild == null) + throw new ArgumentNullException("newChild"); + if (before == null) + throw new ArgumentNullException("before"); + + _DomObject.InsertBefore(newChild._DomObject, before._DomObject); + return newChild; + } + + public GeckoNode RemoveChild(GeckoNode node) + { + if (node == null) + throw new ArgumentNullException("node"); + + _DomObject.RemoveChild(node._DomObject); + return node; + } + + public GeckoNode ReplaceChild(GeckoNode newChild, GeckoNode oldChild) + { + if (newChild == null) + throw new ArgumentNullException("newChild"); + if (oldChild == null) + throw new ArgumentNullException("oldChild"); + + _DomObject.ReplaceChild(newChild._DomObject, oldChild._DomObject); + return newChild; + } + + public GeckoNamedNodeMap Attributes + { + get { return new GeckoNamedNodeMap(_DomObject.GetAttributes()); } + } + } + + /// <summary> + /// Represents a DOM attribute. + /// </summary> + public class GeckoAttribute : GeckoNode + { + internal GeckoAttribute(nsIDOMAttr attr) + : base(attr) + { + this.DomAttr = attr; + } + nsIDOMAttr DomAttr; + + internal static GeckoAttribute Create(nsIDOMAttr attr) + { + return (attr == null) ? null : new GeckoAttribute(attr); + } + + /// <summary> + /// Gets the name of the attribute. + /// </summary> + public string Name + { + get { return nsString.Get(DomAttr.GetName); } + } + + /// <summary> + /// Gets the value of the attribute. + /// </summary> + public string Value + { + get { return nsString.Get(DomAttr.GetValue); } + set { nsString.Set(DomAttr.SetValue, value); } + } + + /// <summary> + /// Gets a value indicating whether the attribute is specified. + /// </summary> + public bool Specified + { + get { return DomAttr.GetSpecified(); } + } + + /// <summary> + /// Gets the <see cref="GeckoElement"/> which contains this attribute. + /// </summary> + public GeckoElement OwnerElement + { + get { return GeckoElement.Create((nsIDOMHTMLElement)DomAttr.GetOwnerElement()); } + } + } + + /// <summary> + /// Represents a DOM element. + /// </summary> + public class GeckoElement : GeckoNode + { + internal GeckoElement(nsIDOMHTMLElement element) + : base(element) + { + this.DomElement = element; + this.DomNSElement = (nsIDOMNSElement)element; + this.DomNSHTMLElement = (nsIDOMNSHTMLElement)element; + + // since a reference is stored in the base class, we only need weak references here + Marshal.ChangeWrapperHandleStrength(DomNSElement, true); + Marshal.ChangeWrapperHandleStrength(DomNSHTMLElement, true); + } + + internal static GeckoElement Create(nsIDOMHTMLElement element) + { + return (element == null) ? null : new GeckoElement(element); + } + + nsIDOMHTMLElement DomElement; + nsIDOMNSElement DomNSElement; + nsIDOMNSHTMLElement DomNSHTMLElement; + + /// <summary> + /// Gets the parent element of this one. + /// </summary> + public GeckoElement Parent + { + get + { + // note: the parent node could also be the document + return GeckoElement.Create(Xpcom.QueryInterface<nsIDOMHTMLElement>(DomElement.GetParentNode())); + } + } + + /// <summary> + /// Gets the name of the tag. + /// </summary> + public string TagName + { + get { return nsString.Get(DomElement.GetTagName); } + } + + /// <summary> + /// Gets the value of the id attribute. + /// </summary> + public string Id + { + get { return nsString.Get(DomElement.GetId); } + set { nsString.Set(DomElement.SetId, value); } + } + + /// <summary> + /// Gets the value of the class attribute. + /// </summary> + public string ClassName + { + get { return nsString.Get(DomElement.GetClassName); } + set { nsString.Set(DomElement.SetClassName, value); } + } + + /// <summary> + /// Returns a collection containing the child elements of this element with a given tag name. + /// </summary> + /// <param name="tagName"></param> + /// <returns></returns> + public GeckoElementCollection GetElementsByTagName(string tagName) + { + if (string.IsNullOrEmpty(tagName)) + return null; + + return new GeckoElementCollection(DomElement.GetElementsByTagName(new nsAString(tagName))); + } + + /// <summary> + /// Gets the value of an attribute on this element with the specified name. + /// </summary> + /// <param name="attributeName"></param> + /// <returns></returns> + public string GetAttribute(string attributeName) + { + if (string.IsNullOrEmpty(attributeName)) + throw new ArgumentException("attributeName"); + + using (nsAString retval = new nsAString()) + { + DomElement.GetAttribute(new nsAString(attributeName), retval); + return retval.ToString(); + } + } + + /// <summary> + /// Gets the value of an attribute on this element with the specified name and namespace. + /// </summary> + /// <param name="attributeName"></param> + /// <returns></returns> + public string GetAttributeNS(string namespaceUri, string attributeName) + { + if (string.IsNullOrEmpty(namespaceUri)) + return GetAttribute(attributeName); + + if (string.IsNullOrEmpty(attributeName)) + throw new ArgumentException("attributeName"); + + using (nsAString retval = new nsAString()) + { + DomElement.GetAttributeNS(new nsAString(namespaceUri), new nsAString(attributeName), retval); + return retval.ToString(); + } + } + + /// <summary> + /// Sets the value of an attribute on this element with the specified name. + /// </summary> + /// <param name="attributeName"></param> + /// <param name="value"></param> + public void SetAttribute(string attributeName, string value) + { + if (string.IsNullOrEmpty(attributeName)) + throw new ArgumentException("attributeName"); + + DomElement.SetAttribute(new nsAString(attributeName), new nsAString(value)); + } + + /// <summary> + /// Sets the value of an attribute on this element with the specified name and namespace. + /// </summary> + /// <param name="attributeName"></param> + /// <param name="value"></param> + public void SetAttributeNS(string namespaceUri, string attributeName, string value) + { + if (string.IsNullOrEmpty(namespaceUri)) + { + SetAttribute(attributeName, value); + } + else + { + if (string.IsNullOrEmpty(attributeName)) + throw new ArgumentException("attributeName"); + + DomElement.SetAttributeNS(new nsAString(namespaceUri), new nsAString(attributeName), new nsAString(value)); + } + } + + /// <summary> + /// Removes an attribute from this element. + /// </summary> + /// <param name="attributeName"></param> + public void RemoveAttribute(string attributeName) + { + if (string.IsNullOrEmpty(attributeName)) + throw new ArgumentException("attributeName"); + + DomElement.RemoveAttribute(new nsAString(attributeName)); + } + +#if GECKO_1_9_1 + public int ScrollLeft { get { return DomNSElement.GetScrollLeft(); } set { DomNSElement.SetScrollLeft(value); } } + public int ScrollTop { get { return DomNSElement.GetScrollTop(); } set { DomNSElement.SetScrollTop(value); } } + public int ScrollWidth { get { return DomNSElement.GetScrollWidth(); } } + public int ScrollHeight { get { return DomNSElement.GetScrollHeight(); } } + public int ClientWidth { get { return DomNSElement.GetClientWidth(); } } + public int ClientHeight { get { return DomNSElement.GetClientHeight(); } } +#else public int ScrollLeft { get { return DomNSHTMLElement.GetScrollLeft(); } set { DomNSHTMLElement.SetScrollLeft(value); } } public int ScrollTop { get { return DomNSHTMLElement.GetScrollTop(); } set { DomNSHTMLElement.SetScrollTop(value); } } public int ScrollWidth { get { return DomNSHTMLElement.GetScrollWidth(); } } public int ScrollHeight { get { return DomNSHTMLElement.GetScrollHeight(); } } public int ClientWidth { get { return DomNSHTMLElement.GetClientWidth(); } } public int ClientHeight { get { return DomNSHTMLElement.GetClientHeight(); } } - #endif - public int OffsetLeft { get { return DomNSHTMLElement.GetOffsetLeft(); } } - public int OffsetTop { get { return DomNSHTMLElement.GetOffsetTop(); } } - public int OffsetWidth { get { return DomNSHTMLElement.GetOffsetWidth(); } } - public int OffsetHeight { get { return DomNSHTMLElement.GetOffsetHeight(); } } - - public GeckoElement OffsetParent - { - get { return GeckoElement.Create((nsIDOMHTMLElement)DomNSHTMLElement.GetOffsetParent()); } - } - - public void ScrollIntoView(bool top) - { - DomNSHTMLElement.ScrollIntoView(top); - } - - public string InnerHtml - { - get { return nsString.Get(DomNSHTMLElement.GetInnerHTML); } - set { nsString.Set(DomNSHTMLElement.SetInnerHTML, value); } - } - - public void Focus() - { - DomNSHTMLElement.Focus(); - } - - public void Blur() - { - DomNSHTMLElement.Blur(); - } +#endif + public int OffsetLeft { get { return DomNSHTMLElement.GetOffsetLeft(); } } + public int OffsetTop { get { return DomNSHTMLElement.GetOffsetTop(); } } + public int OffsetWidth { get { return DomNSHTMLElement.GetOffsetWidth(); } } + public int OffsetHeight { get { return DomNSHTMLElement.GetOffsetHeight(); } } - public int TabIndex - { - get { return DomNSHTMLElement.GetTabIndex(); } - set { DomNSHTMLElement.SetTabIndex(value); } - } - - #if GECKO_1_9 - /// <summary> - /// Returns a set of elements with the given class name. This element and all child elements are searched. - /// </summary> - /// <param name="classes"></param> - /// <returns></returns> - public GeckoNodeCollection GetElementsByClassName(string classes) - { - using (nsAString str = new nsAString(classes)) - return new GeckoNodeCollection(((nsIDOMNSElement)DomElement).GetElementsByClassName(str)); - } - - /// <summary> - /// Gets a rectangle which represents the union of all bounding rectangles within the element. - /// </summary> - public RectangleF BoundingClientRect - { - get - { - nsIDOMNSElement ns = (nsIDOMNSElement)DomElement; - nsIDOMClientRect rect = ns.GetBoundingClientRect(); - return RectangleF.FromLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom()); - } - } - - /// <summary> - /// Returns an array containing all bounding rectangles within the element. - /// </summary> - /// <returns></returns> - public RectangleF [] GetClientRects() - { - nsIDOMNSElement ns = (nsIDOMNSElement)DomElement; - nsIDOMClientRectList rects = ns.GetClientRects(); - RectangleF [] result = new RectangleF[rects.GetLength()]; - for (int i = 0; i < result.Length; i++) - { - nsIDOMClientRect rect = rects.Item(i); - result[i] = RectangleF.FromLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom()); - } - return result; - } - #endif - } - - /// <summary> - /// Represents a DOM document. - /// </summary> - public class GeckoDocument : GeckoNode - { - internal GeckoDocument(nsIDOMHTMLDocument document) : base(document) - { - this.DomDocument = document; - } - - internal static GeckoDocument Create(nsIDOMHTMLDocument document) - { - return (document == null) ? null : new GeckoDocument(document); - } - - nsIDOMHTMLDocument DomDocument; - - /// <summary> - /// Gets the document title. - /// </summary> - public string Title - { - get { return nsString.Get(DomDocument.GetTitle); } - set { nsString.Set(DomDocument.SetTitle, value); } - } - - /// <summary> - /// Gets the HTML body element. - /// </summary> - public GeckoElement Body - { - get { return GeckoElement.Create(DomDocument.GetBody()); } - } - - /// <summary> - /// Gets the top-level document element (for HTML documents, this is the html tag). - /// </summary> - public GeckoElement DocumentElement - { - get { return GeckoElement.Create((nsIDOMHTMLElement)DomDocument.GetDocumentElement()); } - } - - /// <summary> - /// Searches for and returns the element in the document with the given id. - /// </summary> - /// <param name="id"></param> - /// <returns></returns> - public GeckoElement GetElementById(string id) - { - if (string.IsNullOrEmpty(id)) - return null; - - return GeckoElement.Create((nsIDOMHTMLElement)DomDocument.GetElementById(new nsAString(id))); - } - - /// <summary> - /// Represents a collection of style sheets in a <see cref="GeckoDocument"/>. - /// </summary> - public class StyleSheetCollection : IEnumerable<GeckoStyleSheet> - { - internal StyleSheetCollection(GeckoDocument document) - { - this.List = ((nsIDOMDocumentStyle)document.DomDocument).GetStyleSheets(); - } - nsIDOMStyleSheetList List; - - /// <summary> - /// Gets the number of items in the collection. - /// </summary> - public int Count - { - get { return (List == null) ? 0 : List.GetLength(); } - } - - /// <summary> - /// Gets the item at the specified index in the collection. - /// </summary> - /// <param name="index"></param> - /// <returns></returns> - public GeckoStyleSheet this[int index] - { - get - { - if (index < 0 || index >= Count) - throw new ArgumentOutOfRangeException("index"); - - return GeckoStyleSheet.Create((nsIDOMCSSStyleSheet)List.Item(index)); - } - } - - #region IEnumerable<GeckoStyleSheet> Members - - /// <summary> - /// Returns an <see cref="IEnumerator{GeckoStyleSheet}"/> which can enumerate through the collection. - /// </summary> - /// <returns></returns> - public IEnumerator<GeckoStyleSheet> GetEnumerator() - { - int length = Count; - for (int i = 0; i < length; i++) - { - yield return GeckoStyleSheet.Create((nsIDOMCSSStyleSheet)List.Item(i)); - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - foreach (GeckoStyleSheet element in this) - yield return element; - } + public GeckoElement OffsetParent + { + get { return GeckoElement.Create((nsIDOMHTMLElement)DomNSHTMLElement.GetOffsetParent()); } + } - #endregion - } - - /// <summary> - /// Gets the collection of style sheets in the <see cref="GeckoDocument"/>. - /// </summary> - public StyleSheetCollection StyleSheets - { - get { return (_StyleSheets == null) ? ( _StyleSheets = new StyleSheetCollection(this)) : _StyleSheets; } - } - StyleSheetCollection _StyleSheets; - - /// <summary> - /// Gets the URL of the document. - /// </summary> - public Uri Url - { - get { return new Uri(nsString.Get(DomDocument.GetURL)); } - } - - public GeckoElementCollection Frames - { - get { return new GeckoHtmlElementCollection(DomDocument.GetForms()); } - } - - public GeckoElementCollection Images - { - get { return new GeckoHtmlElementCollection(DomDocument.GetImages()); } - } - - public GeckoElementCollection Anchors - { - get { return new GeckoHtmlElementCollection(DomDocument.GetAnchors()); } - } - - public GeckoElementCollection Applets - { - get { return new GeckoHtmlElementCollection(DomDocument.GetApplets()); } - } - - public GeckoElementCollection Links - { - get { return new GeckoHtmlElementCollection(DomDocument.GetLinks()); } - } - - public string Cookie - { - get { return nsString.Get(DomDocument.GetCookie); } - set { nsString.Set(DomDocument.SetCookie, value); } - } - - public string Domain - { - get { return nsString.Get(DomDocument.GetDomain); } - } - - /// <summary> - /// Returns a collection containing all elements in the document with a given tag name. - /// </summary> - /// <param name="tagName"></param> - /// <returns></returns> - public GeckoElementCollection GetElementsByTagName(string tagName) - { - if (string.IsNullOrEmpty(tagName)) - return null; - - return new GeckoElementCollection(DomDocument.GetElementsByTagName(new nsAString(tagName))); - } - - /// <summary> - /// Returns a collection containing all elements in the document with a given name. - /// </summary> - /// <param name="name"></param> - /// <returns></returns> - public GeckoElementCollection GetElementsByName(string name) - { - if (string.IsNullOrEmpty(name)) - return null; - - return new GeckoElementCollection(DomDocument.GetElementsByName(new nsAString(name))); - } - - public GeckoElement CreateElement(string tagName) - { - if (string.IsNullOrEmpty(tagName)) - throw new ArgumentException("tagName"); - - return GeckoElement.Create((nsIDOMHTMLElement)DomDocument.CreateElement(new nsAString(tagName))); - } - - public GeckoElement CreateElement(string tagName, string qualifiedName) - { - if (string.IsNullOrEmpty(tagName)) - throw new ArgumentException("tagName"); - if (string.IsNullOrEmpty(qualifiedName)) - throw new ArgumentException("qualifiedName"); - - return GeckoElement.Create((nsIDOMHTMLElement)DomDocument.CreateElementNS(new nsAString(tagName), new nsAString(qualifiedName))); - } - - public GeckoAttribute CreateAttribute(string name) - { - if (string.IsNullOrEmpty(name)) - throw new ArgumentException("name"); - - return GeckoAttribute.Create(DomDocument.CreateAttribute(new nsAString(name))); - } - - public GeckoAttribute CreateAttribute(string namespaceUri, string qualifiedName) - { - if (string.IsNullOrEmpty(namespaceUri)) - throw new ArgumentException("namespaceUri"); - if (string.IsNullOrEmpty(qualifiedName)) - throw new ArgumentException("qualifiedName"); - - return GeckoAttribute.Create(DomDocument.CreateAttributeNS(new nsAString(namespaceUri), new nsAString(qualifiedName))); - } - - public GeckoNode ImportNode(GeckoNode node, bool deep) - { - if (node == null) - throw new ArgumentNullException("node"); - - return GeckoNode.Create(DomDocument.ImportNode((nsIDOMNode)node.DomObject, deep)); - } - - public bool IsSupported(string feature, string version) - { - if (string.IsNullOrEmpty(feature)) - throw new ArgumentException("feature"); - if (string.IsNullOrEmpty(version)) - throw new ArgumentException("version"); - - return DomDocument.IsSupported(new nsAString(feature), new nsAString(version)); - } - - #if GECKO_1_9 - /// <summary> - /// Gets the currently focused element. - /// </summary> - public GeckoElement ActiveElement - { - get { return (GeckoElement)GeckoElement.Create(((nsIDOMNSDocument)DomDocument).GetActiveElement()); } - } - - /// <summary> - /// Returns a set of elements with the given class name. When called on the document object, the complete document is searched, including the root node. - /// </summary> - /// <param name="classes"></param> - /// <returns></returns> - public GeckoNodeCollection GetElementsByClassName(string classes) - { - using (nsAString str = new nsAString(classes)) - return new GeckoNodeCollection(((nsIDOMNSDocument)DomDocument).GetElementsByClassName(str)); - } - - /// <summary> - /// Returns the element visible at the given point, relative to the upper-left-most visible point in the document. - /// </summary> - /// <param name="x"></param> - /// <param name="y"></param> - /// <returns></returns> - public GeckoElement ElementFromPoint(int x, int y) - { - return GeckoElement.Create((nsIDOMHTMLElement)((nsIDOMNSDocument)DomDocument).ElementFromPoint(x, y)); - } - #endif - } - - public class GeckoNamedNodeMap : IEnumerable<GeckoNode> - { - internal GeckoNamedNodeMap(nsIDOMNamedNodeMap map) - { - this.Map = map; - } - - nsIDOMNamedNodeMap Map; - - /// <summary> - /// Gets the number of items in the map. - /// </summary> - public int Count - { - get { return (Map == null) ? 0 : Map.GetLength(); } - } - - public GeckoNode this[int index] - { - get - { - if (index < 0 || index >= Count) - throw new ArgumentOutOfRangeException("index"); - - return GeckoNode.Create(Map.Item(index)); - } - } - - public GeckoNode this[string name] - { - get - { - return GeckoNode.Create(Map.GetNamedItem(new nsAString(name))); - } - } - - public GeckoNode this[string namespaceUri, string localName] - { - get - { - return GeckoNode.Create(Map.GetNamedItemNS(new nsAString(namespaceUri), new nsAString(localName))); - } - } + public void ScrollIntoView(bool top) + { + DomNSHTMLElement.ScrollIntoView(top); + } - #region IEnumerable<GeckoNode> Members + public string InnerHtml + { + get { return nsString.Get(DomNSHTMLElement.GetInnerHTML); } + set { nsString.Set(DomNSHTMLElement.SetInnerHTML, value); } + } - public IEnumerator<GeckoNode> GetEnumerator() - { - int length = Count; - for (int i = 0; i < length; i++) - { - yield return GeckoNode.Create(Map.Item(i)); - } - } + public void Focus() + { + DomNSHTMLElement.Focus(); + } - #endregion + public void Blur() + { + DomNSHTMLElement.Blur(); + } - #region IEnumerable Members + public int TabIndex + { + get { return DomNSHTMLElement.GetTabIndex(); } + set { DomNSHTMLElement.SetTabIndex(value); } + } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - foreach (GeckoNode node in this) - yield return node; - } +#if GECKO_1_9 + /// <summary> + /// Returns a set of elements with the given class name. This element and all child elements are searched. + /// </summary> + /// <param name="classes"></param> + /// <returns></returns> + public GeckoNodeCollection GetElementsByClassName(string classes) + { + using (nsAString str = new nsAString(classes)) + return new GeckoNodeCollection(((nsIDOMNSElement)DomElement).GetElementsByClassName(str)); + } - #endregion - } - - /// <summary> - /// Represents a DOM window. - /// </summary> - public class GeckoWindow - { - private GeckoWindow(nsIDOMWindow window) - { - _DomWindow = window; - } - - /// <summary> - /// Gets the underlying unmanaged DOM object. - /// </summary> - public object DomWindow - { - get { return _DomWindow; } - } - nsIDOMWindow _DomWindow; - - internal static GeckoWindow Create(nsIDOMWindow window) - { - return (window == null) ? null : new GeckoWindow(window); - } - - /// <summary> - /// Gets the document displayed in the window. - /// </summary> - public GeckoDocument Document - { - get { return GeckoDocument.Create((nsIDOMHTMLDocument)_DomWindow.GetDocument()); } - } - - /// <summary> - /// Gets the parent window of this one. - /// </summary> - public GeckoWindow Parent - { - get { return GeckoWindow.Create((nsIDOMWindow)_DomWindow.GetParent()); } - } + /// <summary> + /// Gets a rectangle which represents the union of all bounding rectangles within the element. + /// </summary> + public RectangleF BoundingClientRect + { + get + { + nsIDOMNSElement ns = (nsIDOMNSElement)DomElement; + nsIDOMClientRect rect = ns.GetBoundingClientRect(); + return RectangleF.FromLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom()); + } + } - public int ScrollX - { - get { return _DomWindow.GetScrollX(); } - } - - public int ScrollY - { - get { return _DomWindow.GetScrollY(); } - } + /// <summary> + /// Returns an array containing all bounding rectangles within the element. + /// </summary> + /// <returns></returns> + public RectangleF[] GetClientRects() + { + nsIDOMNSElement ns = (nsIDOMNSElement)DomElement; + nsIDOMClientRectList rects = ns.GetClientRects(); + RectangleF[] result = new RectangleF[rects.GetLength()]; + for (int i = 0; i < result.Length; i++) + { + nsIDOMClientRect rect = rects.Item(i); + result[i] = RectangleF.FromLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), rect.GetBottom()); + } + return result; + } +#endif + } - public float TextZoom - { - get { return _DomWindow.GetTextZoom(); } - set { _DomWindow.SetTextZoom(value); } - } + /// <summary> + /// Represents a DOM document. + /// </summary> + public class GeckoDocument : GeckoNode + { + internal GeckoDocument(nsIDOMHTMLDocument document) + : base(document) + { + this.DomDocument = document; + } - public void ScrollTo(int x, int y) + internal static GeckoDocument Create(nsIDOMHTMLDocument document) + { + return (document == null) ? null : new GeckoDocument(document); + } + + nsIDOMHTMLDocument DomDocument; + + /// <summary> + /// Gets the document title. + /// </summary> + public string Title + { + get { return nsString.Get(DomDocument.GetTitle); } + set { nsString.Set(DomDocument.SetTitle, value); } + } + + /// <summary> + /// Gets the HTML body element. + /// </summary> + public GeckoElement Body + { + get { return GeckoElement.Create(DomDocument.GetBody()); } + } + + /// <summary> + /// Gets the top-level document element (for HTML documents, this is the html tag). + /// </summary> + public GeckoElement DocumentElement + { + get { return GeckoElement.Create((nsIDOMHTMLElement)DomDocument.GetDocumentElement()); } + } + + /// <summary> + /// Searches for and returns the element in the document with the given id. + /// </summary> + /// <param name="id"></param> + /// <returns></returns> + public GeckoElement GetElementById(string id) + { + if (string.IsNullOrEmpty(id)) + return null; + + return GeckoElement.Create((nsIDOMHTMLElement)DomDocument.GetElementById(new nsAString(id))); + } + + /// <summary> + /// Represents a collection of style sheets in a <see cref="GeckoDocument"/>. + /// </summary> + public class StyleSheetCollection : IEnumerable<GeckoStyleSheet> + { + internal StyleSheetCollection(GeckoDocument document) + { + this.List = ((nsIDOMDocumentStyle)document.DomDocument).GetStyleSheets(); + } + nsIDOMStyleSheetList List; + + /// <summary> + /// Gets the number of items in the collection. + /// </summary> + public int Count + { + get { return (List == null) ? 0 : List.GetLength(); } + } + + /// <summary> + /// Gets the item at the specified index in the collection. + /// </summary> + /// <param name="index"></param> + /// <returns></returns> + public GeckoStyleSheet this[int index] + { + get + { + if (index < 0 || index >= Count) + throw new ArgumentOutOfRangeException("index"); + + return GeckoStyleSheet.Create((nsIDOMCSSStyleSheet)List.Item(index)); + } + } + + #region IEnumerable<GeckoStyleSheet> Members + + /// <summary> + /// Returns an <see cref="IEnumerator{GeckoStyleSheet}"/> which can enumerate through the collection. + /// </summary> + /// <returns></returns> + public IEnumerator<GeckoStyleSheet> GetEnumerator() + { + int length = Count; + for (int i = 0; i < length; i++) + { + yield return GeckoStyleSheet.Create((nsIDOMCSSStyleSheet)List.Item(i)); + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + ... [truncated message content] |