///////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> protected CHtmlNode(CHtmlNode obj) { System.Diagnostics.Debug.Assert(obj != null); obj.AssertValid(); m_parent = obj.m_parent; m_nodeID = obj.m_nodeID; m_bindObject = obj.m_bindObject; }
private void FindLink(CHtmlNodeCollection parentNodes, ref CHtmlNodeCollection links) { if (parentNodes == null || parentNodes.Count == 0) { return; } CHtmlAttribute attr; foreach (CHtmlNode node in parentNodes) { if (node is CHtmlElement) { if (node == null) { continue; } attr = null; CHtmlElement element = node as CHtmlElement; switch (element.Name.Trim().ToLower()) { case "a": case "link": case "frame": attr = element.Attributes["href"]; break; case "script": attr = element.Attributes["src"]; break; } if (attr != null) { links.Add(node); } if (element.Nodes.Count > 0) { FindLink(element.Nodes, ref links); } } } }
/////////////////////////////////////////////////////////////////////////////// /// <summary> /// ������ /// </summary> public CHtmlElement(CHtmlElement obj) : base(obj) { System.Diagnostics.Debug.Assert(obj != null); obj.AssertValid(); m_name = obj.m_name; m_nodes = new CHtmlNodeCollection(this); int count = obj.m_nodes.Count; m_nodes.Capacity = count; for(int index = 0; index < count; ++index) m_nodes.Add((CHtmlNode)obj.m_nodes[index].Clone()); count = obj.m_attributes.Count; m_attributes.Capacity = count; for(int index = 0; index < count; ++index) m_attributes.Add((CHtmlAttribute)obj.m_attributes[index].Clone()); }
/////////////////////////////////////////////////////////////////////////////// /// <summary> /// »ý¼ºÀÚ /// </summary> public CHtmlElement(CHtmlElement obj) : base(obj) { System.Diagnostics.Debug.Assert(obj != null); obj.AssertValid(); m_name = obj.m_name; m_nodes = new CHtmlNodeCollection(this); int count = obj.m_nodes.Count; m_nodes.Capacity = count; for (int index = 0; index < count; ++index) { m_nodes.Add((CHtmlNode)obj.m_nodes[index].Clone()); } count = obj.m_attributes.Count; m_attributes.Capacity = count; for (int index = 0; index < count; ++index) { m_attributes.Add((CHtmlAttribute)obj.m_attributes[index].Clone()); } }
///////////////////////////////////////////////////////////////////////////////// #region ///////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /// <param name="htmlStream"></param> /// <returns></returns> private Encoding DetectCharset(CHtmlNodeCollection nodes) { Encoding result = null; string charset = ""; CHtmlNodeCollection metaNodes = new CHtmlNodeCollection(); CHtmlElement node = nodes["html"] as CHtmlElement; if (node != null) { node = node.Nodes["head"] as CHtmlElement; } if (node != null) { node.Nodes.FindByNameAttribute(metaNodes, "meta", "content", false); } for (int nodeIndex = 0, count = metaNodes.Count; nodeIndex < count; ++nodeIndex) { CHtmlElement metaElement = metaNodes[nodeIndex] as CHtmlElement; if (metaElement != null) { int index = -1; CHtmlAttributeCollection attributes = metaElement.Attributes.FindByName("content"); for (int attributeIndex = 0, attributeCount = attributes.Count; attributeIndex < attributeCount; ++attributeIndex) { CHtmlAttribute attribute = attributes[attributeIndex]; if ((index = attribute.Value.IndexOf("charset")) != -1) { string value = attribute.Value; int startIndex = index + 7; while (startIndex < value.Length && CHtmlUtil.EqualesOfAnyChar(value[startIndex], " =")) { ++startIndex; } int endIndex = startIndex + 1; while (endIndex < value.Length && !CHtmlUtil.EqualesOfAnyChar(value[endIndex], " ")) { ++endIndex; } if (startIndex < value.Length && endIndex - startIndex > 0) { charset = value.Substring(startIndex, endIndex - startIndex); try { result = Encoding.GetEncoding(charset); break; } catch (Exception) { } } } } } } return(result); }
///////////////////////////////////////////////////////////////////////////////// /// <summary> /// A collection is usually associated with a parent node (an CHtmlElement, actually) /// but you can pass null to implement an abstracted collection. /// </summary> /// <param name="element"></param> internal CHtmlNodeCollection(CHtmlElement element) : base() { m_ownerNode = element; }
///////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /// <param name="visitor"></param> /// <param name="nodeIDCount"></param> /// <returns></returns> private void ResolveElement(ref int visitor, ref int nodeIDCount) { System.Diagnostics.Debug.Assert(m_tokens[visitor].Type == Token.TokenType.TagName); CHtmlElement element = new CHtmlElement(m_tokens[visitor].Content); element.m_close = false; ++nodeIDCount; element.NodeID = nodeIDCount; ++visitor; ResolveAttribute(ref visitor, element.Attributes); System.Diagnostics.Debug.Assert(m_tokens[visitor].Type == Token.TokenType.TagEnd || m_tokens[visitor].Type == Token.TokenType.TagCloseEnd); if(m_tokens[visitor].Type == Token.TokenType.TagEnd) // <tag> { switch(element.Name) { // Empty tag case "area": case "bgsound": case "base": case "br": case "basefont": case "col": case "embed": case "frame": case "hr": case "img": case "isindex": case "input": case "keygen": case "link": case "meta": case "nextid": case "option": case "param": case "sound": case "spacer": case "wbr": element.TerminatedType = CHtmlElement.EndTagType.NonTerminated; CloseElement(element); if(ElementCreatedEvent != null) ElementCreatedEvent(element); m_currentLevel.Add(element); break; default: { element.m_previousWithSameNameNode = (CHtmlElement)m_lastOpenNodes[element.Name]; m_lastOpenNodes[element.Name] = element; if(ElementCreatedEvent != null) ElementCreatedEvent(element); m_currentLevel.Add(element); m_currentLevel = element.Nodes; } break; } } else // <tag/> { element.TerminatedType = CHtmlElement.EndTagType.Terminated; CloseElement(element); if(ElementCreatedEvent != null) ElementCreatedEvent(element); m_currentLevel.Add(element); } ++visitor; }
///////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /// <param name="element"></param> private void CloseElement(CHtmlElement element) { System.Diagnostics.Debug.Assert(element != null); System.Diagnostics.Debug.Assert(element.m_close == false); /* for(int index = element.Nodes.Count - 1; index >= 0; --index) { CHtmlElement childElement = element.Nodes[index] as CHtmlElement; if(childElement != null && childElement.m_close == false) CloseElement(childElement); } */ if(m_lastOpenNodes[element.Name] == element) m_lastOpenNodes[element.Name] = element.m_previousWithSameNameNode; element.m_close = true; element.m_previousWithSameNameNode = null; }