UNPKG

2.93 kBJavaScriptView Raw
1var fs = require('fs'),
2 path = require('path');
3
4module.exports = function (tree, lessPath, additional_import_paths) {
5 additional_import_paths = additional_import_paths || [];
6
7 var less_root_dir = path.dirname(lessPath);
8 var result = new ImportSet();
9
10 process_tree_node(tree, less_root_dir, less_root_dir, additional_import_paths, result);
11
12 return result.items;
13};
14
15// Process each less file node, with a list of rules
16var process_tree_node = module.exports.process_tree_node = function (node, current_dir, root_dir, additional_import_paths, imports) {
17 // When a less file is imported twice it comes through with an undefined node.
18 if (node === undefined) {
19 return false;
20 }
21
22 var import_rules = node.rules
23 .filter(function (rule) {
24 return rule.path && !rule.css;
25 });
26
27 import_rules.forEach(function (import_rule) {
28 process_import_rule(import_rule, current_dir, root_dir, additional_import_paths, imports);
29 });
30};
31
32// Process an import rule, with a path and a single less file node
33var process_import_rule = module.exports.process_import_rule = function process_import_rule(import_rule, current_dir, root_dir, additional_import_paths, imports) {
34 var found_path = locate(import_rule.path, current_dir, root_dir, additional_import_paths);
35 var this_import = {
36 mtime: Date.now(),
37 path: found_path
38 };
39 imports.add(this_import);
40 var new_current_dir = path.dirname(found_path);
41 process_tree_node(import_rule.root, new_current_dir, root_dir, additional_import_paths, imports);
42};
43
44// Less imports check for the path first in the local directory of the file,
45// and then again in the directory of the top level less file being imported.
46var locate = module.exports.locate = function (filename, current_dir, root_dir, additional_import_paths) {
47 var i, import_path, from_import_path;
48 filename = filename.value;
49 if (!filename.match(/\.(css|less)$/))
50 filename += '.less';
51 var from_current_path = path.join(current_dir, filename);
52 var from_root_path = path.join(root_dir, filename);
53
54 if (fs.existsSync(from_current_path)) {
55 return from_current_path;
56 }
57
58 if (fs.existsSync(from_root_path)){
59 return from_root_path;
60 }
61
62 for(i = 0; i < additional_import_paths.length; i++){
63 import_path = additional_import_paths[i];
64 from_import_path = path.join(import_path, filename);
65 if (fs.existsSync(from_import_path)) {
66 return from_import_path;
67 }
68 }
69
70 throw new Error("'"+filename+"' wasn't found.");
71};
72
73
74// It's quick to check here for duplicate items,
75// and it avoids an fs call in the middleware proper
76var ImportSet = module.exports.ImportSet = function(){
77 this.items = [];
78};
79
80ImportSet.prototype.add = function(item){
81 var that = this;
82 if (!already_in(item)){
83 this.items.push(item);
84 }
85
86 function already_in(item){
87 return that.items.some(function(element){
88 return element.path === item.path;
89 });
90 }
91};