-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
128 lines (112 loc) · 2.94 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
* A DOM view engine for Express.
*/
var util = require('util');
var path = require('path');
var jsdom = require('jsdom');
module.exports = function (app) {
var Handler = function (file, options, next) {
this.file = file;
this.options = options;
this.next = next;
this.params = {};
this.injects = [];
this.scripts = options.scripts || [];
};
Handler.prototype.env = function () {
var self = this;
jsdom.env({
file: this.file,
scripts: this.scripts,
src: this.options.src,
done: self.jsdomReady.bind(self)
});
};
Handler.prototype.callback = function (err, instead) {
if (err) {
this.next(err);
}
else {
if (instead) {
var insteadFile = path.join(app.get('views'), instead + '.html');
this.file = insteadFile;
this.params.instead = instead;
this.env();
}
else {
var window = this.window;
var document = window.document;
// remove scripts added by jsdom
var scripts = document.querySelectorAll('script.jsdom');
Array.prototype.forEach.call(scripts, function (script) {
script.parentNode.removeChild(script);
});
var doctype = document.doctype ? document.doctype.toString() : '';
var root = document.documentElement;
var html = root ? root.outerHTML : '<html></html>';
var full = doctype + html;
this.next(null, full);
}
}
};
Handler.prototype.jsdomReady = function(errors, window) {
var self = this;
this.window = window;
if (errors) {
this.next(errors);
}
else if ( ! this.options.render ) {
this.next(new Error("requires render callback"));
}
else {
var args = [window];
this.injects.forEach(function (inject) {
var exported = window[inject.exports];
args.push(exported);
});
args.push(self.callback.bind(self));
args.push(self.params);
this.options.render.apply(window, args);
}
};
return function (file, options, next) {
var handler = new Handler(file, options, next);
var deps = options.deps;
var eachDep = function (dep) {
var scriptPath;
var moduleName;
var fileName;
var inject;
if (typeof dep === 'string') {
moduleName = dep;
inject = false;
}
else {
moduleName = dep.module;
fileName = dep.file;
inject = typeof dep.inject === 'undefined' ? true : dep.inject;
}
if (moduleName) {
try {
scriptPath = require.resolve(moduleName);
}
catch (e) {
fileName = moduleName;
}
}
if (fileName) {
scriptPath = fileName;
}
handler.scripts.push(scriptPath);
if (inject && dep.exports) {
handler.injects.push({
exports: dep.exports
});
}
};
if (deps) {
deps.forEach(eachDep);
}
handler.env();
};
};