public void ApplyCssText(string cssText) { if (!string.IsNullOrEmpty(cssText)) { var stylesheet = CSSParser.ParseCSSStyleSheet(cssText, string.Empty, true); this.ApplyCssRules(stylesheet.cssRules, string.Empty); } }
/// <summary> /// parse and download the stylesheets and make them available at StyleSheets. /// </summary> public void ParseStyleSheet() { HTMLCollection styletags = this.getElementsByTagName("link, style"); HTMLCollection availablesheets = new HTMLCollection(); foreach (var item in styletags.item) { if (item.tagName == "style") { availablesheets.Add(item); } else if (item.hasAttribute("type")) { if (item.getAttribute("type").ToLower().Contains("css")) { availablesheets.Add(item); } } else if (item.hasAttribute("rel")) { if (item.getAttribute("rel").ToLower().Contains("stylesheet")) { availablesheets.Add(item); } } } foreach (var item in availablesheets.item) { if (item.tagName == "link") { string href = item.getAttribute("href"); if (string.IsNullOrEmpty(href)) { continue; } string absoluteUrl = PathHelper.combine(this.getBaseUrl(), href); string cssText = Loader.LoadCss(absoluteUrl); if (string.IsNullOrEmpty(cssText)) { continue; } CSSStyleSheet newStyleSheet = CSSParser.ParseCSSStyleSheet(cssText, absoluteUrl, true); newStyleSheet.ownerNode = item; if (newStyleSheet != null) { newStyleSheet.ownerNode = item; string media = item.getAttribute("media"); if (!string.IsNullOrEmpty(media)) { string[] medialist = media.Split(','); foreach (var mediaitem in medialist) { newStyleSheet.Medialist.appendMedium(mediaitem); } } this.StyleSheets.appendStyleSheet(newStyleSheet); } } else if (item.tagName == "style") { string cssText = item.InnerHtml; CSSStyleSheet newStyleSheet = CSSParser.ParseCSSStyleSheet(cssText, this.getBaseUrl(), true); newStyleSheet.ownerNode = item; string media = item.getAttribute("media"); if (!string.IsNullOrEmpty(media)) { string[] medialist = media.Split(','); foreach (var mediaitem in medialist) { newStyleSheet.Medialist.appendMedium(mediaitem); } } this.StyleSheets.appendStyleSheet(newStyleSheet); } } hasParseCSS = true; }
/// <summary> /// The @import at-rule is a simple statement. After its name, it takes a single string or url() function to indicate the stylesheet that it should import. /// </summary> /// <param name="rule"></param> /// <returns></returns> private static CSSRule ParseImportRule(AtRule rule, string baseurl, bool downloadImportRule, ref string OriginalCss) { /// the import starts with import atkeyword token. /// it should have been checked before calling this method, can be ignored. PreservedToken token = rule.prelude[0] as PreservedToken; int count = rule.prelude.Count; CSSImportRule importrule = new CSSImportRule(); string media = string.Empty; int startindex = -1; int endindex = -1; for (int i = 0; i < count; i++) { if (startindex < 0) { startindex = rule.prelude[i].startindex; } if (rule.prelude[i].endindex > endindex) { endindex = rule.prelude[i].endindex; } if (rule.prelude[i].Type == CompoenentValueType.preservedToken) { PreservedToken preservedToken = rule.prelude[i] as PreservedToken; /// ignore the whitespace and at-keyword token. if (preservedToken.token.Type == enumTokenType.at_keyword || (string.IsNullOrEmpty(importrule.href) && preservedToken.token.Type == enumTokenType.whitespace)) { continue; } if (string.IsNullOrEmpty(importrule.href)) { if (preservedToken.token.Type == enumTokenType.String) { string_token stringtoken = preservedToken.token as string_token; string url = string.Empty; if (string.IsNullOrEmpty(baseurl)) { url = stringtoken.value; } else { url = PathHelper.combine(baseurl, stringtoken.value); } importrule.href = url; if (downloadImportRule && !string.IsNullOrEmpty(url)) { importrule.stylesheet = CSSParser.ParseCSSStyleSheetFromUrl(url); } } else if (preservedToken.token.Type == enumTokenType.url) { url_token urltoken = preservedToken.token as url_token; string url = string.Empty; if (string.IsNullOrEmpty(baseurl)) { url = urltoken.value; } else { url = PathHelper.combine(baseurl, urltoken.value); } importrule.href = url; if (downloadImportRule && !string.IsNullOrEmpty(url)) { importrule.stylesheet = CSSParser.ParseCSSStyleSheetFromUrl(url); } } else { // must start with a string or url token as the next. string error = "this is an error"; } } else { // the import rule has href already, next is the media rules. if (preservedToken.token.Type == enumTokenType.comma || preservedToken.token.Type == enumTokenType.semicolon) { if (!string.IsNullOrEmpty(media)) { importrule.media.appendMedium(media.Trim()); media = string.Empty; } } else { // can be delim token. if (string.IsNullOrEmpty(media) && preservedToken.token.Type == enumTokenType.whitespace) { // the start of whitespace will be ignored. } else { media += preservedToken.token.GetString(ref OriginalCss); } } } } else if (rule.prelude[i].Type == CompoenentValueType.function) { Function urlfunction = rule.prelude[i] as Function; string href = string.Empty; if (urlfunction.name == "url") { foreach (var item in urlfunction.value) { if (item.Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = item as PreservedToken; if (pretoken.token.Type == enumTokenType.String) { string_token stringtoken = pretoken.token as string_token; href += stringtoken.value; } } } } if (!string.IsNullOrEmpty(href)) { importrule.href = href; } } else if (rule.prelude[i].Type == CompoenentValueType.simpleBlock) { // simple block is the block like screen and (min-width:300); SimpleBlock block = rule.prelude[i] as SimpleBlock; string mediarule = string.Empty; foreach (var item in block.value) { if (item.Type == CompoenentValueType.preservedToken) { PreservedToken pretoken = item as PreservedToken; mediarule += pretoken.token.GetString(ref OriginalCss); if (token.token.endIndex > endindex) { endindex = token.token.endIndex; } } } if (block.token.Type == enumTokenType.round_bracket_left || block.token.Type == enumTokenType.round_bracket_right) { mediarule = "(" + mediarule + ")"; } else if (block.token.Type == enumTokenType.square_bracket_left || block.token.Type == enumTokenType.square_bracket_right) { mediarule = "[" + mediarule + "]"; } else if (block.token.Type == enumTokenType.curly_bracket_left || block.token.Type == enumTokenType.curly_bracket_right) { mediarule = "{" + mediarule + "}"; } media += mediarule; } } if (!string.IsNullOrEmpty(media)) { importrule.media.appendMedium(media.Trim()); media = string.Empty; } importrule.StartIndex = startindex; if (rule.endindex > endindex) { endindex = rule.endindex; } importrule.EndIndex = endindex; int endselectorindex = rule.prelude[0].endindex + 1; ///import rule does not have one extra char like { // importrule.EndSelectorIndex = endselectorindex - importrule.StartIndex + 1; importrule.EndSelectorIndex = endselectorindex - importrule.StartIndex; return(importrule); }