diff options
| author | ruki <waruqi@gmail.com> | 2018-11-08 00:38:48 +0800 |
|---|---|---|
| committer | ruki <waruqi@gmail.com> | 2018-11-07 21:53:09 +0800 |
| commit | 26105034da4fcce7ac883c899d781f016559310d (patch) | |
| tree | c459a5dc4e3aa0972d9919033ece511ce76dd129 /node_modules/stylus-loader/lib/evaluator.js | |
| parent | 2c77f00f1a7ecb6c8192f9c16d3b2001b254a107 (diff) | |
| download | xmake-docs-26105034da4fcce7ac883c899d781f016559310d.tar.gz xmake-docs-26105034da4fcce7ac883c899d781f016559310d.zip | |
switch to vuepress
Diffstat (limited to 'node_modules/stylus-loader/lib/evaluator.js')
| -rw-r--r-- | node_modules/stylus-loader/lib/evaluator.js | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/node_modules/stylus-loader/lib/evaluator.js b/node_modules/stylus-loader/lib/evaluator.js new file mode 100644 index 00000000..dc6013d8 --- /dev/null +++ b/node_modules/stylus-loader/lib/evaluator.js @@ -0,0 +1,166 @@ +// Except for a block in #visitImport, everything here is an exact copy of the +// source in stylus this currently depends on. If stylus is updated, update +// this appropriately. + +var Evaluator = require('stylus/lib/visitor/evaluator') + , nodes = require('stylus/lib/nodes') + , Stack = require('stylus/lib/stack') + , Frame = require('stylus/lib/stack/frame') + , Scope = require('stylus/lib/stack/scope') + , utils = require('stylus/lib/utils') + , bifs = require('stylus/lib/functions') + , basename = require('path').basename + , dirname = require('path').dirname + , relative = require('path').relative + , join = require('path').join + , colors = require('stylus/lib/colors') + // , debug = require('debug')('stylus:evaluator') + , fs = require('fs'); + +module.exports = CachedPathEvaluator; + +/** + * Import `file` and return Block node. + * + * @api private + */ +function importFile(node, file, literal, index) { + var importStack = this.importStack + , Parser = require('stylus/lib/parser') + , stat; + + // Handling the `require` + if (node.once) { + if (this.requireHistory[file]) return nodes.null; + this.requireHistory[file] = true; + + if (literal && !this.includeCSS) { + return node; + } + } + + // Expose imports + node.path = file; + node.dirname = dirname(file); + // Store the modified time + stat = fs.statSync(file); + node.mtime = stat.mtime; + this.paths.push(node.dirname); + + // Avoid overflows from importing the same file over again + if (file === importStack[importStack.length - 1]) return nodes.null; + + if (this.options._imports) this.options._imports.push(node.clone()); + + // Parse the file + importStack.push(file); + nodes.filename = file; + + var str; + if (this.cache.sources && this.cache.sources[file]) { + str = this.cache.sources[file]; + } else { + str = fs.readFileSync(file, 'utf8'); + } + + if (literal && !this.resolveURL) return new nodes.Literal(str.replace(/\r\n?/g, '\n')); + + // parse + var block = new nodes.Block + , parser = new Parser(str, utils.merge({ root: block }, this.options)); + + try { + block = parser.parse(); + } catch (err) { + err.filename = file; + err.lineno = parser.lexer.lineno; + err.input = str; + throw err; + } + + // Evaluate imported "root" + block.parent = this.root; + block.scope = false; + var ret = this.visit(block); + importStack.pop(); + if (importStack.length || index) this.paths.pop(); + + return ret; +} + +function CachedPathEvaluator(root, options) { + Evaluator.apply(this, arguments); + + this.cache = options.cache; +} + +CachedPathEvaluator.prototype = Object.create(Evaluator.prototype); +CachedPathEvaluator.prototype.constructor = CachedPathEvaluator; + +CachedPathEvaluator.prototype.visitImport = function(imported) { + this.return++; + + var path = this.visit(imported.path).first + , nodeName = imported.once ? 'require' : 'import' + , found + , literal + , index; + + this.return--; + // debug('import %s', path); + + // url() passed + if ('url' == path.name) { + if (imported.once) throw new Error('You cannot @require a url'); + + return imported; + } + + // Ensure string + if (!path.string) throw new Error('@' + nodeName + ' string expected'); + + var name = path = path.string; + + // Absolute URL + if (/url\s*\(\s*['"]?(?:https?:)?\/\//i.test(path)) { + if (imported.once) throw new Error('You cannot @require a url'); + return imported; + } + + // Literal + if (/\.css(?:"|$)/.test(path)) { + literal = true; + if (!imported.once && !this.includeCSS) { + return imported; + } + } + + // support optional .styl + if (!literal && !/\.styl$/i.test(path)) path += '.styl'; + + /***************************************************************************** + * THIS IS THE ONLY BLOCK THAT DIFFERS FROM THE ACTUAL STYLUS IMPLEMENTATION. * + *****************************************************************************/ + // Lookup + var dirname = this.paths[this.paths.length - 1]; + found = this.cache.find(path, dirname); + index = this.cache.isIndex(path, dirname); + if (!found) { + found = utils.find(path, this.paths, this.filename); + if (!found) { + found = utils.lookupIndex(name, this.paths, this.filename); + index = true; + } + } + + // Throw if import failed + if (!found) throw new Error('failed to locate @' + nodeName + ' file ' + path); + + var block = new nodes.Block; + + for (var i = 0, len = found.length; i < len; ++i) { + block.push(importFile.call(this, imported, found[i], literal, index)); + } + + return block; +} |
