123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585 |
- "use strict";
- var postcss = require('postcss');
- var gonzales = require('gonzales-pe');
- var DEFAULT_RAWS_ROOT = {
- before: ''
- };
- var DEFAULT_RAWS_RULE = {
- before: '',
- between: ''
- };
- var DEFAULT_RAWS_DECL = {
- before: '',
- between: '',
- semicolon: false
- };
- var DEFAULT_COMMENT_DECL = {
- before: ''
- };
- var SUPPORTED_AT_KEYWORDS = ['media'];
- var SassParser =
- function () {
- function SassParser(input) {
- this.input = input;
- }
- var _proto = SassParser.prototype;
- _proto.parse = function parse() {
- try {
- this.node = gonzales.parse(this.input.css, {
- syntax: 'sass'
- });
- } catch (error) {
- throw this.input.error(error.message, error.line, 1);
- }
- this.lines = this.input.css.match(/^.*(\r?\n|$)/gm);
- this.root = this.stylesheet(this.node);
- };
- _proto.extractSource = function extractSource(start, end) {
- var nodeLines = this.lines.slice(start.line - 1, end.line);
- nodeLines[0] = nodeLines[0].substring(start.column - 1);
- var last = nodeLines.length - 1;
- nodeLines[last] = nodeLines[last].substring(0, end.column);
- return nodeLines.join('');
- };
- _proto.stylesheet = function stylesheet(node) {
- var _this = this;
-
- var root = postcss.root();
- root.source = {
- start: node.start,
- end: node.end,
- input: this.input
- };
- root.raws = {
- semicolon: DEFAULT_RAWS_ROOT.semicolon,
- before: DEFAULT_RAWS_ROOT.before
- };
- this.raws = {
- before: ''
- };
- node.content.forEach(function (contentNode) {
- return _this.process(contentNode, root);
- });
- return root;
- };
- _proto.process = function process(node, parent) {
- if (this[node.type]) return this[node.type](node, parent) || null;
- return null;
- };
- _proto.ruleset = function ruleset(node, parent) {
- var _this2 = this;
-
- this.raws.multiRuleProp = '';
- node.content.forEach(function (contentNode) {
- switch (contentNode.type) {
- case 'block':
- {
-
- var rule = postcss.rule();
- rule.selector = '';
- var ruleRaws = {
- before: _this2.raws.before || DEFAULT_RAWS_RULE.before,
- between: DEFAULT_RAWS_RULE.between
- };
- _this2.raws.before = '';
- _this2.raws.comment = false;
- node.content.filter(function (content) {
- return content.type === 'block';
- }).forEach(function (innerContentNode) {
- return _this2.process(innerContentNode, rule);
- });
- if (rule.nodes.length) {
-
- rule.selector = _this2.extractSource(node.start, contentNode.start).slice(0, -1).replace(/\s+$/, function (spaces) {
- ruleRaws.between = spaces;
- return '';
- });
- rule.parent = parent;
- rule.source = {
- start: node.start,
- end: node.end,
- input: _this2.input
- };
- rule.raws = ruleRaws;
- parent.nodes.push(rule);
- }
- break;
- }
- default:
- }
- });
- };
- _proto.block = function block(node, parent) {
- var _this3 = this;
-
- if (this.raws.multiRule) {
- if (this.raws.multiRulePropVariable) {
- this.raws.multiRuleProp = "$" + this.raws.multiRuleProp;
- }
- var multiRule = Object.assign(postcss.rule(), {
- source: {
- start: {
- line: node.start.line - 1,
- column: node.start.column
- },
- end: node.end,
- input: this.input
- },
- raws: {
- before: this.raws.before || DEFAULT_RAWS_RULE.before,
- between: DEFAULT_RAWS_RULE.between
- },
- parent: parent,
- selector: (this.raws.customProperty ? '--' : '') + this.raws.multiRuleProp
- });
- parent.push(multiRule);
- parent = multiRule;
- }
- this.raws.before = '';
- node.content.forEach(function (contentNode) {
- return _this3.process(contentNode, parent);
- });
- if (this.raws.multiRule) {
- this.raws.beforeMulti = this.raws.before;
- }
- };
- _proto.declaration = function declaration(node, parent) {
- var _this4 = this;
- var isBlockInside = false;
- var declarationNode = postcss.decl();
- declarationNode.prop = '';
- var declarationRaws = Object.assign(declarationNode.raws, {
- before: this.raws.before || DEFAULT_RAWS_DECL.before,
- between: DEFAULT_RAWS_DECL.between,
- semicolon: DEFAULT_RAWS_DECL.semicolon
- });
- this.raws.property = false;
- this.raws.betweenBefore = false;
- this.raws.comment = false;
- node.content.forEach(function (contentNode) {
- switch (contentNode.type) {
- case 'customProperty':
- _this4.raws.customProperty = true;
-
- case 'property':
- {
-
- _this4.raws.property = true;
- _this4.raws.multiRuleProp = contentNode.content[0].content;
- _this4.raws.multiRulePropVariable = contentNode.content[0].type === 'variable';
- _this4.process(contentNode, declarationNode);
- break;
- }
- case 'propertyDelimiter':
- {
- if (_this4.raws.property && !_this4.raws.betweenBefore) {
-
- declarationRaws.between += contentNode.content;
- _this4.raws.multiRuleProp += contentNode.content;
- } else {
-
- _this4.raws.betweenBefore = true;
- declarationRaws.before += contentNode.content;
- _this4.raws.multiRuleProp += contentNode.content;
- }
- break;
- }
- case 'space':
- {
- declarationRaws.between += contentNode.content;
- break;
- }
- case 'value':
- {
-
- switch (contentNode.content[0].type) {
- case 'block':
- {
- isBlockInside = true;
- if (Array.isArray(contentNode.content[0].content)) {
- _this4.raws.multiRule = true;
- }
- _this4.process(contentNode.content[0], parent);
- break;
- }
- case 'variable':
- {
- declarationNode.value = '$';
- _this4.process(contentNode, declarationNode);
- break;
- }
- case 'color':
- {
- declarationNode.value = '#';
- _this4.process(contentNode, declarationNode);
- break;
- }
- case 'number':
- {
- if (contentNode.content.length > 1) {
- declarationNode.value = contentNode.content.join('');
- } else {
- _this4.process(contentNode, declarationNode);
- }
- break;
- }
- case 'parentheses':
- {
- declarationNode.value = '(';
- _this4.process(contentNode, declarationNode);
- break;
- }
- default:
- {
- _this4.process(contentNode, declarationNode);
- }
- }
- break;
- }
- default:
- }
- });
- if (!isBlockInside) {
-
- declarationNode.source = {
- start: node.start,
- end: node.end,
- input: this.input
- };
- declarationNode.parent = parent;
- parent.nodes.push(declarationNode);
- }
- this.raws.before = '';
- this.raws.customProperty = false;
- this.raws.multiRuleProp = '';
- this.raws.property = false;
- };
- _proto.customProperty = function customProperty(node, parent) {
- this.property(node, parent);
- parent.prop = "--" + parent.prop;
- };
- _proto.property = function property(node, parent) {
-
- switch (node.content[0].type) {
- case 'variable':
- {
- parent.prop += '$';
- break;
- }
- case 'interpolation':
- {
- this.raws.interpolation = true;
- parent.prop += '#{';
- break;
- }
- default:
- }
- parent.prop += node.content[0].content;
- if (this.raws.interpolation) {
- parent.prop += '}';
- this.raws.interpolation = false;
- }
- };
- _proto.value = function value(node, parent) {
- if (!parent.value) {
- parent.value = '';
- }
- if (node.content.length) {
- node.content.forEach(function (contentNode) {
- switch (contentNode.type) {
- case 'important':
- {
- parent.raws.important = contentNode.content;
- parent.important = true;
- var match = parent.value.match(/^(.*?)(\s*)$/);
- if (match) {
- parent.raws.important = match[2] + parent.raws.important;
- parent.value = match[1];
- }
- break;
- }
- case 'parentheses':
- {
- parent.value += contentNode.content.join('') + ')';
- break;
- }
- case 'percentage':
- {
- parent.value += contentNode.content.join('') + '%';
- break;
- }
- default:
- {
- if (contentNode.content.constructor === Array) {
- parent.value += contentNode.content.join('');
- } else {
- parent.value += contentNode.content;
- }
- }
- }
- });
- }
- };
- _proto.singlelineComment = function singlelineComment(node, parent) {
- return this.comment(node, parent, true);
- };
- _proto.multilineComment = function multilineComment(node, parent) {
- return this.comment(node, parent, false);
- };
- _proto.comment = function comment(node, parent, inline) {
-
-
- var text = node.content.match(/^(\s*)((?:\S[\S\s]*?)?)(\s*)$/);
- this.raws.comment = true;
- var comment = Object.assign(postcss.comment(), {
- text: text[2],
- raws: {
- before: this.raws.before || DEFAULT_COMMENT_DECL.before,
- left: text[1],
- right: text[3],
- inline: inline
- },
- source: {
- start: {
- line: node.start.line,
- column: node.start.column
- },
- end: node.end,
- input: this.input
- },
- parent: parent
- });
- if (this.raws.beforeMulti) {
- comment.raws.before += this.raws.beforeMulti;
- this.raws.beforeMulti = undefined;
- }
- parent.nodes.push(comment);
- this.raws.before = '';
- };
- _proto.space = function space(node, parent) {
-
- switch (parent.type) {
- case 'root':
- {
- this.raws.before += node.content;
- break;
- }
- case 'rule':
- {
- if (this.raws.comment) {
- this.raws.before += node.content;
- } else if (this.raws.loop) {
- parent.selector += node.content;
- } else {
- this.raws.before = (this.raws.before || '\n') + node.content;
- }
- break;
- }
- default:
- }
- };
- _proto.declarationDelimiter = function declarationDelimiter(node) {
- this.raws.before += node.content;
- };
- _proto.loop = function loop(node, parent) {
- var _this5 = this;
- var 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(function (contentNode, i) {
- if (node.content[i + 1] && node.content[i + 1].type === 'block') {
- _this5.raws.loop = false;
- }
- _this5.process(contentNode, loop);
- });
- parent.nodes.push(loop);
- this.raws.loop = false;
- };
- _proto.atrule = function atrule(node, parent) {
- var _this6 = this;
-
- var supportedNode = node.content[0].content.some(function (contentNode) {
- return SUPPORTED_AT_KEYWORDS.includes(contentNode.content);
- });
- if (!supportedNode) return;
- var atrule = postcss.rule();
- atrule.selector = '';
- atrule.raws = {
- before: this.raws.before || DEFAULT_RAWS_RULE.before,
- between: DEFAULT_RAWS_RULE.between
- };
- node.content.forEach(function (contentNode, i) {
- if (contentNode.type === 'space') {
- var prevNodeType = node.content[i - 1].type;
- switch (prevNodeType) {
- case 'atkeyword':
- case 'ident':
- atrule.selector += contentNode.content;
- break;
- default:
- }
- return;
- }
- _this6.process(contentNode, atrule);
- });
- parent.nodes.push(atrule);
- };
- _proto.parentheses = function parentheses(node, parent) {
- parent.selector += '(';
- node.content.forEach(function (contentNode) {
- if (typeof contentNode.content === 'string') {
- parent.selector += contentNode.content;
- }
- if (typeof contentNode.content === 'object') {
- contentNode.content.forEach(function (childrenContentNode) {
- if (contentNode.type === 'variable') parent.selector += '$';
- parent.selector += childrenContentNode.content;
- });
- }
- });
- parent.selector += ')';
- };
- _proto.interpolation = function interpolation(node, parent) {
- var _this7 = this;
- parent.selector += '#{';
- node.content.forEach(function (contentNode) {
- _this7.process(contentNode, parent);
- });
- parent.selector += '}';
- };
- _proto.atkeyword = function atkeyword(node, parent) {
- parent.selector += "@" + node.content;
- };
- _proto.operator = function operator(node, parent) {
- parent.selector += node.content;
- };
- _proto.variable = function variable(node, parent) {
- if (this.raws.loop) {
- parent.selector += "$" + node.content[0].content;
- return;
- }
- parent.selector += "$" + node.content;
- };
- _proto.ident = function ident(node, parent) {
- parent.selector += node.content;
- };
- return SassParser;
- }();
- module.exports = SassParser;
|