flatten import visitor so that variable imports can be processed at the end of a global queue

This commit is contained in:
Luke Page
2014-10-23 21:33:28 +01:00
parent 5f09ee7079
commit c757befb4f
3 changed files with 50 additions and 14 deletions

View File

@@ -73,6 +73,17 @@ Import.prototype.getPath = function () {
}
return null;
};
Import.prototype.isVariableImport = function () {
var path = this.path;
if (path instanceof URL) {
path = path.value;
}
if (path instanceof Quoted) {
return path.containsVariables();
}
return true;
};
Import.prototype.evalForImport = function (context) {
var path = this.path;
if (path instanceof URL) {

View File

@@ -20,6 +20,9 @@ Quoted.prototype.genCSS = function (context, output) {
output.add(this.quote);
}
};
Quoted.prototype.containsVariables = function() {
return this.value.match(/(`([^`]+)`)|@\{([\w-]+)\}/);
};
Quoted.prototype.eval = function (context) {
var that = this, value = this.value;
var javascriptReplacement = function (_, exp) {

View File

@@ -3,10 +3,13 @@ var contexts = require("../contexts"),
ImportSequencer = require("./import-sequencer");
var ImportVisitor = function(importer, finish, evalEnv, onceFileDetectionMap, recursionDetector) {
// TODO arguments not all necessary now
this._visitor = new Visitor(this);
this._importer = importer;
this._finish = finish;
this.context = evalEnv || new contexts.Eval();
// TODO probably doesnt need to be an array
this.contextStack = [evalEnv || new contexts.Eval()];
this.importCount = 0;
this.onceFileDetectionMap = onceFileDetectionMap || {};
this.recursionDetector = {};
@@ -43,8 +46,14 @@ ImportVisitor.prototype = {
if (!importNode.css || inlineCSS) {
// TODO - process this type of imports *last*
//if (importNode.isVariableImport()) {
// console.log("variable import detected");
//}
var currentContext = this.contextStack[this.contextStack.length - 1];
try {
evaldImportNode = importNode.evalForImport(this.context);
evaldImportNode = importNode.evalForImport(currentContext);
} catch(e){
if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; }
// attempt to eval properly and treat as css
@@ -56,7 +65,7 @@ ImportVisitor.prototype = {
if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) {
importNode = evaldImportNode;
this.importCount++;
var context = new contexts.Eval(this.context, this.context.frames.slice(0));
var context = new contexts.Eval(currentContext, currentContext.frames.slice(0));
if (importNode.options.multiple) {
context.importMultiple = true;
@@ -113,9 +122,14 @@ ImportVisitor.prototype = {
if (!inlineCSS && (context.importMultiple || !duplicateImport)) {
importVisitor.recursionDetector[fullPath] = true;
new ImportVisitor(importVisitor._importer, subFinish, context, importVisitor.onceFileDetectionMap, importVisitor.recursionDetector)
.run(root);
return;
this.contextStack.push(context);
try {
this._visitor.visit(root);
} catch (e) {
this.error = e;
}
this.contextStack.pop();
}
}
@@ -126,32 +140,40 @@ ImportVisitor.prototype = {
return ruleNode;
},
visitDirective: function (directiveNode, visitArgs) {
this.context.frames.unshift(directiveNode);
var currentContext = this.contextStack[this.contextStack.length - 1];
currentContext.frames.unshift(directiveNode);
return directiveNode;
},
visitDirectiveOut: function (directiveNode) {
this.context.frames.shift();
var currentContext = this.contextStack[this.contextStack.length - 1];
currentContext.frames.shift();
},
visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
this.context.frames.unshift(mixinDefinitionNode);
var currentContext = this.contextStack[this.contextStack.length - 1];
currentContext.frames.unshift(mixinDefinitionNode);
return mixinDefinitionNode;
},
visitMixinDefinitionOut: function (mixinDefinitionNode) {
this.context.frames.shift();
var currentContext = this.contextStack[this.contextStack.length - 1];
currentContext.frames.shift();
},
visitRuleset: function (rulesetNode, visitArgs) {
this.context.frames.unshift(rulesetNode);
var currentContext = this.contextStack[this.contextStack.length - 1];
currentContext.frames.unshift(rulesetNode);
return rulesetNode;
},
visitRulesetOut: function (rulesetNode) {
this.context.frames.shift();
var currentContext = this.contextStack[this.contextStack.length - 1];
currentContext.frames.shift();
},
visitMedia: function (mediaNode, visitArgs) {
this.context.frames.unshift(mediaNode.rules[0]);
var currentContext = this.contextStack[this.contextStack.length - 1];
currentContext.frames.unshift(mediaNode.rules[0]);
return mediaNode;
},
visitMediaOut: function (mediaNode) {
this.context.frames.shift();
var currentContext = this.contextStack[this.contextStack.length - 1];
currentContext.frames.shift();
}
};
module.exports = ImportVisitor;