UNPKG

9.22 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3var tslib_1 = require("tslib");
4var contexts_1 = tslib_1.__importDefault(require("./contexts"));
5var parser_1 = tslib_1.__importDefault(require("./parser/parser"));
6var less_error_1 = tslib_1.__importDefault(require("./less-error"));
7var utils = tslib_1.__importStar(require("./utils"));
8var logger_1 = tslib_1.__importDefault(require("./logger"));
9function default_1(environment) {
10 // FileInfo = {
11 // 'rewriteUrls' - option - whether to adjust URL's to be relative
12 // 'filename' - full resolved filename of current file
13 // 'rootpath' - path to append to normal URLs for this node
14 // 'currentDirectory' - path to the current file, absolute
15 // 'rootFilename' - filename of the base file
16 // 'entryPath' - absolute path to the entry file
17 // 'reference' - whether the file should not be output and only output parts that are referenced
18 var ImportManager = /** @class */ (function () {
19 function ImportManager(less, context, rootFileInfo) {
20 this.less = less;
21 this.rootFilename = rootFileInfo.filename;
22 this.paths = context.paths || []; // Search paths, when importing
23 this.contents = {}; // map - filename to contents of all the files
24 this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore
25 this.mime = context.mime;
26 this.error = null;
27 this.context = context;
28 // Deprecated? Unused outside of here, could be useful.
29 this.queue = []; // Files which haven't been imported yet
30 this.files = {}; // Holds the imported parse trees.
31 }
32 /**
33 * Add an import to be imported
34 * @param path - the raw path
35 * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension)
36 * @param currentFileInfo - the current file info (used for instance to work out relative paths)
37 * @param importOptions - import options
38 * @param callback - callback for when it is imported
39 */
40 ImportManager.prototype.push = function (path, tryAppendExtension, currentFileInfo, importOptions, callback) {
41 var importManager = this, pluginLoader = this.context.pluginManager.Loader;
42 this.queue.push(path);
43 var fileParsedFunc = function (e, root, fullPath) {
44 importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue
45 var importedEqualsRoot = fullPath === importManager.rootFilename;
46 if (importOptions.optional && e) {
47 callback(null, { rules: [] }, false, null);
48 logger_1.default.info("The file " + fullPath + " was skipped because it was not found and the import was marked optional.");
49 }
50 else {
51 // Inline imports aren't cached here.
52 // If we start to cache them, please make sure they won't conflict with non-inline imports of the
53 // same name as they used to do before this comment and the condition below have been added.
54 if (!importManager.files[fullPath] && !importOptions.inline) {
55 importManager.files[fullPath] = { root: root, options: importOptions };
56 }
57 if (e && !importManager.error) {
58 importManager.error = e;
59 }
60 callback(e, root, importedEqualsRoot, fullPath);
61 }
62 };
63 var newFileInfo = {
64 rewriteUrls: this.context.rewriteUrls,
65 entryPath: currentFileInfo.entryPath,
66 rootpath: currentFileInfo.rootpath,
67 rootFilename: currentFileInfo.rootFilename
68 };
69 var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);
70 if (!fileManager) {
71 fileParsedFunc({ message: "Could not find a file-manager for " + path });
72 return;
73 }
74 var loadFileCallback = function (loadedFile) {
75 var plugin;
76 var resolvedFilename = loadedFile.filename;
77 var contents = loadedFile.contents.replace(/^\uFEFF/, '');
78 // Pass on an updated rootpath if path of imported file is relative and file
79 // is in a (sub|sup) directory
80 //
81 // Examples:
82 // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',
83 // then rootpath should become 'less/module/nav/'
84 // - If path of imported file is '../mixins.less' and rootpath is 'less/',
85 // then rootpath should become 'less/../'
86 newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
87 if (newFileInfo.rewriteUrls) {
88 newFileInfo.rootpath = fileManager.join((importManager.context.rootpath || ''), fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
89 if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {
90 newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);
91 }
92 }
93 newFileInfo.filename = resolvedFilename;
94 var newEnv = new contexts_1.default.Parse(importManager.context);
95 newEnv.processImports = false;
96 importManager.contents[resolvedFilename] = contents;
97 if (currentFileInfo.reference || importOptions.reference) {
98 newFileInfo.reference = true;
99 }
100 if (importOptions.isPlugin) {
101 plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo);
102 if (plugin instanceof less_error_1.default) {
103 fileParsedFunc(plugin, null, resolvedFilename);
104 }
105 else {
106 fileParsedFunc(null, plugin, resolvedFilename);
107 }
108 }
109 else if (importOptions.inline) {
110 fileParsedFunc(null, contents, resolvedFilename);
111 }
112 else {
113 // import (multiple) parse trees apparently get altered and can't be cached.
114 // TODO: investigate why this is
115 if (importManager.files[resolvedFilename]
116 && !importManager.files[resolvedFilename].options.multiple
117 && !importOptions.multiple) {
118 fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename);
119 }
120 else {
121 new parser_1.default(newEnv, importManager, newFileInfo).parse(contents, function (e, root) {
122 fileParsedFunc(e, root, resolvedFilename);
123 });
124 }
125 }
126 };
127 var loadedFile;
128 var promise;
129 var context = utils.clone(this.context);
130 if (tryAppendExtension) {
131 context.ext = importOptions.isPlugin ? '.js' : '.less';
132 }
133 if (importOptions.isPlugin) {
134 context.mime = 'application/javascript';
135 if (context.syncImport) {
136 loadedFile = pluginLoader.loadPluginSync(path, currentFileInfo.currentDirectory, context, environment, fileManager);
137 }
138 else {
139 promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager);
140 }
141 }
142 else {
143 if (context.syncImport) {
144 loadedFile = fileManager.loadFileSync(path, currentFileInfo.currentDirectory, context, environment);
145 }
146 else {
147 promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) {
148 if (err) {
149 fileParsedFunc(err);
150 }
151 else {
152 loadFileCallback(loadedFile);
153 }
154 });
155 }
156 }
157 if (loadedFile) {
158 if (!loadedFile.filename) {
159 fileParsedFunc(loadedFile);
160 }
161 else {
162 loadFileCallback(loadedFile);
163 }
164 }
165 else if (promise) {
166 promise.then(loadFileCallback, fileParsedFunc);
167 }
168 };
169 return ImportManager;
170 }());
171 return ImportManager;
172}
173exports.default = default_1;
174;
175//# sourceMappingURL=import-manager.js.map
\No newline at end of file