private void OnPseudoClass(CssSelectorToken token) { _state = State.Data; _ready = true; if (token.Type == CssTokenType.Colon) { _state = State.PseudoElement; return; } else if (token.Type == CssTokenType.Function) { if (pseudoClassFunctions.TryGetValue(token.Data, out var creator)) { _state = State.Function; _function = creator.Invoke(this); _ready = false; return; } } else if (token.Type == CssTokenType.Ident) { var sel = _pseudoClassSelector.Create(token.Data); if (sel != null) { Insert(sel); return; } } _valid = false; }
private Boolean OnAfterInitialSign(CssSelectorToken token) { if (token.Type == CssTokenType.Number) { return(OnOffset(token)); } if (token.Type == CssTokenType.Dimension) { var integral = token.Data.Remove(token.Data.Length - 1); _valid = _valid && token.Data.EndsWith("n", StringComparison.OrdinalIgnoreCase) && Int32.TryParse(integral, NumberStyles.Integer, CultureInfo.InvariantCulture, out _step); _step *= _sign; _sign = 1; _state = ParseState.Offset; return(false); } else if (token.Type == CssTokenType.Ident && token.Data.Isi("n")) { _step = _sign; _sign = 1; _state = ParseState.Offset; return(false); } else if (_state == ParseState.Initial && token.Type == CssTokenType.Ident && token.Data.Isi("-n")) { _step = -1; _state = ParseState.Offset; return(false); } _valid = false; return(token.Type == CssTokenType.RoundBracketClose); }
private void OnAttributeOperator(CssSelectorToken token) { if (token.Type != CssTokenType.Whitespace) { if (token.Type == CssTokenType.SquareBracketClose) { _state = State.AttributeValue; OnAttributeEnd(token); } else if (token.Type == CssTokenType.Match || token.Type == CssTokenType.Delim) { _state = State.AttributeValue; _attrOp = token.Data; if (_attrOp == CombinatorSymbols.Pipe) { _attrNs = _attrName; _attrName = null; _attrOp = String.Empty; _state = State.Attribute; } } else { _state = State.AttributeEnd; _valid = false; } } }
private void OnAttribute(CssSelectorToken token) { if (token.Type != CssTokenType.Whitespace) { if (token.Type == CssTokenType.Ident || token.Type == CssTokenType.String) { _state = State.AttributeOperator; _attrName = token.Data; } else if (token.Type == CssTokenType.Delim && token.Data.Is(CombinatorSymbols.Pipe)) { _state = State.Attribute; _attrNs = String.Empty; } else if (token.Type == CssTokenType.Delim && token.Data.Is("*")) { _state = State.AttributeOperator; _attrName = "*"; } else { _state = State.Data; _valid = false; } } }
private Boolean OnInitial(CssSelectorToken token) { if (token.Type == CssTokenType.Whitespace) { return(false); } if (token.Data.Isi(Keywords.Odd)) { _state = ParseState.BeforeOf; _step = 2; _offset = 1; return(false); } else if (token.Data.Isi(Keywords.Even)) { _state = ParseState.BeforeOf; _step = 2; _offset = 0; return(false); } else if (token.Type == CssTokenType.Delim && token.Data.IsOneOf("+", "-")) { _sign = token.Data == "-" ? -1 : +1; _state = ParseState.AfterInitialSign; return(false); } return(OnAfterInitialSign(token)); }
protected override Boolean OnToken(CssSelectorToken token) { if (token.Type != CssTokenType.RoundBracketClose || _selector._state != State.Data) { _selector.Apply(token); return(false); } return(true); }
private Boolean OnAfter(CssSelectorToken token) { if (token.Type != CssTokenType.RoundBracketClose || _nested._state != State.Data) { _nested.Apply(token); return(false); } return(true); }
private void OnAttributeValue(CssSelectorToken token) { if (token.Type != CssTokenType.Whitespace) { if (token.Type == CssTokenType.Ident || token.Type == CssTokenType.String || token.Type == CssTokenType.Number) { _state = State.AttributeEnd; _attrValue = token.Data; } else { _state = State.Data; _valid = false; } } }
private Boolean OnOffset(CssSelectorToken token) { if (token.Type == CssTokenType.Whitespace) { return(false); } if (token.Type == CssTokenType.Number) { _valid = _valid && Int32.TryParse(token.Data, NumberStyles.Integer, CultureInfo.InvariantCulture, out _offset); _offset *= _sign; _state = ParseState.BeforeOf; return(false); } return(OnBeforeOf(token)); }
protected override Boolean OnToken(CssSelectorToken token) { if (token.Type == CssTokenType.Ident || token.Type == CssTokenType.String) { _value = token.Data; } else if (token.Type == CssTokenType.RoundBracketClose) { return(true); } else if (token.Type != CssTokenType.Whitespace) { _valid = false; } return(false); }
private void OnDelim(CssSelectorToken token) { switch (token.Data[0]) { case Symbols.Comma: InsertOr(); _ready = false; break; case Symbols.GreaterThan: Insert(CssCombinator.Child); _ready = false; break; case Symbols.Plus: Insert(CssCombinator.AdjacentSibling); _ready = false; break; case Symbols.Tilde: Insert(CssCombinator.Sibling); _ready = false; break; case Symbols.Asterisk: Insert(AllSelector.Instance); _ready = true; break; case Symbols.Pipe: if (_combinators.Count > 0 && _combinators.Peek() == CssCombinator.Descendent) { Insert(new TypeSelector(String.Empty)); } Insert(CssCombinator.Namespace); _ready = false; break; default: _valid = false; break; } }
private void OnPseudoElement(CssSelectorToken token) { _state = State.Data; _ready = true; if (token.Type == CssTokenType.Ident) { var sel = _pseudoElementSelector.Create(token.Data); if (sel != null) { _valid = _valid && !_nested; Insert(sel); return; } } _valid = false; }
private void Apply(CssSelectorToken token) { _invoked = true; switch (_state) { case State.Data: OnData(token); break; case State.Attribute: OnAttribute(token); break; case State.AttributeOperator: OnAttributeOperator(token); break; case State.AttributeValue: OnAttributeValue(token); break; case State.AttributeEnd: OnAttributeEnd(token); break; case State.PseudoClass: OnPseudoClass(token); break; case State.PseudoElement: OnPseudoElement(token); break; case State.Function: OnFunctionState(token); break; default: _valid = false; break; } }
protected override Boolean OnToken(CssSelectorToken token) { if (token.Type != CssTokenType.RoundBracketClose || _nested._state != State.Data) { if (_firstToken && token.Type == CssTokenType.Delim) { // Roughly equivalent to inserting an implicit :scope _nested.Insert(ScopePseudoClassSelector.Instance); _nested.Apply(CssSelectorToken.Whitespace); _matchSiblings = true; } _firstToken = false; _nested.Apply(token); return(false); } return(true); }
protected override Boolean OnToken(CssSelectorToken token) { switch (_state) { case ParseState.Initial: return(OnInitial(token)); case ParseState.AfterInitialSign: return(OnAfterInitialSign(token)); case ParseState.Offset: return(OnOffset(token)); case ParseState.BeforeOf: return(OnBeforeOf(token)); default: return(OnAfter(token)); } }
private Boolean OnBeforeOf(CssSelectorToken token) { if (token.Type == CssTokenType.Whitespace) { return(false); } if (token.Data.Isi(Keywords.Of)) { _valid = _allowOf; _state = ParseState.AfterOf; _nested = _parent.CreateChild(); return(false); } else if (token.Type == CssTokenType.RoundBracketClose) { return(true); } _valid = false; return(false); }
private void OnAttributeEnd(CssSelectorToken token) { if (!_attrInsensitive && token.Type == CssTokenType.Ident && token.Data == "i") { _attrInsensitive = true; } else if (token.Type != CssTokenType.Whitespace) { _state = State.Data; _ready = true; if (token.Type == CssTokenType.SquareBracketClose) { var selector = _attributeSelector.Create(_attrOp, _attrName, _attrValue, _attrNs, _attrInsensitive); _attrInsensitive = false; Insert(selector); } else { _valid = false; } } }
private void OnFunctionState(CssSelectorToken token) { if (_function.Finished(token)) { var sel = _function.Produce(); if (_nested && _function is NotFunctionState) { sel = null; } _function = null; _state = State.Data; _ready = true; if (sel != null) { Insert(sel); return; } _valid = false; } }
protected abstract Boolean OnToken(CssSelectorToken token);
public Boolean Finished(CssSelectorToken token) { return(OnToken(token)); }
private void OnData(CssSelectorToken token) { switch (token.Type) { //Begin of attribute [A] case CssTokenType.SquareBracketOpen: _attrName = null; _attrValue = null; _attrOp = String.Empty; _attrNs = null; _state = State.Attribute; _ready = false; break; //Begin of Pseudo :P case CssTokenType.Colon: _state = State.PseudoClass; _ready = false; break; //Begin of ID #I case CssTokenType.Hash: Insert(new IdSelector(token.Data)); _ready = true; break; //Begin of Class .c case CssTokenType.Class: Insert(new ClassSelector(token.Data)); _ready = true; break; //Begin of Type E case CssTokenType.Ident: Insert(new TypeSelector(token.Data)); _ready = true; break; //Whitespace could be significant case CssTokenType.Whitespace: Insert(CssCombinator.Descendent); break; //Various case CssTokenType.Delim: OnDelim(token); break; case CssTokenType.Comma: InsertOr(); _ready = false; break; case CssTokenType.Column: Insert(CssCombinator.Column); _ready = false; break; case CssTokenType.Descendent: Insert(CssCombinator.Descendent); _ready = false; break; case CssTokenType.Deep: Insert(CssCombinator.Deep); _ready = false; break; default: _valid = false; break; } }