public void DiscoverStyleDefinitions(XmlElement htmlElement)
{
if (htmlElement.LocalName.ToLower() == "link") {
return;
// Add LINK elements processing for included stylesheets
// <LINK href="http://sc.msn.com/global/css/ptnr/orange.css" type=text/css \r\nrel=stylesheet>
}
if (htmlElement.LocalName.ToLower() != "style") {
// This is not a STYLE element. Recurse into it
for (XmlNode htmlChildNode = htmlElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling) {
if (htmlChildNode is XmlElement) {
DiscoverStyleDefinitions((XmlElement) htmlChildNode);
}
}
return;
}
// Add style definitions from this style.
// Collect all text from this style definition
StringBuilder stylesheetBuffer = new StringBuilder();
for (XmlNode htmlChildNode = htmlElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling) {
if (htmlChildNode is XmlText || htmlChildNode is XmlComment) {
stylesheetBuffer.Append(RemoveComments(htmlChildNode.Value));
}
}
// CssStylesheet has the following syntactical structure:
// @import declaration;
// selector { definition }
// where "selector" is one of: ".classname", "tagname"
// It can contain comments in the following form: /*...*/
int nextCharacterIndex = 0;
while (nextCharacterIndex < stylesheetBuffer.Length) {
// Extract selector
int selectorStart = nextCharacterIndex;
while (nextCharacterIndex < stylesheetBuffer.Length && stylesheetBuffer[nextCharacterIndex] != '{') {
// Skip declaration directive starting from @
if (stylesheetBuffer[nextCharacterIndex] == '@') {
while (nextCharacterIndex < stylesheetBuffer.Length && stylesheetBuffer[nextCharacterIndex] != ';') {
nextCharacterIndex++;
}
selectorStart = nextCharacterIndex + 1;
}
nextCharacterIndex++;
}
if (nextCharacterIndex < stylesheetBuffer.Length) {
// Extract definition
int definitionStart = nextCharacterIndex;
while (nextCharacterIndex < stylesheetBuffer.Length && stylesheetBuffer[nextCharacterIndex] != '}') {
nextCharacterIndex++;
}
// Define a style
if (nextCharacterIndex - definitionStart > 2) {
AddStyleDefinition(
stylesheetBuffer.ToString(selectorStart, definitionStart - selectorStart),
stylesheetBuffer.ToString(definitionStart + 1, nextCharacterIndex - definitionStart - 2));
}
// Skip closing brace
if (nextCharacterIndex < stylesheetBuffer.Length) {
Debug.Assert(stylesheetBuffer[nextCharacterIndex] == '}');
nextCharacterIndex++;
}
}
}
}