public Directive KeyFrameBlock(Parser parser, string name, string identifier, int index) { if (!parser.Tokenizer.Match('{')) { return(null); } NodeList keyFrames = new NodeList(); const string identifierRegEx = "from|to|([0-9]+%)"; while (true) { GatherComments(parser); string keyFrameIdentifier; var keyFrameIdentifier1 = parser.Tokenizer.Match(identifierRegEx); if (!keyFrameIdentifier1) { break; } keyFrameIdentifier = keyFrameIdentifier1.Value; if (parser.Tokenizer.Match(",")) { var keyFrameIdentifier2 = parser.Tokenizer.Match(identifierRegEx); if (!keyFrameIdentifier2) { throw new ParsingException("Comma in @keyframe followed by unknown identifier", parser.Tokenizer.Location.Index); } keyFrameIdentifier += "," + keyFrameIdentifier2; } var preComments = GatherAndPullComments(parser); var block = Block(parser); if (block == null) { throw new ParsingException("Expected css block after key frame identifier", parser.Tokenizer.Location.Index); } block.PreComments = preComments; block.PostComments = GatherAndPullComments(parser); keyFrames.Add(NodeProvider.KeyFrame(keyFrameIdentifier, block, parser.Tokenizer.Location.Index)); } if (!parser.Tokenizer.Match('}')) { throw new ParsingException("Expected start, finish, % or '}'", parser.Tokenizer.Location.Index); } return(NodeProvider.Directive(name, identifier, keyFrames, index)); }
public Directive Media(Parser parser) { if (!parser.Tokenizer.Match("@media")) { return(null); } var index = parser.Tokenizer.Location.Index; var features = MediaFeatures(parser); var preRulesComments = GatherAndPullComments(parser); var rules = Block(parser); if (rules != null) { rules.PreComments = preRulesComments; return(NodeProvider.Directive("@media", rules, features, index)); } throw new ParsingException("@media block with unrecognised format", index); }
// // A CSS Directive // // @charset "utf-8"; // public Directive Directive(Parser parser) { if (parser.Tokenizer.CurrentChar != '@') { return(null); } var import = Import(parser); if (import) { return(import); } GatherComments(parser); var index = parser.Tokenizer.Location.Index; var name = parser.Tokenizer.MatchString(@"@[-a-z]+"); bool hasIdentifier = false, hasBlock = false, isKeyFrame = false; NodeList rules, preRulesComments = null, preComments = null; string identifierRegEx = @"[^{]+"; string nonVendorSpecificName = name; if (name.StartsWith("@-") && name.IndexOf('-', 2) > 0) { nonVendorSpecificName = "@" + name.Substring(name.IndexOf('-', 2) + 1); } switch (nonVendorSpecificName) { case "@font-face": hasBlock = true; break; case "@page": case "@document": case "@media": case "@supports": hasBlock = true; hasIdentifier = true; break; case "@top-left": case "@top-left-corner": case "@top-center": case "@top-right": case "@top-right-corner": case "@bottom-left": case "@bottom-left-corner": case "@bottom-center": case "@bottom-right": case "@bottom-right-corner": case "@left-top": case "@left-middle": case "@left-bottom": case "@right-top": case "@right-middle": case "@right-bottom": hasBlock = true; break; case "@keyframes": isKeyFrame = true; hasIdentifier = true; break; } string identifier = ""; preComments = PullComments(); if (hasIdentifier) { GatherComments(parser); var identifierRegResult = parser.Tokenizer.MatchAny(identifierRegEx); if (identifierRegResult != null) { identifier = identifierRegResult.Value.Trim(); } } preRulesComments = GatherAndPullComments(parser); if (hasBlock) { rules = Block(parser); if (rules != null) { rules.PreComments = preRulesComments; return(NodeProvider.Directive(name, identifier, rules, index)); } } else if (isKeyFrame) { var keyframeblock = KeyFrameBlock(parser, name, identifier, index); keyframeblock.PreComments = preRulesComments; return(keyframeblock); } else { Node value; if (value = Expression(parser)) { value.PreComments = preRulesComments; value.PostComments = GatherAndPullComments(parser); if (parser.Tokenizer.Match(';')) { var directive = NodeProvider.Directive(name, value, index); directive.PreComments = preComments; return(directive); } } } return(null); }