Skip to content
2 changes: 1 addition & 1 deletion parse.es6
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const Input = require('postcss/lib/input')

const Parser = require('./parser')
const Parser = require('./parser.es6')

module.exports = (sass, opts) => {
const input = new Input(sass, opts)
Expand Down
211 changes: 188 additions & 23 deletions parser.es6
Original file line number Diff line number Diff line change
Expand Up @@ -381,29 +381,7 @@ class SassParser {
declarationDelimiter (node) {
this.raws.before += node.content
}
loop (node, parent) {
const loop = postcss.rule()
this.raws.comment = false
this.raws.multiRule = false
this.raws.loop = true
loop.selector = ''
loop.raws = {
before: this.raws.before || DEFAULT_RAWS_RULE.before,
between: DEFAULT_RAWS_RULE.between
}
if (this.raws.beforeMulti) {
loop.raws.before += this.raws.beforeMulti
this.raws.beforeMulti = undefined
}
node.content.forEach((contentNode, i) => {
if (node.content[i + 1] && node.content[i + 1].type === 'block') {
this.raws.loop = false
}
this.process(contentNode, loop)
})
parent.nodes.push(loop)
this.raws.loop = false
}

atkeyword (node, parent) {
parent.selector += `@${ node.content }`
}
Expand All @@ -420,6 +398,193 @@ class SassParser {
ident (node, parent) {
parent.selector += node.content
}

atrule (node, parent) {
// Loop to find the deepest ruleset node
this.raws.multiRuleProp = ''

node.content.forEach(contentNode => {
switch (contentNode.type) {
case 'block': {
// Create Rule node
const atrule = postcss.atRule()
atrule.name = node.type === 'atrule' ? 'media' : node.type
atrule.nodes = []

// Object to store raws for Atrule
const atRuleRaws = {
before: this.raws.before || DEFAULT_RAWS_RULE.before,
between: DEFAULT_RAWS_RULE.between,
afterName: ''
}

// Variable to store spaces and symbols before declaration property
this.raws.before = ''
this.raws.comment = false

// Look up throw all nodes in current atrule node
node.content
.filter(content => content.type === 'block')
.forEach(innerContentNode => this.process(innerContentNode, atrule))

if (atrule.nodes.length) {
// create a 'selector'('atname' + atRuleRaws.afterName + 'atrule parameters') string from the node
let atSelectorString = this.extractSource(
node.start,
contentNode.start
).slice(1, -1).replace(/\s+$/, spaces => {
if (spaces.indexOf('\n') > -1) {
atRuleRaws.after = spaces.slice(spaces.indexOf('\n'))
spaces = spaces.slice(0, spaces.indexOf('\n'))
}
atRuleRaws.between = spaces
return ''
})
if (node.type === 'atrule') {
// save spaces between the name of atrule and parameters
atSelectorString = atSelectorString.slice(atSelectorString.indexOf(' '))
atRuleRaws.afterName = atSelectorString.slice(0, atSelectorString.search(/[a-z]|\(|\.|#|'|"|\$/i))

// save the parameters of this atRule
atrule.params = atSelectorString.slice(atSelectorString.search(/[a-z]|\(|\.|#|'|"|\$/i))
} else {
// save the parameters of this atRule
atrule.params = atSelectorString
}

// Set parameters for Atrule node
atrule.parent = parent
atrule.source = {
start: node.start,
end: node.end,
input: this.input
}
atrule.raws = atRuleRaws
parent.nodes.push(atrule)
}
break
}
default:
}
})
}

mixin (node, parent) {
this.atrule(node, parent)
}

include (node, parent) {
// if include has content than call this.atrule
for (const contentNode of node.content) {
if (contentNode.type === 'block') {
this.atrule(node, parent)
return
}
}

// Loop to find the deepest ruleset node
this.raws.multiRuleProp = ''

// Create Rule node
const atrule = postcss.atRule()
atrule.name = node.type

// Object to store raws for Atrule
const atRuleRaws = {
before: this.raws.before || DEFAULT_RAWS_RULE.before,
between: DEFAULT_RAWS_RULE.between,
afterName: ''
}

// Variable to store spaces and symbols before declaration property
this.raws.before = ''
this.raws.comment = false

// create a 'selector'('atname' + atRuleRaws.afterName + 'atrule parameters') string from the node
const atSelectorString = this.extractSource(
node.start,
{
line: node.content[node.content.length - 1].start.line,
column: undefined
}
).replace(/\s+$/, spaces => {
if (spaces.indexOf('\n') > -1) {
atRuleRaws.after = spaces.slice(spaces.indexOf('\n'))
spaces = spaces.slice(0, spaces.indexOf('\n'))
}
atRuleRaws.between = spaces
return ''
})

// save the parameters of this atRule
atrule.params = atSelectorString.slice(1)

// Set parameters for Atrule node
atrule.parent = parent
atrule.source = {
start: node.start,
end: node.end,
input: this.input
}
atrule.raws = atRuleRaws
parent.nodes.push(atrule)
}

loop (node, parent) {
this.atrule(node, parent)
}
extend (node, parent) {
// Loop to find the deepest ruleset node
this.raws.multiRuleProp = ''

// Create Rule node
const atrule = postcss.atRule()
atrule.name = node.type

// Object to store raws for Atrule
const atRuleRaws = {
before: this.raws.before || DEFAULT_RAWS_RULE.before,
between: DEFAULT_RAWS_RULE.between,
afterName: ''
}

// Variable to store spaces and symbols before declaration property
this.raws.before = ''
this.raws.comment = false

// create a 'selector'('atname' + atRuleRaws.afterName + 'atrule parameters') string from the node
let atSelectorString = this.extractSource(
node.start,
{
line: node.content[node.content.length - 1].start.line,
column: undefined
}
).replace(/\s+$/, spaces => {
if (spaces.indexOf('\n') > -1) {
atRuleRaws.after = spaces.slice(spaces.indexOf('\n'))
spaces = spaces.slice(0, spaces.indexOf('\n'))
}
atRuleRaws.between = spaces
return ''
})

// save spaces between the name of atrule and parameters
atSelectorString = atSelectorString.slice(atSelectorString.indexOf(' '))
atRuleRaws.afterName = atSelectorString.slice(0, atSelectorString.search(/[a-z]|\(|\.|#|'|"|\$/i))

// save the parameters of this atRule
atrule.params = atSelectorString.slice(atSelectorString.search(/[a-z]|\(|\.|#|'|"|\$/i))

// Set parameters for Atrule node
atrule.parent = parent
atrule.source = {
start: node.start,
end: node.end,
input: this.input
}
atrule.raws = atRuleRaws
parent.nodes.push(atrule)
}
}

module.exports = SassParser