Example #1
0
        private static CSSRule ParseAtRule(AtRule rule, CSSStyleSheet parentSheet, string baseurl, bool downloadImportRule, ref string OriginalCss)
        {
            /// the first item in rule is the atkeyword.

            if (rule.prelude[0].Type == CompoenentValueType.preservedToken)
            {
                PreservedToken token = rule.prelude[0] as PreservedToken;
                if (token.token.Type == enumTokenType.at_keyword)
                {
                    at_keyword_token keywordToken = token.token as at_keyword_token;

                    if (keywordToken.value.ToLower() == "import")
                    {
                        return(ParseImportRule(rule, baseurl, downloadImportRule, ref OriginalCss));
                    }
                    else if (keywordToken.value.ToLower() == "media")
                    {
                        return(ParseMediaRule(rule, parentSheet, ref OriginalCss));
                    }
                    else if (keywordToken.value.ToLower() == "font-face")
                    {
                        return(ParseFontFace(rule, ref OriginalCss));
                    }
                }
            }

            return(null);
        }
Example #2
0
        public static List <UrlInfo> GetUrlInfos(string CssText)
        {
            List <UrlInfo> urllist = new List <UrlInfo>();

            if (string.IsNullOrEmpty(CssText))
            {
                return(urllist);
            }

            Kooboo.Dom.CSS.Tokenizer toknizer = new Kooboo.Dom.CSS.Tokenizer(CssText);

            while (true)
            {
                cssToken token = toknizer.ConsumeNextToken();

                if (token == null || token.Type == enumTokenType.EOF)
                {
                    break;
                }
                else
                {
                    if (token.Type == enumTokenType.url)
                    {
                        url_token urltoken    = token as url_token;
                        string    resourceurl = urltoken.value;
                        if (!string.IsNullOrEmpty(resourceurl))
                        {
                            urllist.Add(new UrlInfo()
                            {
                                StartIndex = urltoken.startIndex, EndIndex = urltoken.endIndex, RawUrl = resourceurl, isUrlToken = true
                            });
                        }
                    }
                    else if (token.Type == enumTokenType.at_keyword)
                    {
                        at_keyword_token keywordtoken = token as at_keyword_token;
                        if (keywordtoken.value.ToLower() == "import")
                        {
                            cssToken nexttoken = toknizer.ConsumeNextToken();
                            while (nexttoken.Type == enumTokenType.whitespace)
                            {
                                nexttoken = toknizer.ConsumeNextToken();
                            }

                            if (nexttoken.Type == enumTokenType.String)
                            {
                                string_token stringtoken = nexttoken as string_token;

                                if (!string.IsNullOrEmpty(stringtoken.value))
                                {
                                    urllist.Add(new UrlInfo()
                                    {
                                        StartIndex = stringtoken.startIndex, EndIndex = stringtoken.endIndex, RawUrl = stringtoken.value, isImportRule = true
                                    });
                                }
                            }
                            else if (nexttoken.Type == enumTokenType.url)
                            {
                                url_token urltoken    = nexttoken as url_token;
                                string    resourceurl = urltoken.value;
                                if (!string.IsNullOrEmpty(resourceurl))
                                {
                                    urllist.Add(new UrlInfo()
                                    {
                                        StartIndex = urltoken.startIndex, EndIndex = urltoken.endIndex, RawUrl = resourceurl, isUrlToken = true, isImportRule = true
                                    });
                                }
                            }

                            else if (nexttoken.Type == enumTokenType.function)
                            {
                                function_token functoken = nexttoken as function_token;

                                string functionvalue = functoken.Value;
                                if (functionvalue.ToLower() == "url")
                                {
                                    nexttoken = toknizer.ConsumeNextToken();
                                    while (nexttoken.Type == enumTokenType.whitespace)
                                    {
                                        nexttoken = toknizer.ConsumeNextToken();
                                    }
                                    if (nexttoken == null || nexttoken.Type == enumTokenType.EOF)
                                    {
                                        break;
                                    }

                                    if (nexttoken.Type == enumTokenType.String)
                                    {
                                        string_token stringtoken = nexttoken as string_token;

                                        if (!string.IsNullOrEmpty(stringtoken.value))
                                        {
                                            urllist.Add(new UrlInfo()
                                            {
                                                StartIndex = stringtoken.startIndex, EndIndex = stringtoken.endIndex, RawUrl = stringtoken.value, isImportRule = true
                                            });
                                        }
                                    }
                                    else if (nexttoken.Type == enumTokenType.url)
                                    {
                                        url_token urltoken    = nexttoken as url_token;
                                        string    resourceurl = urltoken.value;
                                        if (!string.IsNullOrEmpty(resourceurl))
                                        {
                                            urllist.Add(new UrlInfo()
                                            {
                                                StartIndex = urltoken.startIndex, EndIndex = urltoken.endIndex, RawUrl = resourceurl, isUrlToken = true, isImportRule = true
                                            });
                                        }
                                    }
                                }
                            }
                        }
                    }

                    else if (token.Type == enumTokenType.function)
                    {
                        function_token functoken = token as function_token;

                        string functionvalue = functoken.Value;
                        if (functionvalue.ToLower() == "url")
                        {
                            cssToken nexttoken = toknizer.ConsumeNextToken();
                            while (nexttoken.Type == enumTokenType.whitespace)
                            {
                                nexttoken = toknizer.ConsumeNextToken();
                            }
                            if (nexttoken == null || nexttoken.Type == enumTokenType.EOF)
                            {
                                break;
                            }

                            if (nexttoken.Type == enumTokenType.String)
                            {
                                string_token stringtoken = nexttoken as string_token;

                                if (!string.IsNullOrEmpty(stringtoken.value))
                                {
                                    urllist.Add(new UrlInfo()
                                    {
                                        StartIndex = stringtoken.startIndex, EndIndex = stringtoken.endIndex, RawUrl = stringtoken.value
                                    });
                                }
                            }
                        }
                    }
                }
            }

            return(cleanSpecialMark(urllist));
        }
Example #3
0
        /// <summary>
        /// consume a list of cssrule from simpleblock,
        /// Recursive.
        /// </summary>
        /// <param name="block"></param>
        /// <returns></returns>
        private static CSSRuleList ParseMediaRuleList(SimpleBlock block, ref int endindex, CSSMediaRule parentmediarule, ref string OriginalCss)
        {
            int         count    = block.value.Count;
            CSSRuleList rulelist = new CSSRuleList();

            MediaRuleParseState state = MediaRuleParseState.init;

            CSSStyleRule stylerule = null;
            CSSMediaRule mediarule = null;

            string media = string.Empty;
            string wholeconditiontext = string.Empty;

            int startindex = -1;

            for (int i = 0; i < count; i++)
            {
                if (block.value[i].endindex > endindex)
                {
                    endindex = block.value[i].endindex;
                }

                if (startindex < 0)
                {
                    startindex = block.value[i].startindex;
                }

                switch (state)
                {
                case MediaRuleParseState.init:
                {
                    if (block.value[i].Type == CompoenentValueType.preservedToken)
                    {
                        PreservedToken pretoken = block.value[i] as PreservedToken;

                        if (pretoken.token.Type == enumTokenType.whitespace)
                        {
                            // ignored whitespace at the beginning.
                        }
                        else if (pretoken.token.Type == enumTokenType.at_keyword)
                        {
                            // at keyword token, only handle media now.
                            // others to be added.
                            at_keyword_token token = pretoken.token as at_keyword_token;
                            if (token.value.ToLower() == "media")
                            {
                                state = MediaRuleParseState.mediarule;
                                i     = i - 1;     // reconsume to have correct startindex.
                            }
                            else
                            {
                                // other at rules.
                                state = MediaRuleParseState.OtherAtRule;
                                i     = i - 1;
                            }
                        }

                        /// else treat as regular style rule.
                        else
                        {
                            state = MediaRuleParseState.stylerule;
                            i     = i - 1;     // reconsume.
                        }
                    }
                    break;
                }

                case MediaRuleParseState.stylerule:
                {
                    if (stylerule == null)
                    {
                        stylerule  = new CSSStyleRule();
                        startindex = block.value[i].startindex;
                    }

                    if (block.value[i].Type == CompoenentValueType.preservedToken)
                    {
                        PreservedToken pretoken = block.value[i] as PreservedToken;
                        // not a defined way to parse the selector, assembly them back and give it to selector module.
                        // in the new way of getting selectorText, we have not need to assign it any more.
                        //stylerule.selectorText += pretoken.token.getString();
                    }
                    else if (block.value[i].Type == CompoenentValueType.simpleBlock)
                    {
                        int endselectorindex = block.value[i].startindex;

                        stylerule.style = ParseDeclarations(block.value[i] as SimpleBlock, ref endindex, ref OriginalCss);

                        stylerule.StartIndex = startindex;
                        stylerule.EndIndex   = endindex;

                        stylerule.EndSelectorIndex = endselectorindex - stylerule.StartIndex;

                        stylerule.parentRule = parentmediarule;

                        stylerule.parentStyleSheet = parentmediarule.parentStyleSheet;

                        rulelist.appendRule(stylerule);
                        stylerule = null;

                        state      = MediaRuleParseState.init;
                        startindex = -1;
                    }


                    break;
                }

                case MediaRuleParseState.mediarule:
                {
                    if (mediarule == null)
                    {
                        mediarule          = new CSSMediaRule();
                        media              = string.Empty;
                        wholeconditiontext = string.Empty;
                        startindex         = block.value[i].startindex;

                        mediarule.parentStyleSheet = parentmediarule.parentStyleSheet;
                        mediarule.parentRule       = parentmediarule;
                    }

                    if (block.value[i].Type == CompoenentValueType.preservedToken)
                    {
                        PreservedToken pretoken = block.value[i] as PreservedToken;

                        if (pretoken.token.Type == enumTokenType.comma)
                        {
                            if (!string.IsNullOrEmpty(media))
                            {
                                mediarule.media.appendMedium(media.Trim());
                                media = string.Empty;
                            }
                            wholeconditiontext += ",";
                        }
                        else
                        {
                            // can be delim token.
                            if (string.IsNullOrEmpty(media) && pretoken.token.Type == enumTokenType.whitespace)
                            {
                                // the start of whitespace will be ignored.
                            }
                            else
                            {
                                media += pretoken.token.GetString(ref OriginalCss);
                                wholeconditiontext += pretoken.token.GetString(ref OriginalCss);
                            }
                        }
                    }
                    else if (block.value[i].Type == CompoenentValueType.simpleBlock)
                    {
                        CSSRuleList mediarulelist = ParseMediaRuleList(block.value[i] as SimpleBlock, ref endindex, mediarule, ref OriginalCss);

                        mediarule.cssRules = mediarulelist;

                        if (!string.IsNullOrEmpty(media))
                        {
                            mediarule.media.appendMedium(media.Trim());
                            wholeconditiontext += media;
                        }

                        mediarule.conditionText = wholeconditiontext;
                        mediarule.selectorText  = wholeconditiontext;        /// NON-W3C.

                        mediarule.StartIndex = startindex;
                        mediarule.EndIndex   = endindex;

                        rulelist.appendRule(mediarule);

                        state              = 0;
                        mediarule          = null;
                        media              = string.Empty;
                        wholeconditiontext = string.Empty;
                        startindex         = -1;
                    }

                    break;
                }

                case MediaRuleParseState.OtherAtRule:
                {
                    //if (mediarule == null)
                    //{
                    //    mediarule = new CSSMediaRule();
                    //    media = string.Empty;
                    //    wholeconditiontext = string.Empty;
                    //    startindex = block.value[i].startindex;

                    //    mediarule.parentStyleSheet = parentmediarule.parentStyleSheet;
                    //    mediarule.parentRule = parentmediarule;
                    //}

                    if (block.value[i].Type == CompoenentValueType.preservedToken)
                    {
                        //PreservedToken pretoken = block.value[i] as PreservedToken;

                        //if (pretoken.token.Type == enumTokenType.comma)
                        //{
                        //    if (!string.IsNullOrEmpty(media))
                        //    {
                        //        mediarule.media.appendMedium(media.Trim());
                        //        media = string.Empty;
                        //    }
                        //    wholeconditiontext += ",";
                        //}
                        //else
                        //{
                        //    // can be delim token.
                        //    if (string.IsNullOrEmpty(media) && pretoken.token.Type == enumTokenType.whitespace)
                        //    {
                        //        // the start of whitespace will be ignored.
                        //    }
                        //    else
                        //    {
                        //        media += pretoken.token.GetString(ref OriginalCss);
                        //        wholeconditiontext += pretoken.token.GetString(ref OriginalCss);
                        //    }
                        //}
                    }
                    else if (block.value[i].Type == CompoenentValueType.simpleBlock)
                    {
                        // not implemented now.
                        //CSSRuleList mediarulelist = ParseMediaRuleList(block.value[i] as SimpleBlock, ref endindex, mediarule, ref OriginalCss);

                        //mediarule.cssRules = mediarulelist;

                        //if (!string.IsNullOrEmpty(media))
                        //{
                        //    mediarule.media.appendMedium(media.Trim());
                        //    wholeconditiontext += media;
                        //}

                        //mediarule.conditionText = wholeconditiontext;
                        //mediarule.selectorText = wholeconditiontext; /// NON-W3C.

                        //mediarule.StartIndex = startindex;
                        //mediarule.EndIndex = endindex;

                        //rulelist.appendRule(mediarule);

                        state      = MediaRuleParseState.init;
                        startindex = -1;
                    }

                    break;
                }

                default:
                    break;
                }
            }


            if (stylerule != null)
            {
                if (stylerule.EndIndex > stylerule.StartIndex)
                {
                    rulelist.appendRule(stylerule);
                }
                stylerule = null;
            }

            if (mediarule != null)
            {
                rulelist.appendRule(mediarule);
                mediarule = null;
            }
            return(rulelist);
        }