Skip to content

Commit

Permalink
Added client option to reference runtime helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
tj committed Aug 26, 2011
1 parent 5ea12ef commit a22ce62
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 133 deletions.
20 changes: 17 additions & 3 deletions Readme.md
Expand Up @@ -57,15 +57,14 @@ via npm:

$ make jade.min.js

By default Jade instruments templates with line number statements such as `__.lineno = 3` for debugging purposes. When used in a browser it's useful to minimize this boiler plate, you can do so by passing the option `{ compileDebug: false }`, and `{ inline: false }`. The following template
By default Jade instruments templates with line number statements such as `__.lineno = 3` for debugging purposes. When used in a browser it's useful to minimize this boiler plate, you can do so by passing the option `{ compileDebug: false }`. The following template

p Hello #{name}

Can then be as small as the following generated function:

```js
function anonymous(locals) {
var attrs = jade.attrs, escape = jade.escape;
var buf = [];
with (locals || {}) {
var interp;
Expand All @@ -77,7 +76,22 @@ function anonymous(locals) {
}
```

Through the use of Jade's `./runtime.js` you may utilize these pre-compiled templates on the client-side _without_ Jade itself, all you need is the associated utility functions (in runtime.js), which are then available as `jade.attrs`, `jade.escape` etc.
Through the use of Jade's `./runtime.js` you may utilize these pre-compiled templates on the client-side _without_ Jade itself, all you need is the associated utility functions (in runtime.js), which are then available as `jade.attrs`, `jade.escape` etc. To enable this you should pass `{ client: true }` to `jade.compile()` to tell Jade to reference the helper functions
via `jade.attrs`, `jade.escape` etc.

```js
function anonymous(locals) {
var attrs = jade.attrs, escape = jade.escape;
var buf = [];
with (locals || {}) {
var interp;
buf.push('<p>');
buf.push('Hello ' + escape((interp = name) == null ? '' : interp) + '');
buf.push('</p>');
}
return buf.join("");
}
```

## Public API

Expand Down
140 changes: 13 additions & 127 deletions jade.js
Expand Up @@ -740,21 +740,11 @@ exports.runtime = runtime;
*/

function parse(str, options){
var filename = options.filename
, inline = false !== options.inline
, inlined = '';

if (inline) {
inlined += runtime.attrs.toString() + '\n';
inlined += runtime.escape.toString() + '\n';
} else {
inlined = 'var attrs = jade.attrs, escape = jade.escape;\n';
}
var filename = options.filename;

try {
// Parse
var parser = new Parser(str, filename, options);
if (options.debug) parser.debug();

// Compile
var compiler = new (options.compiler || Compiler)(parser.parse(), options)
Expand All @@ -767,7 +757,6 @@ function parse(str, options){

try {
return ''
+ inlined
+ 'var buf = [];\n'
+ (options.self
? 'var self = locals || {}, __ = __ || locals.__;\n' + js
Expand All @@ -789,7 +778,6 @@ function parse(str, options){
* Options:
*
* - `compileDebug` when `false` debugging code is stripped from the compiled template
* - `inline` when `false` helpers are not inlined, and `jade.<helper>` is used
*
* @param {String} str
* @param {Options} options
Expand All @@ -800,24 +788,15 @@ function parse(str, options){
exports.compile = function(str, options){
var options = options || {}
, input = JSON.stringify(str)
, inline = false !== options.inline
, filename = options.filename
? JSON.stringify(options.filename)
: 'undefined'
, inlined = ''
, fn;

if (inline) {
inlined = runtime.rethrow.toString();
} else {
inlined = 'var rethrow = jade.rethrow;';
}

if (options.compileDebug !== false) {
// Reduce closure madness by injecting some locals
fn = [
'var __ = { lineno: 1, input: ' + input + ', filename: ' + filename + ' };'
, inlined
, 'try {'
, parse(String(str), options || {})
, '} catch (err) {'
Expand All @@ -827,100 +806,13 @@ exports.compile = function(str, options){
} else {
fn = parse(String(str), options || {});
}

return new Function('locals', fn);
};

/**
* Render the given `str` of jade.
*
* Options:
*
* - `scope` Evaluation scope (`this`)
* - `locals` Local variable object
* - `filename` Used in exceptions, and required by `cache`
* - `cache` Cache intermediate JavaScript in memory keyed by `filename`
* - `compiler` Compiler to replade jade's default
* - `doctype` Specify the default doctype
*
* @param {String|Buffer} str
* @param {Object} options
* @return {String}
* @api public
*/

exports.render = function(str, options){
var fn
, options = options || {}
, filename = options.filename;

// Accept Buffers
str = String(str);

// Cache support
if (options.cache) {
if (filename) {
if (cache[filename]) {
fn = cache[filename];
} else {
fn = cache[filename] = new Function('locals', parse(str, options));
}
} else {
throw new Error('filename is required when using the cache option');
}
} else {
fn = new Function('locals', parse(str, options));
}

// Render the template
try {
var locals = options.locals || {}
, meta = { lineno: 1 };
locals.__ = meta;
return fn.call(options.scope, locals);
} catch (err) {
runtime.rethrow(err, str, filename, meta.lineno);
}
fn = new Function('locals, attrs, escape, rethrow', fn);
return function(locals){
return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow);
};
};

/**
* Render jade template at the given `path`.
*
* @param {String} path
* @param {Object} options
* @param {Function} fn
* @api public
*/

exports.renderFile = function(path, options, fn){
var ret;

if (typeof options === 'function') {
fn = options;
options = {};
}
options.filename = path;

// Primed cache
if (options.cache && cache[path]) {
try {
ret = exports.render('', options);
} catch (err) {
return fn(err);
}
fn(null, ret);
} else {
fs.readFile(path, 'utf8', function(err, str){
if (err) return fn(err);
try {
ret = exports.render(str, options);
} catch (err) {
return fn(err);
}
fn(null, ret);
});
}
};
}); // module: jade.js

require.register("lexer.js", function(module, exports, require){
Expand Down Expand Up @@ -2088,20 +1980,6 @@ var textOnly = exports.textOnly = ['code', 'script', 'textarea', 'style', 'title

Parser.prototype = {

/**
* Output parse tree to stdout.
*
* @api public
*/

debug: function(){
var lexer = new Lexer(this.input)
, tree = require('sys').inspect(this.parse(), false, 12, true);
console.log('\n\x1b[1mParse Tree\x1b[0m:\n');
console.log(tree);
this.lexer = lexer;
},

/**
* Return the next token object.
*
Expand Down Expand Up @@ -2562,12 +2440,20 @@ require.register("runtime.js", function(module, exports, require){
* MIT Licensed
*/

/**
* Lame Array.isArray() polyfill for now.
*/

if (!Array.isArray) {
Array.isArray = function(arr){
return '[object Array]' == toString.call(arr);
};
}

/**
* Lame Object.keys() polyfill for now.
*/

if (!Object.keys) {
Object.keys = function(obj){
var arr = [];
Expand Down
2 changes: 1 addition & 1 deletion jade.min.js

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions lib/jade.js
Expand Up @@ -105,7 +105,7 @@ function parse(str, options){
return ''
+ 'var buf = [];\n'
+ (options.self
? 'var self = locals || {}, __ = __ || locals.__;\n' + js
? 'var self = locals || {};\n' + js
: 'with (locals || {}) {\n' + js + '\n}\n')
+ 'return buf.join("");';

Expand All @@ -124,6 +124,8 @@ function parse(str, options){
* Options:
*
* - `compileDebug` when `false` debugging code is stripped from the compiled template
* - `client` when `true` the helper functions `escape()` etc will reference `jade.escape()`
* for use with the Jade client-side runtime.js
*
* @param {String} str
* @param {Options} options
Expand All @@ -134,13 +136,13 @@ function parse(str, options){
exports.compile = function(str, options){
var options = options || {}
, input = JSON.stringify(str)
, client = options.client
, filename = options.filename
? JSON.stringify(options.filename)
: 'undefined'
, fn;

if (options.compileDebug !== false) {
// Reduce closure madness by injecting some locals
fn = [
'var __ = { lineno: 1, input: ' + input + ', filename: ' + filename + ' };'
, 'try {'
Expand All @@ -153,7 +155,14 @@ exports.compile = function(str, options){
fn = parse(String(str), options || {});
}

if (client) {
fn = 'var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow;\n' + fn;
}

fn = new Function('locals, attrs, escape, rethrow', fn);

if (client) return fn;

return function(locals){
return fn(locals, runtime.attrs, runtime.escape, runtime.rethrow);
};
Expand Down
8 changes: 8 additions & 0 deletions runtime.js
Expand Up @@ -6,12 +6,20 @@ var jade = (function(exports){
* MIT Licensed
*/

/**
* Lame Array.isArray() polyfill for now.
*/

if (!Array.isArray) {
Array.isArray = function(arr){
return '[object Array]' == toString.call(arr);
};
}

/**
* Lame Object.keys() polyfill for now.
*/

if (!Object.keys) {
Object.keys = function(obj){
var arr = [];
Expand Down

0 comments on commit a22ce62

Please sign in to comment.