示例#1
0
 public BinaryExpression(BinaryOperator @operator, CssExpression left, CssExpression right)
 {
     _operator = @operator;
     _left     = left;
     _right    = right;
 }
示例#2
0
 public static CssExpression State(CssExpression expression, string state) =>
 new StateExpression(expression, state);
 private static CssExpression Combine(CssExpression left, CssExpression right, CssExpression.BinaryOperator op) =>
 left == null ? right : CssExpression.Binary(op, left, right);
示例#4
0
 public static CssExpression Binary(BinaryOperator op, CssExpression left, CssExpression right) =>
 new BinaryExpression(op, left, right);
        public static CssExpression Parse(TextReader reader)
        {
            var ors = new List <CssExpression>();

            CssExpression current = null;

            var currentOp = CssExpression.BinaryOperator.And;

            int code;

            while ((code = reader.Read()) >= 0)
            {
                var c = (char)code;
                switch (c)
                {
                case '*': current = Combine(current, CssExpression.All, currentOp);; break;

                case '.': current = Combine(current, CssExpression.Class(ReadText(reader)), currentOp); break;

                case '#': current = Combine(current, CssExpression.Id(ReadText(reader)), currentOp); break;

                case ':': current = CssExpression.State(current, ReadText(reader)); break;

                case '~':
                    while (reader.Peek() == ' ')
                    {
                        reader.Read();
                    }
                    currentOp = CssExpression.BinaryOperator.Prev;
                    break;

                case '+':
                    while (reader.Peek() == ' ')
                    {
                        reader.Read();
                    }
                    currentOp = CssExpression.BinaryOperator.PrevSibling;
                    break;

                case ',':
                    while (reader.Peek() == ' ')
                    {
                        reader.Read();
                    }
                    ors.Add(current);
                    current = null;
                    break;

                case '>':
                    while (reader.Peek() == ' ')
                    {
                        reader.Read();
                    }
                    currentOp = CssExpression.BinaryOperator.Parent;
                    break;

                case ' ':
                    currentOp = ReadOperator(reader);
                    break;

                case '[':
                {
                    var attrValue = ReadText(reader, true).Split('=');
                    reader.Read();

                    var attr = attrValue[0];

                    if (attr.Length == 0)
                    {
                        break;
                    }

                    if (attrValue.Length == 1)
                    {
                        current = Combine(current,
                                          CssExpression.Attr(CssExpression.AttributeOperator.Exists, attrValue[0], null),
                                          currentOp);
                        break;
                    }

                    var opChar = attr.Last();
                    var attrOp = CssExpression.AttributeOperator.Equals;
                    switch (opChar)
                    {
                    case '~': attrOp = CssExpression.AttributeOperator.DelimitedContains; break;

                    case '|': attrOp = CssExpression.AttributeOperator.DelimitedStartWith; break;

                    case '^': attrOp = CssExpression.AttributeOperator.StartWith; break;

                    case '$': attrOp = CssExpression.AttributeOperator.EndWith; break;

                    case '*': attrOp = CssExpression.AttributeOperator.Contains; break;
                    }

                    var val = attrValue[1];
                    if (val.StartsWith("\""))
                    {
                        val = val.Trim('"');
                    }
                    else if (val.StartsWith("'"))
                    {
                        val = val.Trim('\'');
                    }

                    current = Combine(current, CssExpression.Attr(
                                          attrOp,
                                          attrOp == CssExpression.AttributeOperator.Equals ? attr : attr.Substring(0, attr.Length - 1),
                                          val),
                                      currentOp);
                    break;
                }

                case '\r':
                case '\n':
                case '\t':
                    break;

                default:
                    current = Combine(current, CssExpression.Tag(c + ReadText(reader)), currentOp);
                    break;
                }
            }

            if (ors.Count > 0)
            {
                ors.Add(current);
                return(CssExpression.Or(ors));
            }

            return(current ?? CssExpression.None);
        }