You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.0 KiB
107 lines
3.0 KiB
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' |
|
};
|
|
|