Skip to content

Commit

Permalink
code conformity per jslint specifications.
Browse files Browse the repository at this point in the history
  • Loading branch information
paularmstrong committed Aug 5, 2011
1 parent aa848fa commit 2071180
Show file tree
Hide file tree
Showing 9 changed files with 687 additions and 631 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Node-T is a templating engine inspired by the django syntax. It has a few extens

var template = require('node-t');
var tmpl = template.fromFile("/path/to/template.html");
console.log( tmpl.render({names: ["Duke", "Django", "Louis"]}) );
console.log(tmpl.render({names: ["Duke", "Django", "Louis"]}));

### How it works

Expand Down Expand Up @@ -139,13 +139,13 @@ Node.js code
}

context.widgets = {
analytics: function(context){
analytics: function (context) {
// this inside widget functions is bound to the widget object
return "<script>..." + this.uaCode + "...</script>";
},
navigation: function(context){
navigation: function (context) {
var i, html = "";
for( i=0; i<this.links; i++ )
for (i=0; i<this.links; i++)
html += "<a href='" + links[i] + "'>" + links[i] + "</a>";
return html;
}
Expand Down
193 changes: 103 additions & 90 deletions helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,119 +14,132 @@ var KEYWORDS = /^(Array|RegExpt|Object|String|Number|Math|Error|break|continue|d
var VALID_BLOCK_NAME = /^[A-Za-z]+[A-Za-z_0-9]*$/;

// Returns TRUE if the passed string is a valid javascript number or string literal
function isLiteral( string ){
var literal = false;
// Check if it's a number literal
if( NUMBER_LITERAL.test( string ) ){
literal = true;
}

// Check if it's a valid string literal (throw exception otherwise)
else if( (string[0] === string[string.length-1]) && (string[0] === "'" || string[0] === '"') ) {
var teststr = string.substr( 1, string.length-2 ).split("").reverse().join("");
if( string[0] === "'" && UNESCAPED_QUOTE.test( teststr ) || string[1] === '"' && UNESCAPED_DQUOTE.test( teststr ) ){
throw new Error("Invalid string literal. Unescaped quote (" + string[0] + ") found.");
function isLiteral(string) {
var literal = false,
teststr;

// Check if it's a number literal
if (NUMBER_LITERAL.test(string)) {
literal = true;
} else if ((string[0] === string[string.length - 1]) && (string[0] === "'" || string[0] === '"')) {
// Check if it's a valid string literal (throw exception otherwise)
teststr = string.substr(1, string.length - 2).split("").reverse().join("");

if (string[0] === "'" && UNESCAPED_QUOTE.test(teststr) || string[1] === '"' && UNESCAPED_DQUOTE.test(teststr)) {
throw new Error("Invalid string literal. Unescaped quote (" + string[0] + ") found.");
}

literal = true;
}
literal = true;
}

return literal;
return literal;
}

// Returns TRUE if the passed string is a valid javascript string literal
function isStringLiteral( string ){
// Check if it's a valid string literal (throw exception otherwise)
if( (string[0] === string[string.length-1]) && (string[0] === "'" || string[0] === '"') ) {
var teststr = string.substr( 1, string.length-2 ).split("").reverse().join("");
if( string[0] === "'" && UNESCAPED_QUOTE.test( teststr ) || string[1] === '"' && UNESCAPED_DQUOTE.test( teststr ) ){
throw new Error("Invalid string literal. Unescaped quote (" + string[0] + ") found.");
function isStringLiteral(string) {
// Check if it's a valid string literal (throw exception otherwise)
if ((string[0] === string[string.length - 1]) && (string[0] === "'" || string[0] === '"')) {
var teststr = string.substr(1, string.length - 2).split("").reverse().join("");

if (string[0] === "'" && UNESCAPED_QUOTE.test(teststr) || string[1] === '"' && UNESCAPED_DQUOTE.test(teststr)) {
throw new Error("Invalid string literal. Unescaped quote (" + string[0] + ") found.");
}

return true;
}
return true;
}
return false;

return false;
}

// Variable names starting with __ are reserved.
function isValidName( string ){
return VALID_NAME.test(string) && !KEYWORDS.test(string) && string.substr(0,2) !== "__";
function isValidName(string) {
return VALID_NAME.test(string) && !KEYWORDS.test(string) && string.substr(0, 2) !== "__";
}

// Variable names starting with __ are reserved.
function isValidShortName( string ){
return VALID_SHORT_NAME.test(string) && !KEYWORDS.test(string) && string.substr(0,2) !== "__";
function isValidShortName(string) {
return VALID_SHORT_NAME.test(string) && !KEYWORDS.test(string) && string.substr(0, 2) !== "__";
}

// Checks if a name is a vlaid block name
function isValidBlockName( string ){
return VALID_BLOCK_NAME.test(string);
function isValidBlockName(string) {
return VALID_BLOCK_NAME.test(string);
}

/**
* Returns a valid javascript code that will
* check if a variable (or property chain) exists
* in the evaled context. For example:
* check( "foo.bar.baz" )
* will return the following string:
* "typeof foo !== 'undefined' && typeof foo.bar !== 'undefined' && typeof foo.bar.baz !== 'undefined'"
*/
exports.check = function( variable, context ){
/* 'this' inside of the render function is bound to the tag closure which is meaningless, so we can't use it.
* '__this' is bound to the original template whose render function we called.
* Using 'this' in the HTML templates will result in '__this.__currentContext'. This is an additional context
* for binding data to a specific template - e.g. binding widget data.
*/
variable = variable.replace(/^this/, '__this.__currentContext');

if( isLiteral( variable ) )
return "(true)";

var props = variable.split("."), chain = "", output = [];

if( typeof context === 'string' && context.length )
props.unshift( context );

props.forEach(function(prop){
chain += (chain ? (isNaN(prop) ? "." + prop : "[" + prop + "]") : prop);
output.push( "typeof " + chain + " !== 'undefined'" )
});
return "(" + output.join(" && ") + ")";
}
* Returns a valid javascript code that will
* check if a variable (or property chain) exists
* in the evaled context. For example:
* check("foo.bar.baz")
* will return the following string:
* "typeof foo !== 'undefined' && typeof foo.bar !== 'undefined' && typeof foo.bar.baz !== 'undefined'"
*/
exports.check = function (variable, context) {
/* 'this' inside of the render function is bound to the tag closure which is meaningless, so we can't use it.
* '__this' is bound to the original template whose render function we called.
* Using 'this' in the HTML templates will result in '__this.__currentContext'. This is an additional context
* for binding data to a specific template - e.g. binding widget data.
*/
variable = variable.replace(/^this/, '__this.__currentContext');

if (isLiteral(variable)) {
return "(true)";
}

var props = variable.split("."), chain = "", output = [];

if (typeof context === 'string' && context.length) {
props.unshift(context);
}

props.forEach(function (prop) {
chain += (chain ? (isNaN(prop) ? "." + prop : "[" + prop + "]") : prop);
output.push("typeof " + chain + " !== 'undefined'");
});
return "(" + output.join(" && ") + ")";
};

/**
* Returns an escaped string (safe for evaling). If context is passed
* then returns a concatenation of context and the escaped variable name.
*/
exports.escape = function( variable, context ){
/* 'this' inside of the render function is bound to the tag closure which is meaningless, so we can't use it.
* '__this' is bound to the original template whose render function we called.
* Using 'this' in the HTML templates will result in '__this.__currentContext'. This is an additional context
* for binding data to a specific template - e.g. binding widget data.
*/
variable = variable.replace(/^this/, '__this.__currentContext');
if( isLiteral( variable ) )
variable = "(" + variable + ")";

else if( typeof context === 'string' && context.length )
variable = context + '.' + variable;
var chain = "", props = variable.split(".");
props.forEach(function(prop){
chain += (chain ? (isNaN(prop) ? "." + prop : "[" + prop + "]") : prop);
});

return chain.replace(/\n/g, '\\n').replace(/\r/g, '\\r');
}
* Returns an escaped string (safe for evaling). If context is passed
* then returns a concatenation of context and the escaped variable name.
*/
exports.escape = function (variable, context) {
/* 'this' inside of the render function is bound to the tag closure which is meaningless, so we can't use it.
* '__this' is bound to the original template whose render function we called.
* Using 'this' in the HTML templates will result in '__this.__currentContext'. This is an additional context
* for binding data to a specific template - e.g. binding widget data.
*/
variable = variable.replace(/^this/, '__this.__currentContext');

if (isLiteral(variable)) {
variable = "(" + variable + ")";
} else if (typeof context === 'string' && context.length) {
variable = context + '.' + variable;
}

var chain = "", props = variable.split(".");
props.forEach(function (prop) {
chain += (chain ? (isNaN(prop) ? "." + prop : "[" + prop + "]") : prop);
});

return chain.replace(/\n/g, '\\n').replace(/\r/g, '\\r');
};

/**
* Merges b into a and returns a
*/
exports.merge = function(a, b){
if (a && b)
for (var key in b) {
a[key] = b[key];
* Merges b into a and returns a
*/
exports.merge = function (a, b) {
var key;

if (a && b) {
for (key in b) {
if (b.hasOwnProperty(key)) {
a[key] = b[key];
}
}
}
return a;

return a;
};

exports.isLiteral = isLiteral;
Expand Down
Loading

0 comments on commit 2071180

Please sign in to comment.