Пример #1
0
        public NthMatcherBase(CssNodeType type, string text)
            : base(type, text)
        {
            Text = GetParameterExpression(text);

            GetFactorAndDistance(Text, out factor, out distance);
        }
Пример #2
0
        public AttributeMatcher(CssNodeType type, string text) : base(type, text)
        {
            var match = attributeMatcher.Match(text);

            if (match.Groups.Count > 1 &&
                match.Groups[1].Success)
            {
                PropertyName = match.Groups[1].Value;
            }
            if (match.Groups.Count > 2 &&
                match.Groups[2].Success)
            {
                Operator = match.Groups[2].Value;
            }
            if (match.Groups.Count > 3 &&
                match.Groups[3].Success)
            {
                Value = match.Groups[3].Value.Trim('"');
            }
        }
Пример #3
0
        /// <summary>
        /// Transforms all relative paths to absolute in CSS code
        /// </summary>
        /// <param name="content">Text content of CSS asset</param>
        /// <param name="path">CSS file path</param>
        /// <returns>Processed text content of CSS asset</returns>
        public string ResolveAllRelativePaths(string content, string path)
        {
            int contentLength = content.Length;

            if (contentLength == 0)
            {
                return(content);
            }

            MatchCollection urlRuleMatches    = CommonRegExps.CssUrlRuleRegex.Matches(content);
            MatchCollection importRuleMatches = _cssImportRuleRegex.Matches(content);

            if (urlRuleMatches.Count == 0 && importRuleMatches.Count == 0)
            {
                return(content);
            }

            var nodeMatches = new List <CssNodeMatch>();

            foreach (Match urlRuleMatch in urlRuleMatches)
            {
                var nodeMatch = new CssNodeMatch(urlRuleMatch.Index,
                                                 urlRuleMatch.Length,
                                                 CssNodeType.UrlRule,
                                                 urlRuleMatch);
                nodeMatches.Add(nodeMatch);
            }

            foreach (Match importRuleMatch in importRuleMatches)
            {
                var nodeMatch = new CssNodeMatch(importRuleMatch.Index,
                                                 importRuleMatch.Length,
                                                 CssNodeType.ImportRule,
                                                 importRuleMatch);
                nodeMatches.Add(nodeMatch);
            }

            MatchCollection multilineCommentMatches = CommonRegExps.CssMultilineCommentRegex.Matches(content);

            foreach (Match multilineCommentMatch in multilineCommentMatches)
            {
                var nodeMatch = new CssNodeMatch(multilineCommentMatch.Index,
                                                 multilineCommentMatch.Length,
                                                 CssNodeType.MultilineComment,
                                                 multilineCommentMatch);
                nodeMatches.Add(nodeMatch);
            }

            nodeMatches = nodeMatches
                          .OrderBy(n => n.Position)
                          .ThenByDescending(n => n.Length)
                          .ToList()
            ;

            var contentBuilder  = new StringBuilder();
            int endPosition     = contentLength - 1;
            int currentPosition = 0;

            foreach (CssNodeMatch nodeMatch in nodeMatches)
            {
                CssNodeType nodeType     = nodeMatch.NodeType;
                int         nodePosition = nodeMatch.Position;
                Match       match        = nodeMatch.Match;

                if (nodePosition < currentPosition)
                {
                    continue;
                }

                if (nodeType == CssNodeType.UrlRule || nodeType == CssNodeType.ImportRule)
                {
                    ProcessOtherContent(contentBuilder, content,
                                        ref currentPosition, nodePosition);

                    if (nodeType == CssNodeType.UrlRule)
                    {
                        GroupCollection urlRuleGroups = match.Groups;

                        string url   = urlRuleGroups["url"].Value.Trim();
                        string quote = urlRuleGroups["quote"].Success ?
                                       urlRuleGroups["quote"].Value : string.Empty;

                        string urlRule          = match.Value;
                        string processedUrlRule = ProcessUrlRule(path, url, quote);

                        contentBuilder.Append(processedUrlRule);
                        currentPosition += urlRule.Length;
                    }
                    else if (nodeType == CssNodeType.ImportRule)
                    {
                        GroupCollection importRuleGroups = match.Groups;

                        string url = importRuleGroups["url"].Value.Trim();

                        string importRule          = match.Value;
                        string processedImportRule = ProcessImportRule(path, url);

                        contentBuilder.Append(processedImportRule);
                        currentPosition += importRule.Length;
                    }
                }
                else if (nodeType == CssNodeType.MultilineComment)
                {
                    int nextPosition = nodePosition + match.Length;

                    ProcessOtherContent(contentBuilder, content,
                                        ref currentPosition, nextPosition);
                }
            }

            if (currentPosition > 0 && currentPosition <= endPosition)
            {
                ProcessOtherContent(contentBuilder, content,
                                    ref currentPosition, endPosition + 1);
            }

            return(contentBuilder.ToString());
        }
Пример #4
0
 public FirstChildMatcher(CssNodeType type, string text) : base(type, text)
 {
 }
Пример #5
0
 public CssNode(CssNodeType type, CssNode parent, string text)
 {
     Type        = type;
     Parent      = parent;
     TextBuilder = new StringBuilder(text);
 }
Пример #6
0
        public SelectorMatcher Create(CssNodeType type, string text)
        {
            if (type == CssNodeType.TypeSelector)
            {
                return(new TypeMatcher(type, text));
            }
            else if (type == CssNodeType.ClassSelector)
            {
                return(new ClassMatcher(type, text));
            }
            else if (type == CssNodeType.IdSelector)
            {
                return(new IdMatcher(type, text));
            }
            else if (type == CssNodeType.UniversalSelector)
            {
                return(new UnivseralMatcher(type, text));
            }
            else if (type == CssNodeType.PseudoSelector)
            {
                if (text.StartsWith(":nth-child", StringComparison.Ordinal))
                {
                    return(new NthChildMatcher(CssNodeType.PseudoSelector, text));
                }
                else if (text.StartsWith(":nth-of-type", StringComparison.Ordinal))
                {
                    return(new NthOfTypeMatcher(CssNodeType.PseudoSelector, text));
                }
                else if (text.StartsWith(":nth-last-child", StringComparison.Ordinal))
                {
                    return(new NthLastChildMatcher(CssNodeType.PseudoSelector, text));
                }
                else if (text.StartsWith(":nth-last-of-type", StringComparison.Ordinal))
                {
                    return(new NthLastOfTypeMatcher(CssNodeType.PseudoSelector, text));
                }
                else if (text.StartsWith(":first-child", StringComparison.Ordinal))
                {
                    return(new FirstChildMatcher(CssNodeType.PseudoSelector, text));
                }
                else if (text.StartsWith(":last-child", StringComparison.Ordinal))
                {
                    return(new LastChildMatcher(CssNodeType.PseudoSelector, text));
                }
                else if (text.StartsWith(":first-of-type", StringComparison.Ordinal))
                {
                    return(new FirstOfTypeMatcher(CssNodeType.PseudoSelector, text));
                }
                else if (text.StartsWith(":last-of-type", StringComparison.Ordinal))
                {
                    return(new LastOfTypeMatcher(CssNodeType.PseudoSelector, text));
                }
                else if (text.StartsWith(":only-of-type", StringComparison.Ordinal))
                {
                    return(new OnlyOfTypeMatcher(CssNodeType.PseudoSelector, text));
                }
            }
            else if (type == CssNodeType.InheritedTypeSelector)
            {
                return(new InheritedTypeMatcher(type, text));
            }
            else if (type == CssNodeType.AttributeSelector)
            {
                return(new AttributeMatcher(CssNodeType.AttributeSelector, text));
            }

            return(new SelectorMatcher(type, text));
        }
        /// <summary>
        /// Eject a <code>@charset</code> and <code>@import</code> rules
        /// </summary>
        /// <param name="content">Text content of style asset</param>
        /// <param name="topCharset">Processed top <code>@charset</code> rule</param>
        /// <param name="imports">List of processed <code>@import</code> rules</param>
        /// <returns>Text content of style asset without <code>@charset</code> and <code>@import</code> rules</returns>
        private static string EjectCssCharsetAndImports(
            string content,
            ref string topCharset,
            IList <string> imports)
        {
            int length = content.Length;

            if (length == 0)
            {
                return(content);
            }
            MatchCollection matchCollection1 = CommonRegExps.CssCharsetRuleRegex.Matches(content);
            MatchCollection matchCollection2 = StyleCombiner._cssImportRuleRegex.Matches(content);

            if (matchCollection1.Count == 0 && matchCollection2.Count == 0)
            {
                return(content);
            }
            List <CssNodeMatch> source = new List <CssNodeMatch>();

            foreach (Match match in matchCollection1)
            {
                CssNodeMatch cssNodeMatch = new CssNodeMatch(match.Index, match.Length, CssNodeType.CharsetRule, match);
                source.Add(cssNodeMatch);
            }
            foreach (Match match in matchCollection2)
            {
                CssNodeMatch cssNodeMatch = new CssNodeMatch(match.Index, match.Length, CssNodeType.ImportRule, match);
                source.Add(cssNodeMatch);
            }
            foreach (Match match in CommonRegExps.CssMultilineCommentRegex.Matches(content))
            {
                CssNodeMatch cssNodeMatch = new CssNodeMatch(match.Index, match.Length, CssNodeType.MultilineComment, match);
                source.Add(cssNodeMatch);
            }
            List <CssNodeMatch> list          = source.OrderBy <CssNodeMatch, int>((Func <CssNodeMatch, int>)(n => n.Position)).ThenByDescending <CssNodeMatch, int>((Func <CssNodeMatch, int>)(n => n.Length)).ToList <CssNodeMatch>();
            StringBuilderPool   shared        = StringBuilderPool.Shared;
            StringBuilder       stringBuilder = shared.Rent();
            int num             = length - 1;
            int currentPosition = 0;

            foreach (CssNodeMatch cssNodeMatch in list)
            {
                CssNodeType nodeType = cssNodeMatch.NodeType;
                int         position = cssNodeMatch.Position;
                Match       match    = cssNodeMatch.Match;
                if (position >= currentPosition)
                {
                    switch (nodeType)
                    {
                    case CssNodeType.CharsetRule:
                    case CssNodeType.ImportRule:
                        StyleCombiner.ProcessOtherContent(stringBuilder, content, ref currentPosition, position);
                        if (nodeType == CssNodeType.CharsetRule)
                        {
                            string str1 = match.Groups["charset"].Value;
                            string str2 = match.Value;
                            if (string.IsNullOrWhiteSpace(topCharset))
                            {
                                topCharset = string.Format("@charset \"{0}\";", (object)str1);
                            }
                            currentPosition += str2.Length;
                            continue;
                        }
                        if (nodeType == CssNodeType.ImportRule)
                        {
                            GroupCollection groups = match.Groups;
                            string          str1   = groups["url"].Value;
                            string          str2   = groups["media"].Success ? " " + groups["media"].Value : string.Empty;
                            string          str3   = match.Value;
                            string          str4   = string.Format("@import \"{0}\"{1};", (object)str1, (object)str2);
                            imports.Add(str4);
                            currentPosition += str3.Length;
                            continue;
                        }
                        continue;

                    case CssNodeType.MultilineComment:
                        int nextPosition = position + match.Length;
                        StyleCombiner.ProcessOtherContent(stringBuilder, content, ref currentPosition, nextPosition);
                        continue;

                    default:
                        continue;
                    }
                }
            }
            if (currentPosition > 0 && currentPosition <= num)
            {
                StyleCombiner.ProcessOtherContent(stringBuilder, content, ref currentPosition, num + 1);
            }
            string str = stringBuilder.ToString();

            shared.Return(stringBuilder);
            return(str);
        }
Пример #8
0
 public NthLastChildMatcher(CssNodeType type, string text) : base(type, text)
 {
     Text = text?.Substring(11).Replace(")", "");
 }
Пример #9
0
        /// <summary>
        /// Eject a <code>@charset</code> and <code>@import</code> rules
        /// </summary>
        /// <param name="content">Text content of style asset</param>
        /// <param name="topCharset">Processed top <code>@charset</code> rule</param>
        /// <param name="imports">List of processed <code>@import</code> rules</param>
        /// <returns>Text content of style asset without <code>@charset</code> and <code>@import</code> rules</returns>
        private static string EjectCssCharsetAndImports(string content, ref string topCharset,
                                                        IList <string> imports)
        {
            int contentLength = content.Length;

            if (contentLength == 0)
            {
                return(content);
            }

            MatchCollection charsetRuleMatches = CommonRegExps.CssCharsetRuleRegex.Matches(content);
            MatchCollection importRuleMatches  = _cssImportRuleRegex.Matches(content);

            if (charsetRuleMatches.Count == 0 && importRuleMatches.Count == 0)
            {
                return(content);
            }

            var nodeMatches = new List <CssNodeMatch>();

            foreach (Match charsetRuleMatch in charsetRuleMatches)
            {
                var nodeMatch = new CssNodeMatch(charsetRuleMatch.Index,
                                                 charsetRuleMatch.Length,
                                                 CssNodeType.CharsetRule,
                                                 charsetRuleMatch);
                nodeMatches.Add(nodeMatch);
            }

            foreach (Match importRuleMatch in importRuleMatches)
            {
                var nodeMatch = new CssNodeMatch(importRuleMatch.Index,
                                                 importRuleMatch.Length,
                                                 CssNodeType.ImportRule,
                                                 importRuleMatch);
                nodeMatches.Add(nodeMatch);
            }

            MatchCollection multilineCommentMatches = CommonRegExps.CssMultilineCommentRegex.Matches(content);

            foreach (Match multilineCommentMatch in multilineCommentMatches)
            {
                var nodeMatch = new CssNodeMatch(multilineCommentMatch.Index,
                                                 multilineCommentMatch.Length,
                                                 CssNodeType.MultilineComment,
                                                 multilineCommentMatch);
                nodeMatches.Add(nodeMatch);
            }

            nodeMatches = nodeMatches
                          .OrderBy(n => n.Position)
                          .ThenByDescending(n => n.Length)
                          .ToList()
            ;

            var contentBuilder  = new StringBuilder();
            int endPosition     = contentLength - 1;
            int currentPosition = 0;

            foreach (CssNodeMatch nodeMatch in nodeMatches)
            {
                CssNodeType nodeType     = nodeMatch.NodeType;
                int         nodePosition = nodeMatch.Position;
                Match       match        = nodeMatch.Match;

                if (nodePosition < currentPosition)
                {
                    continue;
                }

                if (nodeType == CssNodeType.MultilineComment)
                {
                    int nextPosition = nodePosition + match.Length;

                    ProcessOtherContent(contentBuilder, content,
                                        ref currentPosition, nextPosition);
                }
                else if (nodeType == CssNodeType.CharsetRule || nodeType == CssNodeType.ImportRule)
                {
                    ProcessOtherContent(contentBuilder, content,
                                        ref currentPosition, nodePosition);

                    if (nodeType == CssNodeType.CharsetRule)
                    {
                        string charset = match.Groups["charset"].Value;

                        string charsetRule = match.Value;
                        if (string.IsNullOrWhiteSpace(topCharset))
                        {
                            topCharset = string.Format(@"@charset ""{0}"";", charset);
                        }

                        currentPosition += charsetRule.Length;
                    }
                    else if (nodeType == CssNodeType.ImportRule)
                    {
                        GroupCollection importRuleGroups = match.Groups;

                        string url   = importRuleGroups["url"].Value;
                        string media = importRuleGroups["media"].Success ?
                                       (" " + importRuleGroups["media"].Value) : string.Empty;

                        string importRule          = match.Value;
                        string processedImportRule = string.Format(@"@import ""{0}""{1};", url, media);
                        imports.Add(processedImportRule);

                        currentPosition += importRule.Length;
                    }
                }
            }

            if (currentPosition > 0 && currentPosition <= endPosition)
            {
                ProcessOtherContent(contentBuilder, content,
                                    ref currentPosition, endPosition + 1);
            }

            return(contentBuilder.ToString());
        }
Пример #10
0
 public InheritedTypeMatcher(CssNodeType type, string text) : base(type, text)
 {
     Text = text.Substring(1);
 }
Пример #11
0
 public TypeMatcher(CssNodeType type, string text) : base(type, text)
 {
 }
Пример #12
0
 /// <summary>Constructs a instance of CSS node match</summary>
 /// <param name="position">Position in the original string where
 /// the first character of the captured substring was found</param>
 /// <param name="length">Length of the captured substring</param>
 /// <param name="nodeType">Type of CSS node</param>
 /// <param name="match">Single regular expression match</param>
 public CssNodeMatch(int position, int length, CssNodeType nodeType, Match match)
     : base(position, length, match)
     => this.NodeType = nodeType;
Пример #13
0
 public UnivseralMatcher(CssNodeType type, string text) : base(type, text)
 {
 }
Пример #14
0
 public CssNode(CssNodeType type)
 {
     Type        = type;
     TextBuilder = new StringBuilder();
 }
Пример #15
0
 public SelectorMatcher(CssNodeType type, string text)
 {
     Type = type;
     Text = text;
 }
Пример #16
0
        private static List <TriggerAction> GetTriggerActions(CssNode astTriggerStyleDeclarationBlock, CssNodeType type, IDictionary <string, string> parameterValues)
        {
            if (type != CssNodeType.EnterAction &&
                type != CssNodeType.ExitAction)
            {
                throw new InvalidOperationException("Type must be either EnterAction or ExitAction");
            }

            var actionDeclarationBlockAst = astTriggerStyleDeclarationBlock.Children
                                            .Where(y => y.Type == type)
                                            .SelectMany(y => y.Children)
                                            .Where(y => y.Type == CssNodeType.ActionDeclarationBlock)
                                            .SingleOrDefault();

            if (actionDeclarationBlockAst == null)
            {
                return(new List <TriggerAction>());
            }

            return(GetActionDeclarationsFromBlock(actionDeclarationBlockAst, parameterValues));
        }
        /// <summary>
        /// Ejects a <code>@charset</code> rules
        /// </summary>
        /// <param name="content">Text content of CSS asset</param>
        /// <param name="topCharset">Processed top <code>@charset</code> rule</param>
        /// <returns>Text content of CSS asset without <code>@charset</code> rules</returns>
        private static string EjectCssCharset(string content, ref string topCharset)
        {
            int contentLength = content.Length;

            if (contentLength == 0)
            {
                return(content);
            }

            MatchCollection charsetRuleMatches = CommonRegExps.CssCharsetRuleRegex.Matches(content);

            if (charsetRuleMatches.Count == 0)
            {
                return(content);
            }

            var nodeMatches = new List <CssNodeMatch>();

            foreach (Match charsetRuleMatch in charsetRuleMatches)
            {
                var nodeMatch = new CssNodeMatch(charsetRuleMatch.Index,
                                                 charsetRuleMatch.Length,
                                                 CssNodeType.CharsetRule,
                                                 charsetRuleMatch);
                nodeMatches.Add(nodeMatch);
            }

            MatchCollection multilineCommentMatches = CommonRegExps.CssMultilineCommentRegex.Matches(content);

            foreach (Match multilineCommentMatch in multilineCommentMatches)
            {
                var nodeMatch = new CssNodeMatch(multilineCommentMatch.Index,
                                                 multilineCommentMatch.Length,
                                                 CssNodeType.MultilineComment,
                                                 multilineCommentMatch);
                nodeMatches.Add(nodeMatch);
            }

            nodeMatches = nodeMatches
                          .OrderBy(n => n.Position)
                          .ThenByDescending(n => n.Length)
                          .ToList()
            ;

            var           stringBuilderPool = StringBuilderPool.Shared;
            StringBuilder resultBuilder     = stringBuilderPool.Rent();
            int           endPosition       = contentLength - 1;
            int           currentPosition   = 0;

            foreach (CssNodeMatch nodeMatch in nodeMatches)
            {
                CssNodeType nodeType     = nodeMatch.NodeType;
                int         nodePosition = nodeMatch.Position;
                Match       match        = nodeMatch.Match;

                if (nodePosition < currentPosition)
                {
                    continue;
                }

                if (nodeType == CssNodeType.MultilineComment)
                {
                    int nextPosition = nodePosition + match.Length;

                    ProcessOtherContent(resultBuilder, content,
                                        ref currentPosition, nextPosition);
                }
                else if (nodeType == CssNodeType.CharsetRule)
                {
                    ProcessOtherContent(resultBuilder, content,
                                        ref currentPosition, nodePosition);

                    string charset = match.Groups["charset"].Value;

                    string charsetRule = match.Value;
                    if (string.IsNullOrWhiteSpace(topCharset))
                    {
                        topCharset = string.Format(@"@charset ""{0}"";", charset);
                    }

                    currentPosition += charsetRule.Length;
                }
            }

            if (currentPosition > 0 && currentPosition <= endPosition)
            {
                ProcessOtherContent(resultBuilder, content,
                                    ref currentPosition, endPosition + 1);
            }

            string result = resultBuilder.ToString();

            stringBuilderPool.Return(resultBuilder);

            return(result);
        }
Пример #18
0
 public ClassMatcher(CssNodeType type, string text) : base(type, text)
 {
     Text = text?.Substring(1);
 }
Пример #19
0
 public NthLastOfTypeMatcher(CssNodeType type, string text) : base(type, text)
 {
 }
Пример #20
0
		/// <summary>
		/// Constructs a instance of CSS node match
		/// </summary>
		/// <param name="position">Position in the original string where
		/// the first character of the captured substring was found</param>
		/// <param name="length">Length of the captured substring</param>
		/// <param name="nodeType">Type of CSS-node</param>
		/// <param name="match">Single regular expression match</param>
		public CssNodeMatch(int position, int length, CssNodeType nodeType, Match match)
			: base(position, length, match)
		{
			NodeType = nodeType;
		}