/// <summary> /// Utility for properly printing the start tag for an element. /// This utility takes care of including/suppressing attributes and namespaces properly. /// </summary> /// <param name="writer"></param> /// <param name="element"></param> private static void printElementStart(HtmlWriter writer, IHTMLElement element) { string tagName = element.tagName; // If there is no tag name, this is mostly an artificial tag reported by mshtml, // and not really present in the markup // (e.g HTMLTableCaptionClass) if (string.IsNullOrEmpty(tagName)) { return; } //XHTML tags are all lowercase tagName = tagName.ToLower(CultureInfo.InvariantCulture); //this is a standard HTML tag, so just write it out. writer.WriteStartElement(tagName); IHTMLDOMNode node = element as IHTMLDOMNode; IHTMLAttributeCollection attrs = node.attributes as IHTMLAttributeCollection; if (attrs != null) { foreach (IHTMLDOMAttribute attr in attrs) { string attrName = attr.nodeName as string; if (attr.specified) { string attrNameLower = attrName.ToLower(CultureInfo.InvariantCulture); //get the raw attribute value (so that IE doesn't try to expand out paths in the value). string attrValue = element.getAttribute(attrName, 2) as string; if (attrValue == null) { //IE won't return some attributes (like class) using IHTMLElement.getAttribute(), //so if the value is null, try to get the value directly from the DOM Attribute. //Note: we can't use the DOM value by default, because IE will rewrite the value //to contain a fully-qualified path on some attributes (like src and href). attrValue = attr.nodeValue as string; if (attrValue == null) { if ((attrNameLower == "hspace" || attrNameLower == "vspace") && attr.nodeValue is int) { attrValue = ((int)attr.nodeValue).ToString(CultureInfo.InvariantCulture); } else if (attrNameLower == "style") { //Avoid bug: Images that are resized with the editor insert a STYLE attribute. //IE won't return the style attribute using the standard API, so we have to grab //it from the style object attrValue = element.style.cssText; } else if (attrNameLower == "colspan") { attrValue = (element as IHTMLTableCell).colSpan.ToString(CultureInfo.InvariantCulture); } else if (attrNameLower == "rowspan") { attrValue = (element as IHTMLTableCell).rowSpan.ToString(CultureInfo.InvariantCulture); } else if (attrNameLower == "align" && attr.nodeValue is int) { // This is not documented anywhere. Just discovered the values empirically on IE7 (Vista). switch ((int)attr.nodeValue) { case 1: attrValue = "left"; break; case 2: attrValue = "center"; break; case 3: attrValue = "right"; break; case 4: attrValue = "texttop"; break; case 5: attrValue = "absmiddle"; break; case 6: attrValue = "baseline"; break; case 7: attrValue = "absbottom"; break; case 8: attrValue = "bottom"; break; case 9: attrValue = "middle"; break; case 10: attrValue = "top"; break; } } } Debug.WriteLineIf(attrValue != null && attrName != "id", String.Format(CultureInfo.InvariantCulture, "{0}.{1} attribute value not retreived", tagName, attrName), element.outerHTML); } // Minimized attributes are not allowed, according // to section 4.5 of XHTML 1.0 specification. // TODO: Deal with simple values that are not strings if (attrValue == null && attrNameLower != "id") { attrValue = attrName; } if (attrName != null && attrValue != null) { //write out this attribute. writer.WriteAttributeString(attrName, attrValue); } } } } }
/// <summary> /// Utility for properly printing the start tag for an element. /// This utility takes care of including/suppresing attributes and namespaces properly. /// </summary> /// <param name="writer"></param> /// <param name="element"></param> private static void printElementStart(HtmlWriter writer, IHTMLElement element) { string tagName = element.tagName; // If there is no tag name, this is mostly an artificial tag reported by mshtml, // and not really present in the markup // (e.g HTMLTableCaptionClass) if (string.IsNullOrEmpty(tagName)) { return; } //XHTML tags are all lowercase tagName = tagName.ToLower(CultureInfo.InvariantCulture); //this is a standard HTML tag, so just write it out. writer.WriteStartElement(tagName); IHTMLDOMNode node = element as IHTMLDOMNode; IHTMLAttributeCollection attrs = node.attributes as IHTMLAttributeCollection; if (attrs != null) { foreach (IHTMLDOMAttribute attr in attrs) { string attrName = attr.nodeName as string; if (attr.specified) { string attrNameLower = attrName.ToLower(CultureInfo.InvariantCulture); //get the raw attribute value (so that IE doesn't try to expand out paths in the value). string attrValue = element.getAttribute(attrName, 2) as string; if (attrValue == null) { //IE won't return some attributes (like class) using IHTMLElement.getAttribute(), //so if the value is null, try to get the value directly from the DOM Attribute. //Note: we can't use the DOM value by default, because IE will rewrite the value //to contain a fully-qualified path on some attribures (like src and href). attrValue = attr.nodeValue as string; if (attrValue == null) { if ((attrNameLower == "hspace" || attrNameLower == "vspace") && attr.nodeValue is int) { attrValue = ((int)attr.nodeValue).ToString(CultureInfo.InvariantCulture); } else if (attrNameLower == "style") { //Avoid bug: Images that are resized with the editor insert a STYLE attribute. //IE won't return the style attribute using the standard API, so we have to grab //it from the style object attrValue = element.style.cssText; } else if (attrNameLower == "colspan") { attrValue = (element as IHTMLTableCell).colSpan.ToString(CultureInfo.InvariantCulture); } else if (attrNameLower == "rowspan") { attrValue = (element as IHTMLTableCell).rowSpan.ToString(CultureInfo.InvariantCulture); } else if (attrNameLower == "align" && attr.nodeValue is int) { // This is not documented anywhere. Just discovered the values empirically on IE7 (Vista). switch ((int)attr.nodeValue) { case 1: attrValue = "left"; break; case 2: attrValue = "center"; break; case 3: attrValue = "right"; break; case 4: attrValue = "texttop"; break; case 5: attrValue = "absmiddle"; break; case 6: attrValue = "baseline"; break; case 7: attrValue = "absbottom"; break; case 8: attrValue = "bottom"; break; case 9: attrValue = "middle"; break; case 10: attrValue = "top"; break; } } } Debug.WriteLineIf(attrValue != null && attrName != "id", String.Format(CultureInfo.InvariantCulture, "{0}.{1} attribute value not retreived", tagName, attrName), element.outerHTML); } // Minimized attributes are not allowed, according // to section 4.5 of XHTML 1.0 specification. // TODO: Deal with simple values that are not strings if (attrValue == null && attrNameLower != "id") attrValue = attrName; if (attrName != null && attrValue != null) { //write out this attribute. writer.WriteAttributeString(attrName, attrValue); } } } } }