| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- var contexts = require("./contexts"),
- Parser = require('./parser/parser'),
- FunctionImporter = require('./plugins/function-importer');
- module.exports = function(environment) {
- // FileInfo = {
- // 'relativeUrls' - option - whether to adjust URL's to be relative
- // 'filename' - full resolved filename of current file
- // 'rootpath' - path to append to normal URLs for this node
- // 'currentDirectory' - path to the current file, absolute
- // 'rootFilename' - filename of the base file
- // 'entryPath' - absolute path to the entry file
- // 'reference' - whether the file should not be output and only output parts that are referenced
- var ImportManager = function(context, rootFileInfo) {
- this.rootFilename = rootFileInfo.filename;
- this.paths = context.paths || []; // Search paths, when importing
- this.contents = {}; // map - filename to contents of all the files
- this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore
- this.mime = context.mime;
- this.error = null;
- this.context = context;
- // Deprecated? Unused outside of here, could be useful.
- this.queue = []; // Files which haven't been imported yet
- this.files = {}; // Holds the imported parse trees.
- };
- /**
- * Add an import to be imported
- * @param path - the raw path
- * @param tryAppendLessExtension - whether to try appending the less extension (if the path has no extension)
- * @param currentFileInfo - the current file info (used for instance to work out relative paths)
- * @param importOptions - import options
- * @param callback - callback for when it is imported
- */
- ImportManager.prototype.push = function (path, tryAppendLessExtension, currentFileInfo, importOptions, callback) {
- var importManager = this;
- this.queue.push(path);
- var fileParsedFunc = function (e, root, fullPath) {
- importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue
- var importedEqualsRoot = fullPath === importManager.rootFilename;
- if (importOptions.optional && e) {
- callback(null, {rules:[]}, false, null);
- }
- else {
- importManager.files[fullPath] = root;
- if (e && !importManager.error) { importManager.error = e; }
- callback(e, root, importedEqualsRoot, fullPath);
- }
- };
- var newFileInfo = {
- relativeUrls: this.context.relativeUrls,
- entryPath: currentFileInfo.entryPath,
- rootpath: currentFileInfo.rootpath,
- rootFilename: currentFileInfo.rootFilename
- };
- var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);
- if (!fileManager) {
- fileParsedFunc({ message: "Could not find a file-manager for " + path });
- return;
- }
- if (tryAppendLessExtension) {
- path = fileManager.tryAppendExtension(path, importOptions.plugin ? ".js" : ".less");
- }
- var loadFileCallback = function(loadedFile) {
- var resolvedFilename = loadedFile.filename,
- contents = loadedFile.contents.replace(/^\uFEFF/, '');
- // Pass on an updated rootpath if path of imported file is relative and file
- // is in a (sub|sup) directory
- //
- // Examples:
- // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',
- // then rootpath should become 'less/module/nav/'
- // - If path of imported file is '../mixins.less' and rootpath is 'less/',
- // then rootpath should become 'less/../'
- newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
- if (newFileInfo.relativeUrls) {
- newFileInfo.rootpath = fileManager.join(
- (importManager.context.rootpath || ""),
- fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
- if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {
- newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);
- }
- }
- newFileInfo.filename = resolvedFilename;
- var newEnv = new contexts.Parse(importManager.context);
- newEnv.processImports = false;
- importManager.contents[resolvedFilename] = contents;
- if (currentFileInfo.reference || importOptions.reference) {
- newFileInfo.reference = true;
- }
- if (importOptions.plugin) {
- new FunctionImporter(newEnv, newFileInfo).eval(contents, function (e, root) {
- fileParsedFunc(e, root, resolvedFilename);
- });
- } else if (importOptions.inline) {
- fileParsedFunc(null, contents, resolvedFilename);
- } else {
- new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) {
- fileParsedFunc(e, root, resolvedFilename);
- });
- }
- };
- var promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, this.context, environment,
- function(err, loadedFile) {
- if (err) {
- fileParsedFunc(err);
- } else {
- loadFileCallback(loadedFile);
- }
- });
- if (promise) {
- promise.then(loadFileCallback, fileParsedFunc);
- }
- };
- return ImportManager;
- };
|