|
|
- var TYPE = require('../../tokenizer').TYPE;
- var rawMode = require('./Raw').mode;
-
- var ATKEYWORD = TYPE.AtKeyword;
- var SEMICOLON = TYPE.Semicolon;
- var LEFTCURLYBRACKET = TYPE.LeftCurlyBracket;
- var RIGHTCURLYBRACKET = TYPE.RightCurlyBracket;
-
- function consumeRaw(startToken) {
- return this.Raw(startToken, rawMode.leftCurlyBracketOrSemicolon, true);
- }
-
- function isDeclarationBlockAtrule() {
- for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
- if (type === RIGHTCURLYBRACKET) {
- return true;
- }
-
- if (type === LEFTCURLYBRACKET ||
- type === ATKEYWORD) {
- return false;
- }
- }
-
- return false;
- }
-
- module.exports = {
- name: 'Atrule',
- structure: {
- name: String,
- prelude: ['AtrulePrelude', 'Raw', null],
- block: ['Block', null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var name;
- var nameLowerCase;
- var prelude = null;
- var block = null;
-
- this.eat(ATKEYWORD);
-
- name = this.scanner.substrToCursor(start + 1);
- nameLowerCase = name.toLowerCase();
- this.scanner.skipSC();
-
- // parse prelude
- if (this.scanner.eof === false &&
- this.scanner.tokenType !== LEFTCURLYBRACKET &&
- this.scanner.tokenType !== SEMICOLON) {
- if (this.parseAtrulePrelude) {
- prelude = this.parseWithFallback(this.AtrulePrelude.bind(this, name), consumeRaw);
-
- // turn empty AtrulePrelude into null
- if (prelude.type === 'AtrulePrelude' && prelude.children.head === null) {
- prelude = null;
- }
- } else {
- prelude = consumeRaw.call(this, this.scanner.tokenIndex);
- }
-
- this.scanner.skipSC();
- }
-
- switch (this.scanner.tokenType) {
- case SEMICOLON:
- this.scanner.next();
- break;
-
- case LEFTCURLYBRACKET:
- if (this.atrule.hasOwnProperty(nameLowerCase) &&
- typeof this.atrule[nameLowerCase].block === 'function') {
- block = this.atrule[nameLowerCase].block.call(this);
- } else {
- // TODO: should consume block content as Raw?
- block = this.Block(isDeclarationBlockAtrule.call(this));
- }
-
- break;
- }
-
- return {
- type: 'Atrule',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- prelude: prelude,
- block: block
- };
- },
- generate: function(node) {
- this.chunk('@');
- this.chunk(node.name);
-
- if (node.prelude !== null) {
- this.chunk(' ');
- this.node(node.prelude);
- }
-
- if (node.block) {
- this.node(node.block);
- } else {
- this.chunk(';');
- }
- },
- walkContext: 'atrule'
- };
|