internal void Apply(Block token) { switch (_selectorOperation) { case SelectorOperation.Data: ParseSymbol(token); break; case SelectorOperation.Class: ParseClass(token); break; case SelectorOperation.Attribute: ParseAttribute(token); break; case SelectorOperation.AttributeOperator: ParseAttributeOperator(token); break; case SelectorOperation.AttributeValue: ParseAttributeValue(token); break; case SelectorOperation.AttributeEnd: ParseAttributeEnd(token); break; case SelectorOperation.PseudoClass: ParsePseudoClass(token); break; case SelectorOperation.PseudoClassFunction: ParsePseudoClassFunction(token); break; case SelectorOperation.PseudoClassFunctionEnd: PrasePseudoClassFunctionEnd(token); break; case SelectorOperation.PseudoElement: ParsePseudoElement(token); break; } }
private bool ParseImportant(Block token) { if (token.GrammarSegment != GrammarSegment.Ident || ((SymbolBlock)token).Value != "important") { return ParsePostValue(token); } SetParsingContext(ParsingContext.AfterValue); _property.Important = true; return true; }
private void ParseDelimiter(Block token) { switch (((DelimiterBlock)token).Value) { case Specification.Comma: InsertCommaDelimited(); return; case Specification.GreaterThan: Insert(Combinator.Child); return; case Specification.PlusSign: Insert(Combinator.AdjacentSibling); return; case Specification.Tilde: Insert(Combinator.Sibling); return; case Specification.Asterisk: Insert(AllSelector.All()); return; case Specification.Period: _selectorOperation = SelectorOperation.Class; return; case Specification.Pipe: Insert(Combinator.Namespace); return; } }
private void PrasePseudoClassFunctionEnd(Block token) { _selectorOperation = SelectorOperation.Data; if (token.GrammarSegment != GrammarSegment.ParenClose) { return; } switch (_attributeName) { case PseudoSelectorPrefix.PseudoFunctionNthchild: Insert(GetChildSelector(PseudoTypes.FunctionNthchild)); break; case PseudoSelectorPrefix.PseudoFunctionNthlastchild: Insert(GetChildSelector(PseudoTypes.FunctionNthlastchild)); break; case PseudoSelectorPrefix.PseudoFunctionNthOfType: Insert(GetChildSelector(PseudoTypes.FunctionNthOfType)); break; case PseudoSelectorPrefix.PseudoFunctionNthLastOfType: Insert(GetChildSelector(PseudoTypes.FunctionNthLastOfType)); break; case PseudoSelectorPrefix.PseudoFunctionNot: { var selector = _nestedSelectorFactory.GetSelector(); Insert(new PseudoFunction(PseudoTypes.FunctionNot) { Body = selector }); break; } case PseudoSelectorPrefix.PseudoFunctionDir: { Insert(new PseudoFunction(PseudoTypes.FunctionDir) { Body = _attributeValue }); break; } case PseudoSelectorPrefix.PseudoFunctionLang: { Insert(new PseudoFunction(PseudoTypes.FunctionLang) { Body = _attributeValue }); break; } case PseudoSelectorPrefix.PseudoFunctionContains: { Insert(new PseudoFunction(PseudoTypes.FunctionContains) { Body = _attributeValue }); break; } } }
private void ParseClass(Block token) { _selectorOperation = SelectorOperation.Data; if (token.GrammarSegment == GrammarSegment.Ident) { Insert(AttributeRestriction.Class(((SymbolBlock)token).Value)); } }
private void ParsePseudoClass(Block token) { _selectorOperation = SelectorOperation.Data; switch (token.GrammarSegment) { case GrammarSegment.Colon: _selectorOperation = SelectorOperation.PseudoElement; break; case GrammarSegment.Function: _attributeName = ((SymbolBlock)token).Value; _attributeValue = string.Empty; _selectorOperation = SelectorOperation.PseudoClassFunction; if (_nestedSelectorFactory != null) { _nestedSelectorFactory.ResetFactory(); } break; case GrammarSegment.Ident: var pseudoSelector = GetPseudoSelector(token); if (pseudoSelector != null) { Insert(pseudoSelector); } break; } }
private void ParseAttributeValue(Block token) { if (token.GrammarSegment == GrammarSegment.Whitespace) { return; } _selectorOperation = SelectorOperation.AttributeEnd; switch (token.GrammarSegment) { case GrammarSegment.Ident: _attributeValue = ((SymbolBlock)token).Value; break; case GrammarSegment.String: _attributeValue = ((StringBlock)token).Value; break; case GrammarSegment.Number: _attributeValue = ((NumericBlock)token).Value.ToString(CultureInfo.InvariantCulture); break; default: _selectorOperation = SelectorOperation.Data; break; } }
private void ParseAttribute(Block token) { if (token.GrammarSegment == GrammarSegment.Whitespace) { return; } _selectorOperation = SelectorOperation.AttributeOperator; switch (token.GrammarSegment) { case GrammarSegment.Ident: _attributeName = ((SymbolBlock)token).Value; break; case GrammarSegment.String: _attributeName = ((StringBlock)token).Value; break; default: _selectorOperation = SelectorOperation.Data; break; } }
private bool ParseKeyframesData(Block token) { if (token.GrammarSegment == GrammarSegment.CurlyBracketClose) { SetParsingContext(ParsingContext.DataBlock); return FinalizeRule(); } _buffer = new StringBuilder(); return ParseKeyframeText(token); }
private bool ParsePreKeyframesData(Block token) { if (token.GrammarSegment != GrammarSegment.CurlyBraceOpen) { return false; } SetParsingContext(ParsingContext.BeforeKeyframesData); return true; }
private bool ParseKeyframesName(Block token) { //SetParsingContext(ParsingContext.BeforeKeyframesData); if (token.GrammarSegment == GrammarSegment.Ident) { CastRuleSet<KeyframesRule>().Identifier = ((SymbolBlock)token).Value; return true; } if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen) { SetParsingContext(ParsingContext.KeyframesData); return true; } return false; }
private bool ParseFontface(Block token) { if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen) { SetParsingContext(ParsingContext.InDeclaration); return true; } return false; }
private bool ParseImport(Block token) { if (token.GrammarSegment == GrammarSegment.String || token.GrammarSegment == GrammarSegment.Url) { CastRuleSet<ImportRule>().Href = ((StringBlock)token).Value; SetParsingContext(ParsingContext.InMediaList); return true; } SetParsingContext(ParsingContext.AfterInstruction); return false; }
private bool ParseCharacterSet(Block token) { SetParsingContext(ParsingContext.AfterInstruction); if (token.GrammarSegment != GrammarSegment.String) { return ParsePostInstruction(token); } CastRuleSet<CharacterSetRule>().Encoding = ((StringBlock)token).Value; return true; }
private bool ParseNamespace(Block token) { SetParsingContext(ParsingContext.AfterInstruction); if (token.GrammarSegment != GrammarSegment.String) { return ParsePostInstruction(token); } CastRuleSet<NamespaceRule>().Uri = ((StringBlock)token).Value; return true; }
private bool ParseMediaValue(Block token) { switch (token.GrammarSegment) { case GrammarSegment.CurlyBraceOpen: case GrammarSegment.Semicolon: { var container = CurrentRule as ISupportsMedia; if (container != null) { container.Media.AppendMedium(_mediaDefn); } if (CurrentRule is ImportRule) { return ParsePostInstruction(token); } SetParsingContext(ParsingContext.DataBlock); _mediaDefn = null; return token.GrammarSegment == GrammarSegment.CurlyBraceOpen; } case GrammarSegment.Comma: { var container = CurrentRule as ISupportsMedia; if (container != null) { container.Media.AppendMedium(_mediaDefn); } _mediaDefn = null; return true; } case GrammarSegment.Whitespace: { // Do Nothing return true; } default: { if (_mediaDefn == null) _mediaDefn = new MediaDefinition(); switch (token.ToString()) { case "only": _mediaDefn.Modifier = MediaTypeModifier.Only; break; case "not": _mediaDefn.Modifier = MediaTypeModifier.Not; break; case "screen": _mediaDefn.Type = MediaType.Screen; break; case "speech": _mediaDefn.Type = MediaType.Speech; break; case "print": _mediaDefn.Type = MediaType.Print; break; case "all": _mediaDefn.Type = MediaType.All; break; case "braille": _mediaDefn.Type = MediaType.Braille; break; case "embossed": _mediaDefn.Type = MediaType.Embossed; break; case "handheld": _mediaDefn.Type = MediaType.Handheld; break; case "projection": _mediaDefn.Type = MediaType.Projection; break; case "tty": _mediaDefn.Type = MediaType.Tty; break; case "tv": _mediaDefn.Type = MediaType.Tv; break; case "and": // do nothing break; case "(": _mediaProp = new MediaProperty(); break; case ")": if (_mediaProp != null) { var plain = _mediaProp as MediaPropertyPlain; if (plain != null && _terms.Length == 1) { plain.Value = _terms[0]; } else if (!string.IsNullOrEmpty(_compare1) && _terms.Length > 0) { var range = new MediaPropertyRange { Name = _mediaProp.Name }; if (_nameFirst) { if (_compare1.StartsWith("<")) { range.UpperBound = _terms[0]; range.UpperCompare = _compare1; } else { range.LowerBound = _terms[0]; range.LowerCompare = _compare1.Replace('>', '<'); } } else { if (_terms.Length == 1) { if (_compare1.StartsWith(">")) { range.UpperBound = _terms[0]; range.UpperCompare = _compare1.Replace('>', '<'); } else { range.LowerBound = _terms[0]; range.LowerCompare = _compare1; } } else { if (_compare1.StartsWith("<")) { range.LowerBound = _terms[0]; range.LowerCompare = _compare1; range.UpperBound = _terms[1]; range.UpperCompare = _compare2; } else { range.UpperBound = _terms[0]; range.UpperCompare = _compare1.Replace('>', '<'); range.LowerBound = _terms[1]; range.LowerCompare = _compare2.Replace('>', '<'); } } } _mediaProp = range; } _mediaDefn.Properties.Add(_mediaProp); } _compare1 = null; _compare2 = null; _mediaProp = null; _terms = new TermList(); break; case ":": if (_mediaProp != null) _mediaProp = new MediaPropertyPlain { Name = _mediaProp.Name }; break; case "<": case ">": if (string.IsNullOrEmpty(_compare1)) _compare1 = token.ToString(); else _compare2 = token.ToString(); break; case "=": if (string.IsNullOrEmpty(_compare1) || (string.IsNullOrEmpty(_compare2) && _compare1 != "=")) _compare1 = (_compare1 ?? "") + token.ToString(); else _compare2 = (_compare2 ?? "") + token.ToString(); break; default: if (token.GrammarSegment == GrammarSegment.Ident && string.IsNullOrEmpty(_mediaProp.Name)) { _mediaProp.Name = token.ToString(); _nameFirst = string.IsNullOrEmpty(_compare1); } else { ParseSingleValue(token); } break; } return true; } } }
private void ParseSymbol(Block token) { switch (token.GrammarSegment) { // Attribute [A] case GrammarSegment.SquareBraceOpen: _attributeName = null; _attributeValue = null; _attributeOperator = string.Empty; _selectorOperation = SelectorOperation.Attribute; return; // Pseudo :P case GrammarSegment.Colon: _selectorOperation = SelectorOperation.PseudoClass; return; // ID #I case GrammarSegment.Hash: Insert(AttributeRestriction.Id(((SymbolBlock)token).Value)); return; // Type E case GrammarSegment.Ident: Insert(ElementRestriction.LocalName(((SymbolBlock)token).Value)); return; // Whitespace case GrammarSegment.Whitespace: Insert(Combinator.Descendent); return; case GrammarSegment.Delimiter: ParseDelimiter(token); return; case GrammarSegment.Comma: InsertCommaDelimited(); return; } }
private bool ParseKeyframeText(Block token) { if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen) { _frame = null; SetParsingContext(ParsingContext.InDeclaration); return true; } if (token.GrammarSegment == GrammarSegment.CurlyBracketClose) { ParseKeyframesData(token); return false; } if (token.GrammarSegment == GrammarSegment.Comma) { return true; } if (_frame == null) { _frame = new KeyframeRule(); _frame.AddValue(token.ToString()); CastRuleSet<KeyframesRule>().Declarations.Add(_frame); _activeRuleSets.Push(_frame); } else { _frame.AddValue(token.ToString()); } return true; }
private void ParseAttributeOperator(Block token) { if (token.GrammarSegment == GrammarSegment.Whitespace) { return; } _selectorOperation = SelectorOperation.AttributeValue; if (token.GrammarSegment == GrammarSegment.SquareBracketClose) { ParseAttributeEnd(token); } else if (token is MatchBlock || token.GrammarSegment == GrammarSegment.Delimiter) { _attributeOperator = token.ToString(); } else { _selectorOperation = SelectorOperation.AttributeEnd; } }
private bool ParsePageSelector(Block token) { if (token.GrammarSegment == GrammarSegment.Colon || token.GrammarSegment == GrammarSegment.Whitespace) { return true; } if (token.GrammarSegment == GrammarSegment.Ident) { CastRuleSet<PageRule>().Selector = ElementRestriction.LocalName(token.ToString()); return true; } if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen) { SetParsingContext(ParsingContext.InDeclaration); return true; } return false; }
private void ParseAttributeEnd(Block token) { if (token.GrammarSegment == GrammarSegment.Whitespace) { return; } _selectorOperation = SelectorOperation.Data; if (token.GrammarSegment != GrammarSegment.SquareBracketClose) { return; } switch (_attributeOperator) { case "=": Insert(new AttributeRestriction(_attributeName) { Comparison = AttributeComparison.Equals, Value = _attributeValue}); break; case "~=": Insert(new AttributeRestriction(_attributeName) { Comparison = AttributeComparison.WhitespaceListContains, Value = _attributeValue }); break; case "|=": Insert(new AttributeRestriction(_attributeName) { Comparison = AttributeComparison.HyphenatedListStartsWith, Value = _attributeValue }); break; case "^=": Insert(new AttributeRestriction(_attributeName) { Comparison = AttributeComparison.StartsWith, Value = _attributeValue }); break; case "$=": Insert(new AttributeRestriction(_attributeName) { Comparison = AttributeComparison.EndsWith, Value = _attributeValue }); break; case "*=": Insert(new AttributeRestriction(_attributeName) { Comparison = AttributeComparison.Contains, Value = _attributeValue }); break; case "!=": Insert(new AttributeRestriction(_attributeName) { Comparison = AttributeComparison.NotEquals, Value = _attributeValue }); break; default: Insert(new AttributeRestriction(_attributeName) { Comparison = AttributeComparison.Exists }); break; } }
private bool ParsePreDocumentFunction(Block token) { switch (token.GrammarSegment) { case GrammarSegment.Url: CastRuleSet<DocumentRule>().Conditions.Add(new KeyValuePair<DocumentFunction, string>(DocumentFunction.Url, ((StringBlock)token).Value)); break; case GrammarSegment.UrlPrefix: CastRuleSet<DocumentRule>().Conditions.Add(new KeyValuePair<DocumentFunction, string>(DocumentFunction.UrlPrefix, ((StringBlock)token).Value)); break; case GrammarSegment.Domain: CastRuleSet<DocumentRule>().Conditions.Add(new KeyValuePair<DocumentFunction, string>(DocumentFunction.Domain, ((StringBlock)token).Value)); break; case GrammarSegment.Function: if (string.Compare(((SymbolBlock)token).Value, "regexp", StringComparison.OrdinalIgnoreCase) == 0) { SetParsingContext(ParsingContext.InDocumentFunction); return true; } SetParsingContext(ParsingContext.AfterDocumentFunction); return false; default: SetParsingContext(ParsingContext.DataBlock); return false; } SetParsingContext(ParsingContext.BetweenDocumentFunctions); return true; }
private void ParsePseudoElement(Block token) { if (token.GrammarSegment != GrammarSegment.Ident) { return; } var data = ((SymbolBlock)token).Value; switch (data) { case PseudoSelectorPrefix.PseudoElementBefore: Insert(new PseudoElementSelector(PseudoElements.Before)); break; case PseudoSelectorPrefix.PseudoElementAfter: Insert(new PseudoElementSelector(PseudoElements.After)); break; case PseudoSelectorPrefix.PseudoElementSelection: Insert(new PseudoElementSelector(PseudoElements.Selection)); break; case PseudoSelectorPrefix.PseudoElementFirstline: Insert(new PseudoElementSelector(PseudoElements.Firstline)); break; case PseudoSelectorPrefix.PseudoElementFirstletter: Insert(new PseudoElementSelector(PseudoElements.Firstletter)); break; default: Insert(new UnknownSelector(":" + data)); break; } }
private bool ParseDocumentFunction(Block token) { SetParsingContext(ParsingContext.AfterDocumentFunction); if (token.GrammarSegment != GrammarSegment.String) return false; CastRuleSet<DocumentRule>().Conditions.Add(new KeyValuePair<DocumentFunction, string>(DocumentFunction.RegExp, ((StringBlock)token).Value)); return true; }
private void ParsePseudoClassFunction(Block token) { if (token.GrammarSegment == GrammarSegment.Whitespace) { return; } switch (_attributeName) { case PseudoSelectorPrefix.PseudoFunctionNthchild: case PseudoSelectorPrefix.PseudoFunctionNthlastchild: case PseudoSelectorPrefix.PseudoFunctionNthOfType: case PseudoSelectorPrefix.PseudoFunctionNthLastOfType: { switch (token.GrammarSegment) { case GrammarSegment.Ident: case GrammarSegment.Number: case GrammarSegment.Dimension: _attributeValue += token.ToString(); return; case GrammarSegment.Delimiter: var chr = ((DelimiterBlock)token).Value; if (chr == Specification.PlusSign || chr == Specification.MinusSign) { _attributeValue += chr; return; } break; } break; } case PseudoSelectorPrefix.PseudoFunctionNot: { if (_nestedSelectorFactory == null) { _nestedSelectorFactory = new SelectorFactory(); } if (token.GrammarSegment != GrammarSegment.ParenClose || _nestedSelectorFactory._selectorOperation != SelectorOperation.Data) { _nestedSelectorFactory.Apply(token); return; } break; } case PseudoSelectorPrefix.PseudoFunctionDir: { if (token.GrammarSegment == GrammarSegment.Ident) { _attributeValue = ((SymbolBlock)token).Value; } _selectorOperation = SelectorOperation.PseudoClassFunctionEnd; return; } case PseudoSelectorPrefix.PseudoFunctionLang: { if (token.GrammarSegment == GrammarSegment.Ident) { _attributeValue = ((SymbolBlock)token).Value; } _selectorOperation = SelectorOperation.PseudoClassFunctionEnd; return; } case PseudoSelectorPrefix.PseudoFunctionContains: { switch (token.GrammarSegment) { case GrammarSegment.String: _attributeValue = ((StringBlock)token).Value; break; case GrammarSegment.Ident: _attributeValue = ((SymbolBlock)token).Value; break; } _selectorOperation = SelectorOperation.PseudoClassFunctionEnd; return; } } PrasePseudoClassFunctionEnd(token); }
private bool ParsePostDocumentFunction(Block token) { SetParsingContext(ParsingContext.BetweenDocumentFunctions); return token.GrammarSegment == GrammarSegment.ParenClose; }
private bool ParseDocumentFunctions(Block token) { if (token.GrammarSegment == GrammarSegment.Comma) { SetParsingContext(ParsingContext.BeforeDocumentFunction); return true; } if (token.GrammarSegment == GrammarSegment.CurlyBraceOpen) { SetParsingContext(ParsingContext.DataBlock); return true; } SetParsingContext(ParsingContext.DataBlock); return false; }
private bool ParseMediaList(Block token) { if (token.GrammarSegment == GrammarSegment.Semicolon) { FinalizeRule(); SetParsingContext(ParsingContext.DataBlock); return true; } _buffer = new StringBuilder(); SetParsingContext(ParsingContext.InMediaValue); return ParseMediaValue(token); }
private static BaseSelector GetPseudoSelector(Block token) { switch (((SymbolBlock)token).Value) { case PseudoSelectorPrefix.PseudoRoot: return new PseudoSelector(PseudoTypes.Root); case PseudoSelectorPrefix.PseudoFirstOfType: return new PseudoSelector(PseudoTypes.FirstOfType); case PseudoSelectorPrefix.PseudoLastoftype: return new PseudoSelector(PseudoTypes.Lastoftype); case PseudoSelectorPrefix.PseudoOnlychild: return new PseudoSelector(PseudoTypes.Onlychild); case PseudoSelectorPrefix.PseudoOnlyOfType: return new PseudoSelector(PseudoTypes.OnlyOfType); case PseudoSelectorPrefix.PseudoFirstchild: return new PseudoSelector(PseudoTypes.Firstchild); case PseudoSelectorPrefix.PseudoLastchild: return new PseudoSelector(PseudoTypes.Lastchild); case PseudoSelectorPrefix.PseudoEmpty: return new PseudoSelector(PseudoTypes.Empty); case PseudoSelectorPrefix.PseudoLink: return new PseudoSelector(PseudoTypes.Link); case PseudoSelectorPrefix.PseudoVisited: return new PseudoSelector(PseudoTypes.Visited); case PseudoSelectorPrefix.PseudoActive: return new PseudoSelector(PseudoTypes.Active); case PseudoSelectorPrefix.PseudoHover: return new PseudoSelector(PseudoTypes.Hover); case PseudoSelectorPrefix.PseudoFocus: return new PseudoSelector(PseudoTypes.Focus); case PseudoSelectorPrefix.PseudoTarget: return new PseudoSelector(PseudoTypes.Target); case PseudoSelectorPrefix.PseudoEnabled: return new PseudoSelector(PseudoTypes.Enabled); case PseudoSelectorPrefix.PseudoDisabled: return new PseudoSelector(PseudoTypes.Disabled); case PseudoSelectorPrefix.PseudoDefault: return new PseudoSelector(PseudoTypes.Default); case PseudoSelectorPrefix.PseudoChecked: return new PseudoSelector(PseudoTypes.Checked); case PseudoSelectorPrefix.PseudoIndeterminate: return new PseudoSelector(PseudoTypes.Indeterminate); case PseudoSelectorPrefix.PseudoUnchecked: return new PseudoSelector(PseudoTypes.Unchecked); case PseudoSelectorPrefix.PseudoValid: return new PseudoSelector(PseudoTypes.Valid); case PseudoSelectorPrefix.PseudoInvalid: return new PseudoSelector(PseudoTypes.Invalid); case PseudoSelectorPrefix.PseudoRequired: return new PseudoSelector(PseudoTypes.Required); case PseudoSelectorPrefix.PseudoReadonly: return new PseudoSelector(PseudoTypes.Readonly); case PseudoSelectorPrefix.PseudoReadwrite: return new PseudoSelector(PseudoTypes.Readwrite); case PseudoSelectorPrefix.PseudoInrange: return new PseudoSelector(PseudoTypes.Inrange); case PseudoSelectorPrefix.PseudoOutofrange: return new PseudoSelector(PseudoTypes.Outofrange); case PseudoSelectorPrefix.PseudoOptional: return new PseudoSelector(PseudoTypes.Optional); case PseudoSelectorPrefix.PseudoElementBefore: return new PseudoElementSelector(PseudoElements.Before); case PseudoSelectorPrefix.PseudoElementAfter: return new PseudoElementSelector(PseudoElements.After); case PseudoSelectorPrefix.PseudoElementFirstline: return new PseudoElementSelector(PseudoElements.Firstline); case PseudoSelectorPrefix.PseudoElementFirstletter: return new PseudoElementSelector(PseudoElements.Firstletter); case PseudoSelectorPrefix.PseudoElementSelection: return new PseudoElementSelector(PseudoElements.Selection); default: return new UnknownSelector(":" + token.ToString()); } }
private bool ParsePostValue(Block token) { if (token.GrammarSegment == GrammarSegment.Semicolon) { FinalizeProperty(); SetParsingContext(ParsingContext.InDeclaration); return true; } if (token.GrammarSegment == GrammarSegment.CurlyBracketClose) { return ParseDeclaration(token); } return false; }