Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

vash

Package Overview
Dependencies
Maintainers
1
Versions
81
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vash - npm Package Compare versions

Comparing version 0.7.12-1 to 0.8.0-beta

build/.flowconfig

793

build/vash-runtime.js

@@ -1,474 +0,525 @@

/**
* Vash - JavaScript Template Parser, v0.7.12-1
*
* https://github.com/kirbysayshi/vash
*
* Copyright (c) 2013 Andrew Petersen
* MIT License (LICENSE)
*/
void(0); // hack for https://github.com/mishoo/UglifyJS/issues/465
/*jshint strict:false, asi: false, laxcomma:true, laxbreak:true, boss:true, curly:true, node:true, browser:true, devel:true */
;(function(){
!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.vash=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
vash = typeof vash === 'undefined' ? {} : vash;
exports.context = function(input, lineno, columnno, linebreak) {
linebreak = linebreak || '!LB!';
// only fully define if this is standalone
if(!vash.compile){
if(typeof define === 'function' && define['amd']){
define(function(){ return vash }); // AMD
} else if(typeof module === 'object' && module['exports']){
module['exports'] = vash; // NODEJS
} else {
window['vash'] = vash; // BROWSER
}
}
var lines = input.split(linebreak)
, contextSize = lineno === 0 && columnno === 0 ? lines.length - 1 : 3
, start = Math.max(0, lineno - contextSize)
, end = Math.min(lines.length, lineno + contextSize);
var helpers = vash['helpers'];
return lines
.slice(start, end)
.map(function(line, i, all){
var curr = i + start + 1;
var Helpers = function ( model ) {
this.buffer = new Buffer();
this.model = model;
this.options = null; // added at render time
return (curr === lineno ? ' > ' : ' ')
+ (curr < 10 ? ' ' : '')
+ curr
+ ' | '
+ line;
}).join('\n');
}
},{}],2:[function(_dereq_,module,exports){
module.exports={
"name": "vash",
"description": "Razor syntax for JS templating",
"version": "0.8.0-beta",
"author": "Andrew Petersen <senofpeter@gmail.com>",
"homepage": "https://github.com/kirbysayshi/vash",
"bin": {
"vash": "./bin/vash"
},
"keywords": [
"razor",
"parser",
"template",
"express"
],
"repository": {
"type": "git",
"url": "git://github.com/kirbysayshi/vash"
},
"main": "index.js",
"engines": {
"node": ">= 0.8"
},
"scripts": {
"coverage": "VASHPATH=../../index.js VASHRUNTIMEPATH=../../runtime.js browserify -t envify -t coverify test/vows/vash.test.js | node | coverify",
"build": "browserify index.js --standalone vash > build/vash.js && browserify --standalone vash runtime.js > build/vash-runtime.js && browserify --standalone vash --external fs --external path lib/helpers/index.js > build/vash-runtime-all.js",
"test": "VASHPATH=../../index.js VASHRUNTIMEPATH=../../runtime.js vows test/vows/vash.*.js --spec",
"docs": "scripts/docs.sh",
"docs-dev": "scripts/docs-dev.sh"
},
"dependencies": {
"commander": "~1.1.1",
"uglify-js": "1.0.6",
"debug": "^0.7.4"
},
"devDependencies": {
"browserify": "^3.33.0",
"coverify": "~1.0.6",
"envify": "^1.2.1",
"jshint": "0.8.0",
"marked": "~0.2.8",
"semver": "~1",
"uglify-js": "^2.4.13",
"vows": "^0.8.1"
}
}
this.vl = 0;
this.vc = 0;
};
},{}],3:[function(_dereq_,module,exports){
vash['helpers']
= helpers
= Helpers.prototype
= { constructor: Helpers, config: {}, tplcache: {} };
var error = _dereq_('./lib/error');
var runtime = {
version: _dereq_('./package.json').version
};
// this allows a template to return the context, and coercion
// will handle it
helpers.toString = helpers.toHtmlString = function(){
// not calling buffer.toString() results in 2x speedup
return this.buffer._vo.join('');//.toString();
}
var helpers = runtime['helpers'];
///////////////////////////////////////////////////////////////////////////
// HTML ESCAPING
module.exports = runtime;
var HTML_REGEX = /[&<>"'`]/g
,HTML_REPLACER = function(match) { return HTML_CHARS[match]; }
,HTML_CHARS = {
"&": "&amp;"
,"<": "&lt;"
,">": "&gt;"
,'"': "&quot;"
,"'": "&#x27;"
,"`": "&#x60;"
};
function Helpers( model ) {
this.buffer = new Buffer();
this.model = model;
this.options = null; // added at render time
helpers['raw'] = function( val ) {
var func = function() { return val; };
this.vl = 0;
this.vc = 0;
};
val = val != null ? val : "";
runtime['helpers']
= helpers
= Helpers.prototype
= { constructor: Helpers, config: {}, tplcache: {} };
return {
toHtmlString: func
,toString: func
};
};
// this allows a template to return the context, and coercion
// will handle it
helpers.toString = helpers.toHtmlString = function(){
// not calling buffer.toString() results in 2x speedup
return this.buffer._vo.join('');//.toString();
}
helpers['escape'] = function( val ) {
var func = function() { return val; };
///////////////////////////////////////////////////////////////////////////
// HTML ESCAPING
val = val != null ? val : "";
var HTML_REGEX = /[&<>"'`]/g
,HTML_REPLACER = function(match) { return HTML_CHARS[match]; }
,HTML_CHARS = {
"&": "&amp;"
,"<": "&lt;"
,">": "&gt;"
,'"': "&quot;"
,"'": "&#x27;"
,"`": "&#x60;"
};
if ( typeof val.toHtmlString !== "function" ) {
helpers['raw'] = function( val ) {
var func = function() { return val; };
val = val.toString().replace( HTML_REGEX, HTML_REPLACER );
val = val != null ? val : "";
return {
toHtmlString: func
,toString: func
};
}
return {
toHtmlString: func
,toString: func
};
};
return val;
};
helpers['escape'] = function( val ) {
var func = function() { return val; };
// HTML ESCAPING
///////////////////////////////////////////////////////////////////////////
val = val != null ? val : "";
if ( typeof val.toHtmlString !== "function" ) {
///////////////////////////////////////////////////////////////////////////
// BUFFER MANIPULATION
//
// These are to be used from within helpers, to allow for manipulation of
// output in a sane manner.
val = val.toString().replace( HTML_REGEX, HTML_REPLACER );
var Buffer = function() {
this._vo = [];
}
return {
toHtmlString: func
,toString: func
};
}
Buffer.prototype.mark = function( debugName ) {
var mark = new Mark( this, debugName );
mark.markedIndex = this._vo.length;
this._vo.push( mark.uid );
return mark;
};
return val;
};
Buffer.prototype.fromMark = function( mark ) {
var found = mark.findInBuffer();
// HTML ESCAPING
///////////////////////////////////////////////////////////////////////////
if( found > -1 ){
// automatically destroy the mark from the buffer
mark.destroy();
// `found` will still be valid for a manual splice
return this._vo.splice( found, this._vo.length );
}
return [];
};
///////////////////////////////////////////////////////////////////////////
// BUFFER MANIPULATION
//
// These are to be used from within helpers, to allow for manipulation of
// output in a sane manner.
Buffer.prototype.spliceMark = function( mark, numToRemove, add ){
var found = mark.findInBuffer();
var Buffer = function() {
this._vo = [];
}
if( found > -1 ){
mark.destroy();
arguments[0] = found;
return this._vo.splice.apply( this._vo, arguments );
}
Buffer.prototype.mark = function( debugName ) {
var mark = new Mark( this, debugName );
mark.markedIndex = this._vo.length;
this._vo.push( mark.uid );
return mark;
};
return [];
};
Buffer.prototype.fromMark = function( mark ) {
var found = mark.findInBuffer();
Buffer.prototype.empty = function() {
return this._vo.splice( 0, this._vo.length );
};
if( found > -1 ){
// automatically destroy the mark from the buffer
mark.destroy();
// `found` will still be valid for a manual splice
return this._vo.splice( found, this._vo.length );
}
Buffer.prototype.push = function( buffer ) {
return this._vo.push( buffer );
};
return [];
};
Buffer.prototype.pushConcat = function( buffer ){
var buffers;
if (Array.isArray(buffer)) {
buffers = buffer;
} else if ( arguments.length > 1 ) {
buffers = Array.prototype.slice.call( arguments );
} else {
buffers = [buffer];
}
Buffer.prototype.spliceMark = function( mark, numToRemove, add ){
var found = mark.findInBuffer();
for (var i = 0; i < buffers.length; i++) {
this._vo.push( buffers[i] );
}
if( found > -1 ){
mark.destroy();
arguments[0] = found;
return this._vo.splice.apply( this._vo, arguments );
}
return this.__vo;
}
return [];
};
Buffer.prototype.indexOf = function( str ){
Buffer.prototype.empty = function() {
return this._vo.splice( 0, this._vo.length );
};
for( var i = 0; i < this._vo.length; i++ ){
if(
( str.test && this._vo[i] && this._vo[i].search(str) > -1 )
|| this._vo[i] == str
){
return i;
}
}
Buffer.prototype.push = function( buffer ) {
return this._vo.push( buffer );
};
return -1;
}
Buffer.prototype.pushConcat = function( buffer ){
var buffers;
if (Array.isArray(buffer)) {
buffers = buffer;
} else if ( arguments.length > 1 ) {
buffers = Array.prototype.slice.call( arguments );
} else {
buffers = [buffer];
}
Buffer.prototype.lastIndexOf = function( str ){
var i = this._vo.length;
for (var i = 0; i < buffers.length; i++) {
this._vo.push( buffers[i] );
}
while( --i >= 0 ){
if(
( str.test && this._vo[i] && this._vo[i].search(str) > -1 )
|| this._vo[i] == str
){
return i;
}
}
return this.__vo;
}
return -1;
}
Buffer.prototype.indexOf = function( str ){
Buffer.prototype.splice = function(){
return this._vo.splice.apply( this._vo, arguments );
}
for( var i = 0; i < this._vo.length; i++ ){
if(
( str.test && this._vo[i] && this._vo[i].search(str) > -1 )
|| this._vo[i] == str
){
return i;
}
}
Buffer.prototype.index = function( idx ){
return this._vo[ idx ];
}
return -1;
}
Buffer.prototype.flush = function() {
return this.empty().join( "" );
};
Buffer.prototype.lastIndexOf = function( str ){
var i = this._vo.length;
Buffer.prototype.toString = Buffer.prototype.toHtmlString = function(){
// not using flush because then console.log( tpl() ) would artificially
// affect the output
return this._vo.join( "" );
}
while( --i >= 0 ){
if(
( str.test && this._vo[i] && this._vo[i].search(str) > -1 )
|| this._vo[i] == str
){
return i;
}
}
// BUFFER MANIPULATION
///////////////////////////////////////////////////////////////////////////
return -1;
}
///////////////////////////////////////////////////////////////////////////
// MARKS
// These can be used to manipulate the existing entries in the rendering
// context. For an example, see the highlight helper.
Buffer.prototype.splice = function(){
return this._vo.splice.apply( this._vo, arguments );
}
var Mark = vash['Mark'] = function( buffer, debugName ){
this.uid = '[VASHMARK-'
+ ~~( Math.random() * 10000000 )
+ (debugName ? ':' + debugName : '')
+ ']';
this.markedIndex = 0;
this.buffer = buffer;
this.destroyed = false;
}
Buffer.prototype.index = function( idx ){
return this._vo[ idx ];
}
var reMark = Mark.re = /\[VASHMARK\-\d{1,8}(?::[\s\S]+?)?]/g
Buffer.prototype.flush = function() {
return this.empty().join( "" );
};
// tests if a string has a mark-like uid within it
Mark.uidLike = function( str ){
return (str || '').search( reMark ) > -1;
}
Buffer.prototype.toString = Buffer.prototype.toHtmlString = function(){
// not using flush because then console.log( tpl() ) would artificially
// affect the output
return this._vo.join( "" );
}
Mark.prototype.destroy = function(){
// BUFFER MANIPULATION
///////////////////////////////////////////////////////////////////////////
var found = this.findInBuffer();
///////////////////////////////////////////////////////////////////////////
// MARKS
// These can be used to manipulate the existing entries in the rendering
// context. For an example, see the highlight helper.
if( found > -1 ){
this.buffer.splice( found, 1 );
this.markedIndex = -1;
}
var Mark = runtime['Mark'] = function( buffer, debugName ){
this.uid = '[VASHMARK-'
+ ~~( Math.random() * 10000000 )
+ (debugName ? ':' + debugName : '')
+ ']';
this.markedIndex = 0;
this.buffer = buffer;
this.destroyed = false;
}
this.destroyed = true;
}
var reMark = Mark.re = /\[VASHMARK\-\d{1,8}(?::[\s\S]+?)?]/g
Mark.prototype.findInBuffer = function(){
// tests if a string has a mark-like uid within it
Mark.uidLike = function( str ){
return (str || '').search( reMark ) > -1;
}
if( this.destroyed ){
return -1;
}
Mark.prototype.destroy = function(){
if( this.markedIndex && this.buffer.index( this.markedIndex ) === this.uid ){
return this.markedIndex;
}
var found = this.findInBuffer();
// The mark may be within a string due to string shenanigans. If this is
// true this is bad, because all the Mark manipulation commands assume
// that the Mark is the only content at that index in the buffer, which
// means that splice commands will result in lost content.
var escaped = this.uid.replace(/(\[|\])/g, '\\$1');
var re = new RegExp(escaped);
return this.markedIndex = this.buffer.indexOf( re );
}
if( found > -1 ){
this.buffer.splice( found, 1 );
this.markedIndex = -1;
}
// MARKS
///////////////////////////////////////////////////////////////////////////
this.destroyed = true;
}
///////////////////////////////////////////////////////////////////////////
// ERROR REPORTING
Mark.prototype.findInBuffer = function(){
// Liberally modified from https://github.com/visionmedia/jade/blob/master/jade.js
helpers.constructor.reportError = function(e, lineno, chr, orig, lb){
if( this.destroyed ){
return -1;
}
lb = lb || '!LB!';
if( this.markedIndex && this.buffer.index( this.markedIndex ) === this.uid ){
return this.markedIndex;
}
var lines = orig.split(lb)
,contextSize = lineno === 0 && chr === 0 ? lines.length - 1 : 3
,start = Math.max(0, lineno - contextSize)
,end = Math.min(lines.length, lineno + contextSize);
// The mark may be within a string due to block manipulation shenanigans.
var escaped = this.uid.replace(/(\[|\])/g, '\\$1');
var re = new RegExp(escaped);
return this.markedIndex = this.buffer.indexOf( re );
}
var contextStr = lines.slice(start, end).map(function(line, i, all){
var curr = i + start + 1;
// MARKS
///////////////////////////////////////////////////////////////////////////
return (curr === lineno ? ' > ' : ' ')
+ (curr < 10 ? ' ' : '')
+ curr
+ ' | '
+ line;
}).join('\n');
///////////////////////////////////////////////////////////////////////////
// ERROR REPORTING
e.vashlineno = lineno;
e.vashcharno = chr;
e.message = 'Problem while rendering template at line '
+ lineno + ', character ' + chr
+ '.\nOriginal message: ' + e.message + '.'
+ '\nContext: \n\n' + contextStr + '\n\n';
// Liberally modified from https://github.com/visionmedia/jade/blob/master/jade.js
helpers.constructor.reportError = function(e, lineno, chr, orig, lb, atRenderTime){
throw e;
};
lb = lb || '!LB!';
helpers['reportError'] = function() {
this.constructor.reportError.apply( this, arguments );
};
var contextStr = error.context(orig, lineno, chr, lb);
// ERROR REPORTING
///////////////////////////////////////////////////////////////////////////
e.vashlineno = lineno;
e.vashcharno = chr;
e.message = 'Problem while '
+ (atRenderTime ? 'rendering' : 'compiling')
+ ' template at line '
+ lineno + ', character ' + chr
+ '.\nOriginal message: ' + e.message + '.'
+ '\nContext: \n\n' + contextStr + '\n\n';
///////////////////////////////////////////////////////////////////////////
// VASH.LINK
// Take a compiled string or function and "link" it to the current vash
// runtime. This is necessary to allow instantiation of `Helpers` and
// proper decompilation via `toClientString`.
//
// If `options.asHelper` and `options.args` are defined, the `cmpFunc` is
// interpreted as a compiled helper, and is attached to `vash.helpers` at
// a property name equal to `options.asHelper`.
throw e;
};
vash['link'] = function( cmpFunc, options ){
helpers['reportError'] = function() {
this.constructor.reportError.apply( this, arguments );
};
// TODO: allow options.filename to be used as sourceUrl?
// ERROR REPORTING
///////////////////////////////////////////////////////////////////////////
var originalFunc
,cmpOpts;
///////////////////////////////////////////////////////////////////////////
// VASH.LINK
// Take a compiled string or function and "link" it to the current vash
// runtime. This is necessary to allow instantiation of `Helpers` and
// proper decompilation via `toClientString`.
//
// If `options.asHelper` and `options.args` are defined, the `cmpFunc` is
// interpreted as a compiled helper, and is attached to `runtime.helpers` at
// a property name equal to `options.asHelper`.
if( !options.args ){
// every template has these arguments
options.args = [options.modelName, options.helpersName, '__vopts', 'vash'];
}
runtime['link'] = function( cmpFunc, options ){
if( typeof cmpFunc === 'string' ){
originalFunc = cmpFunc;
// TODO: allow options.filename to be used as sourceUrl?
try {
// do not pollute the args array for later attachment to the compiled
// function for later decompilation/linking
cmpOpts = options.args.slice();
cmpOpts.push(cmpFunc);
cmpFunc = Function.apply(null, cmpOpts);
} catch(e) {
// TODO: add flag to reportError to know if it's at compile time or runtime
helpers.reportError(e, 0, 0, originalFunc, /\n/);
}
}
var originalFunc
,cmpOpts;
// need this to enable decompilation / relinking
cmpFunc.options = {
simple: options.simple
,modelName: options.modelName
,helpersName: options.helpersName
}
if( !options.args ){
// every template has these arguments
options.args = [options.modelName, options.helpersName, '__vopts', 'runtime'];
}
var linked;
if( typeof cmpFunc === 'string' ){
originalFunc = cmpFunc;
if( options.asHelper ){
try {
// do not pollute the args array for later attachment to the compiled
// function for later decompilation/linking
cmpOpts = options.args.slice();
cmpOpts.push(cmpFunc);
cmpFunc = Function.apply(null, cmpOpts);
} catch(e) {
// TODO: add flag to reportError to know if it's at compile time or runtime
helpers.reportError(e, 0, 0, originalFunc, /\n/, false);
}
}
cmpFunc.options.args = options.args;
cmpFunc.options.asHelper = options.asHelper;
// need this to enable decompilation / relinking
cmpFunc.options = {
simple: options.simple
,modelName: options.modelName
,helpersName: options.helpersName
}
linked = function(){
return cmpFunc.apply(this, slice.call(arguments));
}
var linked;
helpers[options.asHelper] = linked;
if( options.asHelper ){
} else {
cmpFunc.options.args = options.args;
cmpFunc.options.asHelper = options.asHelper;
linked = function( model, opts ){
if( options.simple ){
var ctx = {
buffer: []
,escape: Helpers.prototype.escape
,raw: Helpers.prototype.raw
}
return cmpFunc( model, ctx, opts, vash );
}
linked = function(){
return cmpFunc.apply(this, slice.call(arguments));
}
opts = divineRuntimeTplOptions( model, opts );
return cmpFunc( model, (opts && opts.context) || new Helpers( model ), opts, vash );
}
}
helpers[options.asHelper] = linked;
// show the template-specific code, instead of the generic linked function
linked['toString'] = function(){ return cmpFunc.toString(); }
} else {
// shortcut to show the actual linked function
linked['_toString'] = function(){ return Function.prototype.toString.call(linked) }
linked = function( model, opts ){
if( options.simple ){
var ctx = {
buffer: []
,escape: Helpers.prototype.escape
,raw: Helpers.prototype.raw
}
return cmpFunc( model, ctx, opts, runtime );
}
linked['toClientString'] = function(){
return 'vash.link( '
+ cmpFunc.toString() + ', '
+ JSON.stringify( cmpFunc.options ) + ' )';
}
opts = divineRuntimeTplOptions( model, opts );
return cmpFunc( model, (opts && opts.context) || new Helpers( model ), opts, runtime );
}
}
return linked;
}
// show the template-specific code, instead of the generic linked function
linked['toString'] = function(){ return cmpFunc.toString(); }
// given a model and options, allow for various tpl signatures and options:
// ( model, {} )
// ( model, function onRenderEnd(){} )
// ( model )
// and model.onRenderEnd
function divineRuntimeTplOptions( model, opts ){
// shortcut to show the actual linked function
linked['_toString'] = function(){ return Function.prototype.toString.call(linked) }
// allow for signature: model, callback
if( typeof opts === 'function' ) {
opts = { onRenderEnd: opts };
}
// This assumes a vash global, and should be deprecated.
// TODO: @deprecate
linked['toClientString'] = function(){
return 'vash.link( '
+ cmpFunc.toString() + ', '
+ JSON.stringify( cmpFunc.options ) + ' )';
}
// allow for passing in onRenderEnd via model
if( model && model.onRenderEnd ){
opts = opts || {};
return linked;
}
if( !opts.onRenderEnd ){
opts.onRenderEnd = model.onRenderEnd;
}
// given a model and options, allow for various tpl signatures and options:
// ( model, {} )
// ( model, function onRenderEnd(){} )
// ( model )
// and model.onRenderEnd
function divineRuntimeTplOptions( model, opts ){
delete model.onRenderEnd;
}
// allow for signature: model, callback
if( typeof opts === 'function' ) {
opts = { onRenderEnd: opts };
}
// ensure options can be referenced
if( !opts ){
opts = {};
}
// allow for passing in onRenderEnd via model
if( model && model.onRenderEnd ){
opts = opts || {};
return opts;
}
if( !opts.onRenderEnd ){
opts.onRenderEnd = model.onRenderEnd;
}
// shortcut for compiled helpers
var slice = Array.prototype.slice;
delete model.onRenderEnd;
}
// VASH.LINK
///////////////////////////////////////////////////////////////////////////
// ensure options can be referenced
if( !opts ){
opts = {};
}
///////////////////////////////////////////////////////////////////////////
// TPL CACHE
return opts;
}
vash['lookup'] = function( path, model ){
var tpl = vash.helpers.tplcache[path];
if( !tpl ){ throw new Error('Could not find template: ' + path); }
if( model ){ return tpl(model); }
else return tpl;
};
// shortcut for compiled helpers
var slice = Array.prototype.slice;
vash['install'] = function( path, tpl ){
var cache = vash.helpers.tplcache;
if( typeof tpl === 'string' ){
if( !vash.compile ){ throw new Error('vash.install(path, [string]) is not available in the standalone runtime.') }
tpl = vash.compile(tpl);
} else if( typeof path === 'object' ){
tpl = path;
Object.keys(tpl).forEach(function(path){
cache[path] = tpl[path];
});
return cache;
}
return cache[path] = tpl;
};
// VASH.LINK
///////////////////////////////////////////////////////////////////////////
vash['uninstall'] = function( path ){
var cache = vash.helpers.tplcache
,deleted = false;
///////////////////////////////////////////////////////////////////////////
// TPL CACHE
if( typeof path === 'string' ){
return delete cache[path];
} else {
Object.keys(cache).forEach(function(key){
if( cache[key] === path ){ deleted = delete cache[key]; }
})
return deleted;
}
};
runtime['lookup'] = function( path, model ){
var tpl = runtime.helpers.tplcache[path];
if( !tpl ){ throw new Error('Could not find template: ' + path); }
if( model ){ return tpl(model); }
else return tpl;
};
}());
runtime['install'] = function( path, tpl ){
var cache = runtime.helpers.tplcache;
if( typeof tpl === 'string' ){
// Super hacky: if the calling context has a `compile` function,
// then `this` is likely full vash. This is simply for backwards
// compatibility.
// TODO: @deprecate
if ( typeof this.compile === 'function') {
tpl = this.compile(tpl);
} else {
throw new Error('.install(path, [string]) is not available in the standalone runtime.');
}
} else if( typeof path === 'object' ){
tpl = path;
Object.keys(tpl).forEach(function(path){
cache[path] = tpl[path];
});
return cache;
}
return cache[path] = tpl;
};
runtime['uninstall'] = function( path ){
var cache = runtime.helpers.tplcache
,deleted = false;
if( typeof path === 'string' ){
return delete cache[path];
} else {
Object.keys(cache).forEach(function(key){
if( cache[key] === path ){ deleted = delete cache[key]; }
})
return deleted;
}
};
},{"./lib/error":1,"./package.json":2}]},{},[3])
(3)
});

@@ -7,21 +7,13 @@ How to Contribute

* Before rewriting major portions of code, open an Issue to discuss it. Someone might be working on what you want already!
* Maintain code style whenever possible: make your code look like the code around it. General syntax rules:
* Comma-first
* Keep line length within reason (< 80 chars)
* Use tabs, not spaces (for now...)
* Maintain code style whenever possible: make your code look like the code around it.
Building Vash
-------------
Building Vash for distribution
------------------------------
Simple as:
$ support/task build
$ npm run build
And tests (includes `build` task):
$ support/task test
If you need to test the minified version of `vash.js`:
$ support/task test --min
$ npm test
{
"name": "vash",
"description": "Razor syntax for JS templating",
"version": "0.7.12-1",
"version": "0.8.0-beta",
"author": "Andrew Petersen <senofpeter@gmail.com>",

@@ -20,3 +20,3 @@ "homepage": "https://github.com/kirbysayshi/vash",

},
"main": "build/vash",
"main": "index.js",
"engines": {

@@ -26,16 +26,23 @@ "node": ">= 0.8"

"scripts": {
"build": "make build",
"test": "make test && make test-min",
"docs": "make docs"
"coverage": "VASHPATH=../../index.js VASHRUNTIMEPATH=../../runtime.js browserify -t envify -t coverify test/vows/vash.test.js | node | coverify",
"build": "browserify index.js --standalone vash > build/vash.js && browserify --standalone vash runtime.js > build/vash-runtime.js && browserify --standalone vash --external fs --external path lib/helpers/index.js > build/vash-runtime-all.js",
"test": "VASHPATH=../../index.js VASHRUNTIMEPATH=../../runtime.js vows test/vows/vash.*.js --spec",
"docs": "scripts/docs.sh",
"docs-dev": "scripts/docs-dev.sh"
},
"dependencies": {
"commander": "~1.1.1",
"uglify-js": "1.0.6"
"uglify-js": "1.0.6",
"debug": "^0.7.4"
},
"devDependencies": {
"vows": "~0.7.0",
"browserify": "^3.33.0",
"coverify": "~1.0.6",
"envify": "^1.2.1",
"jshint": "0.8.0",
"marked": "~0.2.8",
"semver": "~1",
"jshint": "0.8.0",
"marked": "~0.2.8"
"uglify-js": "^2.4.13",
"vows": "^0.8.1"
}
}
}

@@ -30,2 +30,3 @@ <!-- This document was generated from README.vash -->

- [Browser - Vanilla](#browser---vanilla)
- [Browser - Browserify et al](#browser---browserify-et-al)
- [Browser - RequireJS](#browser---requirejs)

@@ -146,12 +147,12 @@ - [Playground](#playground)

<a name="browser---browserify-et-al"></a>Browser - Browserify et al
----------------------------------
Just `require` Vash, and compile. If you want something fancier, try [vashify](https://www.npmjs.com/package/vashify)!
<a name="browser---requirejs"></a>Browser - RequireJS
---------------------------
Be sure to configure paths appropriately, but vash is AMD ready.
RequireJS support has been recently dropped. However Vash does support CJS environments, so as long as you configure RequireJS to consume Vash as a CJS project (including `node_modules` resolution), everything should work.
require(['vash'], function(vash){
var tpl = vash.compile( '<p>I am a @model.t!</p>' );
document.querySelector('#content').innerHTML = tpl({ t: 'template' });
})
<a name="playground"></a>Playground

@@ -982,2 +983,4 @@ ==================

Note: this assumes that `vash` is available globally. A future version of Vash will hopefully remove this assumption.
<a name="vash-runtime-browser"></a>Vash Runtime (Browser)

@@ -993,2 +996,10 @@ ====================

If you're in a Browserify-like environemnt, you should be able to:
```js
var vashruntime = require('vash/runtime');
```
..and have access to the [Runtime API][].
[vash-runtime.min.js]: https://github.com/kirbysayshi/vash/blob/master/build/vash-runtime.min.js

@@ -1119,3 +1130,3 @@ [vash-runtime-all.min.js]: https://github.com/kirbysayshi/vash/blob/master/build/vash-runtime-all.min.js

-a, --no-autolink Wrap each template in `vash.link`.
-r, --render [json] Render the template using <json> as the model
-r, --render [json] Render the template using <json> as the model. If <json> is not valid json, assume a filename and load those contents as json.
-s, --separator [separator] Templates are auto-named by concatenating the file path with [separator]

@@ -1224,2 +1235,3 @@ --helper Assume the input is a to-be-compiled helper

[Browser - Vanilla]: #browser---vanilla
[Browser - Browserify et al]: #browser---browserify-et-al
[Browser - RequireJS]: #browser---requirejs

@@ -1289,6 +1301,10 @@ [Playground]: #playground

<a rev="footnote" href="#fnref:razor-ms">&#8617;</a>
</li><li id="fn:this-doc">
</li>
<li id="fn:this-doc">
This document starts off as a [Vash template][] that is then compiled and rendered via [vash(1)][] into markdown! It uses several custom helpers that are not shipped with Vash, but are of course available [for perusal][]. They include things like these footnotes and an autogenerated and linked table of contents.
<a rev="footnote" href="#fnref:this-doc">&#8617;</a>
</li>
</ol>

@@ -1295,0 +1311,0 @@

@@ -10,3 +10,3 @@ var vows = require('vows')

vash.config.useWith = false;
vash.config.debug = false;
vash.config.debug = true;

@@ -29,2 +29,13 @@ var tryCompile = function(str){

// SUPER HACK:
var aeToStringVows = assert.AssertionError.prototype.toString;
assert.AssertionError.prototype.toString = function wrapper() {
// ...Put the default back to get around vows#278 caused by recursively
// calling itself.
assert.AssertionError.prototype.toString = Error.prototype.toString;
var out = aeToStringVows.call(this);
assert.AssertionError.prototype.toString = wrapper;
return out;
}
vows.describe('vash templating library').addBatch({

@@ -351,2 +362,60 @@

}
,'explicit expressions containing quoted characters': {
topic: function() {
// For now just include ASCII.
var UNICODE_MAX = 127; // 1114111;
// 0-31 are control characters.
for(var i = 32, chars = []; i <= UNICODE_MAX; i++) {
chars.push(String.fromCharCode(i));
}
return chars;
}
,'do not need to be escaped': function(chars){
var str = chars.map(wrapCharWithExpression).join('');
var tpl = vash.compile(str, { htmlEscape: false });
var expected = chars.map(wrapCharWithP);
assert.equal( tpl(), expected.join('') );
function wrapCharWithExpression(chr) {
return '<p>@("' + escapeIfNeeded(chr) + '")</p>\n';
}
function wrapCharWithP(chr) {
return '<p>' + chr + '</p>\n';
}
function escapeIfNeeded(chr) {
if (chr === '"' || chr === '\n' || chr === '\\') return '\\' + chr;
else return chr;
}
}
}
,'a parent expression': {
topic: '@(function() { <p>)</p> }())'
,'should not consume content PAREN_CLOSE': function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '<p>)</p>' );
}
}
,'a parent block': {
topic: '@{ function what() { <p>}</p> } }'
,'should not consume content BRACE_CLOSE': function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '' );
}
}
,'anonymous blocks': {

@@ -445,10 +514,11 @@

}
//,'array literal': {
// topic: function(){
// return vash.compile('<a>@["a", "b", "c"]</a>');
// }
// ,'toStrings': function(topic){
// assert.equal( topic(), '<a>a,b,c</a>' );
// }
//}
,'array literal within markup': {
topic: '<a>@["a", "b", "c"].join("")</a>'
,'outputs': function(topic){
var tpl = vash.compile(topic);
assert.equal( tpl(), '<a>abc</a>' );
}
}
,'function invocation within expression buffers': {

@@ -603,47 +673,2 @@ topic: function(){

}
,'markup within a code block followed by else with an expression': {
topic: function(){
var str = '@if(false){ \n'
+ '<span>this is text \n'
+ 'that spans multiple lines</span> \n'
+ ' } else { \n'
+ ' @name.how \n'
+ ' } ';
return str;
}
,'disregards newline re-entry into BLK mode': function(topic){
vash.config.useWith = true;
var tpl = tryCompile(topic);
vash.config.useWith = false;
assert.equal(tpl( { name: {how: 'you' } } ), 'you');
}
}
,'markup within a complex if code block followed by else with an expression': {
topic: function(){
var str = '@if( heyo.ya !== true ){ \n'
+ '<input name="item-quantity-@item.id" type="text" value="@item.quantity" maxlength="5" size="6" />'
+ ' } else { \n'
+ ' @name.how \n'
+ ' } ';
return str;
}
,'disregards newline re-entry into BLK mode': function(topic){
var tpl = tryCompile(topic);
assert.equal(tpl( { heyo: { ya: true }, name: {how: 'you' }, item: { id: 0, quantity: 23 } } ), 'you');
}
}
,'markup within a complex if code block followed by else with an expression, all within markup': {
topic: function(){
var str = '<td>@if( false ){ } else { @name.how }</td>';
return str;
}
,'"else" is a keyword': function(topic){
var tpl = tryCompile(topic);
assert.equal(tpl( {
name: {
how: 'you'
}
} ), '<td>you</td>');
}
}
,'markup within a code block with an expression in the tag name': {

@@ -660,3 +685,3 @@ topic: function(){

var tpl = tryCompile(topic);
assert.equal(tpl({ name: 'what' }), '<span-what>this is text \nthat spans multiple lines</span-what> \n');
assert.equal(tpl({ name: 'what' }), '<span-what>this is text \nthat spans multiple lines</span-what>');
}

@@ -676,3 +701,3 @@ }

var tpl = tryCompile(topic);
assert.equal(tpl({ name: 'what' }), '<span-what>this is text \nthat spans multiple lines</span-what> \n<span class="what">this is text \nthat spans multiple lines</span> \n');
assert.equal(tpl({ name: 'what' }), '<span-what>this is text \nthat spans multiple lines</span-what><span class="what">this is text \nthat spans multiple lines</span>');
}

@@ -747,4 +772,5 @@ }

,'exits MKP with expression': function(topic){
var tpl = vash.compile(topic.replace('/>', '@(true)/>'))
,expected = '<br true/>';
var str = topic.replace('/>', '@(true)/>')
var tpl = vash.compile(str)
,expected = '<br true />';

@@ -791,3 +817,3 @@ assert.equal(tpl(), expected);

var tpl = vash.compile(topic)
,expected = '<button data-bind="enable:0>0"/>';
,expected = '<button data-bind="enable:0>0" />';

@@ -804,3 +830,3 @@ assert.equal(tpl([]), expected);

var tpl = vash.compile(topic)
, expected = '<b ></b><img />'
, expected = '<b></b><img />'

@@ -840,3 +866,3 @@ assert.equal(tpl(), expected);

,'is allowed': function(topic){
assert.equal( vash.compile(topic, { useWith: true })({name: 'what'}), '<what>This is content</what> ' );
assert.equal( vash.compile(topic, { useWith: true })({name: 'what'}), '<what>This is content</what>' );
}

@@ -917,6 +943,6 @@ }

'simple expression': {
topic: '<span>@a.replace(/a/gi, "o")</span>'
topic: '<span>@a.replace(/\\)a"\'/gi, "o")</span>'
,'replaces': function( topic ){
var tpl = vash.compile( topic, { useWith: true } );
assert.equal( tpl({ a: 'a' }), '<span>o</span>');
assert.equal( tpl({ a: ')a"\'' }), '<span>o</span>');
}

@@ -926,6 +952,6 @@ }

,'period meta character': {
topic: '<span>@a.replace(/./gi, "o")</span>'
topic: '<span>@a.replace(/\\)."\'/gi, "o")</span>'
,'replaces': function( topic ){
var tpl = vash.compile( topic, { useWith: true } );
assert.equal( tpl({ a: 'a' }), '<span>o</span>')
assert.equal( tpl({ a: ')a"\'' }), '<span>o</span>')
}

@@ -935,3 +961,3 @@ }

,'within BLK': {
topic: '@{ var re = /[@\'"]/gi; }<span>@a.replace(re, "o")</span>'
topic: '@{ var re = /[@}\'"]/gi; }<span>@a.replace(re, "o")</span>'
,'replaces': function( topic ){

@@ -942,2 +968,57 @@ var tpl = vash.compile( topic, { useWith: true } );

}
,'within an expression': {
topic: '@(/a/.exec(\'abc\')[0])'
,outputs: function( topic ){
var tpl = vash.compile(topic);
assert.equal( tpl(), 'a' );
}
}
,'literal': {
'within markup': {
topic: '<span>@/a/.test(\'abc\')</span>'
,outputs: function ( topic ) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '<span>true</span>' );
}
}
,'within markup attribute': {
topic: '<span b="@/a/.exec(\'abc\')[0]"></span>'
,outputs: function ( topic ) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '<span b="a"></span>' );
}
}
}
,'following conditional': {
topic: '@if (true) /a/.test(\'abc\')'
,outputs: function ( topic ) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '' );
}
}
,'are not mistaken for': {
'division expression': {
topic: '@{ var test = 100/2; }<span>@test</span>'
,'is not mistaken for regex': function (topic) {
var tpl = vash.compile(topic);
assert.equal( tpl({}), '<span>50</span>' );
}
}
,'division within condition': {
topic: '@{ if(100/2) <span></span> }'
,'is not mistaken for regex': function (topic) {
var tpl = vash.compile(topic);
assert.equal( tpl({}), '<span></span>' );
}
}
}
}

@@ -965,4 +1046,74 @@

}
,'within ProgramNode (root) in front of keywords': {
topic: ''
+ '@@if(model.type){\n'
+ ' <p>I\'m a @@model.type!</p>\n'
+ '} else if(model.name){\n'
+ ' <p>My name is @@model.name.</p>\n'
+ '} else {\n'
+ ' <p>I DON\'T KNOW WHO OR WHAT I AM...</p>\n'
+ '}\n'
,'outputs': function(topic) {
var tpl = vash.compile( topic );
assert.equal( tpl(), ''
+ '@if(model.type){\n'
+ ' <p>I\'m a @model.type!</p>\n'
+ '} else if(model.name){\n'
+ ' <p>My name is @model.name.</p>\n'
+ '} else {\n'
+ ' <p>I DON\'T KNOW WHO OR WHAT I AM...</p>\n'
+ '}\n');
}
}
,'within markup attribute': {
topic: '<figure id="fig-@@(figcount++)"></figure>'
,outputs: function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '<figure id="fig-@(figcount++)"></figure>' );
}
}
,'within markup node': {
topic: '<f@@e></f@@e>'
,outputs: function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '<f@e></f@e>' );
}
}
,'<ul class="@@(model.active ? \'highlight\' : \'\')"></ul>': {
topic: '<ul class="@@(model.active ? \'highlight\' : \'\')"></ul>'
,outputs: function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '<ul class="@(model.active ? \'highlight\' : \'\')"></ul>' );
}
}
,'@@@@' : {
topic: '`@@@@`'
,outputs: function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '`@@`' );
}
}
,'@@{ }': {
topic: '@@{ }'
,outputs: function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '@{ }' );
}
}
}
,'PHP-like tags are not confused for attributes': {
topic: '<? $what = \'what\' ?>'
,outputs: function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '<? $what = \'what\' ?>' );
}
}
,'"server-side" comments': {

@@ -1019,2 +1170,9 @@

}
,'can be escaped': {
topic: 'with `@@*` and `*@@`'
,'successfully': function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), 'with `@*` and `*@`' );
}
}
}

@@ -1114,9 +1272,17 @@ ,'mixing expressions and text': {

}
,'content following parens preserves whitespace': {
topic: '<(bin/vash <docs/helpers/* --helper) > README2.md'
,outputs: function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '<(bin/vash <docs/helpers/* --helper) > README2.md' );
}
}
,'content } in closed markup': {
topic: function(){
var str = '@if(true) { <li> @} </li> }';
var str = '@if(true) { <li> } </li> }';
return str;
}
,'does not need to be escaped': function(topic){
//assert.doesNotThrow( function(){ vash.compile(topic) }, Error);
assert.doesNotThrow( function(){ vash.compile(topic) }, Error );

@@ -1126,12 +1292,2 @@ assert.equal( vash.compile(topic)(), '<li> } </li>');

}
,'content } in open markup': {
topic: function(){
var str = '@if(true) { <img src="" /> @} }';
return str;
}
,'can be escaped with @': function(topic){
assert.doesNotThrow( function(){ vash.compile(topic) }, Error );
assert.equal( vash.compile(topic)(), '<img src="" />} ');
}
}
,'content } in expression': {

@@ -1168,3 +1324,3 @@ topic: function(){

,'HTML5:': {
'unclosed tags': {
/*'unclosed tags': {
topic: function(){

@@ -1178,3 +1334,3 @@ var str = '<div class="how what">This is content @for(var i = 0; i < 1; i++){ <p>@i }';

}
,'unclosed tag followed by previous closing tag does not bork': {
,*/'unclosed tag followed by previous closing tag does not bork': {
topic: function(){

@@ -1190,3 +1346,3 @@ var str = '<div class="how what">This is content @for(var i = 0; i < 1; i++){ <p>@i </div> }';

topic: function(){
var str = '<div class="how what">This is content @for(var i = 0; i < 1; i++){ <br>@i </div> }'
var str = '<div class="how what">This is content @for(var i = 0; i < 1; i++){ <text><br>@i</text> } </div>'
return str;

@@ -1198,3 +1354,10 @@ }

}
,'closing tag within block': {
,'explicitly unclosed tags': {
topic: '<a><b><c>'
,'do not become closed': function(topic) {
var tpl = vash.compile(topic);
assert.equal(tpl(), topic);
}
}
/*,'closing tag within block': {
topic: function(){

@@ -1208,3 +1371,3 @@ var str = '<div>This is content @if(true){ </div> } else { </div> }';

}
}
}*/

@@ -1227,6 +1390,6 @@ ,'operators': {

,'does not prevent HTML matching': function(topic) {
var tpl = vash.compile(topic)
var tpl = vash.compile(topic, {useWith: false})
, actual = tpl('1');
assert.equal( '<span>1<span\n></span></span>', actual )
assert.equal( '<span>1<span></span></span>', actual )
}

@@ -1236,10 +1399,32 @@ }

}
,'unbalanced characters are ok': {
// https://github.com/kirbysayshi/vash/issues/26
'open paren': {
topic: '@("(")'
,'outputs': function( topic ) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '(' );
}
}
,'open paren within markup within block': {
topic: '@(function(model) { <p>(</p> }())'
,'outputs': function( topic ) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '<p>(</p>' );
}
}
}
,'simple expression followed by @()': {
topic: function(){
return '<li data-score="@model.Score" class="user-panel-track @(model.i % 2 === 0 ? \'even\' : \'odd\')">';
return '<li data-score="@model.Score" class="user-panel-track @(model.i % 2 === 0 ? \'even\' : \'odd\')"></li>';
}
,'renders': function(topic){
assert.equal( vash.compile(topic)({ Score: '1', i: 0 })
, '<li data-score="1" class="user-panel-track even">');
, '<li data-score="1" class="user-panel-track even"></li>');
}

@@ -1372,3 +1557,3 @@ }

topic: function(){
return vash.compile( '@function f(i){ <b>@i</b> function d(i){ <b>@i</b> } @d(model.it) }<span>@f(model.it)</span>@f(model.it)' );
return vash.compile( '@function f(i){ <b>@i</b> function d(i){ <b>@i</b> } d(model.it) }<span>@f(model.it)</span>@f(model.it)' );
}

@@ -1526,3 +1711,3 @@ ,'are escaped': function(topic){

topic: function(){
return '<style type="text/css">#parallax_field #parallax_bg { position: absolute; top: -20px; left: -20px; width: 110%; height: 425px; z-index: 1; }'
return '<style type="text/css">#parallax_field #parallax_bg { position: absolute; top: -20px; left: -20px; width: 110%; height: 425px; z-index: 1; }</style>'
}

@@ -1602,9 +1787,20 @@ ,"is unchanged": function(topic){

topic: '@switch(model){ case 1: <p></p>break; case 2: <b></b>break; }'
'without braced cases': {
topic: '@switch(model){ case 1: <p></p>break; case 2: <b></b>break; }'
,'work': function( topic ){
var tpl = vash.compile( topic );
assert.equal( tpl(1), '<p></p>' );
assert.equal( tpl(2), '<b></b>' );
,'work': function( topic ){
var tpl = vash.compile( topic );
assert.equal( tpl(1), '<p></p>' );
assert.equal( tpl(2), '<b></b>' );
}
}
,'with braced cases': {
topic: '@switch(model){ case 1: { <p></p>break; } case 2: { <b></b>break; } }'
,work: function( topic ) {
var tpl = vash.compile( topic );
assert.equal( tpl(1), '<p></p>' );
assert.equal( tpl(2), '<b></b>' );
}
}
}

@@ -1624,2 +1820,10 @@

}
,'within content regex': {
topic: '/^([a-zA-Z0-9.%]+@@[a-zA-Z0-9.\\-]+\\.(?:ca|co\\.uk|com|edu|net|org))\\b/'
,outputs: function(topic) {
var tpl = vash.compile(topic);
assert.equal( tpl(), '/^([a-zA-Z0-9.%]+@[a-zA-Z0-9.\\-]+\\.(?:ca|co\\.uk|com|edu|net|org))\\b/' );
}
}
}

@@ -1941,21 +2145,26 @@

topic: '@if(true){ <a><br /></a> }'
topic: '@if(true){<a><br /></a>}'
,'does not close parent tag': function(topic){
var p = this.parse(this.lex(topic));
var flattened = p.ast.flatten()
// this is like "indexOf" for a complex object
,openIdx = flattened.reduce(function(prev, curr, i){
return prev !== undefined
? prev
: curr.type === 'HTML_TAG_OPEN' && curr.val === '<a>'
? i
: undefined;
}, undefined);
var Lexer = require('../../lib/lexer');
var Parser = require('../../lib/parser');
var l = new Lexer();
assert.equal( flattened[openIdx].type, 'HTML_TAG_OPEN' );
assert.equal( flattened[openIdx+2].type, 'HTML_TAG_OPEN' );
assert.equal( flattened[openIdx+3].type, 'HTML_TAG_VOID_CLOSE' );
assert.equal( flattened[openIdx+5].type, 'HTML_TAG_CLOSE' );
l.write(topic);
var tokens = l.read();
var p = new Parser();
p.write(tokens);
var more = true;
while(more !== null) more = p.read();
var root = p.stack[0];
assert.equal( root.body[0].type, 'VashMarkup' );
assert.equal( root.body[0].values[0].type, 'VashMarkupContent' );
assert.equal( root.body[0].values[0].values[1].type, 'VashBlock' );
assert.equal( root.body[0].values[0].values[1].values[0].type, 'VashMarkup' );
assert.equal( root.body[0].values[0].values[1].values[0].values[0].type, 'VashMarkupContent' );
assert.equal( root.body[0].values[0].values[1].values[0].values[0].values[0].type, 'VashText' );
assert.equal( root.body[0].values[0].values[1].values[0].values[0].values[1].isVoid, true );
}

@@ -1962,0 +2171,0 @@ }

@@ -10,2 +10,5 @@ var vows = require('vows')

var copyrtl = require(path.join(path.dirname(process.env.VASHPATH), 'lib', 'util', 'copyrtl'));
require(path.join(path.dirname(process.env.VASHRUNTIMEPATH), 'lib', 'helpers', 'layout'));
vash.config.useWith = false;

@@ -21,3 +24,3 @@ vash.config.debug = false;

this.opts = function(model){
return vash.vQuery.extend( model || {}, {
return copyrtl( model || {}, {
// mock up express settings

@@ -190,4 +193,7 @@ settings: {

,actual = maker( footer + block )( this.opts() )
,actual = maker( footer + block )( this.opts() );
//console.log('UNCOMPILED', footer + block + 'END');
//console.log('FN', maker( footer + block ))
//console.log('actual', 'START', actual, 'END');
assert.equal( actual, '<footer></footer><footer2></footer2>' )

@@ -347,3 +353,2 @@ }

var actual = tpl( this.opts({ cache: true }) )
assert.equal( actual, '<p></p>' );

@@ -406,2 +411,16 @@

,'empty include throws': function() {
var str = '@html.include("empty.include.vash")';
var opts = this.opts();
var tpl = vash.compile(str);
assert.throws(function() { tpl(opts) }, /Empty or non\-string/g);
}
,'empty layout throws': function() {
var str = '@html.extend("empty.layout.vash")';
var opts = this.opts();
var tpl = vash.compile(str);
assert.throws(function() { tpl(opts) }, /Empty or non\-string/g);
}
}

@@ -408,0 +427,0 @@

@@ -13,6 +13,21 @@ var vows = require('vows')

require(path.join(path.dirname(process.env.VASHRUNTIMEPATH), 'lib', 'helpers'));
vows.describe('vash templating library runtime').addBatch({
'default runtime helpers': {
// TODO:
/*'requiring': {
'does not expose global': function() {
var ctx = {};
vm.runInNewContext( 'var vash = require("vash/runtime")', ctx );
assert.equal(ctx.vash, undefined);
}
,'does not have full vash': function() {
assert.equal(vruntime.compile, undefined);
}
}
,*/'default runtime helpers': {
'highlight': {

@@ -81,5 +96,15 @@ topic: "@html.highlight('javascript', function(){<text>I am code</text>})"

,'installing with string auto-compiles': function(){
// Trick the runtime into thinking it's the full thing.
vruntime.compile = vash.compile;
vruntime.compileBatch = vash.compileBatch;
vruntime.compileHelper = vash.compileHelper;
var str = '<p></p>'
,tpl = vash.install('testpath', str);
delete vruntime.compile;
delete vruntime.compileBatch;
delete vruntime.compileHelper;
assert.equal( tpl(), str );

@@ -169,2 +194,9 @@ }

topic: function(){
// Trick the runtime into thinking it's the full thing.
vruntime.compile = vash.compile;
vruntime.compileBatch = vash.compileBatch;
vruntime.compileHelper = vash.compileHelper;
vruntime.config = vash.config;
return {

@@ -174,2 +206,6 @@

var tpl = vash.compile(str, { debug: true });
model = model || {};
model.settings = model.settings || {};
model.settings.views = __dirname + '/../fixtures/views/';
model.settings['view engine'] = 'vash';
try {

@@ -204,3 +240,3 @@ tpl(model);

// when debugging, dumping this is useful to clearly see the mismatch
//console.log(e.message);
// console.log(e.message);

@@ -207,0 +243,0 @@ assert.equal( e.vashlineno, actualLine, 'expected error line ' + actualLine + ', got ' + e.vashlineno );

Ensure vash#46, vash#27?, vash#26, and vash#22 are handled in tests
Add license comment headers to builds (ignore version number inclusion)
Update changelog
Add documentation for 0.7 -> 0.8 migration
Plan future deprecations, like helper system, layout `fs` usage?
Reformat helpers code style (esp layout)
Reformat runtime code style
Add debug statements to layout helpers
Most Important Things:

@@ -3,0 +15,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc