Example #1
0
 void Reset()
 {
     cssDocument = new CssDocument();
     _currentAtMedia = new CssAtMedia();
     cssDocument.Add(_currentAtMedia);
     _mediaStack.Clear();
     this._currentSelectorAttr = null;
     this._currentSelectorExpr = null;
     this._currentProperty = null;
     this._latestPropertyValue = null;
 }
Example #2
0
        void LexerEmitHandler(CssTokenName tkname, int start, int len)
        {
            switch (parseState)
            {
                default:
                    {
                        throw new NotSupportedException();
                    }
                    break;
                case CssParseState.Init:
                    {
                        switch (tkname)
                        {
                            case CssTokenName.Comment:
                                {
                                    //comment token  
                                }
                                break;
                            case CssTokenName.RBrace:
                                {
                                    //exit from current ruleset block
                                    if (this._mediaStack.Count > 0)
                                    {
                                        this._currentAtMedia = this._mediaStack.Pop();
                                    }
                                }
                                break;
                            case CssTokenName.Star:
                                {
                                    //start new code block 
                                    CssRuleSet newblock;
                                    this._currentAtMedia.AddRuleSet(this._currentRuleSet = newblock = new CssRuleSet());
                                    newblock.AddSelector(this._currentSelectorExpr = new CssSimpleElementSelector(SimpleElementSelectorKind.All));
                                    parseState = CssParseState.MoreBlockName;
                                }
                                break;
                            case CssTokenName.At:
                                {
                                    //at rule                                    
                                    parseState = CssParseState.ExpectAtRuleName;
                                }
                                break;
                            //--------------------------------------------------
                            //1.
                            case CssTokenName.Colon:
                                {
                                    CssRuleSet newblock;
                                    _currentAtMedia.AddRuleSet(this._currentRuleSet = newblock = new CssRuleSet());
                                    newblock.AddSelector(this._currentSelectorExpr = new CssSimpleElementSelector(SimpleElementSelectorKind.PseudoClass));
                                    parseState = CssParseState.ExpectIdenAfterSpecialBlockNameSymbol;
                                }
                                break;
                            //2.
                            case CssTokenName.Dot:
                                {
                                    CssRuleSet newblock;
                                    _currentAtMedia.AddRuleSet(this._currentRuleSet = newblock = new CssRuleSet());
                                    newblock.AddSelector(this._currentSelectorExpr = new CssSimpleElementSelector(SimpleElementSelectorKind.ClassName));
                                    parseState = CssParseState.ExpectIdenAfterSpecialBlockNameSymbol;
                                }
                                break;
                            //3. 
                            case CssTokenName.DoubleColon:
                                {
                                    CssRuleSet newblock;
                                    _currentAtMedia.AddRuleSet(this._currentRuleSet = newblock = new CssRuleSet());
                                    newblock.AddSelector(this._currentSelectorExpr = new CssSimpleElementSelector(SimpleElementSelectorKind.Extend));
                                    parseState = CssParseState.ExpectIdenAfterSpecialBlockNameSymbol;
                                }
                                break;
                            //4.
                            case CssTokenName.Iden:
                                {
                                    //block name
                                    CssRuleSet newblock;
                                    _currentAtMedia.AddRuleSet(this._currentRuleSet = newblock = new CssRuleSet());
                                    newblock.AddSelector(this._currentSelectorExpr = new CssSimpleElementSelector());
                                    this._currentSelectorExpr.Name = new string(this.textBuffer, start, len);
                                    parseState = CssParseState.MoreBlockName;
                                }
                                break;
                            //5. 
                            case CssTokenName.Sharp:
                                {
                                    CssRuleSet newblock;
                                    _currentAtMedia.AddRuleSet(this._currentRuleSet = newblock = new CssRuleSet());
                                    newblock.AddSelector(this._currentSelectorExpr = new CssSimpleElementSelector(SimpleElementSelectorKind.Id));
                                    parseState = CssParseState.ExpectIdenAfterSpecialBlockNameSymbol;
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.MoreBlockName:
                    {
                        //more 
                        switch (tkname)
                        {
                            case CssTokenName.LBrace:
                                {
                                    //block body
                                    parseState = CssParseState.BlockBody;
                                }
                                break;
                            case CssTokenName.LBracket:
                                {
                                    //element attr
                                    parseState = CssParseState.ExpectBlockAttrIden;
                                }
                                break;
                            //1. 
                            case CssTokenName.Colon:
                                {
                                    //wait iden after colon
                                    var cssSelector = new CssSimpleElementSelector();
                                    cssSelector.selectorType = SimpleElementSelectorKind.PseudoClass;
                                    _currentRuleSet.AddSelector(cssSelector);
                                    this._currentSelectorExpr = cssSelector;
                                    parseState = CssParseState.ExpectIdenAfterSpecialBlockNameSymbol;
                                }
                                break;
                            //2. 
                            case CssTokenName.Dot:
                                {
                                    var cssSelector = new CssSimpleElementSelector();
                                    cssSelector.selectorType = SimpleElementSelectorKind.ClassName;
                                    _currentRuleSet.AddSelector(cssSelector);
                                    this._currentSelectorExpr = cssSelector;
                                    parseState = CssParseState.ExpectIdenAfterSpecialBlockNameSymbol;
                                }
                                break;
                            //3. 
                            case CssTokenName.DoubleColon:
                                {
                                    var cssSelector = new CssSimpleElementSelector();
                                    cssSelector.selectorType = SimpleElementSelectorKind.Extend;
                                    _currentRuleSet.AddSelector(cssSelector);
                                    this._currentSelectorExpr = cssSelector;
                                    parseState = CssParseState.ExpectIdenAfterSpecialBlockNameSymbol;
                                }
                                break;
                            //4. 
                            case CssTokenName.Iden:
                                {
                                    //add more block name                                     
                                    var cssSelector = new CssSimpleElementSelector();
                                    cssSelector.selectorType = SimpleElementSelectorKind.TagName;
                                    cssSelector.Name = new string(this.textBuffer, start, len);
                                    _currentRuleSet.AddSelector(cssSelector);
                                    this._currentSelectorExpr = cssSelector;
                                }
                                break;
                            //5. 
                            case CssTokenName.Sharp:
                                {
                                    //id
                                    var cssSelector = new CssSimpleElementSelector();
                                    cssSelector.selectorType = SimpleElementSelectorKind.Id;
                                    _currentRuleSet.AddSelector(cssSelector);
                                    this._currentSelectorExpr = cssSelector;
                                    parseState = CssParseState.ExpectIdenAfterSpecialBlockNameSymbol;
                                }
                                break;
                            //----------------------------------------------------
                               
                            //element combinator operators
                            case CssTokenName.Comma:
                                {
                                    this._currentRuleSet.PrepareExpression(CssCombinatorOperator.List);
                                }
                                break;
                            case CssTokenName.Star:
                                {
                                }break;

                            case CssTokenName.RAngle:
                                {
                                }
                                break;
                            case CssTokenName.Plus:
                                {
                                }
                                break;
                            case CssTokenName.Tile:
                                {
                                }
                                break;
                            //----------------------------------------------------
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.ExpectIdenAfterSpecialBlockNameSymbol:
                    {
                        switch (tkname)
                        {
                            case CssTokenName.Iden:
                                {
                                    this._currentSelectorExpr.Name = new string(this.textBuffer, start, len);
                                    parseState = CssParseState.MoreBlockName;
                                }
                                break;
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                        }
                    }
                    break;
                case CssParseState.ExpectBlockAttrIden:
                    {
                        switch (tkname)
                        {
                            case CssTokenName.Iden:
                                {
                                    //attribute  
                                    parseState = CssParseState.AfterAttrName;
                                    this._currentSelectorExpr.AddAttribute(this._currentSelectorAttr = new CssAttributeSelectorExpression());
                                    this._currentSelectorAttr.AttributeName = new string(this.textBuffer, start, len);
                                }
                                break;
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.AfterAttrName:
                    {
                        switch (tkname)
                        {
                            case CssTokenName.OpEq:
                                {
                                    parseState = CssParseState.ExpectedBlockAttrValue;
                                    //expected  attr value
                                }
                                break;
                            case CssTokenName.RBracket:
                                {
                                    //no attr value
                                    parseState = CssParseState.MoreBlockName;
                                }
                                break;
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.ExpectedBlockAttrValue:
                    {
                        switch (tkname)
                        {
                            case CssTokenName.LiteralString:
                                {
                                    this._currentSelectorAttr.valueExpression = this._latestPropertyValue =
                                        new CssCodePrimitiveExpression(new string(this.textBuffer, start, len), CssValueHint.LiteralString);
                                    this._currentSelectorAttr = null;
                                }
                                break;
                            default:
                                {
                                }
                                break;
                        }
                        parseState = CssParseState.AfterBlockNameAttr;
                    }
                    break;
                case CssParseState.AfterBlockNameAttr:
                    {
                        switch (tkname)
                        {
                            default:
                                {
                                }
                                break;
                            case CssTokenName.RBracket:
                                {
                                    parseState = CssParseState.MoreBlockName;
                                    this._currentSelectorAttr = null;
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.BlockBody:
                    {
                        switch (tkname)
                        {
                            case CssTokenName.Iden:
                                {
                                    //block name

                                    //create css property 
                                    string cssPropName = new string(this.textBuffer, start, len);
                                    var wellknownName = UserMapUtil.GetWellKnownPropName(cssPropName);
                                    if (wellknownName == WellknownCssPropertyName.Unknown)
                                    {
                                        _currentRuleSet.AddCssCodeProperty(this._currentProperty =
                                            new CssPropertyDeclaration(cssPropName));
                                    }
                                    else
                                    {
                                        _currentRuleSet.AddCssCodeProperty(this._currentProperty =
                                            new CssPropertyDeclaration(wellknownName));
                                    }
                                    this._latestPropertyValue = null;
                                    parseState = CssParseState.AfterPropertyName;
                                }
                                break;
                            case CssTokenName.RBrace:
                                {
                                    //close current block
                                    this._currentProperty = null;
                                    this._currentSelectorAttr = null;
                                    this._currentSelectorExpr = null;
                                    parseState = CssParseState.Init;
                                }
                                break;
                            case CssTokenName.SemiColon:
                                {
                                    //another semi colon just skip
                                }
                                break;
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.AfterPropertyName:
                    {
                        if (tkname == CssTokenName.Colon)
                        {
                            parseState = CssParseState.ExpectPropertyValue;
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }
                    }
                    break;
                case CssParseState.ExpectPropertyValue:
                    {
                        switch (tkname)
                        {
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                            case CssTokenName.Sharp:
                                {
                                    //follow by hex color value
                                    parseState = CssParseState.ExpectValueOfHexColor;
                                }
                                break;
                            case CssTokenName.LiteralString:
                                {
                                    this._currentProperty.AddValue(this._latestPropertyValue =
                                         new CssCodePrimitiveExpression(new string(this.textBuffer, start, len), CssValueHint.LiteralString));
                                    parseState = CssParseState.AfterPropertyValue;
                                }
                                break;
                            case CssTokenName.Number:
                                {
                                    float number = float.Parse(new string(this.textBuffer, start, len));
                                    this._currentProperty.AddValue(this._latestPropertyValue =
                                          new CssCodePrimitiveExpression(number));
                                    parseState = CssParseState.AfterPropertyValue;
                                }
                                break;
                            case CssTokenName.NumberUnit:
                                {
                                }
                                break;
                            case CssTokenName.Iden:
                                {
                                    //property value
                                    this._currentProperty.AddValue(this._latestPropertyValue =
                                        new CssCodePrimitiveExpression(new string(this.textBuffer, start, len), CssValueHint.Iden));
                                    parseState = CssParseState.AfterPropertyValue;
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.ExpectValueOfHexColor:
                    {
                        switch (tkname)
                        {
                            case CssTokenName.Iden:
                                {
                                    this._currentProperty.AddValue(this._latestPropertyValue =
                                       new CssCodePrimitiveExpression("#" + new string(this.textBuffer, start, len),
                                           CssValueHint.HexColor));
                                }
                                break;
                            case CssTokenName.Number:
                                {
                                    this._currentProperty.AddValue(this._latestPropertyValue =
                                         new CssCodePrimitiveExpression("#" + new string(this.textBuffer, start, len),
                                             CssValueHint.HexColor));
                                }
                                break;
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                        }
                        parseState = CssParseState.AfterPropertyValue;
                    }
                    break;
                case CssParseState.AfterPropertyValue:
                    {
                        switch (tkname)
                        {
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                            case CssTokenName.Comma:
                                {
                                    //skip comma
                                }
                                break;
                            case CssTokenName.Percent:
                                {
                                    if (_latestPropertyValue is CssCodePrimitiveExpression)
                                    {
                                        ((CssCodePrimitiveExpression)_latestPropertyValue).Unit = "%";
                                    }
                                }
                                break;
                            case CssTokenName.Divide:
                                {
                                    //eg. font: style variant weight size/line-height family;

                                    CssCodeBinaryExpression codeBinaryOpExpr = new CssCodeBinaryExpression();
                                    codeBinaryOpExpr.OpName = CssValueOpName.Divide;
                                    codeBinaryOpExpr.Left = this._latestPropertyValue;
                                    //replace previous add value ***
                                    int valueCount = this._currentProperty.ValueCount;
                                    //replace
                                    this._currentProperty.ReplaceValue(valueCount - 1, codeBinaryOpExpr);
                                    this._latestPropertyValue = codeBinaryOpExpr;
                                }
                                break;
                            case CssTokenName.LiteralString:
                                {
                                    var literalValue = new string(this.textBuffer, start, len);
                                    throw new NotSupportedException();
                                }
                                break;
                            case CssTokenName.LParen:
                                {
                                    //function 
                                    parseState = CssParseState.ExpectedFuncParameter;
                                    //make current prop value as func
                                    CssCodeFunctionCallExpression funcCallExpr = new CssCodeFunctionCallExpression(
                                        this._latestPropertyValue.ToString());
                                    int valueCount = this._currentProperty.ValueCount;
                                    this._currentProperty.ReplaceValue(valueCount - 1, funcCallExpr);
                                    this._latestPropertyValue = funcCallExpr;
                                }
                                break;
                            case CssTokenName.RBrace:
                                {
                                    //close block
                                    parseState = CssParseState.Init;
                                }
                                break;
                            case CssTokenName.SemiColon:
                                {
                                    //start new proeprty
                                    parseState = CssParseState.BlockBody;
                                    this._currentProperty = null;
                                }
                                break;
                            case CssTokenName.Iden:
                                {
                                    //another property value                                     
                                    this._currentProperty.AddValue(this._latestPropertyValue =
                                        new CssCodePrimitiveExpression(new string(this.textBuffer, start, len), CssValueHint.Iden));
                                }
                                break;
                            case CssTokenName.Number:
                                {
                                    //another property value
                                    float number = float.Parse(new string(this.textBuffer, start, len));
                                    this._currentProperty.AddValue(this._latestPropertyValue =
                                        new CssCodePrimitiveExpression(number));
                                }
                                break;
                            case CssTokenName.NumberUnit:
                                {
                                    //number unit 
                                    if (_latestPropertyValue is CssCodePrimitiveExpression)
                                    {
                                        ((CssCodePrimitiveExpression)_latestPropertyValue).Unit = new string(this.textBuffer, start, len);
                                    }
                                }
                                break;
                            case CssTokenName.Sharp:
                                {
                                    parseState = CssParseState.ExpectValueOfHexColor;
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.ExpectAtRuleName:
                    {
                        //iden
                        switch (tkname)
                        {
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                            case CssTokenName.Iden:
                                {
                                    string iden = new string(this.textBuffer, start, len);
                                    //create new rule
                                    _currentRuleSet = null;
                                    _currentProperty = null;
                                    _currentSelectorAttr = null;
                                    _currentSelectorExpr = null;
                                    switch (iden)
                                    {
                                        case "media":
                                            {
                                                parseState = CssParseState.MediaList;
                                                //store previous media 
                                                if (this._currentAtMedia != null)
                                                {
                                                    this._mediaStack.Push(this._currentAtMedia);
                                                }

                                                this.cssDocument.Add(this._currentAtMedia = new CssAtMedia());
                                            }
                                            break;
                                        case "import":
                                            {
                                                parseState = CssParseState.ExpectImportURL;
                                            }
                                            break;
                                        case "page":
                                            {
                                                throw new NotSupportedException();
                                            }
                                            break;
                                        default:
                                            {
                                                throw new NotSupportedException();
                                            }
                                            break;
                                    }
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.MediaList:
                    {
                        //medialist sep by comma
                        switch (tkname)
                        {
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                            case CssTokenName.Iden:
                                {
                                    //media name                                     
                                    this._currentAtMedia.AddMedia(new string(this.textBuffer, start, len));
                                }
                                break;
                            case CssTokenName.Comma:
                                {
                                    //wait for another media
                                }
                                break;
                            case CssTokenName.LBrace:
                                {
                                    //begin rule set part
                                    parseState = CssParseState.Init;
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.ExpectedFuncParameter:
                    {
                        string funcArg = new string(this.textBuffer, start, len);
                        switch (tkname)
                        {
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                            case CssTokenName.RParen:
                                {
                                    this.parseState = CssParseState.AfterPropertyValue;
                                }
                                break;
                            case CssTokenName.LiteralString:
                                {
                                    ((CssCodeFunctionCallExpression)this._latestPropertyValue).AddFuncArg(
                                        new CssCodePrimitiveExpression(funcArg, CssValueHint.LiteralString));
                                    this.parseState = CssParseState.AfterFuncParameter;
                                }
                                break;
                            case CssTokenName.Number:
                                {
                                    float number = float.Parse(funcArg);
                                    ((CssCodeFunctionCallExpression)this._latestPropertyValue).AddFuncArg(
                                          new CssCodePrimitiveExpression(number));
                                    this.parseState = CssParseState.AfterFuncParameter;
                                }
                                break;
                            case CssTokenName.Iden:
                                {
                                    ((CssCodeFunctionCallExpression)this._latestPropertyValue).AddFuncArg(
                                        new CssCodePrimitiveExpression(funcArg, CssValueHint.Iden));
                                    this.parseState = CssParseState.AfterFuncParameter;
                                }
                                break;
                        }
                    }
                    break;
                case CssParseState.AfterFuncParameter:
                    {
                        switch (tkname)
                        {
                            default:
                                {
                                    throw new NotSupportedException();
                                }
                            case CssTokenName.RParen:
                                {
                                    this.parseState = CssParseState.AfterPropertyValue;
                                }
                                break;
                            case CssTokenName.Comma:
                                {
                                    this.parseState = CssParseState.ExpectedFuncParameter;
                                }
                                break;
                        }
                    }
                    break;
            }
        }