Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[compiler] save context into __this variable

* Added examples
* Extended readme
  • Loading branch information...
commit e63d4b2388182fc8ca8c566aa00691155ff950d9 1 parent b08b7ee
@indutny indutny authored
View
13 README.md
@@ -48,6 +48,8 @@ switch (this.elem) {
}
```
+[More examples][5]
+
## Installation
```bash
@@ -129,11 +131,11 @@ template(this.type === 'second') {
```
XJST is intended to be applied recursively to the same data, while making small
-reversible changes to it. `apply` keyword works exactly like a `local` (applying
-changes in the parens and reverting them after the execution), but with small
-distinction - `apply` doesn't have a body, so it's just doing some
-changes to the data and applying template recursively
-(the context will be preserved).
+temporary changes to it (all changes will be reverted back after operation).
+`apply` keyword works exactly like a `local` (applying changes in the parens and
+reverting them after the execution), but with small distinction - `apply`
+doesn't have a body, so it's just doing some changes to the data and applying
+template recursively (the context will be preserved).
## CLI interface
@@ -201,3 +203,4 @@ Some technical details (in Russian) can be found in [doc/tech.ru.md][4].
[2]: https://github.com/veged/ometa-js
[3]: http://veged.github.com/xjst/
[4]: https://github.com/veged/xjst/blob/master/doc/tech.ru.md
+[5]: https://github.com/veged/xjst/tree/master/examples
View
27 examples/recursion/compiled.js
@@ -0,0 +1,27 @@
+(function(exports) {
+ var __r0, __r1;
+ exports.apply = apply;
+ function apply() {
+ var __this = this;
+ var __t = this["type"];
+ if (__t === "item") {
+ return "<li>" + this["ctx"]["value"] + "</li>";
+ return;
+ } else if (__t === "list") {
+ var res = [ "<ul>" ];
+ this["items"].forEach(function(item) {
+ res.push(("", __r0 = __this["type"], __this["type"] = "item", __r1 = __this["ctx"], __this["ctx"] = item, __r2 = apply.call(__this), __this["type"] = __r0, __this["ctx"] = __r1, "", __r2));
+ });
+ res.push("</ul>");
+ return res.join("");
+ return;
+ } else {
+ return $e.call(this, []);
+ }
+ }
+ function $e() {
+ throw new Error;
+ return;
+ }
+ return exports;
+})(typeof exports === "undefined" ? {} : exports);
View
26 examples/recursion/source.xjst
@@ -0,0 +1,26 @@
+// Pass
+// {
+// "type": "list",
+// "items": [
+// { "value": "test" }
+// ]
+// }
+// as context
+
+template(this.type === 'list') {
+ var res = ['<ul>'];
+
+ this.items.forEach(function(item) {
+ // This will temporarily change context's properties (type and ctx)
+ res.push(apply({ type: 'item', ctx: item }));
+ // And revert them here
+ });
+
+ res.push('</ul>');
+
+ return res.join('');
+}
+
+template(this.type === 'item') {
+ return '<li>' + this.ctx.value + '</li>';
+}
View
26 examples/simple/compiled.js
@@ -0,0 +1,26 @@
+(function(exports) {
+ exports.apply = apply;
+ function apply() {
+ var __this = this;
+ var __t = this["elem"];
+ if (__t === "div") {
+ if (this["colour"] === "blue") {
+ return '<div class="blue">' + this["body"] + "</div>";
+ return;
+ } else {
+ return "<div>" + this["body"] + "</div>";
+ return;
+ }
+ } else if (__t === "a") {
+ return '<a href="' + this["href"] + '">' + this["text"] + "</a>";
+ return;
+ } else {
+ return $e.call(this, []);
+ }
+ }
+ function $e() {
+ throw new Error;
+ return;
+ }
+ return exports;
+})(typeof exports === "undefined" ? {} : exports);
View
11 examples/simple/source.xjst
@@ -0,0 +1,11 @@
+template(this.elem === 'a') {
+ return '<a href="' + this.href + '">' + this.text + '</a>';
+}
+
+template(this.elem === 'div') {
+ return '<div>' + this.body + '</div>';
+}
+
+template(this.elem === 'div' && this.colour === 'blue') {
+ return '<div class="blue">' + this.body + '</div>';
+}
View
19 lib/xjst/compiler.js
@@ -156,7 +156,7 @@ exports.generate = function generate(ast, options) {
}
if (o.fn) {
- fns[o.id] = { body: res.join(''), alt: o.longId };
+ fns[o.id] = { tag: o.tag, body: res.join(''), alt: o.longId };
res = ['return ', fnName(o), '.call(this);'];
}
@@ -169,7 +169,7 @@ exports.generate = function generate(ast, options) {
// if we was directly asked to do this
if (o.size > 1 || o.fn) {
// Save function body
- fns[o.id] = { body: body, alt: o.longId };
+ fns[o.id] = { tag: o.tag, body: body, alt: o.longId };
// Tagged statements should be called with a parents list
// (needed for client-side merging)
@@ -246,17 +246,19 @@ exports.generate = function generate(ast, options) {
} else {
var body = serialize(t, tails, []);
if (!fns[id]) {
- fns[id] = { body: body, alt: t.longId};
+ fns[id] = { tag: t.tag, body: body, alt: t.longId};
}
}
}
+ var storeCtx = 'var __this = this;';
+
return [
options.merge ? 'var _c = exports.config = {};' +
// Insert .mergeWith template function
'exports.mergeWith = ' + utils.mergeWith.toString() + ';' : '',
'exports.apply = apply;',
- 'function apply() {'
+ 'function apply() {', storeCtx
].concat(
heads.reverse(), res, '};',
@@ -270,12 +272,13 @@ exports.generate = function generate(ast, options) {
res.push(
' ', key,
': function() {',
+ storeCtx,
hashs[id].map[key], '},'
);
});
res.push(' },\n');
- res.push(' "d": function() {', hashs[id]['default'], '}');
+ res.push(' "d": function() {', storeCtx, hashs[id]['default'], '}');
res.push('};\n');
return res.join('');
@@ -295,7 +298,11 @@ exports.generate = function generate(ast, options) {
fnName({ id: id }) + ' = function() {';
}
- return prefix + fn.body + '};';
+ if (fn.tag === 'unexpected') {
+ return prefix + fn.body + '};';
+ } else {
+ return prefix + storeCtx + fn.body + '};';
+ }
})
).join('');
}
View
4 lib/xjst/ometa/xjst.ometajs
@@ -81,7 +81,7 @@ ometa XJSTTranslator <: BSJSIdentity {
},
bindingToAsmt = [#binding :k :v]
- localAsmt([#set, [#getp, [#string, k], [#this]], v]):r -> r,
+ localAsmt([#set, [#getp, [#string, k], [#get, '__this']], v]):r -> r,
localAsmts = [#json bindingToAsmt*:as] -> {
var es = [];
@@ -215,7 +215,7 @@ ometa XJSTLocalAndApplyCompiler <: BSJSIdentity {
ometa XJSTCompiler <: BSJSTranslator {
- applyStmt = :param -> { param.code || 'apply.call(this)' },
+ applyStmt = :param -> { param.code || 'apply.call(__this)' },
nhApplyStmt = :param -> 'apply()',
nhApplyExpr -> 'apply',
Please sign in to comment.
Something went wrong with that request. Please try again.