Comparing version 0.8.2 to 1.0.0
{ | ||
"name": "Mustache.js", | ||
"name": "mustache.js", | ||
"main": "mustache.js", | ||
"version": "0.8.2", | ||
"version": "1.0.0", | ||
"homepage": "https://github.com/janl/mustache.js", | ||
@@ -6,0 +6,0 @@ "authors": [ |
202
mustache.js
@@ -8,28 +8,12 @@ /*! | ||
(function (root, factory) { | ||
(function (global, factory) { | ||
if (typeof exports === "object" && exports) { | ||
factory(exports); // CommonJS | ||
} else if (typeof define === "function" && define.amd) { | ||
define(['exports'], factory); // AMD | ||
} else { | ||
var mustache = {}; | ||
factory(mustache); | ||
if (typeof define === "function" && define.amd) { | ||
define(mustache); // AMD | ||
} else { | ||
root.Mustache = mustache; // <script> | ||
} | ||
factory(global.Mustache = {}); // <script> | ||
} | ||
}(this, function (mustache) { | ||
// Workaround for https://issues.apache.org/jira/browse/COUCHDB-577 | ||
// See https://github.com/janl/mustache.js/issues/189 | ||
var RegExp_test = RegExp.prototype.test; | ||
function testRegExp(re, string) { | ||
return RegExp_test.call(re, string); | ||
} | ||
var nonSpaceRe = /\S/; | ||
function isWhitespace(string) { | ||
return !testRegExp(nonSpaceRe, string); | ||
} | ||
var Object_toString = Object.prototype.toString; | ||
@@ -48,2 +32,14 @@ var isArray = Array.isArray || function (object) { | ||
// Workaround for https://issues.apache.org/jira/browse/COUCHDB-577 | ||
// See https://github.com/janl/mustache.js/issues/189 | ||
var RegExp_test = RegExp.prototype.test; | ||
function testRegExp(re, string) { | ||
return RegExp_test.call(re, string); | ||
} | ||
var nonSpaceRe = /\S/; | ||
function isWhitespace(string) { | ||
return !testRegExp(nonSpaceRe, string); | ||
} | ||
var entityMap = { | ||
@@ -64,13 +60,2 @@ "&": "&", | ||
function escapeTags(tags) { | ||
if (!isArray(tags) || tags.length !== 2) { | ||
throw new Error('Invalid tags: ' + tags); | ||
} | ||
return [ | ||
new RegExp(escapeRegExp(tags[0]) + "\\s*"), | ||
new RegExp("\\s*" + escapeRegExp(tags[1])) | ||
]; | ||
} | ||
var whiteRe = /\s*/; | ||
@@ -105,12 +90,5 @@ var spaceRe = /\s+/; | ||
function parseTemplate(template, tags) { | ||
tags = tags || mustache.tags; | ||
template = template || ''; | ||
if (!template) | ||
return []; | ||
if (typeof tags === 'string') { | ||
tags = tags.split(spaceRe); | ||
} | ||
var tagRes = escapeTags(tags); | ||
var scanner = new Scanner(template); | ||
var sections = []; // Stack to hold section tokens | ||
@@ -126,5 +104,4 @@ var tokens = []; // Buffer to hold the tokens | ||
if (hasTag && !nonSpace) { | ||
while (spaces.length) { | ||
while (spaces.length) | ||
delete tokens[spaces.pop()]; | ||
} | ||
} else { | ||
@@ -138,2 +115,19 @@ spaces = []; | ||
var openingTagRe, closingTagRe, closingCurlyRe; | ||
function compileTags(tags) { | ||
if (typeof tags === 'string') | ||
tags = tags.split(spaceRe, 2); | ||
if (!isArray(tags) || tags.length !== 2) | ||
throw new Error('Invalid tags: ' + tags); | ||
openingTagRe = new RegExp(escapeRegExp(tags[0]) + '\\s*'); | ||
closingTagRe = new RegExp('\\s*' + escapeRegExp(tags[1])); | ||
closingCurlyRe = new RegExp('\\s*' + escapeRegExp('}' + tags[1])); | ||
} | ||
compileTags(tags || mustache.tags); | ||
var scanner = new Scanner(template); | ||
var start, type, value, chr, token, openSection; | ||
@@ -144,5 +138,6 @@ while (!scanner.eos()) { | ||
// Match any text between tags. | ||
value = scanner.scanUntil(tagRes[0]); | ||
value = scanner.scanUntil(openingTagRe); | ||
if (value) { | ||
for (var i = 0, len = value.length; i < len; ++i) { | ||
for (var i = 0, valueLength = value.length; i < valueLength; ++i) { | ||
chr = value.charAt(i); | ||
@@ -156,9 +151,8 @@ | ||
tokens.push(['text', chr, start, start + 1]); | ||
tokens.push([ 'text', chr, start, start + 1 ]); | ||
start += 1; | ||
// Check for whitespace on the current line. | ||
if (chr === '\n') { | ||
if (chr === '\n') | ||
stripSpace(); | ||
} | ||
} | ||
@@ -168,3 +162,5 @@ } | ||
// Match the opening tag. | ||
if (!scanner.scan(tagRes[0])) break; | ||
if (!scanner.scan(openingTagRe)) | ||
break; | ||
hasTag = true; | ||
@@ -180,16 +176,15 @@ | ||
scanner.scan(equalsRe); | ||
scanner.scanUntil(tagRes[1]); | ||
scanner.scanUntil(closingTagRe); | ||
} else if (type === '{') { | ||
value = scanner.scanUntil(new RegExp('\\s*' + escapeRegExp('}' + tags[1]))); | ||
value = scanner.scanUntil(closingCurlyRe); | ||
scanner.scan(curlyRe); | ||
scanner.scanUntil(tagRes[1]); | ||
scanner.scanUntil(closingTagRe); | ||
type = '&'; | ||
} else { | ||
value = scanner.scanUntil(tagRes[1]); | ||
value = scanner.scanUntil(closingTagRe); | ||
} | ||
// Match the closing tag. | ||
if (!scanner.scan(tagRes[1])) { | ||
if (!scanner.scan(closingTagRe)) | ||
throw new Error('Unclosed tag at ' + scanner.pos); | ||
} | ||
@@ -205,8 +200,7 @@ token = [ type, value, start, scanner.pos ]; | ||
if (!openSection) { | ||
if (!openSection) | ||
throw new Error('Unopened section "' + value + '" at ' + start); | ||
} | ||
if (openSection[1] !== value) { | ||
if (openSection[1] !== value) | ||
throw new Error('Unclosed section "' + openSection[1] + '" at ' + start); | ||
} | ||
} else if (type === 'name' || type === '{' || type === '&') { | ||
@@ -216,3 +210,3 @@ nonSpace = true; | ||
// Set the tags for the next time around. | ||
tagRes = escapeTags(tags = value.split(spaceRe)); | ||
compileTags(value); | ||
} | ||
@@ -223,5 +217,5 @@ } | ||
openSection = sections.pop(); | ||
if (openSection) { | ||
if (openSection) | ||
throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos); | ||
} | ||
@@ -239,3 +233,3 @@ return nestTokens(squashTokens(tokens)); | ||
var token, lastToken; | ||
for (var i = 0, len = tokens.length; i < len; ++i) { | ||
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { | ||
token = tokens[i]; | ||
@@ -269,3 +263,3 @@ | ||
var token, section; | ||
for (var i = 0, len = tokens.length; i < len; ++i) { | ||
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { | ||
token = tokens[i]; | ||
@@ -317,10 +311,11 @@ | ||
if (match && match.index === 0) { | ||
var string = match[0]; | ||
this.tail = this.tail.substring(string.length); | ||
this.pos += string.length; | ||
return string; | ||
} | ||
if (!match || match.index !== 0) | ||
return ''; | ||
return ""; | ||
var string = match[0]; | ||
this.tail = this.tail.substring(string.length); | ||
this.pos += string.length; | ||
return string; | ||
}; | ||
@@ -376,7 +371,9 @@ | ||
Context.prototype.lookup = function (name) { | ||
var cache = this.cache; | ||
var value; | ||
if (name in this.cache) { | ||
value = this.cache[name]; | ||
if (name in cache) { | ||
value = cache[name]; | ||
} else { | ||
var context = this; | ||
var context = this, names, index; | ||
@@ -386,12 +383,13 @@ while (context) { | ||
value = context.view; | ||
names = name.split('.'); | ||
index = 0; | ||
var names = name.split('.'), i = 0; | ||
while (value != null && i < names.length) { | ||
value = value[names[i++]]; | ||
} | ||
} else { | ||
while (value != null && index < names.length) | ||
value = value[names[index++]]; | ||
} else if (typeof context.view == 'object') { | ||
value = context.view[name]; | ||
} | ||
if (value != null) break; | ||
if (value != null) | ||
break; | ||
@@ -401,8 +399,7 @@ context = context.parent; | ||
this.cache[name] = value; | ||
cache[name] = value; | ||
} | ||
if (isFunction(value)) { | ||
if (isFunction(value)) | ||
value = value.call(this.view); | ||
} | ||
@@ -436,5 +433,4 @@ return value; | ||
if (tokens == null) { | ||
if (tokens == null) | ||
tokens = cache[template] = parseTemplate(template, tags); | ||
} | ||
@@ -479,3 +475,3 @@ return tokens; | ||
var token, value; | ||
for (var i = 0, len = tokens.length; i < len; ++i) { | ||
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) { | ||
token = tokens[i]; | ||
@@ -486,6 +482,8 @@ | ||
value = context.lookup(token[1]); | ||
if (!value) continue; | ||
if (!value) | ||
continue; | ||
if (isArray(value)) { | ||
for (var j = 0, jlen = value.length; j < jlen; ++j) { | ||
for (var j = 0, valueLength = value.length; j < valueLength; ++j) { | ||
buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate); | ||
@@ -496,5 +494,4 @@ } | ||
} else if (isFunction(value)) { | ||
if (typeof originalTemplate !== 'string') { | ||
if (typeof originalTemplate !== 'string') | ||
throw new Error('Cannot use higher-order sections without the original template'); | ||
} | ||
@@ -504,3 +501,4 @@ // Extract the portion of the original template that the section contains. | ||
if (value != null) buffer += value; | ||
if (value != null) | ||
buffer += value; | ||
} else { | ||
@@ -516,19 +514,29 @@ buffer += this.renderTokens(token[4], context, partials, originalTemplate); | ||
// See https://github.com/janl/mustache.js/issues/186 | ||
if (!value || (isArray(value) && value.length === 0)) { | ||
if (!value || (isArray(value) && value.length === 0)) | ||
buffer += this.renderTokens(token[4], context, partials, originalTemplate); | ||
} | ||
break; | ||
case '>': | ||
if (!partials) continue; | ||
if (!partials) | ||
continue; | ||
value = isFunction(partials) ? partials(token[1]) : partials[token[1]]; | ||
if (value != null) buffer += this.renderTokens(this.parse(value), context, partials, value); | ||
if (value != null) | ||
buffer += this.renderTokens(this.parse(value), context, partials, value); | ||
break; | ||
case '&': | ||
value = context.lookup(token[1]); | ||
if (value != null) buffer += value; | ||
if (value != null) | ||
buffer += value; | ||
break; | ||
case 'name': | ||
value = context.lookup(token[1]); | ||
if (value != null) buffer += mustache.escape(value); | ||
if (value != null) | ||
buffer += mustache.escape(value); | ||
break; | ||
@@ -545,3 +553,3 @@ case 'text': | ||
mustache.name = "mustache.js"; | ||
mustache.version = "0.8.1"; | ||
mustache.version = "1.0.0"; | ||
mustache.tags = [ "{{", "}}" ]; | ||
@@ -548,0 +556,0 @@ |
{ | ||
"name": "mustache", | ||
"version": "0.8.2", | ||
"version": "1.0.0", | ||
"description": "Logic-less {{mustache}} templates with JavaScript", | ||
@@ -10,13 +10,25 @@ "author": "mustache.js Authors <http://github.com/janl/mustache.js>", | ||
}, | ||
"keywords": ["mustache", "template", "templates", "ejs"], | ||
"keywords": [ | ||
"mustache", | ||
"template", | ||
"templates", | ||
"ejs" | ||
], | ||
"main": "./mustache.js", | ||
"devDependencies": { | ||
"mocha": "1.5.0" | ||
}, | ||
"volo": { | ||
"url": "https://raw.github.com/janl/mustache.js/0.7.3/mustache.js" | ||
"url": "https://raw.github.com/janl/mustache.js/{version}/mustache.js" | ||
}, | ||
"scripts": { | ||
"test": "mocha test" | ||
"test": "mocha --reporter spec test" | ||
}, | ||
"devDependencies": { | ||
"mocha": "2.0.1" | ||
}, | ||
"spm": { | ||
"main": "mustache.js", | ||
"ignore": [ | ||
"test", | ||
"wrappers" | ||
] | ||
} | ||
} |
@@ -19,2 +19,6 @@ # mustache.js - Logic-less {{mustache}} templates with JavaScript | ||
And this will be your templates after you use Mustache: | ||
!['stache](http://d24w6bsrhbeh9d.cloudfront.net/photo/aZPNGon_460sa.gif) | ||
## Who uses mustache.js? | ||
@@ -24,2 +28,16 @@ | ||
## Contributing | ||
mustache.js is a mature project, but it continues to actively invite maintainers. You can help out a high-profile project that is used in a lot of places on the web. There is [plenty](https://github.com/janl/mustache.js/issues) of [work](https://github.com/janl/mustache.js/pulls) to do. No big commitment required, if all you do is review a single [Pull Request](https://github.com/janl/mustache.js/pulls), you are a maintainer. And a hero. | ||
### Your First Contribution | ||
- review a [Pull Request](https://github.com/janl/mustache.js/pulls) | ||
- fix an [Issue](https://github.com/janl/mustache.js/issues) | ||
- update the [documentation](https://github.com/janl/mustache.js#usage) | ||
- make a website | ||
- write a tutorial | ||
* * * | ||
## Usage | ||
@@ -44,6 +62,43 @@ | ||
A [mustache](http://mustache.github.com/) template is a string that contains any number of mustache tags. Tags are indicated by the double mustaches that surround them. `{{person}}` is a tag, as is `{{#person}}`. In both examples we refer to `person` as the tag's key. | ||
A [mustache](http://mustache.github.com/) template is a string that contains any number of mustache tags. Tags are indicated by the double mustaches that surround them. `{{person}}` is a tag, as is `{{#person}}`. In both examples we refer to `person` as the tag's key. There are several types of tags available in mustache.js, described below. | ||
There are several types of tags available in mustache.js. | ||
There are several techniques that can be used to load templates and hand them to mustache.js, here are two of them: | ||
#### Include Templates | ||
If you need a template for a dynamic part in a static website, you can consider including the template in the static HTML file to avoid loading templates separately. Here's a small example using `jQuery`: | ||
```html | ||
<html> | ||
<body onload="loadUser"> | ||
<div id="target">Loading...</div> | ||
<script id="template" type="x-tmpl-mustache"> | ||
Hello {{ name }}! | ||
</script> | ||
</body> | ||
</html> | ||
``` | ||
```js | ||
function loadUser() { | ||
var template = $('#template').html(); | ||
Mustache.parse(template); // optional, speeds up future uses | ||
var rendered = Mustache.render(template, {name: "Luke"}); | ||
$('#target').html(rendered); | ||
} | ||
``` | ||
#### Load External Templates | ||
If your templates reside in individual files, you can load them asynchronously and render them when they arrive. Another example using `jQuery`: | ||
```js | ||
function loadUser() { | ||
$.get('template.mst', function(template) { | ||
var rendered = Mustache.render(template, {name: "Luke"}); | ||
$('#target').html(rendered); | ||
}); | ||
} | ||
``` | ||
### Variables | ||
@@ -50,0 +105,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
55883
25
1
514
497
1