예제 #1
0
        /// <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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        /// <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);
        }