UNPKG

5.03 kBJavaScriptView Raw
1var ComponentBase = require('./ComponentBase.js'),
2 pathUtils = require('../lib/utils/path.js'),
3 path = require('path'),
4 mkdirp = require('mkdirp'),
5 fs = require('fs'),
6 async = require('async'),
7 glob = require('glob');
8
9
10//var partialsRegex = /\{\{> ?([a-zA-Z\/\-_]+)/gm;
11
12
13function Component(options){
14 ComponentBase.call(this, options);
15
16 this.id = options.id;
17 this.buildPath = path.join(__dirname, '../public/_built/' + this.id);///@TODO find something more elegant than path.join(__dirname, ) to reference preoject files
18 this.standaloneCssPath = path.join(this.buildPath + '/standalone.css');
19 this.standaloneCssPublicPath = '/_built/' + this.id + '/standalone.css';
20 this.resourcePaths = {};
21 this.cache = {};
22 this.partialRegistered = false;
23 this.missingPartial = false;
24 this.baseDependencies = [];
25
26}
27Component.prototype = Object.create(ComponentBase.prototype);
28
29
30Component.prototype.build = function(callback) {
31 async.series([
32 // cache stuff
33 this.cacheResourcePathes.bind(this),
34 this.cacheResources.bind(this),
35
36 mkdirp.bind(null, this.buildPath),
37
38 // dependencies
39 this.resolveDependencies.bind(this),
40
41 // build static stuff
42
43 this.buildStandaloneCss.bind(this),
44
45
46 // register handlebars partial
47 this.registerPartial.bind(this),
48
49 ], callback);
50
51};
52
53Component.prototype.rebuild = function(callback) {
54 this.build(callback);
55};
56
57Component.prototype.resolveDependencies = function(callback) {
58 var dependencies = [],
59 m,
60 re = /\{\{> ?([a-zA-Z\/\-_]+)/gm;
61
62 while ((m = re.exec(this.cache.html)) !== null) {
63 if (m.index === re.lastIndex) {
64 re.lastIndex++;
65 }
66
67 if(dependencies.indexOf(m[1]) === -1){
68 dependencies.push(m[1]);
69 }
70 }
71
72 if(this.isBaseCss){
73 this.dependencies = dependencies;
74 }else{
75 this.dependencies = this.baseDependencies.concat(dependencies);
76 }
77
78
79 if(this.dependencies.length > 0){
80 this.dsf.whenLoaded(this.dependencies, this.addDependencies.bind(this, callback));
81 }else{
82 callback();
83 }
84
85};
86
87Component.prototype.addDependencies = function(callback) {
88 var dependecyCss = '';
89 this.dependencies.forEach(function(dependencyId){
90 var dependency = this.dsf.getComponent(dependencyId);
91 if(dependency.isBaseCss){
92 return;
93 }
94 dependecyCss+='\n\n/* dependency: '+dependencyId+' */\n' + dependency.getCss(true) + '\n';
95
96
97 }, this);
98 this.cache.cssDependencies = dependecyCss;
99 //this.buildStandaloneCss();
100 callback();
101};
102
103Component.prototype.registerPartial = function(callback) {
104 this.dsf.getHandlebars().registerPartial(this.id, this.cache.html || '');
105 callback();
106};
107
108Component.prototype.cacheResourcePathes = function(callback) {
109 var self = this;
110 async.map(['css','html','config'], this.getResourcePaths.bind(this), function(err, paths){
111
112 self.resourcePaths.css = paths[0];
113 self.resourcePaths.html = paths[1][0];// there can be only one template
114 self.resourcePaths.config = paths[2][0];// there can be only one config
115
116 callback();
117 });
118};
119Component.prototype.getResourcePaths = function(type, callback) {
120 glob(this.getGlobPath(type), function(err, files){
121 if(err) throw err;
122
123 callback(null, files);
124 });
125};
126
127Component.prototype.cacheResources = function(callback) {
128 async.parallel([
129 this.cacheCss.bind(this),
130 this.cacheHtml.bind(this),
131 this.cacheConfig.bind(this)
132 ], callback);
133
134};
135
136Component.prototype.cacheCss = function(cacheCssCallback) {
137 var self = this;
138 async.map(this.resourcePaths.css, fs.readFile, function(err, files){
139 if(err) throw err;
140 async.reduce(files, '', function(memo, item, callback){
141 callback(null, memo + '\n' + item.toString());
142 }, function(err, css){
143 if(err) throw err;
144 self.cache.css = css;
145 cacheCssCallback();
146 });
147 });
148
149};
150
151
152Component.prototype.cacheHtml = function(callback) {
153 var self = this;
154
155 if(this.resourcePaths.html){
156 fs.readFile(this.resourcePaths.html, function(err, file){
157 var html = file.toString();
158 self.cache.html = html;
159 self.cache.tpl = self.dsf.getHandlebars().compile(html);
160 callback();
161 });
162 }else{
163 self.cache.html = '';
164 callback();
165 }
166
167};
168
169Component.prototype.cacheConfig = function(callback) {
170 if(this.resourcePaths.config){
171 try{
172 this.cache.config = require(path.join(this.absPath, this.resourcePaths.config));
173 }catch(err){
174 this.cache.config = {};
175 }
176
177 }
178 callback();
179};
180
181Component.prototype.buildStandaloneCss = function(callback) {
182 var baseCss = this.isBaseCss ? '' : this.dsf.getBaseCss(),
183 componentCss = this.getCss(),
184 dependecyCss = this.cache.cssDependencies || '';
185 css = baseCss + componentCss + dependecyCss; // dependencies after component so user can't override dependencies
186
187 fs.writeFile(this.standaloneCssPath, css, callback);
188};
189
190Component.prototype.getCss = function(withDependencies) {
191 return this.cache.css + ((withDependencies && this.cache.cssDependencies) ? this.cache.cssDependencies : '');
192};
193
194Component.prototype.render = function(context) {
195 if(this.cache.tpl){
196 return this.cache.tpl(context || (this.cache.config ? this.cache.config : {}));
197 }
198 return '';
199};
200
201
202
203
204
205
206module.exports = Component;