UNPKG

9.6 kBJavaScriptView Raw
1var Ctx = {
2 anon: {}
3};
4
5Ctx.sync = function(cb) {
6 var jobs = 0;
7 this.await = function() {jobs++;};
8 this.signal = function() {if (--jobs == 0) cb();}
9};
10
11Ctx.res = function(dataProvider, sync) {
12 this.sync = sync;
13 this.dataProvider = dataProvider;
14 this.buffer = [];
15 this.getBlock = Ctx.getBlock;
16 this.init = Ctx.init;
17 this._render = Ctx._render;
18
19 this.write = function(str) {
20 this.buffer.push(str);
21 };
22 this.fork = function() {
23 var r = new Ctx.res(this.dataProvider, this.sync);
24 this.buffer.push(r);
25 return r;
26 };
27
28 this._body = function() {
29 var idx = 0;
30 var body = "";
31 while (idx < this.buffer.length) {
32 var b = this.buffer[idx++];
33 if (typeof b !== "undefined" && b._body) {
34 body += b._body();
35 } else {
36 body += b;
37 }
38 }
39 return body;
40 };
41};
42Ctx.getBlock = function(name) {
43 var ref = Ctx.schema[name];
44 if (!ref) throw new Error("Could not find block: " + name);
45 if (!ref.class) {
46 ref = Ctx.init(null, ref);
47 }
48 return ref;
49};
50Ctx.init = function(seq, block) {
51 var a;
52 if (seq) {
53 a = Ctx.anon[seq];
54 }
55 if (!a) {
56 a = function() {};
57 if (block.parent) {
58 a.prototype = Object.create(Ctx.getBlock(block.parent).class.prototype);
59 }
60 }
61 a.handler = block.handler;
62 for (var f in block)
63 if (typeof block[f] === "function") {
64 a.prototype[f] = block[f];
65 }
66
67 var a1 = new a();
68 a1.class = a;
69 if (seq) Ctx.anon[seq] = a;
70 return a1;
71};
72Ctx._render = function(bl, attrs, res) {
73 this.sync.await();
74 if(bl.class.handler && res.dataProvider) {
75 var h = res.dataProvider.get(bl.class.handler);
76 if (!h) {
77 throw new Error("Could not find data provider " + bl.handler);
78 }
79 res = res.fork();
80 var selfSync = this.sync;
81 h(attrs, function(err, data) {
82 if (err) throw err;
83 bl.body(data, res);
84 selfSync.signal();
85 });
86 } else {
87 bl.body(attrs, res);
88 this.sync.signal();
89 }
90};
91Ctx.render = function(name, data, provider, cb) {
92 name = name.replace(/\\/g, "/");
93 var res = new Ctx.res(provider, new Ctx.sync(function() {
94 cb(null, res._body());
95 }));
96 try {
97 res._render(res.getBlock(name), data, res);
98 } catch(e) {
99 cb(e, null);
100 }
101};
102
103if (typeof module !== 'undefined') {module.exports = Ctx;}
104Ctx.schema = { "anon:A":{ body:function (attrs, res) {res.write((attrs.x));
105} },
106 "anon:B":{ body:function (attrs, res) {res._render(res.getBlock('anon:A'),{x:(attrs.x),}, res);
107} },
108 "anon/cascade-named:A":{ def_1:function (attrs, res) {},
109 body:function (attrs, res) {res.write('a');
110this.def_1(attrs, res);
111res.write('a');
112} },
113 "anon/cascade-named:B":{ body:function (attrs, res) {res.write('b');
114var self = this;
115res._render(res.init(0, {parent: 'anon/cascade-named:A',def: function(_a, res) {self.def_1(attrs, res);
116},def_1: function(_a, res) {self.def_1(null, res)},}),{}, res);
117res.write('b');
118} },
119 "anon/cascade-named:C":{ body:function (attrs, res) {res.write('c');
120var self = this;
121res._render(res.init(1, {parent: 'anon/cascade-named:B',def: function(_a, res) {self.def_1(attrs, res);
122},def_1: function(_a, res) {self.def_1(null, res)},}),{}, res);
123res.write('c');
124} },
125 "anon/cascade-named:D":{ body:function (attrs, res) {res.write('d');
126this.class.prototype.def_1=function(_a, res) {res.write('hello');
127};
128var self = this;
129res._render(res.init(2, {parent: 'anon/cascade-named:C',def: function(_a, res) {self.def_1(attrs, res);
130},def_1: function(_a, res) {self.def_1(null, res)},}),{}, res);
131res.write('d');
132} },
133 "anon/cascade:A":{ def:function (attrs, res) {},
134 body:function (attrs, res) {res.write('a');
135this.def(attrs, res);
136res.write('a');
137} },
138 "anon/cascade:B":{ body:function (attrs, res) {res.write('b');
139var self = this;
140res._render(res.init(0, {parent: 'anon/cascade:A',def: function(_a, res) {self.def(attrs, res);
141},def: function(_a, res) {self.def(null, res)},}),{}, res);
142res.write('b');
143} },
144 "anon/cascade:C":{ body:function (attrs, res) {res.write('c');
145var self = this;
146res._render(res.init(1, {parent: 'anon/cascade:B',def: function(_a, res) {self.def(attrs, res);
147},def: function(_a, res) {self.def(null, res)},}),{}, res);
148res.write('c');
149} },
150 "anon/cascade:D":{ body:function (attrs, res) {res.write('d');
151var self = this;
152res._render(res.init(2, {parent: 'anon/cascade:C',def: function(_a, res) {res.write('hello');
153},}),{}, res);
154res.write('d');
155} },
156 "anon/new-def:A":{ def_a:function (attrs, res) {},
157 body:function (attrs, res) {res.write('a');
158this.def_a(attrs, res);
159res.write('a');
160} },
161 "anon/new-def:B":{ def_b:function (attrs, res) {},
162 body:function (attrs, res) {res.write('b');
163this.def_b(attrs, res);
164res.write('b');
165} },
166 "anon/new-def:C":{ parent:"anon/new-def:A",
167 def_a:function (attrs, res) {this.class.prototype.def_b=function(_a, res) {self.def_c(attrs, res);
168};
169var self = this;
170res._render(res.init(0, {parent: 'anon/new-def:B',def: function(_a, res) {self.def_b(attrs, res);
171},def_b: function(_a, res) {self.def_b(null, res)},}),{}, res);
172} },
173 "anon/new-def:D":{ parent:"anon/new-def:C",
174 def_c:function (attrs, res) {res.write('d');
175} },
176 "handler/cascade:A":{ handler:"a",
177 body:function (attrs, res) {res.write((attrs.x));
178} },
179 "handler/cascade:B":{ handler:"b",
180 body:function (attrs, res) {res.write((attrs.z));
181res._render(res.getBlock('handler/cascade:A'),{y1:'f',}, res);
182} },
183 "handler/simple:A":{ handler:"a",
184 body:function (attrs, res) {res.write((attrs.x));
185} },
186 "inheritance/cascade:A":{ def_a:function (attrs, res) {},
187 body:function (attrs, res) {res.write('a1');
188this.def_a(attrs, res);
189res.write('a2');
190} },
191 "inheritance/cascade:B":{ parent:"inheritance/cascade:A",
192 def_a:function (attrs, res) {res.write('b1');
193this.def_b(attrs, res);
194res.write('b2');
195} },
196 "inheritance/cascade:C":{ parent:"inheritance/cascade:B",
197 def_b:function (attrs, res) {res.write('b in C');
198} },
199 "inheritance/default-defs:A":{ def_a:function (attrs, res) {res.write('a definition');
200},
201 body:function (attrs, res) {this.def_a(attrs, res);
202} },
203 "inheritance/default-defs:B":{ parent:"inheritance/default-defs:A" },
204 "inheritance/default-defs:C":{ parent:"inheritance/default-defs:B" },
205 "inheritance/multi:A":{ def:function (attrs, res) {},
206 body:function (attrs, res) {this.def(attrs, res);
207} },
208 "inheritance/multi:B":{ parent:"inheritance/multi:A",
209 def:function (attrs, res) {res.write('hello from B');
210} },
211 "inheritance/multi:C":{ parent:"inheritance/multi:B",
212 def:function (attrs, res) {res.write('hello from C');
213} },
214 "inheritance/named-defs:A":{ def_a:function (attrs, res) {},
215 def_b:function (attrs, res) {},
216 body:function (attrs, res) {this.def_a(attrs, res);
217this.def_b(attrs, res);
218} },
219 "inheritance/named-defs:B":{ parent:"inheritance/named-defs:A",
220 def_a:function (attrs, res) {res.write('a in B');
221},
222 def_b:function (attrs, res) {res.write('b in B');
223} },
224 "inheritance/named-defs:C":{ parent:"inheritance/named-defs:B",
225 def_a:function (attrs, res) {res.write('a in C');
226},
227 def_b:function (attrs, res) {res.write('b in C');
228} },
229 "inheritance/simple:A":{ def:function (attrs, res) {},
230 body:function (attrs, res) {this.def(attrs, res);
231} },
232 "inheritance/simple:B":{ parent:"inheritance/simple:A",
233 def:function (attrs, res) {res.write('hello');
234} },
235 "var/for:A":{ def:function (attrs, res) {},
236 body:function (attrs, res) {this.def(attrs, res);
237} },
238 "var/for:B":{ body:function (attrs, res) {var self = this;
239res._render(res.init(0, {parent: 'var/for:A',def: function(_a, res) {res.write((attrs.x));
240},}),{}, res);
241} },
242 "var/for:C":{ body:function (attrs, res) {res._render(res.getBlock('var/for:B'),{x:'1',}, res);
243res._render(res.getBlock('var/for:B'),{x:'2',}, res);
244res._render(res.getBlock('var/for:B'),{x:'3',}, res);
245} },
246 "var:var":{ body:function (attrs, res) {res.write((attrs.x));
247} },
248 "var:parent_test":{ parent:"var:var" },
249 "var:_anon_def_test":{ def:function (attrs, res) {},
250 body:function (attrs, res) {this.def(attrs, res);
251} },
252 "var:anon_def_test":{ parent:"var:_anon_def_test",
253 def:function (attrs, res) {res.write((attrs.x));
254} },
255 "var:_call_parent":{ def:function (attrs, res) {res.write('parent');
256},
257 body:function (attrs, res) {this.def(attrs, res);
258} },
259 "var:call_parent":{ parent:"var:_call_parent",
260 def:function (attrs, res) {res.getBlock('var:_call_parent')['def'](attrs, res);
261} },
262 "var:__context_":{ def:function (attrs, res) {},
263 body:function (attrs, res) {res.write('0-open '+(attrs.x));
264this.def(attrs, res);
265res.write('0-close '+(attrs.x));
266} },
267 "var:_context":{ def:function (attrs, res) {},
268 body:function (attrs, res) {res.write('1-open '+(attrs.x));
269this.def(attrs, res);
270res.write('1-close '+(attrs.x));
271} },
272 "var:_context_":{ parent:"var:__context_",
273 def:function (attrs, res) {var self = this;
274res._render(res.init(0, {parent: 'var:_context',def: function(_a, res) {res.write('2-open '+(attrs.x));
275self.def_1(attrs, res);
276res.write('2-close '+(attrs.x));
277},def_1: function(_a, res) {self.def_1(null, res)},}),{}, res);
278} },
279 "var:context":{ parent:"var:_context_",
280 def_1:function (attrs, res) {res.write('in '+(attrs.x));
281} } }
\No newline at end of file