diff --git a/.gitignore b/.gitignore index c44d96c..bd08399 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ .DS_Store .rvmrc runner.js -lib jquery.mustache.js qooxdoo.mustache.js dojox diff --git a/CHANGES.md b/CHANGES.md index 40d50b8..0be6033 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,49 +1,52 @@ # mustache.js Changes +## 0.5.0-dev (1/11/2012) + + * Complete rewrite + * Removed support for pragmas + ## 0.3.1-dev-twitter-b (8/23/2011) -* Cached regexes for improved performance + * Cached regexes for improved performance ## 0.3.1-dev-twitter (12/3/2010) -* fixed double-rendering bug -* added Rhino test-runner alongside JavaScriptCore + * Fixed double-rendering bug + * Added Rhino test-runner alongside JavaScriptCore ## 0.3.1 (??-??-????) ## 0.3.0 (21-07-2010) -* Improved whitespace handling. -* Make IMPLICIT ITERATORS a first class feature. -* Fix Rhino compat. -* CommonJS packaging is no longer a special case. -* DRY Rakefile. -* Allow whitespace around tag names. -* Fix partial scope. -* Fix Comments. -* Added inverted sections. -* Avoid double encoding of entities. -* Use sections to dereference subcontexts. -* Added higher order sections. - + * Improved whitespace handling + * Make IMPLICIT ITERATORS a first class feature + * Fix Rhino compat + * CommonJS packaging is no longer a special case + * DRY Rakefile + * Allow whitespace around tag names + * Fix partial scope + * Fix Comments + * Added inverted sections + * Avoid double encoding of entities + * Use sections to dereference subcontexts + * Added higher order sections ## 0.2.3 (28-03-2010) -* Better error message for missing partials. -* Added more robust type detection. -* Parse pragmas only once. -* Throw exception when encountering an unknown pragma. -* Ignore undefined partial contexts. Returns verbatim partials. -* Added yui3 packaging. - + * Better error message for missing partials + * Added more robust type detection + * Parse pragmas only once + * Throw exception when encountering an unknown pragma + * Ignore undefined partial contexts. Returns verbatim partials + * Added yui3 packaging ## 0.2.2 (11-02-2010) -* ctemplate compat: Partials are indicated by >, not <. -* Add support for {{%PRAGMA}} to enable features. -* Made array of strings an option. Enable with `{{%JSTACHE-ENABLE-STRING-ARRAYS}}`. -* mustache compat: Don't barf on unknown variables. -* Add `rake dojo` target to create a dojo package. -* Add streaming api. -* Rename JSTACHE-ENABLE-STRING-ARRAYS to IMPLICIT-ITERATOR. -* Add support for pragma options. + * ctemplate compat: Partials are indicated by >, not < + * Add support for {{%PRAGMA}} to enable features + * Made array of strings an option. Enable with `{{%JSTACHE-ENABLE-STRING-ARRAYS}}` + * mustache compat: Don't barf on unknown variables + * Add `rake dojo` target to create a dojo package + * Add streaming api + * Rename JSTACHE-ENABLE-STRING-ARRAYS to IMPLICIT-ITERATOR + * Add support for pragma options diff --git a/README.md b/README.md index 578df7c..7d941df 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ > What could be more logical awesome than no logic at all? [mustache.js](http://github.com/janl/mustache.js) is an implementation of the -[Mustache](http://mustache.github.com/) templating system in JavaScript. +[Mustache](http://mustache.github.com/) template system in JavaScript. [Mustache](http://mustache.github.com/) is a logic-less template syntax. It can be used for HTML, config files, source code - anything. It works by expanding @@ -274,10 +274,11 @@ own iteration marker: ## Plugins for JavaScript Libraries -mustache.js may be built specifically for several different client libraries -and platforms, including the following: +By default mustache.js may be used in a browser or any [CommonJS](http://www.commonjs.org/) +environment, including [node](http://nodejs.org/). Additionally, mustache.js may +be built specifically for several different client libraries and platforms, +including the following: - - [node](http://nodejs.org/) (or other CommonJS platforms) - [jQuery](http://jquery.com/) - [Dojo](http://www.dojotoolkit.org/) - [YUI](http://developer.yahoo.com/yui/) @@ -287,7 +288,6 @@ and platforms, including the following: These may be built using [Rake](http://rake.rubyforge.org/) and one of the following commands: - $ rake commonjs $ rake jquery $ rake dojo $ rake yui diff --git a/Rakefile b/Rakefile index 16bc724..b2a83b9 100644 --- a/Rakefile +++ b/Rakefile @@ -13,7 +13,7 @@ task :spec do end def version - File.read("mustache.js").match('version: "([^\"]+)",$')[1] + File.read("mustache.js").match('version = "([^\"]+)";$')[1] end # Creates a rule that uses the .tmpl.{pre,post} stuff to make a final, @@ -36,17 +36,10 @@ def templated_build(name, opts={}) sh "cat #{source}/#{target_js}.tpl.pre mustache.js \ #{source}/#{target_js}.tpl.post > #{opts[:location] || '.'}/#{target_js}" - # extra - if opts[:extra] - sh "sed -e 's/{{version}}/#{version}/' #{source}/#{opts[:extra]} \ - > #{opts[:location]}/#{opts[:extra]}" - end - puts "Done, see #{opts[:location] || '.'}/#{target_js}" end end -templated_build "CommonJS", :location => "lib", :extra => "package.json" templated_build "jQuery" templated_build "Dojo", :location => "dojox/string" templated_build "YUI3", :location => "yui3/mustache" diff --git a/TESTING.md b/TESTING.md index 6abec93..47d15e4 100644 --- a/TESTING.md +++ b/TESTING.md @@ -1,4 +1,4 @@ -## Running the mustache.js Test Suite +## Running the mustache.js test suite The mustache.js test suite uses the [RSpec](http://rspec.info/) testing framework. In order to run the tests you'll need to install [Ruby](http://ruby-lang.org/) @@ -57,6 +57,6 @@ suite with the following command: All test files live in the spec/_files directory. To create a new test: - * Create a template file `somename.mustache` - * Create a javascript file with data and functions `somename.js` - * Create a file the expected result `somename.txt` + * Create a template file called `somename.mustache` + * Create a JavaScript file containing the view called `somename.js` + * Create a text file with the expected result called `somename.txt` diff --git a/mustache.js b/mustache.js index da2c410..0121abc 100644 --- a/mustache.js +++ b/mustache.js @@ -1,38 +1,75 @@ -/* - mustache.js — Logic-less templates in JavaScript +/*! + * mustache.js - Logic-less {{mustache}} templates with JavaScript + * http://github.com/janl/mustache.js + */ +var Mustache = (typeof module !== "undefined" && module.exports) || {}; - See http://mustache.github.com/ for more info. -*/ +(function (exports) { + + exports.name = "mustache.js"; + exports.version = "0.5.0-dev"; + exports.tags = ["{{", "}}"]; + exports.parse = parse; + exports.compile = compile; + exports.render = render; + exports.clearCache = clearCache; + + exports.to_html = render; // keep backwards compatibility -var Mustache = function () { var _toString = Object.prototype.toString; + var _isArray = Array.isArray; + var _forEach = Array.prototype.forEach; + var _trim = String.prototype.trim; - Array.isArray = Array.isArray || function (obj) { - return _toString.call(obj) == "[object Array]"; + var isArray; + if (_isArray) { + isArray = _isArray; + } else { + isArray = function (obj) { + return _toString.call(obj) === "[object Array]"; + }; + } + + var forEach; + if (_forEach) { + forEach = function (obj, callback, scope) { + return _forEach.call(obj, callback, scope); + }; + } else { + forEach = function (obj, callback, scope) { + for (var i = 0, len = obj.length; i < len; ++i) { + callback.call(scope, obj[i], i, obj); + } + }; } - var _trim = String.prototype.trim, trim; + var spaceRe = /^\s*$/; + function isWhitespace(string) { + return spaceRe.test(string); + } + + var trim; if (_trim) { - trim = function (text) { - return text == null ? "" : _trim.call(text); - } + trim = function (string) { + return string == null ? "" : _trim.call(string); + }; } else { var trimLeft, trimRight; - // IE doesn't match non-breaking spaces with \s. - if ((/\S/).test("\xA0")) { - trimLeft = /^[\s\xA0]+/; - trimRight = /[\s\xA0]+$/; - } else { + if (isWhitespace("\xA0")) { trimLeft = /^\s+/; trimRight = /\s+$/; + } else { + // IE doesn't match non-breaking spaces with \s, thanks jQuery. + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; } - trim = function (text) { - return text == null ? "" : - text.toString().replace(trimLeft, "").replace(trimRight, ""); - } + trim = function (string) { + return string == null ? "" : + String(string).replace(trimLeft, "").replace(trimRight, ""); + }; } var escapeMap = { @@ -49,388 +86,451 @@ var Mustache = function () { }); } - var regexCache = {}; - var Renderer = function () {}; - - Renderer.prototype = { - otag: "{{", - ctag: "}}", - pragmas: {}, - buffer: [], - pragmas_implemented: { - "IMPLICIT-ITERATOR": true - }, - context: {}, - - render: function (template, context, partials, in_recursion) { - // reset buffer & set context - if (!in_recursion) { - this.context = context; - this.buffer = []; // TODO: make this non-lazy - } + /** + * Adds the `template`, `line`, and `file` properties to the given error + * object and alters the message to provide more useful debugging information. + */ + function debug(e, template, line, file) { + file = file || "