1 | var async = require('async');
|
2 | var fs = require('fs');
|
3 | var minify = require('html-minifier').minify;
|
4 | var path = require('path');
|
5 | var cheerio = require('cheerio');
|
6 | var engine;
|
7 |
|
8 | function TemplateEngine() {
|
9 |
|
10 | var self = this;
|
11 | var _config = {};
|
12 |
|
13 | function readAsync(file, callback) {
|
14 | if (file)
|
15 | fs.readFile(file, 'utf8', callback);
|
16 | }
|
17 |
|
18 | function embedIncludes(template, source) {
|
19 |
|
20 | var $ = cheerio.load(template, {decodeEntities: false});
|
21 | var ele = $('[ng-include]').first();
|
22 | var src = path.dirname(source) + '/' + ($(ele).attr('ng-include') || $(ele).attr('src')).replace(/"/g, '').replace(/'/g, '').trim();
|
23 | var include = fs.readFileSync(src, 'utf8');
|
24 | $(ele).append(include);
|
25 | return $.html();
|
26 | }
|
27 |
|
28 | self.config = {
|
29 | get: function () {
|
30 | return _config;
|
31 | },
|
32 | set: function (config) {
|
33 | _config = config || {};
|
34 | }
|
35 | }
|
36 |
|
37 | self.source = {
|
38 | hash: function (raw, base) {
|
39 | var source = {contents: raw, templates: []};
|
40 | var parts = source.contents.split(/(?=templateUrl)/g);
|
41 |
|
42 | parts.forEach(function (element, index) {
|
43 |
|
44 | var match = (element.match(/(?!,)templateUrl(.*)$/gm));
|
45 |
|
46 | if (match) {
|
47 | var templateUrl = match[0].split(':')[1].split(',')[0].replace(/"/g, '').replace(/'/g, '').trim()
|
48 | var relative = path.resolve(__dirname + base, '../' + templateUrl);
|
49 | source.templates.push(relative);
|
50 | }
|
51 | });
|
52 |
|
53 | return source;
|
54 | },
|
55 | read: function (target) {
|
56 | var deferred = new Promise(function (resolve, reject) {
|
57 | fs.readFile(__dirname + target, 'utf8', function (err, data) {
|
58 | resolve(data);
|
59 | });
|
60 | });
|
61 |
|
62 | return deferred;
|
63 | }
|
64 | }
|
65 |
|
66 | self.templates = {
|
67 | get: function (source) {
|
68 |
|
69 | var deferred = new Promise(function (resolve, reject) {
|
70 | async.map(source.templates, readAsync, function (err, results) {
|
71 |
|
72 | results.forEach(function (element, index, arr) {
|
73 |
|
74 | var t, $ = cheerio.load(element, {decodeEntities: false});
|
75 |
|
76 | if ($($.html()).find('[ng-include]').length > 0 && _config.includes) {
|
77 | t = embedIncludes($.html(), source.templates[index])
|
78 | }
|
79 |
|
80 | var template = minify((t || $.html()), {collapseWhitespace: true, removeComments: true})
|
81 | source.templates[index] = template
|
82 | resolve(source);
|
83 | });
|
84 |
|
85 | resolve(source);
|
86 | });
|
87 | });
|
88 |
|
89 | return deferred;
|
90 | },
|
91 | set: function (transformed) {
|
92 | var deferred = new Promise(function (resolve, reject) {
|
93 |
|
94 | var parts = transformed.contents.split(/(?=templateUrl)(?!,)/g);
|
95 |
|
96 | parts.forEach(function (element, index, arr) {
|
97 |
|
98 | var match = (element.match(/(?!,)templateUrl(.*)$/gm));
|
99 |
|
100 | if (match)
|
101 | arr[index] = arr[index].replace(/(?!,)templateUrl(.*),$/gm, 'template: \'' + transformed.templates.shift().replace(/'/g, "\\'") + '\',')
|
102 | });
|
103 |
|
104 | resolve(parts.join(''));
|
105 | });
|
106 |
|
107 | return deferred;
|
108 | }
|
109 | }
|
110 | }
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 |
|
120 | function TemplateManager() {
|
121 |
|
122 | var self = this;
|
123 |
|
124 | self.inline = function (input, config, done) {
|
125 |
|
126 | engine = new TemplateEngine();
|
127 | engine.config.set(config);
|
128 |
|
129 |
|
130 | if (input.contents) {
|
131 | var base = '/' + path.dirname(path.relative(__dirname, config.target));
|
132 | var source = engine.source.hash(input, base);
|
133 |
|
134 | engine.templates.get(source).then(function (transformed) {
|
135 | engine.templates.set(transformed).then(function (output) {
|
136 | done(output);
|
137 | });
|
138 | });
|
139 | } else {
|
140 | engine.source.read(input).then(function (data) {
|
141 |
|
142 | var base = path.dirname(input);
|
143 | var source = engine.source.hash(data, base);
|
144 |
|
145 | engine.templates.get(source).then(function (transformed) {
|
146 | engine.templates.set(transformed).then(function (output) {
|
147 | done(output);
|
148 | });
|
149 | });
|
150 | });
|
151 | }
|
152 | }
|
153 | }
|
154 |
|
155 | module.exports = new TemplateManager();
|
156 | module.exports.engine = new TemplateEngine(); |
\ | No newline at end of file |