UNPKG

11.5 kBJavaScriptView Raw
1(function() {
2 var DOMElementType, HTMLCompiler, Tag, Template, copy_structure, deep_merge, example, example2, fs, hook, isArray, jQuery, jsonify, mask, match, new_tag, slim, slim_attrs, suitup, traverse, trim, util, _ref;
3 var __slice = Array.prototype.slice;
4
5 fs = require('fs');
6
7 jQuery = require('jquery');
8
9 isArray = Array.isArray;
10
11 DOMElementType = {
12 NORMAL: 1,
13 TEXT: 3,
14 CDATA: 4,
15 FRAGMENT: 11
16 };
17
18 deep_merge = function() {
19 var k, obj, objs, res, v, _i, _len;
20 objs = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
21 if (isArray(objs[0])) objs = objs[0];
22 res = {};
23 for (_i = 0, _len = objs.length; _i < _len; _i++) {
24 obj = objs[_i];
25 for (k in obj) {
26 v = obj[k];
27 if (typeof v === 'object' && !isArray(v)) {
28 res[k] = deep_merge(res[k] || {}, v);
29 } else {
30 res[k] = v;
31 }
32 }
33 }
34 return res;
35 };
36
37 trim = function(str) {
38 return str.replace(/^\s+|\s+$/g, "");
39 };
40
41 slim_attrs = function(el) {
42 var attr, attrs, _i, _len, _ref, _ref2;
43 attrs = {};
44 _ref2 = (_ref = el.attributes) != null ? _ref : [];
45 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
46 attr = _ref2[_i];
47 attrs[attr.name] = attr.value;
48 }
49 return attrs;
50 };
51
52 slim = function(el) {
53 return {
54 name: el.nodeName.toLowerCase(),
55 attrs: slim_attrs(el),
56 children: traverse(el.childNodes)
57 };
58 };
59
60 traverse = function(elems) {
61 var el, res, _i, _len;
62 if (elems == null) return [];
63 res = [];
64 for (_i = 0, _len = elems.length; _i < _len; _i++) {
65 el = elems[_i];
66 if (el.nodeType === DOMElementType.NORMAL) {
67 res.push(slim(el));
68 } else if (el.nodeType === DOMElementType.TEXT) {
69 if (trim(el.value).length) res.push(el.value);
70 } else {
71 continue;
72 }
73 }
74 return res;
75 };
76
77 jsonify = function(elems) {
78 var el, _i, _len, _ref, _results;
79 _ref = elems != null ? elems : [];
80 _results = [];
81 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
82 el = _ref[_i];
83 _results.push(slim(el));
84 }
85 return _results;
86 };
87
88 copy_structure = function(tree) {
89 var el, res, _i, _len, _ref;
90 res = [];
91 _ref = tree != null ? tree : [];
92 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
93 el = _ref[_i];
94 if (typeof el === 'string' || typeof el === 'number') {
95 res.push(el);
96 continue;
97 }
98 res.push({
99 name: el.name,
100 attrs: el.attrs,
101 children: copy_structure(el.children)
102 });
103 }
104 return res;
105 };
106
107 match = function(tag, el) {
108 var key, value, _ref, _ref2;
109 if (el == null) return true;
110 if (tag.name !== el.name) return false;
111 _ref = tag.attrs;
112 for (key in _ref) {
113 value = _ref[key];
114 if (el.attrs[key] !== value) {
115 if (typeof value !== 'string' || (((_ref2 = el.attrs[key]) != null ? _ref2.indexOf(value) : void 0) || -1) === -1) {
116 return false;
117 }
118 }
119 }
120 return true;
121 };
122
123 new_tag = function(parent, el, callback) {
124 var attrs;
125 attrs = deep_merge(el.attrs);
126 return parent.tag(el.name, attrs, function() {
127 var child, _i, _len, _ref, _ref2;
128 _ref2 = (_ref = el.children.slice()) != null ? _ref : [];
129 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
130 child = _ref2[_i];
131 if (typeof child === 'string' || typeof child === 'number') {
132 this.text("" + child, {
133 append: true
134 });
135 } else {
136 new_tag(this, child, function() {
137 if (typeof callback === "function") callback();
138 return callback = null;
139 });
140 }
141 }
142 this.end();
143 return typeof callback === "function" ? callback() : void 0;
144 });
145 };
146
147 mask = function(tag, el) {
148 if (el == null) return;
149 tag.attr(el.attrs);
150 return tag._elems = el.children;
151 };
152
153 hook = function(tpl) {
154 return tpl.xml.use(function(parent, tag, next) {
155 var elems, repeat;
156 elems = parent._elems;
157 if (elems == null) return next(tag);
158 repeat = function() {
159 var el;
160 el = elems[0];
161 if (typeof el === 'string' || typeof el === 'number') {
162 console.log("text".blue, el);
163 elems.shift();
164 if (typeof parent.text === "function") {
165 parent.text(el, {
166 append: true
167 });
168 }
169 return repeat();
170 } else if (match(tag, el)) {
171 console.log("match".yellow, el != null ? el.name : void 0, el != null ? el.attrs : void 0);
172 elems.shift();
173 mask(tag, el);
174 return next(tag);
175 } else {
176 console.log("new".green, el != null ? el.name : void 0, el != null ? el.attrs : void 0, "(", tag.name, tag.attrs, ")");
177 console.log("WTF WTF WTF WTF".bold.red, tag.name, tag.attrs);
178 return new_tag(parent, el, function() {
179 console.log("repeat".red, tag.name, tag.attrs, "(", el != null ? el.name : void 0, el != null ? el.attrs : void 0, ")");
180 return repeat();
181 });
182 }
183 };
184 return repeat();
185 });
186 };
187
188 suitup = function(rawtemplate, tree) {
189 return function() {
190 var args, elems, tpl;
191 args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
192 tpl = rawtemplate.apply(null, args);
193 elems = copy_structure(tree);
194 tpl.xml._elems = elems;
195 hook(tpl);
196 return tpl;
197 };
198 };
199
200 HTMLCompiler = (function() {
201
202 function HTMLCompiler() {
203 this.$ = jQuery.create();
204 this.loadSync = this.open;
205 }
206
207 HTMLCompiler.prototype.read = function(filename, callback) {
208 var _this = this;
209 return fs.readFile(filename, function(err, data) {
210 return callback != null ? callback.call(_this, err, data != null ? data.toString() : void 0) : void 0;
211 });
212 };
213
214 HTMLCompiler.prototype.readSync = function(filename) {
215 var _ref;
216 return (_ref = fs.readFileSync(filename)) != null ? _ref.toString() : void 0;
217 };
218
219 HTMLCompiler.prototype.parse = function(data) {
220 return this.el = this.$(data);
221 };
222
223 HTMLCompiler.prototype.select = function(from, to) {
224 var el;
225 el = this.el.find(from);
226 el = el.clone();
227 el.find(to).remove();
228 return el;
229 };
230
231 HTMLCompiler.prototype.use = function(data) {
232 this.loaded = true;
233 return this.parse(data);
234 };
235
236 HTMLCompiler.prototype.load = function(filename, callback) {
237 return this.read(filename, function(err, data) {
238 if (err) return callback.call(this, err);
239 this.use(data);
240 return callback(null, this.el);
241 });
242 };
243
244 HTMLCompiler.prototype.open = function(filename) {
245 var data;
246 data = this.readSync(filename);
247 return this.use(data);
248 };
249
250 HTMLCompiler.prototype.compile = function(rawtemplate, el) {
251 var r, tree;
252 if (!this.loaded) {
253 throw new Error("no html file loaded or html string used.");
254 }
255 console.log("building data structure ...");
256 if (el == null) el = this.el;
257 tree = jsonify(el);
258 console.log("design is ready loaded. suiting up the template ...");
259 r = suitup(rawtemplate, tree);
260 r.tree = tree;
261 console.log("done.");
262 return r;
263 };
264
265 /*`<div id="channels" class="antiscroll-wrap">
266 <div class="antiscroll-inner scrollHolder">
267 <div class="channel selected">
268 <div class="avatar" style="background-image: url(public/avatars/user2.jpg)">
269 <span class="channelpost counter">2</span>
270 </div>
271 <div class="info">
272 <span class="owner">vera<span class="domain">@buddycloud.com</span></span>
273 <span class="status">What a wonderful day</span>
274 </div>
275 </div>`
276 */
277
278 return HTMLCompiler;
279
280 })();
281
282 require('colors');
283
284 util = require('util');
285
286 util.orginspect = util.inspect;
287
288 util.inspect = require('eyes').inspector({
289 stream: null,
290 hexy: {
291 format: 'fours'
292 }
293 });
294
295 _ref = require('./dynamictemplate'), Template = _ref.Template, Tag = _ref.Tag;
296
297 example = function() {
298 var channelsdesign, design, rawtemplate, streamshtml, template, _ref2;
299 design = new HTMLCompiler;
300 console.log("* loading html ...");
301 streamshtml = design.open('/home/dodo/code/arbyt/buddycloud/webclient/brunch/build/streams.html');
302 console.log("* selecting part of the html ...");
303 channelsdesign = streamshtml.select('#channels', '.channel');
304 console.log("S", (_ref2 = streamshtml.select('.channel')) != null ? _ref2.length : void 0);
305 rawtemplate = function(ee) {
306 return new Template({
307 schema: 5
308 }, function() {
309 return this.$div({
310 id: 'channels'
311 }, function() {
312 return this.$div(function() {
313 var _this = this;
314 return ee != null ? ee.on('new:channel', function(channel) {
315 return _this.$div({
316 "class": 'channel'
317 }, function() {
318 this.$div({
319 "class": 'avatar',
320 style: "background-image:url(" + channel.avatar + ")"
321 }, function() {
322 return this.$span({
323 "class": 'counter'
324 }, channel.counter);
325 });
326 return this.$div({
327 "class": 'info'
328 }, function() {
329 var _ref3;
330 this.$span({
331 "class": 'owner'
332 }, function() {
333 var jid, _ref3;
334 jid = ((_ref3 = channel.get('jid')) != null ? _ref3.split('@') : void 0) || [];
335 this.text("" + jid[0]);
336 return this.$span({
337 "class": 'domain'
338 }, "" + jid[1]);
339 });
340 return this.$span({
341 "class": 'status'
342 }, ((_ref3 = channel.nodes.get('status')) != null ? _ref3.last() : void 0) || "");
343 });
344 });
345 }) : void 0;
346 });
347 });
348 });
349 };
350 console.log("* start compiling ...");
351 return template = design.compile(rawtemplate, channelsdesign);
352 };
353
354 example2 = function() {
355 var design, rawtemplate, template;
356 design = new HTMLCompiler;
357 console.log("* using html ...");
358 design.use("<div id=\"main\">\n <div class=\"logo\" id=\"big\">some <a href=\"#\">linked</a> logo</div>\n <div class=\"tor list\" id=\"zwiebel\">\n <div class=\"entry\">some random entry</div>\n </div>\n <span>impressum</span>\n</div>\n<script>alert('evil');</script>");
359 rawtemplate = function() {
360 return new Template({
361 schema: 5
362 }, function() {
363 return this.$div({
364 id: 'main'
365 }, function() {
366 this.$div({
367 "class": 'list'
368 }, function() {
369 return this.$div({
370 "class": 'entry'
371 }, "specific text");
372 });
373 return this.$footer("stuff");
374 });
375 });
376 };
377 console.log("* start compiling ...");
378 template = design.compile(rawtemplate);
379 template.design = design;
380 return template;
381 };
382
383 module.exports = {
384 example: example,
385 example2: example2,
386 HTMLCompiler: HTMLCompiler,
387 copy_structure: copy_structure
388 };
389
390}).call(this);