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)
{
this.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)
{
this.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++;
}
}
}
}