diff options
Diffstat (limited to 'node_modules/montage/node.js')
-rw-r--r-- | node_modules/montage/node.js | 140 |
1 files changed, 119 insertions, 21 deletions
diff --git a/node_modules/montage/node.js b/node_modules/montage/node.js index 3d0a1edb..100acac5 100644 --- a/node_modules/montage/node.js +++ b/node_modules/montage/node.js | |||
@@ -13,6 +13,10 @@ var Require = require("./require/require"); | |||
13 | var Promise = require("./core/promise"); | 13 | var Promise = require("./core/promise"); |
14 | var URL = require("./core/url"); | 14 | var URL = require("./core/url"); |
15 | 15 | ||
16 | var jsdom = require("jsdom").jsdom; | ||
17 | var Node = require("jsdom").level(1).Node; | ||
18 | var domToHtml = require("jsdom/lib/jsdom/browser/domtohtml").domToHtml; | ||
19 | |||
16 | exports.bootstrap = function (callback) { | 20 | exports.bootstrap = function (callback) { |
17 | var command = process.argv.slice(0, 3); | 21 | var command = process.argv.slice(0, 3); |
18 | var args = process.argv.slice(2); | 22 | var args = process.argv.slice(2); |
@@ -33,27 +37,6 @@ exports.bootstrap = function (callback) { | |||
33 | }); | 37 | }); |
34 | }; | 38 | }; |
35 | 39 | ||
36 | MontageBoot.loadPackage = function (location, config) { | ||
37 | var config = {}; | ||
38 | |||
39 | config.location = URL.resolve('file:/', location + '/'); | ||
40 | |||
41 | // setup the reel loader | ||
42 | config.makeLoader = function (config) { | ||
43 | return MontageBoot.ReelLoader(config, | ||
44 | Require.DefaultLoaderConstructor(config)); | ||
45 | }; | ||
46 | |||
47 | // setup serialization compiler | ||
48 | config.makeCompiler = function (config) { | ||
49 | return MontageBoot.TemplateCompiler(config, | ||
50 | MontageBoot.SerializationCompiler(config, | ||
51 | Require.DefaultCompilerConstructor(config))); | ||
52 | }; | ||
53 | |||
54 | return Require.PackageSandbox(config.location, config); | ||
55 | }; | ||
56 | |||
57 | var findPackage = function (path, callback) { | 40 | var findPackage = function (path, callback) { |
58 | var directory = PATH.dirname(path); | 41 | var directory = PATH.dirname(path); |
59 | if (directory === path) | 42 | if (directory === path) |
@@ -82,3 +65,118 @@ var loadPackagedModule = function (directory, program, command, args) { | |||
82 | .end(); | 65 | .end(); |
83 | }; | 66 | }; |
84 | 67 | ||
68 | MontageBoot.loadPackage = function (location, config) { | ||
69 | var config = {}; | ||
70 | |||
71 | config.location = URL.resolve(Require.getLocation(), location + '/'); | ||
72 | |||
73 | // setup the reel loader | ||
74 | config.makeLoader = function (config) { | ||
75 | return MontageBoot.ReelLoader( | ||
76 | config, | ||
77 | Require.makeLoader(config) | ||
78 | ); | ||
79 | }; | ||
80 | |||
81 | // setup serialization compiler | ||
82 | config.makeCompiler = function (config) { | ||
83 | return MontageBoot.TemplateCompiler( | ||
84 | config, | ||
85 | MontageBoot.SerializationCompiler( | ||
86 | config, | ||
87 | Require.makeCompiler(config) | ||
88 | ) | ||
89 | ); | ||
90 | }; | ||
91 | |||
92 | return Require.loadPackage(config.location, config); | ||
93 | }; | ||
94 | |||
95 | MontageBoot.TemplateLoader = function (config, load) { | ||
96 | return function(id, module) { | ||
97 | var html = id.match(/(.*\/)?(?=[^\/]+\.html$)/); | ||
98 | var serialization = id.match(/(?=[^\/]+\.json$)/); // XXX this is not necessarily a strong indicator of a serialization alone | ||
99 | if (html) { | ||
100 | return load(id, module) | ||
101 | .then(function () { | ||
102 | module.dependencies = parseHtmlDependencies(module.text, module.location); | ||
103 | return module; | ||
104 | }); | ||
105 | } else if (serialization) { | ||
106 | return load(id, module) | ||
107 | .then(function () { | ||
108 | module.dependencies = collectSerializationDependencies(module.text, []); | ||
109 | return module; | ||
110 | }); | ||
111 | } else { | ||
112 | return load(id, module); | ||
113 | } | ||
114 | }; | ||
115 | }; | ||
116 | |||
117 | // add the TemplateLoader to the middleware chain | ||
118 | Require.makeLoader = (function (makeLoader) { | ||
119 | return function (config) { | ||
120 | return MontageBoot.TemplateLoader(config, makeLoader(config)); | ||
121 | }; | ||
122 | })(Require.makeLoader); | ||
123 | |||
124 | var parseHtmlDependencies = function (text, location) { | ||
125 | var dependencies = []; | ||
126 | var document = jsdom(text, null, { | ||
127 | "features": { | ||
128 | "FetchExternalResources": false, | ||
129 | "ProcessExternalResources": false | ||
130 | } | ||
131 | }); | ||
132 | collectHtmlDependencies(document, dependencies); | ||
133 | return dependencies; | ||
134 | }; | ||
135 | |||
136 | var collectHtmlDependencies = function (document, dependencies) { | ||
137 | visit(document, function (element) { | ||
138 | if (element.nodeType == Node.ELEMENT_NODE) { | ||
139 | if (element.tagName === "SCRIPT") { | ||
140 | if (element.getAttribute("type") === "text/montage-serialization") { | ||
141 | collectSerializationDependencies(getText(element), dependencies); | ||
142 | } | ||
143 | } else if (element.tagName === "LINK") { | ||
144 | if (element.getAttribute("type") === "text/montage-serialization") { | ||
145 | dependencies.push(element.getAttribute("href")); | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | }); | ||
150 | }; | ||
151 | |||
152 | function visit(element, visitor) { | ||
153 | var pruned; | ||
154 | var prune = function () { | ||
155 | pruned = true; | ||
156 | }; | ||
157 | visitor(element, prune); | ||
158 | if (pruned) { | ||
159 | return; | ||
160 | } | ||
161 | element = element.firstChild; | ||
162 | while (element) { | ||
163 | visit(element, visitor); | ||
164 | element = element.nextSibling; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | function getText(element) { | ||
169 | return domToHtml(element._childNodes, true, true); | ||
170 | } | ||
171 | |||
172 | var collectSerializationDependencies = function (text, dependencies) { | ||
173 | var serialization = JSON.parse(text); | ||
174 | Object.keys(serialization).forEach(function (label) { | ||
175 | var description = serialization[label]; | ||
176 | if (typeof description.module === "string") { | ||
177 | dependencies.push(description.module); | ||
178 | } | ||
179 | }); | ||
180 | return dependencies; | ||
181 | }; | ||
182 | |||