/// <summary> /// Creates a new @import-rule from the given source. /// </summary> /// <param name="source">The token iterator.</param> /// <returns>The @import-rule.</returns> CSSImportRule CreateImportRule(IEnumerator <CssToken> source) { var import = new CSSImportRule(); import.ParentStyleSheet = sheet; import.ParentRule = CurrentRule; open.Push(import); switch (source.Current.Type) { case CssTokenType.Semicolon: source.MoveNext(); break; case CssTokenType.String: case CssTokenType.Url: import.Href = ((CssStringToken)source.Current).Data; AppendMediaList(source, import.Media, CssTokenType.Semicolon); //TODO //import.StyleSheet = DocumentBuilder.Css(new Uri(import.Href)); break; default: SkipToNextSemicolon(source); break; } open.Pop(); return(import); }
public static CSSImportRule ConvertToCSSImportRule(AntlrModel.Import import, string basePath = "") { var importRule = new CSSImportRule(); importRule.cssText = import.Serialize(); var _href = PathHelper.ParseHref(import.Value); importRule.href = PathHelper.combine(basePath, _href); foreach (var m in import.Medium) { importRule.media.appendMedium(m); } //提供stylesheet.href属性,在访问cssText时就会去下载远程css文件。 //一解析就下载也浪费性能,如果需要完整的stylesheet对象,可以: //importRule.stylesheet=ConvertToCSSStyleSheet(importRule.stylesheet.cssText) importRule.stylesheet = new CSSStyleSheet() { href = importRule.href }; return(importRule); }
public static List <CssConvertResult> ConvertCss(CSSRuleList rulelist, Guid ParentStyleId, Guid ParentCssRuleId = default(Guid)) { List <CssConvertResult> Result = new List <CssConvertResult>(); int counter = rulelist.item.Count; for (int i = 0; i < counter; i++) { CmsCssRule cmsrule = new CmsCssRule(); cmsrule.ParentCssRuleId = ParentCssRuleId; cmsrule.ParentStyleId = ParentStyleId; cmsrule.OwnerObjectId = ParentStyleId; cmsrule.OwnerObjectConstType = ConstObjectType.Style; cmsrule.TempCssRuleIndex = i; CSSRule item = rulelist.item[i]; cmsrule.selectorPositionIndex = item.EndSelectorIndex; if (item.type == enumCSSRuleType.STYLE_RULE) { CSSStyleRule stylerule = item as CSSStyleRule; cmsrule.CssText = stylerule.cssText; cmsrule.ruleType = RuleType.StyleRule; cmsrule.Properties = stylerule.style.item.Where(o => o != null && !string.IsNullOrWhiteSpace(o.propertyname)).Select(o => o.propertyname).ToList(); } else if (item.type == enumCSSRuleType.IMPORT_RULE) { CSSImportRule importrule = item as CSSImportRule; cmsrule.CssText = importrule.cssText; cmsrule.ruleType = RuleType.ImportRule; } else if (item.type == enumCSSRuleType.MEDIA_RULE) { CSSMediaRule mediarule = item as CSSMediaRule; cmsrule.CssText = mediarule.cssText; cmsrule.ruleType = RuleType.MediaRule; } else if (item.type == enumCSSRuleType.FONT_FACE_RULE) { CSSFontFaceRule facerule = item as CSSFontFaceRule; cmsrule.CssText = facerule.cssText; cmsrule.ruleType = RuleType.FontFaceRule; } else { continue; } /// check duplicate in the current collections. cmsrule.DuplicateIndex = CssService.GetDuplicateIndex(Result, cmsrule.SelectorText, cmsrule.ruleType); CssConvertResult converted = new CssConvertResult(); converted.RuleId = cmsrule.Id; converted.CmsRule = cmsrule; converted.CssRule = item; Result.Add(converted); if (item.type == enumCSSRuleType.MEDIA_RULE) { var mediarule = item as Kooboo.Dom.CSS.CSSMediaRule; var sub = ConvertCss(mediarule.cssRules, ParentStyleId, cmsrule.Id); if (sub != null && sub.Count() > 0) { Result.AddRange(sub); } } } return(Result); }
/// <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); }