[Pkg-javascript-commits] [mustache.js] 07/31: Imported Upstream version 0.4.0
Martín Ferrari
tincho at debian.org
Sun Nov 13 22:20:13 UTC 2016
This is an automated email from the git hooks/post-receive script.
tincho pushed a commit to branch master
in repository mustache.js.
commit 357153bb10a5a44972ad5e386fb681ca1d83ae6f
Author: David Paleino <dapal at debian.org>
Date: Wed Feb 22 18:15:27 2012 +0100
Imported Upstream version 0.4.0
---
.gitignore | 7 +-
.travis.yml | 5 +
CHANGES.md | 11 +
LICENSE | 2 +
README.md | 191 +++++++-----
Rakefile | 56 ++--
TESTING.md | 62 ++++
THANKS.md | 20 --
mustache-commonjs/mustache.js.tpl.post | 7 -
mustache-commonjs/package.json | 7 -
mustache-dojo/mustache.js.tpl.post | 5 -
mustache.js | 324 ++++++++++++++-------
spec/_files/ampersand_escape.js | 3 +
spec/_files/ampersand_escape.mustache | 1 +
spec/_files/ampersand_escape.txt | 1 +
spec/_files/apostrophe.js | 1 +
spec/_files/apostrophe.mustache | 1 +
spec/_files/apostrophe.txt | 1 +
.../array_of_partials_implicit_partial.2.mustache | 0
.../_files}/array_of_partials_implicit_partial.js | 0
.../array_of_partials_implicit_partial.mustache | 0
.../_files}/array_of_partials_implicit_partial.txt | 0
.../_files/array_of_partials_partial.2.mustache | 0
.../_files}/array_of_partials_partial.js | 0
.../_files/array_of_partials_partial.mustache | 0
.../_files}/array_of_partials_partial.txt | 0
{examples => spec/_files}/array_of_strings.js | 0
.../_files/array_of_strings.mustache | 0
{examples => spec/_files}/array_of_strings.txt | 0
.../_files}/array_of_strings_options.js | 0
.../_files/array_of_strings_options.mustache | 0
.../_files}/array_of_strings_options.txt | 0
.../_files/array_partial.2.mustache | 0
{examples => spec/_files}/array_partial.js | 0
.../_files/array_partial.mustache | 0
{examples => spec/_files}/array_partial.txt | 0
.../_files}/bug_11_eating_whitespace.js | 0
.../_files/bug_11_eating_whitespace.mustache | 0
.../_files}/bug_11_eating_whitespace.txt | 0
{examples => spec/_files}/comments.js | 0
.../comments.html => spec/_files/comments.mustache | 0
{examples => spec/_files}/comments.txt | 0
{examples => spec/_files}/complex.js | 0
.../complex.html => spec/_files/complex.mustache | 0
{examples => spec/_files}/complex.txt | 0
{examples => spec/_files}/delimiters.js | 0
.../_files/delimiters.mustache | 0
{examples => spec/_files}/delimiters.txt | 0
spec/_files/dot_notation.js | 23 ++
spec/_files/dot_notation.mustache | 9 +
spec/_files/dot_notation.txt | 9 +
spec/_files/double_render.js | 5 +
spec/_files/double_render.mustache | 1 +
spec/_files/double_render.txt | 1 +
.../_files/empty_partial.2.mustache | 0
{examples => spec/_files}/empty_partial.js | 0
.../_files/empty_partial.mustache | 0
{examples => spec/_files}/empty_partial.txt | 0
spec/_files/empty_sections.js | 1 +
spec/_files/empty_sections.mustache | 1 +
spec/_files/empty_sections.txt | 1 +
{examples => spec/_files}/empty_template.js | 0
.../_files/empty_template.mustache | 0
{examples => spec/_files}/empty_template.txt | 0
{examples => spec/_files}/error_not_found.js | 0
.../_files/error_not_found.mustache | 0
{examples => spec/_files}/error_not_found.txt | 0
{examples => spec/_files}/escaped.js | 0
.../escaped.html => spec/_files/escaped.mustache | 0
{examples => spec/_files}/escaped.txt | 0
{examples => spec/_files}/higher_order_sections.js | 0
.../_files/higher_order_sections.mustache | 0
.../_files}/higher_order_sections.txt | 0
{examples => spec/_files}/inverted_section.js | 0
.../_files/inverted_section.mustache | 0
{examples => spec/_files}/inverted_section.txt | 0
spec/_files/keys_with_questionmarks.js | 5 +
spec/_files/keys_with_questionmarks.mustache | 3 +
spec/_files/keys_with_questionmarks.txt | 1 +
spec/_files/nesting.js | 7 +
spec/_files/nesting.mustache | 5 +
spec/_files/nesting.txt | 4 +
{examples => spec/_files}/null_string.js | 0
.../_files/null_string.mustache | 0
{examples => spec/_files}/null_string.txt | 0
.../_files/partial_recursion.2.mustache | 0
{examples => spec/_files}/partial_recursion.js | 0
.../_files/partial_recursion.mustache | 0
{examples => spec/_files}/partial_recursion.txt | 0
.../_files}/recursion_with_same_names.js | 0
.../_files/recursion_with_same_names.mustache | 0
.../_files}/recursion_with_same_names.txt | 0
{examples => spec/_files}/reuse_of_enumerables.js | 0
.../_files/reuse_of_enumerables.mustache | 0
{examples => spec/_files}/reuse_of_enumerables.txt | 0
{examples => spec/_files}/section_as_context.js | 0
.../_files/section_as_context.mustache | 0
{examples => spec/_files}/section_as_context.txt | 0
{examples => spec/_files}/simple.js | 0
.../simple.html => spec/_files/simple.mustache | 0
{examples => spec/_files}/simple.txt | 0
.../_files/template_partial.2.mustache | 0
{examples => spec/_files}/template_partial.js | 0
.../_files/template_partial.mustache | 0
{examples => spec/_files}/template_partial.txt | 0
{examples => spec/_files}/two_in_a_row.js | 0
.../_files/two_in_a_row.mustache | 0
{examples => spec/_files}/two_in_a_row.txt | 0
spec/_files/two_sections.js | 1 +
spec/_files/two_sections.mustache | 4 +
.../_files/two_sections.txt | 0
{examples => spec/_files}/unescaped.js | 0
.../_files/unescaped.mustache | 0
{examples => spec/_files}/unescaped.txt | 0
{examples => spec/_files}/unknown_pragma.js | 0
.../_files/unknown_pragma.mustache | 0
{examples => spec/_files}/unknown_pragma.txt | 0
.../_files/view_partial.2.mustache | 0
{examples => spec/_files}/view_partial.js | 0
.../_files/view_partial.mustache | 0
{examples => spec/_files}/view_partial.txt | 0
.../_files/whitespace_partial.2.mustache | 0
{examples => spec/_files}/whitespace_partial.js | 0
.../_files/whitespace_partial.mustache | 0
{examples => spec/_files}/whitespace_partial.txt | 0
spec/mustache_spec.rb | 276 ++++++++++++++++++
test/mustache_spec.rb | 156 ----------
wrappers/commonjs/mustache.js.tpl.post | 8 +
.../commonjs}/mustache.js.tpl.pre | 0
wrappers/commonjs/package.json | 8 +
wrappers/dojo/mustache.js.tpl.post | 4 +
.../dojo}/mustache.js.tpl.pre | 4 +-
.../jquery}/jquery.mustache.js.tpl.post | 0
.../jquery}/jquery.mustache.js.tpl.pre | 0
wrappers/qooxdoo/qooxdoo.mustache.js.tpl.post | 9 +
wrappers/qooxdoo/qooxdoo.mustache.js.tpl.pre | 127 ++++++++
wrappers/requirejs/requirejs.mustache.js.tpl.post | 3 +
wrappers/requirejs/requirejs.mustache.js.tpl.pre | 6 +
.../yui3}/mustache.js.tpl.post | 0
.../yui3}/mustache.js.tpl.pre | 0
140 files changed, 975 insertions(+), 412 deletions(-)
diff --git a/.gitignore b/.gitignore
index a7ed15c..c44d96c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,10 @@
+.DS_Store
+.rvmrc
runner.js
+lib
jquery.mustache.js
+qooxdoo.mustache.js
dojox
yui3
-commonjs.mustache.js
+requirejs.mustache.js
+
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..b52599e
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,5 @@
+rvm:
+ - 1.9.2
+before_script:
+ - sudo apt-get -y install xulrunner-2.0
+ - gem install rspec
diff --git a/CHANGES.md b/CHANGES.md
index 60be170..40d50b8 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,16 @@
# mustache.js Changes
+## 0.3.1-dev-twitter-b (8/23/2011)
+
+* Cached regexes for improved performance
+
+## 0.3.1-dev-twitter (12/3/2010)
+
+* fixed double-rendering bug
+* added Rhino test-runner alongside JavaScriptCore
+
+## 0.3.1 (??-??-????)
+
## 0.3.0 (21-07-2010)
* Improved whitespace handling.
diff --git a/LICENSE b/LICENSE
index e9f38ab..395e263 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,3 +1,5 @@
+The MIT License
+
Copyright (c) 2009 Chris Wanstrath (Ruby)
Copyright (c) 2010 Jan Lehnardt (JavaScript)
diff --git a/README.md b/README.md
index 7434356..578df7c 100644
--- a/README.md
+++ b/README.md
@@ -1,50 +1,55 @@
-# mustache.js — Logic-less templates with JavaScript
+# mustache.js — Logic-less {{mustache}} templates with JavaScript
> What could be more logical awesome than no logic at all?
-For a list of implementations (other than JavaScript) and editor
-plugins, see <http://mustache.github.com/>.
+[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/) is a logic-less template syntax. It can
+be used for HTML, config files, source code - anything. It works by expanding
+tags in a template using values provided in a hash or object.
-## Where to Use?
+We call it "logic-less" because there are no if statements, else clauses, or for
+loops. Instead there are only tags. Some tags are replaced with a value, some
+nothing, and others a series of values.
-You can use mustache.js rendering stuff in various scenarios. E.g. you can
-render templates in your browser, or rendering server-side stuff with
-[node.js][node.js], use it for rendering stuff in [CouchDB][couchdb]’s views.
+For a language-agnostic overview of Mustache's template syntax, see the
+`mustache(5)` [manpage](http://mustache.github.com/mustache.5.html).
+## Where to use mustache.js?
-## Who Uses Mustache?
+You can use mustache.js to render templates in many various scenarios where you
+can use JavaScript. For example, you can render templates in a browser,
+server-side using [node](http://nodejs.org/), in [CouchDB](http://couchdb.apache.org/)
+views, or in almost any other environment where you can use JavaScript.
-An updated list is kept on the Github wiki. Add yourself, if you use
-mustache.js: <http://wiki.github.com/janl/mustache.js/beard-competition>
+## Who uses mustache.js?
+An updated list of mustache.js users is kept [on the Github wiki](http://wiki.github.com/janl/mustache.js/beard-competition).
+Add yourself or your company if you use mustache.js!
## Usage
-A quick example how to use mustache.js:
+Below is quick example how to use mustache.js:
var view = {
title: "Joe",
calc: function() {
return 2 + 4;
}
- }
-
- var template = "{{title}} spends {{calc}}";
+ };
- var html = Mustache.to_html(template, view);
+ var html = Mustache.to_html("{{title}} spends {{calc}}", view);
-`template` is a simple string with mustache tags and `view` is a JavaScript
-object containing the data and any code to render the template.
+In this example, the `Mustache.to_html` function takes two parameters: 1) the
+[mustache](http://mustache.github.com/) template and 2) a `view` object that
+contains the data and code needed to render the template.
## Template Tag Types
There are several types of tags currently implemented in mustache.js.
-For a language-agnostic overview of Mustache’s template syntax, see the
-`mustache(5)` manpage or <http://mustache.github.com/mustache.5.html>.
-
### Simple Tags
Tags are always surrounded by mustaches like this `{{foobar}}`.
@@ -53,12 +58,27 @@ Tags are always surrounded by mustaches like this `{{foobar}}`.
template = "{{say_hello}}, {{name}}"
+#### Accessing values in nested objects (Dot Notation)
+
+To access data logically grouped into nested objects, specify a '.' delimited
+path to the value.
+
+ var contact = {
+ name: {first: "Bill", last: "Bobitybob" },
+ age: 37
+ }
+
+ template = "Hello, {{name.first}} {{name.last}}. You are {{age}} years old."
+
+*NOTICE*: The dot notation feature was recently implemented for the 0.4
+ release, which is not out as of Nov 9 2011. You can find the feature in the
+ current master branch of mustachejs.
### Conditional Sections
Conditional sections begin with `{{#condition}}` and end with
`{{/condition}}`. When `condition` evaluates to true, the section is rendered,
-otherwise the hole block will output nothing at all. `condition` may be a
+otherwise the whole block will output nothing at all. `condition` may be a
function returning true/false or a simple boolean.
var view = {condition: function() {
@@ -93,7 +113,7 @@ enumeration section.
If a section key returns a function, it will be called and passed both the
unrendered block of text and a renderer convenience function.
-Given this JS:
+Given this object:
"name": "Tater",
"bolder": function() {
@@ -115,39 +135,36 @@ to implement caching, filters (like syntax highlighting), etc.
You can use `this.name` to access the attribute `name` from your view.
-### Dereferencing Section
+### Dereferencing Sections
+
+If your data has components that are logically grouped into nested objects,
+you may wish to dereference an object to access its values.
-If you have a nested object structure in your view, it can sometimes be easier
-to use sections like this:
+Given this object:
- var objects = {
- a_object: {
- title: 'this is an object',
- description: 'one of its attributes is a list',
- a_list: [{label: 'listitem1'}, {label: 'listitem2'}]
+ {
+ "name": "Bill",
+ "address": {
+ "street": "801 Streetly street",
+ "city": "Boston",
+ "state": "MA",
+ "zip" "02101"
}
- };
+ }
-This is our template:
+And this template:
- {{#a_object}}
- <h1>{{title}}</h1>
- <p>{{description}}</p>
- <ul>
- {{#a_list}}
- <li>{{label}}</li>
- {{/a_list}}
- </ul>
- {{/a_object}}
+ <h1>Contact: {{name}}</h1>
+ {{#address}}
+ <p>{{street}}</p>
+ <p>{{city}}, {{state}} {{zip}}</p>
+ {{/address}}
-Here is the result:
+We'll get this output:
- <h1>this is an object</h1>
- <p>one of its attributes is a list</p>
- <ul>
- <li>listitem1</li>
- <li>listitem2</li>
- </ul>
+ <h1>Contact: Bill</h1>
+ <p>801 Streetly street</p>
+ <p>Boston, MA 02101</p>
### Inverted Sections
@@ -199,12 +216,11 @@ will tell mustache.js to look for a object in the context's property
`winnings`. It will then use that object as the context for the template found
in `partials` for `winnings`.
-
## Escaping
mustache.js does escape all values when using the standard double mustache
-syntax. Characters which will be escaped: `& \ " < >`. To disable escaping,
-simply use tripple mustaches like `{{{unescaped_variable}}}`.
+syntax. Characters which will be escaped: `& \ " ' < >`. To disable escaping,
+simply use triple mustaches like `{{{unescaped_variable}}}`.
Example: Using `{{variable}}` inside a template for `5 > 2` will result in `5 > 2`, where as the usage of `{{{variable}}}` will result in `5 > 2`.
@@ -256,31 +272,48 @@ own iteration marker:
{{bob}}
{{/foo}}
-## FaQ
-
-### Why doesn’t Mustache allow dot notation like `{{variable.member}}`?
-
-The reason is given in the [mustache.rb
-bugtracker](http://github.com/defunkt/mustache/issues/issue/6).
-
-Mustache implementations strive to be template-compatible.
-
-
-## More Examples and Documentation
-
-See `examples/` for more goodies and read the [original mustache docs][m]
-
-## Command Line
-
-See `mustache(1)` man page or
-<http://defunkt.github.com/mustache/mustache.1.html>
-for command line docs.
-
-Or just install it as a RubyGem:
-
- $ gem install mustache
- $ mustache -h
-
-[m]: http://github.com/defunkt/mustache/#readme
-[node.js]: http://nodejs.org
-[couchdb]: http://couchdb.apache.org
+## Plugins for JavaScript Libraries
+
+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/)
+ - [RequireJS](http://requirejs.org/)
+ - [qooxdoo](http://qooxdoo.org/)
+
+These may be built using [Rake](http://rake.rubyforge.org/) and one of the
+following commands:
+
+ $ rake commonjs
+ $ rake jquery
+ $ rake dojo
+ $ rake yui
+ $ rake requirejs
+ $ rake qooxdoo
+
+## Thanks
+
+Mustache.js wouldn't kick ass if it weren't for these fine souls:
+
+ * Chris Wanstrath / defunkt
+ * Alexander Lang / langalex
+ * Sebastian Cohnen / tisba
+ * J Chris Anderson / jchris
+ * Tom Robinson / tlrobinson
+ * Aaron Quint / quirkey
+ * Douglas Crockford
+ * Nikita Vasilyev / NV
+ * Elise Wood / glytch
+ * Damien Mathieu / dmathieu
+ * Jakub Kuźma / qoobaa
+ * Will Leinweber / will
+ * dpree
+ * Jason Smith / jhs
+ * Aaron Gibralter / agibralter
+ * Ross Boucher / boucher
+ * Matt Sanford / mzsanford
+ * Ben Cherry / bcherry
+ * Michael Jackson / mjijackson
diff --git a/Rakefile b/Rakefile
index 4629c97..16bc724 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,42 +1,48 @@
require 'rake'
-require 'spec/rake/spectask'
+require 'rake/clean'
task :default => :spec
-Spec::Rake::SpecTask.new(:spec) do |t|
- #t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
- t.spec_files = FileList['test/*_spec.rb']
+desc "Run all specs"
+task :spec do
+ require 'rspec/core/rake_task'
+ RSpec::Core::RakeTask.new(:spec) do |t|
+ #t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
+ t.pattern = 'spec/*_spec.rb'
+ end
end
-desc "Run all specs"
-task :spec
+def version
+ File.read("mustache.js").match('version: "([^\"]+)",$')[1]
+end
+# Creates a rule that uses the .tmpl.{pre,post} stuff to make a final,
+# wrapped, output file. There is some extra complexity because Dojo and YUI3
+# use different template files and final locations.
def templated_build(name, opts={})
- # Create a rule that uses the .tmpl.{pre,post} stuff to make a final,
- # wrapped, output file.
- # There is some extra complexity because Dojo and YUI3 use different
- # template files and final locations.
short = name.downcase
- source = "mustache-#{short}"
+ source = File.join("wrappers", short)
dependencies = ["mustache.js"] + Dir.glob("#{source}/*.tpl.*")
+ target_js = opts[:location] ? "mustache.js" : "#{short}.mustache.js"
+
+ CLEAN.include(opts[:location] ? opts[:location] : target_js)
desc "Package for #{name}"
task short.to_sym => dependencies do
- target_js = opts[:location] ? "mustache.js" : "#{short}.mustache.js"
-
puts "Packaging for #{name}"
- sh "mkdir -p #{opts[:location]}" if opts[:location]
+
+ mkdir_p opts[:location] if opts[:location]
+
sh "cat #{source}/#{target_js}.tpl.pre mustache.js \
- #{source}/#{target_js}.tpl.post > #{opts[:location] || '.'}/#{target_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}"
+ > #{opts[:location]}/#{opts[:extra]}"
+ end
+ puts "Done, see #{opts[:location] || '.'}/#{target_js}"
end
end
@@ -44,13 +50,5 @@ templated_build "CommonJS", :location => "lib", :extra => "package.json"
templated_build "jQuery"
templated_build "Dojo", :location => "dojox/string"
templated_build "YUI3", :location => "yui3/mustache"
-
-def version
- File.read("mustache.js").match('version: "([^\"]+)",$')[1]
-end
-
-
-desc "Remove temporary files."
-task :clean do
- sh "git clean -fdx"
-end
+templated_build "RequireJS"
+templated_build "qooxdoo"
diff --git a/TESTING.md b/TESTING.md
new file mode 100644
index 0000000..6abec93
--- /dev/null
+++ b/TESTING.md
@@ -0,0 +1,62 @@
+## 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/)
+as well as the `rake`, `rspec` (>=2), and `json` [RubyGems](http://rubygems.org/).
+
+### How to install Ruby and the required gems from source
+
+Make sure you have the required tools to compile it:
+
+ $ apt-get install build-essential libssl-dev libreadline5-dev zlib1g-dev
+
+Download and extract the Ruby source, and install it:
+
+ $ wget ftp://ftp.ruby-lang.org/pub/ruby/stable-snapshot.tar.gz
+ $ tar xvzf stable-snapshot.tar.gz
+ $ cd ruby
+ $ ./configure && make && make install
+
+Download and extract RubyGems, and install it:
+
+ $ wget http://production.cf.rubygems.org/rubygems/rubygems-1.8.12.tgz
+ $ tar xzvf rubygems-1.8.12.tgz
+ $ cd rubygems-1.8.12
+ $ ruby setup.rb
+
+If you want to update RubyGems:
+
+ $ gem update --system
+
+Install the required gems:
+
+ $ gem install rake rspec json
+
+That's it!
+
+### How to run the tests
+
+The mustache.js test suite currently uses 4 different JavaScript runtime engines
+to maximize portability across platforms and browsers. They are:
+
+ * node
+ * SpiderMonkey (Mozilla, Firefox)
+ * JavaScriptCore (WebKit, Safari)
+ * Rhino (Mozilla, Java)
+
+When the test suite runs it will automatically determine which platforms are
+available on your machine and run on all of them. The suite must run on at least
+one platform in order to succeed.
+
+Once you have at least one JavaScript platform installed, you can run the test
+suite with the following command:
+
+ $ rake
+
+### How to create a test
+
+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`
diff --git a/THANKS.md b/THANKS.md
deleted file mode 100644
index 6dac939..0000000
--- a/THANKS.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# Thanks
-
-Mustache.js wouldn't kick ass if it weren't for these fine souls:
-
- * Chris Wanstrath / defunkt
- * Alexander Lang / langalex
- * Sebastian Cohnen / tisba
- * J Chris Anderson / jchris
- * Tom Robinson / tlrobinson
- * Aaron Quint / quirkey
- * Douglas Crockford
- * Nikita Vasilyev / NV
- * Elise Wood / glytch
- * Damien Mathieu / dmathieu
- * Jakub Kuźma / qoobaa
- * Will Leinweber / will
- * dpree
- * Jason Smith / jhs
- * Aaron Gibralter / agibralter
- * Ross Boucher / boucher
diff --git a/mustache-commonjs/mustache.js.tpl.post b/mustache-commonjs/mustache.js.tpl.post
deleted file mode 100644
index 885803f..0000000
--- a/mustache-commonjs/mustache.js.tpl.post
+++ /dev/null
@@ -1,7 +0,0 @@
-
-exports.name = Mustache.name;
-exports.version = Mustache.version;
-
-exports.to_html = function() {
- return Mustache.to_html.apply(this, arguments);
-};
diff --git a/mustache-commonjs/package.json b/mustache-commonjs/package.json
deleted file mode 100644
index 74d3aba..0000000
--- a/mustache-commonjs/package.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "mustache",
- "author": "http://mustache.github.com/",
- "description": "{{ mustache }} in JavaScript — Logic-less templates.",
- "keywords": ["template"],
- "version": "{{version}}"
-}
diff --git a/mustache-dojo/mustache.js.tpl.post b/mustache-dojo/mustache.js.tpl.post
deleted file mode 100644
index f659e2f..0000000
--- a/mustache-dojo/mustache.js.tpl.post
+++ /dev/null
@@ -1,5 +0,0 @@
-
- d.mustache = function(template, view, partials) {
- return Mustache.to_html(template, view, partials);
- };
-})(dojo);
\ No newline at end of file
diff --git a/mustache.js b/mustache.js
index 0996227..91ec828 100644
--- a/mustache.js
+++ b/mustache.js
@@ -4,8 +4,53 @@
See http://mustache.github.com/ for more info.
*/
-var Mustache = function() {
- var Renderer = function() {};
+var Mustache = function () {
+ var _toString = Object.prototype.toString;
+
+ Array.isArray = Array.isArray || function (obj) {
+ return _toString.call(obj) == "[object Array]";
+ }
+
+ var _trim = String.prototype.trim, trim;
+
+ if (_trim) {
+ trim = function (text) {
+ return text == null ? "" : _trim.call(text);
+ }
+ } else {
+ var trimLeft, trimRight;
+
+ // IE doesn't match non-breaking spaces with \s.
+ if ((/\S/).test("\xA0")) {
+ trimLeft = /^[\s\xA0]+/;
+ trimRight = /[\s\xA0]+$/;
+ } else {
+ trimLeft = /^\s+/;
+ trimRight = /\s+$/;
+ }
+
+ trim = function (text) {
+ return text == null ? "" :
+ text.toString().replace(trimLeft, "").replace(trimRight, "");
+ }
+ }
+
+ var escapeMap = {
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ '"': '"',
+ "'": '''
+ };
+
+ function escapeHTML(string) {
+ return String(string).replace(/&(?!\w+;)|[<>"']/g, function (s) {
+ return escapeMap[s] || s;
+ });
+ }
+
+ var regexCache = {};
+ var Renderer = function () {};
Renderer.prototype = {
otag: "{{",
@@ -17,16 +62,16 @@ var Mustache = function() {
},
context: {},
- render: function(template, context, partials, in_recursion) {
+ render: function (template, context, partials, in_recursion) {
// reset buffer & set context
- if(!in_recursion) {
+ if (!in_recursion) {
this.context = context;
this.buffer = []; // TODO: make this non-lazy
}
// fail fast
- if(!this.includes("", template)) {
- if(in_recursion) {
+ if (!this.includes("", template)) {
+ if (in_recursion) {
return template;
} else {
this.send(template);
@@ -34,44 +79,64 @@ var Mustache = function() {
}
}
+ // get the pragmas together
template = this.render_pragmas(template);
+
+ // render the template
var html = this.render_section(template, context, partials);
- if(in_recursion) {
- return this.render_tags(html, context, partials, in_recursion);
+
+ // render_section did not find any sections, we still need to render the tags
+ if (html === false) {
+ html = this.render_tags(template, context, partials, in_recursion);
}
- this.render_tags(html, context, partials, in_recursion);
+ if (in_recursion) {
+ return html;
+ } else {
+ this.sendLines(html);
+ }
},
/*
Sends parsed lines
*/
- send: function(line) {
- if(line != "") {
+ send: function (line) {
+ if (line !== "") {
this.buffer.push(line);
}
},
+ sendLines: function (text) {
+ if (text) {
+ var lines = text.split("\n");
+ for (var i = 0; i < lines.length; i++) {
+ this.send(lines[i]);
+ }
+ }
+ },
+
/*
Looks for %PRAGMAS
*/
- render_pragmas: function(template) {
+ render_pragmas: function (template) {
// no pragmas
- if(!this.includes("%", template)) {
+ if (!this.includes("%", template)) {
return template;
}
var that = this;
- var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" +
- this.ctag);
- return template.replace(regex, function(match, pragma, options) {
- if(!that.pragmas_implemented[pragma]) {
- throw({message:
+ var regex = this.getCachedRegex("render_pragmas", function (otag, ctag) {
+ return new RegExp(otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + ctag, "g");
+ });
+
+ return template.replace(regex, function (match, pragma, options) {
+ if (!that.pragmas_implemented[pragma]) {
+ throw({message:
"This implementation of mustache doesn't understand the '" +
pragma + "' pragma"});
}
that.pragmas[pragma] = {};
- if(options) {
+ if (options) {
var opts = options.split("=");
that.pragmas[pragma][opts[0]] = opts[1];
}
@@ -83,12 +148,12 @@ var Mustache = function() {
/*
Tries to find a partial in the curent scope and render it
*/
- render_partial: function(name, context, partials) {
- name = this.trim(name);
- if(!partials || partials[name] === undefined) {
+ render_partial: function (name, context, partials) {
+ name = trim(name);
+ if (!partials || partials[name] === undefined) {
throw({message: "unknown_partial '" + name + "'"});
}
- if(typeof(context[name]) != "object") {
+ if (!context || typeof context[name] != "object") {
return this.render(partials[name], context, partials, true);
}
return this.render(partials[name], context[name], partials, true);
@@ -97,64 +162,94 @@ var Mustache = function() {
/*
Renders inverted (^) and normal (#) sections
*/
- render_section: function(template, context, partials) {
- if(!this.includes("#", template) && !this.includes("^", template)) {
- return template;
+ render_section: function (template, context, partials) {
+ if (!this.includes("#", template) && !this.includes("^", template)) {
+ // did not render anything, there were no sections
+ return false;
}
var that = this;
- // CSW - Added "+?" so it finds the tighest bound, not the widest
- var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag +
- "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag +
- "\\s*", "mg");
+
+ var regex = this.getCachedRegex("render_section", function (otag, ctag) {
+ // This regex matches _the first_ section ({{#foo}}{{/foo}}), and captures the remainder
+ return new RegExp(
+ "^([\\s\\S]*?)" + // all the crap at the beginning that is not {{*}} ($1)
+
+ otag + // {{
+ "(\\^|\\#)\\s*(.+)\\s*" + // #foo (# == $2, foo == $3)
+ ctag + // }}
+
+ "\n*([\\s\\S]*?)" + // between the tag ($2). leading newlines are dropped
+
+ otag + // {{
+ "\\/\\s*\\3\\s*" + // /foo (backreference to the opening tag).
+ ctag + // }}
+
+ "\\s*([\\s\\S]*)$", // everything else in the string ($4). leading whitespace is dropped.
+
+ "g");
+ });
+
// for each {{#foo}}{{/foo}} section do...
- return template.replace(regex, function(match, type, name, content) {
- var value = that.find(name, context);
- if(type == "^") { // inverted section
- if(!value || that.is_array(value) && value.length === 0) {
+ return template.replace(regex, function (match, before, type, name, content, after) {
+ // before contains only tags, no sections
+ var renderedBefore = before ? that.render_tags(before, context, partials, true) : "",
+
+ // after may contain both sections and tags, so use full rendering function
+ renderedAfter = after ? that.render(after, context, partials, true) : "",
+
+ // will be computed below
+ renderedContent,
+
+ value = that.find(name, context);
+
+ if (type === "^") { // inverted section
+ if (!value || Array.isArray(value) && value.length === 0) {
// false or empty list, render it
- return that.render(content, context, partials, true);
+ renderedContent = that.render(content, context, partials, true);
} else {
- return "";
+ renderedContent = "";
}
- } else if(type == "#") { // normal section
- if(that.is_array(value)) { // Enumerable, Let's loop!
- return that.map(value, function(row) {
- return that.render(content, that.create_context(row),
- partials, true);
+ } else if (type === "#") { // normal section
+ if (Array.isArray(value)) { // Enumerable, Let's loop!
+ renderedContent = that.map(value, function (row) {
+ return that.render(content, that.create_context(row), partials, true);
}).join("");
- } else if(that.is_object(value)) { // Object, Use it as subcontext!
- return that.render(content, that.create_context(value),
+ } else if (that.is_object(value)) { // Object, Use it as subcontext!
+ renderedContent = that.render(content, that.create_context(value),
partials, true);
- } else if(typeof value === "function") {
+ } else if (typeof value == "function") {
// higher order section
- return value.call(context, content, function(text) {
+ renderedContent = value.call(context, content, function (text) {
return that.render(text, context, partials, true);
});
- } else if(value) { // boolean section
- return that.render(content, context, partials, true);
+ } else if (value) { // boolean section
+ renderedContent = that.render(content, context, partials, true);
} else {
- return "";
+ renderedContent = "";
}
}
+
+ return renderedBefore + renderedContent + renderedAfter;
});
},
/*
Replace {{foo}} and friends with values from our view
*/
- render_tags: function(template, context, partials, in_recursion) {
+ render_tags: function (template, context, partials, in_recursion) {
// tit for tat
var that = this;
- var new_regex = function() {
- return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" +
- that.ctag + "+", "g");
+ var new_regex = function () {
+ return that.getCachedRegex("render_tags", function (otag, ctag) {
+ return new RegExp(otag + "(=|!|>|&|\\{|%)?([^#\\^]+?)\\1?" + ctag + "+", "g");
+ });
};
var regex = new_regex();
- var tag_replace_callback = function(match, operator, name) {
+ var tag_replace_callback = function (match, operator, name) {
switch(operator) {
case "!": // ignore comments
return "";
@@ -165,33 +260,34 @@ var Mustache = function() {
case ">": // render partial
return that.render_partial(name, context, partials);
case "{": // the triple mustache is unescaped
+ case "&": // & operator is an alternative unescape method
return that.find(name, context);
default: // escape the value
- return that.escape(that.find(name, context));
+ return escapeHTML(that.find(name, context));
}
};
var lines = template.split("\n");
for(var i = 0; i < lines.length; i++) {
lines[i] = lines[i].replace(regex, tag_replace_callback, this);
- if(!in_recursion) {
+ if (!in_recursion) {
this.send(lines[i]);
}
}
- if(in_recursion) {
+ if (in_recursion) {
return lines.join("\n");
}
},
- set_delimiters: function(delimiters) {
+ set_delimiters: function (delimiters) {
var dels = delimiters.split(" ");
this.otag = this.escape_regex(dels[0]);
this.ctag = this.escape_regex(dels[1]);
},
- escape_regex: function(text) {
+ escape_regex: function (text) {
// thank you Simon Willison
- if(!arguments.callee.sRE) {
+ if (!arguments.callee.sRE) {
var specials = [
'/', '.', '*', '+', '?', '|',
'(', ')', '[', ']', '{', '}', '\\'
@@ -207,8 +303,8 @@ var Mustache = function() {
find `name` in current `context`. That is find me a value
from the view object
*/
- find: function(name, context) {
- name = this.trim(name);
+ find: function (name, context) {
+ name = trim(name);
// Checks whether a value is thruthy or false or 0
function is_kinda_truthy(bool) {
@@ -216,53 +312,61 @@ var Mustache = function() {
}
var value;
- if(is_kinda_truthy(context[name])) {
- value = context[name];
- } else if(is_kinda_truthy(this.context[name])) {
- value = this.context[name];
+
+ // check for dot notation eg. foo.bar
+ if (name.match(/([a-z_]+)\./ig)) {
+ var childValue = this.walk_context(name, context);
+ if (is_kinda_truthy(childValue)) {
+ value = childValue;
+ }
+ } else {
+ if (is_kinda_truthy(context[name])) {
+ value = context[name];
+ } else if (is_kinda_truthy(this.context[name])) {
+ value = this.context[name];
+ }
}
- if(typeof value === "function") {
+ if (typeof value == "function") {
return value.apply(context);
}
- if(value !== undefined) {
+ if (value !== undefined) {
return value;
}
// silently ignore unkown variables
return "";
},
+ walk_context: function (name, context) {
+ var path = name.split('.');
+ // if the var doesn't exist in current context, check the top level context
+ var value_context = (context[path[0]] != undefined) ? context : this.context;
+ var value = value_context[path.shift()];
+ while (value != undefined && path.length > 0) {
+ value_context = value;
+ value = value[path.shift()];
+ }
+ // if the value is a function, call it, binding the correct context
+ if (typeof value == "function") {
+ return value.apply(value_context);
+ }
+ return value;
+ },
+
// Utility methods
/* includes tag */
- includes: function(needle, haystack) {
+ includes: function (needle, haystack) {
return haystack.indexOf(this.otag + needle) != -1;
},
- /*
- Does away with nasty characters
- */
- escape: function(s) {
- s = String(s === null ? "" : s);
- return s.replace(/&(?!\w+;)|["<>\\]/g, function(s) {
- switch(s) {
- case "&": return "&";
- case "\\": return "\\\\";
- case '"': return '\"';
- case "<": return "<";
- case ">": return ">";
- default: return s;
- }
- });
- },
-
// by @langalex, support for arrays of strings
- create_context: function(_context) {
- if(this.is_object(_context)) {
+ create_context: function (_context) {
+ if (this.is_object(_context)) {
return _context;
} else {
var iterator = ".";
- if(this.pragmas["IMPLICIT-ITERATOR"]) {
+ if (this.pragmas["IMPLICIT-ITERATOR"]) {
iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator;
}
var ctx = {};
@@ -271,25 +375,14 @@ var Mustache = function() {
}
},
- is_object: function(a) {
+ is_object: function (a) {
return a && typeof a == "object";
},
- is_array: function(a) {
- return Object.prototype.toString.call(a) === '[object Array]';
- },
-
- /*
- Gets rid of leading and trailing whitespace
- */
- trim: function(s) {
- return s.replace(/^\s*|\s*$/g, "");
- },
-
/*
Why, why, why? Because IE. Cry, cry cry.
*/
- map: function(array, fn) {
+ map: function (array, fn) {
if (typeof array.map == "function") {
return array.map(fn);
} else {
@@ -300,23 +393,42 @@ var Mustache = function() {
}
return r;
}
+ },
+
+ getCachedRegex: function (name, generator) {
+ var byOtag = regexCache[this.otag];
+ if (!byOtag) {
+ byOtag = regexCache[this.otag] = {};
+ }
+
+ var byCtag = byOtag[this.ctag];
+ if (!byCtag) {
+ byCtag = byOtag[this.ctag] = {};
+ }
+
+ var regex = byCtag[name];
+ if (!regex) {
+ regex = byCtag[name] = generator(this.otag, this.ctag);
+ }
+
+ return regex;
}
};
return({
name: "mustache.js",
- version: "0.3.0",
+ version: "0.4.0",
/*
Turns a template and view into HTML
*/
- to_html: function(template, view, partials, send_fun) {
+ to_html: function (template, view, partials, send_fun) {
var renderer = new Renderer();
- if(send_fun) {
+ if (send_fun) {
renderer.send = send_fun;
}
- renderer.render(template, view, partials);
- if(!send_fun) {
+ renderer.render(template, view || {}, partials);
+ if (!send_fun) {
return renderer.buffer.join("\n");
}
}
diff --git a/spec/_files/ampersand_escape.js b/spec/_files/ampersand_escape.js
new file mode 100644
index 0000000..645efe1
--- /dev/null
+++ b/spec/_files/ampersand_escape.js
@@ -0,0 +1,3 @@
+var ampersand_escape = {
+ message: "Some <code>"
+};
diff --git a/spec/_files/ampersand_escape.mustache b/spec/_files/ampersand_escape.mustache
new file mode 100644
index 0000000..6501a48
--- /dev/null
+++ b/spec/_files/ampersand_escape.mustache
@@ -0,0 +1 @@
+{{&message}}
diff --git a/spec/_files/ampersand_escape.txt b/spec/_files/ampersand_escape.txt
new file mode 100644
index 0000000..2ed3fd3
--- /dev/null
+++ b/spec/_files/ampersand_escape.txt
@@ -0,0 +1 @@
+Some <code>
diff --git a/spec/_files/apostrophe.js b/spec/_files/apostrophe.js
new file mode 100644
index 0000000..df69cd2
--- /dev/null
+++ b/spec/_files/apostrophe.js
@@ -0,0 +1 @@
+var apostrophe = {'apos': "'", 'control':'X'};
diff --git a/spec/_files/apostrophe.mustache b/spec/_files/apostrophe.mustache
new file mode 100644
index 0000000..e8687aa
--- /dev/null
+++ b/spec/_files/apostrophe.mustache
@@ -0,0 +1 @@
+{{apos}}{{control}}
diff --git a/spec/_files/apostrophe.txt b/spec/_files/apostrophe.txt
new file mode 100644
index 0000000..4427c30
--- /dev/null
+++ b/spec/_files/apostrophe.txt
@@ -0,0 +1 @@
+'X
diff --git a/examples/array_of_partials_implicit_partial.2.html b/spec/_files/array_of_partials_implicit_partial.2.mustache
similarity index 100%
rename from examples/array_of_partials_implicit_partial.2.html
rename to spec/_files/array_of_partials_implicit_partial.2.mustache
diff --git a/examples/array_of_partials_implicit_partial.js b/spec/_files/array_of_partials_implicit_partial.js
similarity index 100%
rename from examples/array_of_partials_implicit_partial.js
rename to spec/_files/array_of_partials_implicit_partial.js
diff --git a/examples/array_of_partials_implicit_partial.html b/spec/_files/array_of_partials_implicit_partial.mustache
similarity index 100%
rename from examples/array_of_partials_implicit_partial.html
rename to spec/_files/array_of_partials_implicit_partial.mustache
diff --git a/examples/array_of_partials_implicit_partial.txt b/spec/_files/array_of_partials_implicit_partial.txt
similarity index 100%
rename from examples/array_of_partials_implicit_partial.txt
rename to spec/_files/array_of_partials_implicit_partial.txt
diff --git a/examples/array_of_partials_partial.2.html b/spec/_files/array_of_partials_partial.2.mustache
similarity index 100%
rename from examples/array_of_partials_partial.2.html
rename to spec/_files/array_of_partials_partial.2.mustache
diff --git a/examples/array_of_partials_partial.js b/spec/_files/array_of_partials_partial.js
similarity index 100%
rename from examples/array_of_partials_partial.js
rename to spec/_files/array_of_partials_partial.js
diff --git a/examples/array_of_partials_partial.html b/spec/_files/array_of_partials_partial.mustache
similarity index 100%
rename from examples/array_of_partials_partial.html
rename to spec/_files/array_of_partials_partial.mustache
diff --git a/examples/array_of_partials_partial.txt b/spec/_files/array_of_partials_partial.txt
similarity index 100%
rename from examples/array_of_partials_partial.txt
rename to spec/_files/array_of_partials_partial.txt
diff --git a/examples/array_of_strings.js b/spec/_files/array_of_strings.js
similarity index 100%
rename from examples/array_of_strings.js
rename to spec/_files/array_of_strings.js
diff --git a/examples/array_of_strings.html b/spec/_files/array_of_strings.mustache
similarity index 100%
rename from examples/array_of_strings.html
rename to spec/_files/array_of_strings.mustache
diff --git a/examples/array_of_strings.txt b/spec/_files/array_of_strings.txt
similarity index 100%
rename from examples/array_of_strings.txt
rename to spec/_files/array_of_strings.txt
diff --git a/examples/array_of_strings_options.js b/spec/_files/array_of_strings_options.js
similarity index 100%
rename from examples/array_of_strings_options.js
rename to spec/_files/array_of_strings_options.js
diff --git a/examples/array_of_strings_options.html b/spec/_files/array_of_strings_options.mustache
similarity index 100%
rename from examples/array_of_strings_options.html
rename to spec/_files/array_of_strings_options.mustache
diff --git a/examples/array_of_strings_options.txt b/spec/_files/array_of_strings_options.txt
similarity index 100%
rename from examples/array_of_strings_options.txt
rename to spec/_files/array_of_strings_options.txt
diff --git a/examples/array_partial.2.html b/spec/_files/array_partial.2.mustache
similarity index 100%
rename from examples/array_partial.2.html
rename to spec/_files/array_partial.2.mustache
diff --git a/examples/array_partial.js b/spec/_files/array_partial.js
similarity index 100%
rename from examples/array_partial.js
rename to spec/_files/array_partial.js
diff --git a/examples/array_partial.html b/spec/_files/array_partial.mustache
similarity index 100%
rename from examples/array_partial.html
rename to spec/_files/array_partial.mustache
diff --git a/examples/array_partial.txt b/spec/_files/array_partial.txt
similarity index 100%
rename from examples/array_partial.txt
rename to spec/_files/array_partial.txt
diff --git a/examples/bug_11_eating_whitespace.js b/spec/_files/bug_11_eating_whitespace.js
similarity index 100%
rename from examples/bug_11_eating_whitespace.js
rename to spec/_files/bug_11_eating_whitespace.js
diff --git a/examples/bug_11_eating_whitespace.html b/spec/_files/bug_11_eating_whitespace.mustache
similarity index 100%
rename from examples/bug_11_eating_whitespace.html
rename to spec/_files/bug_11_eating_whitespace.mustache
diff --git a/examples/bug_11_eating_whitespace.txt b/spec/_files/bug_11_eating_whitespace.txt
similarity index 100%
rename from examples/bug_11_eating_whitespace.txt
rename to spec/_files/bug_11_eating_whitespace.txt
diff --git a/examples/comments.js b/spec/_files/comments.js
similarity index 100%
rename from examples/comments.js
rename to spec/_files/comments.js
diff --git a/examples/comments.html b/spec/_files/comments.mustache
similarity index 100%
rename from examples/comments.html
rename to spec/_files/comments.mustache
diff --git a/examples/comments.txt b/spec/_files/comments.txt
similarity index 100%
rename from examples/comments.txt
rename to spec/_files/comments.txt
diff --git a/examples/complex.js b/spec/_files/complex.js
similarity index 100%
rename from examples/complex.js
rename to spec/_files/complex.js
diff --git a/examples/complex.html b/spec/_files/complex.mustache
similarity index 100%
rename from examples/complex.html
rename to spec/_files/complex.mustache
diff --git a/examples/complex.txt b/spec/_files/complex.txt
similarity index 100%
rename from examples/complex.txt
rename to spec/_files/complex.txt
diff --git a/examples/delimiters.js b/spec/_files/delimiters.js
similarity index 100%
rename from examples/delimiters.js
rename to spec/_files/delimiters.js
diff --git a/examples/delimiters.html b/spec/_files/delimiters.mustache
similarity index 100%
rename from examples/delimiters.html
rename to spec/_files/delimiters.mustache
diff --git a/examples/delimiters.txt b/spec/_files/delimiters.txt
similarity index 100%
rename from examples/delimiters.txt
rename to spec/_files/delimiters.txt
diff --git a/spec/_files/dot_notation.js b/spec/_files/dot_notation.js
new file mode 100644
index 0000000..c1295f5
--- /dev/null
+++ b/spec/_files/dot_notation.js
@@ -0,0 +1,23 @@
+var dot_notation = {
+ name: "A Book",
+ authors: ["John Power", "Jamie Walsh"],
+ price:{
+ value: 200,
+ vat: function() {
+ return this.value * 0.2;
+ },
+ currency: {
+ symbol: '€',
+ name: 'Euro'
+ }
+ },
+ availability:{
+ status: true,
+ text: "In Stock"
+ },
+ // And now, some truthy false values
+ truthy: {
+ zero: 0,
+ notTrue: false
+ }
+};
diff --git a/spec/_files/dot_notation.mustache b/spec/_files/dot_notation.mustache
new file mode 100644
index 0000000..da1bad7
--- /dev/null
+++ b/spec/_files/dot_notation.mustache
@@ -0,0 +1,9 @@
+<!-- exciting part -->
+<h1>{{name}}</h1>
+<p>Authors: <ul>{{#authors}}<li>{{.}}</li>{{/authors}}</ul></p>
+<p>Price: {{price.currency.symbol}}{{price.value}} {{#price.currency}}{{name}} <b>{{availability.text}}</b>{{/price.currency}}</p>
+<p>VAT: {{price.currency.symbol}}{{price.vat}}</p>
+<!-- boring part -->
+<h2>Test truthy false values:</h2>
+<p>Zero: {{truthy.zero}}</p>
+<p>False: {{truthy.notTrue}}</p>
diff --git a/spec/_files/dot_notation.txt b/spec/_files/dot_notation.txt
new file mode 100644
index 0000000..d0e4707
--- /dev/null
+++ b/spec/_files/dot_notation.txt
@@ -0,0 +1,9 @@
+<!-- exciting part -->
+<h1>A Book</h1>
+<p>Authors: <ul><li>John Power</li><li>Jamie Walsh</li></ul></p>
+<p>Price: €200 Euro <b>In Stock</b></p>
+<p>VAT: €40</p>
+<!-- boring part -->
+<h2>Test truthy false values:</h2>
+<p>Zero: 0</p>
+<p>False: false</p>
diff --git a/spec/_files/double_render.js b/spec/_files/double_render.js
new file mode 100644
index 0000000..24125dc
--- /dev/null
+++ b/spec/_files/double_render.js
@@ -0,0 +1,5 @@
+var double_render = {
+ foo: true,
+ bar: "{{win}}",
+ win: "FAIL"
+};
\ No newline at end of file
diff --git a/spec/_files/double_render.mustache b/spec/_files/double_render.mustache
new file mode 100644
index 0000000..4500fd7
--- /dev/null
+++ b/spec/_files/double_render.mustache
@@ -0,0 +1 @@
+{{#foo}}{{bar}}{{/foo}}
diff --git a/spec/_files/double_render.txt b/spec/_files/double_render.txt
new file mode 100644
index 0000000..b6e652d
--- /dev/null
+++ b/spec/_files/double_render.txt
@@ -0,0 +1 @@
+{{win}}
diff --git a/examples/empty_partial.2.html b/spec/_files/empty_partial.2.mustache
similarity index 100%
rename from examples/empty_partial.2.html
rename to spec/_files/empty_partial.2.mustache
diff --git a/examples/empty_partial.js b/spec/_files/empty_partial.js
similarity index 100%
rename from examples/empty_partial.js
rename to spec/_files/empty_partial.js
diff --git a/examples/empty_partial.html b/spec/_files/empty_partial.mustache
similarity index 100%
rename from examples/empty_partial.html
rename to spec/_files/empty_partial.mustache
diff --git a/examples/empty_partial.txt b/spec/_files/empty_partial.txt
similarity index 100%
rename from examples/empty_partial.txt
rename to spec/_files/empty_partial.txt
diff --git a/spec/_files/empty_sections.js b/spec/_files/empty_sections.js
new file mode 100644
index 0000000..6e50514
--- /dev/null
+++ b/spec/_files/empty_sections.js
@@ -0,0 +1 @@
+var empty_sections = {};
diff --git a/spec/_files/empty_sections.mustache b/spec/_files/empty_sections.mustache
new file mode 100644
index 0000000..b6065db
--- /dev/null
+++ b/spec/_files/empty_sections.mustache
@@ -0,0 +1 @@
+{{#foo}}{{/foo}}foo{{#bar}}{{/bar}}
diff --git a/spec/_files/empty_sections.txt b/spec/_files/empty_sections.txt
new file mode 100644
index 0000000..257cc56
--- /dev/null
+++ b/spec/_files/empty_sections.txt
@@ -0,0 +1 @@
+foo
diff --git a/examples/empty_template.js b/spec/_files/empty_template.js
similarity index 100%
rename from examples/empty_template.js
rename to spec/_files/empty_template.js
diff --git a/examples/empty_template.html b/spec/_files/empty_template.mustache
similarity index 100%
rename from examples/empty_template.html
rename to spec/_files/empty_template.mustache
diff --git a/examples/empty_template.txt b/spec/_files/empty_template.txt
similarity index 100%
rename from examples/empty_template.txt
rename to spec/_files/empty_template.txt
diff --git a/examples/error_not_found.js b/spec/_files/error_not_found.js
similarity index 100%
rename from examples/error_not_found.js
rename to spec/_files/error_not_found.js
diff --git a/examples/error_not_found.html b/spec/_files/error_not_found.mustache
similarity index 100%
rename from examples/error_not_found.html
rename to spec/_files/error_not_found.mustache
diff --git a/examples/error_not_found.txt b/spec/_files/error_not_found.txt
similarity index 100%
copy from examples/error_not_found.txt
copy to spec/_files/error_not_found.txt
diff --git a/examples/escaped.js b/spec/_files/escaped.js
similarity index 100%
rename from examples/escaped.js
rename to spec/_files/escaped.js
diff --git a/examples/escaped.html b/spec/_files/escaped.mustache
similarity index 100%
rename from examples/escaped.html
rename to spec/_files/escaped.mustache
diff --git a/examples/escaped.txt b/spec/_files/escaped.txt
similarity index 100%
rename from examples/escaped.txt
rename to spec/_files/escaped.txt
diff --git a/examples/higher_order_sections.js b/spec/_files/higher_order_sections.js
similarity index 100%
rename from examples/higher_order_sections.js
rename to spec/_files/higher_order_sections.js
diff --git a/examples/higher_order_sections.html b/spec/_files/higher_order_sections.mustache
similarity index 100%
rename from examples/higher_order_sections.html
rename to spec/_files/higher_order_sections.mustache
diff --git a/examples/higher_order_sections.txt b/spec/_files/higher_order_sections.txt
similarity index 100%
rename from examples/higher_order_sections.txt
rename to spec/_files/higher_order_sections.txt
diff --git a/examples/inverted_section.js b/spec/_files/inverted_section.js
similarity index 100%
rename from examples/inverted_section.js
rename to spec/_files/inverted_section.js
diff --git a/examples/inverted_section.html b/spec/_files/inverted_section.mustache
similarity index 100%
rename from examples/inverted_section.html
rename to spec/_files/inverted_section.mustache
diff --git a/examples/inverted_section.txt b/spec/_files/inverted_section.txt
similarity index 100%
rename from examples/inverted_section.txt
rename to spec/_files/inverted_section.txt
diff --git a/spec/_files/keys_with_questionmarks.js b/spec/_files/keys_with_questionmarks.js
new file mode 100644
index 0000000..55a220d
--- /dev/null
+++ b/spec/_files/keys_with_questionmarks.js
@@ -0,0 +1,5 @@
+var keys_with_questionmarks = {
+ "person?": {
+ name: "Jon"
+ }
+}
diff --git a/spec/_files/keys_with_questionmarks.mustache b/spec/_files/keys_with_questionmarks.mustache
new file mode 100644
index 0000000..417f17f
--- /dev/null
+++ b/spec/_files/keys_with_questionmarks.mustache
@@ -0,0 +1,3 @@
+{{#person?}}
+ Hi {{name}}!
+{{/person?}}
diff --git a/spec/_files/keys_with_questionmarks.txt b/spec/_files/keys_with_questionmarks.txt
new file mode 100644
index 0000000..0f69b94
--- /dev/null
+++ b/spec/_files/keys_with_questionmarks.txt
@@ -0,0 +1 @@
+ Hi Jon!
diff --git a/spec/_files/nesting.js b/spec/_files/nesting.js
new file mode 100644
index 0000000..1f76cd0
--- /dev/null
+++ b/spec/_files/nesting.js
@@ -0,0 +1,7 @@
+var nesting = {
+ foo: [
+ {a: {b: 1}},
+ {a: {b: 2}},
+ {a: {b: 3}}
+ ]
+};
diff --git a/spec/_files/nesting.mustache b/spec/_files/nesting.mustache
new file mode 100644
index 0000000..551366d
--- /dev/null
+++ b/spec/_files/nesting.mustache
@@ -0,0 +1,5 @@
+{{#foo}}
+ {{#a}}
+ {{b}}
+ {{/a}}
+{{/foo}}
diff --git a/spec/_files/nesting.txt b/spec/_files/nesting.txt
new file mode 100644
index 0000000..caf5afd
--- /dev/null
+++ b/spec/_files/nesting.txt
@@ -0,0 +1,4 @@
+ 1
+ 2
+ 3
+
diff --git a/examples/null_string.js b/spec/_files/null_string.js
similarity index 100%
rename from examples/null_string.js
rename to spec/_files/null_string.js
diff --git a/examples/null_string.html b/spec/_files/null_string.mustache
similarity index 100%
rename from examples/null_string.html
rename to spec/_files/null_string.mustache
diff --git a/examples/null_string.txt b/spec/_files/null_string.txt
similarity index 100%
rename from examples/null_string.txt
rename to spec/_files/null_string.txt
diff --git a/examples/partial_recursion.2.html b/spec/_files/partial_recursion.2.mustache
similarity index 100%
rename from examples/partial_recursion.2.html
rename to spec/_files/partial_recursion.2.mustache
diff --git a/examples/partial_recursion.js b/spec/_files/partial_recursion.js
similarity index 100%
rename from examples/partial_recursion.js
rename to spec/_files/partial_recursion.js
diff --git a/examples/partial_recursion.html b/spec/_files/partial_recursion.mustache
similarity index 100%
rename from examples/partial_recursion.html
rename to spec/_files/partial_recursion.mustache
diff --git a/examples/partial_recursion.txt b/spec/_files/partial_recursion.txt
similarity index 100%
rename from examples/partial_recursion.txt
rename to spec/_files/partial_recursion.txt
diff --git a/examples/recursion_with_same_names.js b/spec/_files/recursion_with_same_names.js
similarity index 100%
rename from examples/recursion_with_same_names.js
rename to spec/_files/recursion_with_same_names.js
diff --git a/examples/recursion_with_same_names.html b/spec/_files/recursion_with_same_names.mustache
similarity index 100%
rename from examples/recursion_with_same_names.html
rename to spec/_files/recursion_with_same_names.mustache
diff --git a/examples/recursion_with_same_names.txt b/spec/_files/recursion_with_same_names.txt
similarity index 100%
rename from examples/recursion_with_same_names.txt
rename to spec/_files/recursion_with_same_names.txt
diff --git a/examples/reuse_of_enumerables.js b/spec/_files/reuse_of_enumerables.js
similarity index 100%
rename from examples/reuse_of_enumerables.js
rename to spec/_files/reuse_of_enumerables.js
diff --git a/examples/reuse_of_enumerables.html b/spec/_files/reuse_of_enumerables.mustache
similarity index 100%
rename from examples/reuse_of_enumerables.html
rename to spec/_files/reuse_of_enumerables.mustache
diff --git a/examples/reuse_of_enumerables.txt b/spec/_files/reuse_of_enumerables.txt
similarity index 100%
rename from examples/reuse_of_enumerables.txt
rename to spec/_files/reuse_of_enumerables.txt
diff --git a/examples/section_as_context.js b/spec/_files/section_as_context.js
similarity index 100%
rename from examples/section_as_context.js
rename to spec/_files/section_as_context.js
diff --git a/examples/section_as_context.html b/spec/_files/section_as_context.mustache
similarity index 100%
rename from examples/section_as_context.html
rename to spec/_files/section_as_context.mustache
diff --git a/examples/section_as_context.txt b/spec/_files/section_as_context.txt
similarity index 100%
rename from examples/section_as_context.txt
rename to spec/_files/section_as_context.txt
diff --git a/examples/simple.js b/spec/_files/simple.js
similarity index 100%
rename from examples/simple.js
rename to spec/_files/simple.js
diff --git a/examples/simple.html b/spec/_files/simple.mustache
similarity index 100%
rename from examples/simple.html
rename to spec/_files/simple.mustache
diff --git a/examples/simple.txt b/spec/_files/simple.txt
similarity index 100%
rename from examples/simple.txt
rename to spec/_files/simple.txt
diff --git a/examples/template_partial.2.html b/spec/_files/template_partial.2.mustache
similarity index 100%
rename from examples/template_partial.2.html
rename to spec/_files/template_partial.2.mustache
diff --git a/examples/template_partial.js b/spec/_files/template_partial.js
similarity index 100%
rename from examples/template_partial.js
rename to spec/_files/template_partial.js
diff --git a/examples/template_partial.html b/spec/_files/template_partial.mustache
similarity index 100%
rename from examples/template_partial.html
rename to spec/_files/template_partial.mustache
diff --git a/examples/template_partial.txt b/spec/_files/template_partial.txt
similarity index 100%
rename from examples/template_partial.txt
rename to spec/_files/template_partial.txt
diff --git a/examples/two_in_a_row.js b/spec/_files/two_in_a_row.js
similarity index 100%
rename from examples/two_in_a_row.js
rename to spec/_files/two_in_a_row.js
diff --git a/examples/two_in_a_row.html b/spec/_files/two_in_a_row.mustache
similarity index 100%
rename from examples/two_in_a_row.html
rename to spec/_files/two_in_a_row.mustache
diff --git a/examples/two_in_a_row.txt b/spec/_files/two_in_a_row.txt
similarity index 100%
rename from examples/two_in_a_row.txt
rename to spec/_files/two_in_a_row.txt
diff --git a/spec/_files/two_sections.js b/spec/_files/two_sections.js
new file mode 100644
index 0000000..8546f64
--- /dev/null
+++ b/spec/_files/two_sections.js
@@ -0,0 +1 @@
+var two_sections = {};
\ No newline at end of file
diff --git a/spec/_files/two_sections.mustache b/spec/_files/two_sections.mustache
new file mode 100644
index 0000000..a4b9f2a
--- /dev/null
+++ b/spec/_files/two_sections.mustache
@@ -0,0 +1,4 @@
+{{#foo}}
+{{/foo}}
+{{#bar}}
+{{/bar}}
diff --git a/examples/error_not_found.txt b/spec/_files/two_sections.txt
similarity index 100%
rename from examples/error_not_found.txt
rename to spec/_files/two_sections.txt
diff --git a/examples/unescaped.js b/spec/_files/unescaped.js
similarity index 100%
rename from examples/unescaped.js
rename to spec/_files/unescaped.js
diff --git a/examples/unescaped.html b/spec/_files/unescaped.mustache
similarity index 100%
rename from examples/unescaped.html
rename to spec/_files/unescaped.mustache
diff --git a/examples/unescaped.txt b/spec/_files/unescaped.txt
similarity index 100%
rename from examples/unescaped.txt
rename to spec/_files/unescaped.txt
diff --git a/examples/unknown_pragma.js b/spec/_files/unknown_pragma.js
similarity index 100%
rename from examples/unknown_pragma.js
rename to spec/_files/unknown_pragma.js
diff --git a/examples/unknown_pragma.html b/spec/_files/unknown_pragma.mustache
similarity index 100%
rename from examples/unknown_pragma.html
rename to spec/_files/unknown_pragma.mustache
diff --git a/examples/unknown_pragma.txt b/spec/_files/unknown_pragma.txt
similarity index 100%
rename from examples/unknown_pragma.txt
rename to spec/_files/unknown_pragma.txt
diff --git a/examples/view_partial.2.html b/spec/_files/view_partial.2.mustache
similarity index 100%
rename from examples/view_partial.2.html
rename to spec/_files/view_partial.2.mustache
diff --git a/examples/view_partial.js b/spec/_files/view_partial.js
similarity index 100%
rename from examples/view_partial.js
rename to spec/_files/view_partial.js
diff --git a/examples/view_partial.html b/spec/_files/view_partial.mustache
similarity index 100%
rename from examples/view_partial.html
rename to spec/_files/view_partial.mustache
diff --git a/examples/view_partial.txt b/spec/_files/view_partial.txt
similarity index 100%
rename from examples/view_partial.txt
rename to spec/_files/view_partial.txt
diff --git a/examples/whitespace_partial.2.html b/spec/_files/whitespace_partial.2.mustache
similarity index 100%
rename from examples/whitespace_partial.2.html
rename to spec/_files/whitespace_partial.2.mustache
diff --git a/examples/whitespace_partial.js b/spec/_files/whitespace_partial.js
similarity index 100%
rename from examples/whitespace_partial.js
rename to spec/_files/whitespace_partial.js
diff --git a/examples/whitespace_partial.html b/spec/_files/whitespace_partial.mustache
similarity index 100%
rename from examples/whitespace_partial.html
rename to spec/_files/whitespace_partial.mustache
diff --git a/examples/whitespace_partial.txt b/spec/_files/whitespace_partial.txt
similarity index 100%
rename from examples/whitespace_partial.txt
rename to spec/_files/whitespace_partial.txt
diff --git a/spec/mustache_spec.rb b/spec/mustache_spec.rb
new file mode 100644
index 0000000..e04bec1
--- /dev/null
+++ b/spec/mustache_spec.rb
@@ -0,0 +1,276 @@
+require 'rubygems'
+require 'json'
+
+ROOT = File.expand_path('../..', __FILE__)
+SPEC = File.join(ROOT, 'spec')
+FILES = File.join(SPEC, '_files')
+
+MUSTACHE = File.read(File.join(ROOT, "mustache.js"))
+
+TESTS = Dir.glob(File.join(FILES, '*.js')).map do |name|
+ File.basename name, '.js'
+end
+
+PARTIALS = TESTS.select {|t| t.include? "partial" }
+NON_PARTIALS = TESTS.select {|t| not t.include? "partial" }
+
+NODE_PATH = `which node`.strip
+JS_PATH = `which js`.strip
+JSC_PATH = "/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc"
+RHINO_JAR = "org.mozilla.javascript.tools.shell.Main"
+
+def load_test(name, is_partial=false)
+ view = File.read(File.join(FILES, "#{name}.js"))
+ template = File.read(File.join(FILES, "#{name}.mustache")).to_json
+ expect = File.read(File.join(FILES, "#{name}.txt"))
+
+ test = [view, template, expect]
+
+ if is_partial
+ test << File.read(File.join(FILES, "#{name}.2.mustache")).to_json
+ end
+
+ test
+end
+
+def run_js(runner, js)
+ cmd = case runner
+ when :spidermonkey
+ JS_PATH
+ when :jsc
+ JSC_PATH
+ when :rhino
+ "java #{RHINO_JAR}"
+ when :node
+ NODE_PATH
+ end
+
+ runner_file = "runner.js"
+ File.open(runner_file, 'w') {|file| file.write(js) }
+ `#{cmd} #{runner_file}`
+ensure
+ FileUtils.rm_r(runner_file)
+end
+
+$engines_run = 0
+
+describe "mustache" do
+ shared_examples_for "mustache rendering" do
+ before(:all) do
+ $engines_run += 1
+ end
+
+ it "should return the same when invoked multiple times" do
+ js = <<-JS
+ #{@boilerplate}
+ Mustache.to_html("x")
+ print(Mustache.to_html("x"));
+ JS
+
+ run_js(@runner, js).should == "x\n"
+ end
+
+ it "should clear the context after each run" do
+ js = <<-JS
+ #{@boilerplate}
+ Mustache.to_html("{{#list}}{{x}}{{/list}}", {list: [{x: 1}]})
+ try {
+ print(Mustache.to_html("{{#list}}{{x}}{{/list}}", {list: [{}]}));
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+
+ run_js(@runner, js).should == "\n"
+ end
+
+ NON_PARTIALS.each do |test|
+ describe test do
+ it "should generate the correct html" do
+ view, template, expect = load_test(test)
+
+ js = <<-JS
+ try {
+ #{@boilerplate}
+ #{view}
+ var template = #{template};
+ var result = Mustache.to_html(template, #{test});
+ print(result);
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+
+ run_js(@runner, js).should == expect
+ end
+
+ it "should sendFun the correct html" do
+ view, template, expect = load_test(test)
+
+ js = <<-JS
+ try {
+ #{@boilerplate}
+ #{view}
+ var chunks = [];
+ var sendFun = function(chunk) {
+ if (chunk != "") {
+ chunks.push(chunk);
+ }
+ }
+ var template = #{template};
+ Mustache.to_html(template, #{test}, null, sendFun);
+ print(chunks.join("\\n"));
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+
+ run_js(@runner, js).strip.should == expect.strip
+ end
+ end
+ end
+
+ PARTIALS.each do |test|
+ describe test do
+ it "should generate the correct html" do
+ view, template, expect, partial = load_test(test, true)
+
+ js = <<-JS
+ try {
+ #{@boilerplate}
+ #{view}
+ var template = #{template};
+ var partials = {"partial": #{partial}};
+ var result = Mustache.to_html(template, partial_context, partials);
+ print(result);
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+
+ run_js(@runner, js).should == expect
+ end
+
+ it "should sendFun the correct html" do
+ view, template, expect, partial = load_test(test, true)
+
+ js = <<-JS
+ try {
+ #{@boilerplate}
+ #{view};
+ var template = #{template};
+ var partials = {"partial": #{partial}};
+ var chunks = [];
+ var sendFun = function(chunk) {
+ if (chunk != "") {
+ chunks.push(chunk);
+ }
+ }
+ Mustache.to_html(template, partial_context, partials, sendFun);
+ print(chunks.join("\\n"));
+ } catch(e) {
+ print('ERROR: ' + e.message);
+ }
+ JS
+
+ run_js(@runner, js).strip.should == expect.strip
+ end
+ end
+ end
+ end
+
+ context "running in node" do
+ if File.exist?(NODE_PATH)
+ before(:all) do
+ $stdout.write "Testing in node "
+ @runner = :node
+ @boilerplate = MUSTACHE.dup
+ @boilerplate << <<-JS
+ function print(message) {
+ console.log(message);
+ }
+ JS
+ end
+
+ after(:all) do
+ puts " Done!"
+ end
+
+ it_should_behave_like "mustache rendering"
+ else
+ puts "Skipping tests in node (node not found)"
+ end
+ end
+
+ context "running in SpiderMonkey (Mozilla, Firefox)" do
+ if File.exist?(JS_PATH)
+ before(:all) do
+ $stdout.write "Testing in SpiderMonkey "
+ @runner = :spidermonkey
+ @boilerplate = MUSTACHE.dup
+ end
+
+ after(:all) do
+ puts " Done!"
+ end
+
+ it_should_behave_like "mustache rendering"
+ else
+ puts "Skipping tests in SpiderMonkey (js not found)"
+ end
+ end
+
+ context "running in JavaScriptCore (WebKit, Safari)" do
+ if File.exist?(JSC_PATH)
+ before(:all) do
+ $stdout.write "Testing in JavaScriptCore "
+ @runner = :jsc
+ @boilerplate = MUSTACHE.dup
+ end
+
+ after(:all) do
+ puts " Done!"
+ end
+
+ it_should_behave_like "mustache rendering"
+ else
+ puts "Skipping tests in JavaScriptCore (jsc not found)"
+ end
+ end
+
+ context "running in Rhino (Mozilla, Java)" do
+ if `java #{RHINO_JAR} 'foo' 2>&1` !~ /ClassNotFoundException/
+ before(:all) do
+ $stdout.write "Testing in Rhino "
+ @runner = :rhino
+ @boilerplate = MUSTACHE.dup
+ end
+
+ after(:all) do
+ puts " Done!"
+ end
+
+ it_should_behave_like "mustache rendering"
+ else
+ puts "Skipping tests in Rhino (JAR #{RHINO_JAR} was not found)"
+ end
+ end
+
+ context "suite" do
+ before(:each) do
+ $stdout.write "Verifying that we ran at the tests in at least one engine ... "
+ end
+
+ after(:each) do
+ if @exception.nil?
+ puts "OK"
+ else
+ puts "ERROR!"
+ end
+ end
+
+ it "should have run at least one time" do
+ $engines_run.should > 0
+ end
+ end
+end
diff --git a/test/mustache_spec.rb b/test/mustache_spec.rb
deleted file mode 100644
index 9ede6c8..0000000
--- a/test/mustache_spec.rb
+++ /dev/null
@@ -1,156 +0,0 @@
-require 'rubygems'
-require 'json'
-
-__DIR__ = File.dirname(__FILE__)
-
-testnames = Dir.glob(__DIR__ + '/../examples/*.js').map do |name|
- File.basename name, '.js'
-end
-
-non_partials = testnames.select{|t| not t.include? "partial"}
-partials = testnames.select{|t| t.include? "partial"}
-
-def load_test(dir, name, partial=false)
- view = File.read(dir + "/../examples/#{name}.js")
- template = File.read(dir + "/../examples/#{name}.html").to_json
- expect = File.read(dir + "/../examples/#{name}.txt")
- if not partial
- [view, template, expect]
- else
- partial = File.read(dir + "/../examples/#{name}.2.html").to_json
- [view, template, partial, expect]
- end
-end
-
-describe "mustache" do
- before(:all) do
- @mustache = File.read(__DIR__ + "/../mustache.js")
- end
-
- it "should return the same when invoked multiple times" do
- js = <<-JS
- #{@mustache}
- Mustache.to_html("x")
- print(Mustache.to_html("x"));
- JS
- run_js(js).should == "x\n"
-
- end
-
- it "should clear the context after each run" do
- js = <<-JS
- #{@mustache}
- Mustache.to_html("{{#list}}{{x}}{{/list}}", {list: [{x: 1}]})
- try {
- print(Mustache.to_html("{{#list}}{{x}}{{/list}}", {list: [{}]}));
- } catch(e) {
- print('ERROR: ' + e.message);
- }
- JS
- run_js(js).should == "\n"
- end
-
- non_partials.each do |testname|
- describe testname do
- it "should generate the correct html" do
-
- view, template, expect = load_test(__DIR__, testname)
-
- runner = <<-JS
- try {
- #{@mustache}
- #{view}
- var template = #{template};
- var result = Mustache.to_html(template, #{testname});
- print(result);
- } catch(e) {
- print('ERROR: ' + e.message);
- }
- JS
-
- run_js(runner).should == expect
- end
- it "should sendFun the correct html" do
-
- view, template, expect = load_test(__DIR__, testname)
-
- runner = <<-JS
- try {
- #{@mustache}
- #{view}
- var chunks = [];
- var sendFun = function(chunk) {
- if (chunk != "") {
- chunks.push(chunk);
- }
- }
- var template = #{template};
- Mustache.to_html(template, #{testname}, null, sendFun);
- print(chunks.join("\\n"));
- } catch(e) {
- print('ERROR: ' + e.message);
- }
- JS
-
- run_js(runner).strip.should == expect.strip
- end
- end
- end
-
- partials.each do |testname|
- describe testname do
- it "should generate the correct html" do
-
- view, template, partial, expect =
- load_test(__DIR__, testname, true)
-
- runner = <<-JS
- try {
- #{@mustache}
- #{view}
- var template = #{template};
- var partials = {"partial": #{partial}};
- var result = Mustache.to_html(template, partial_context, partials);
- print(result);
- } catch(e) {
- print('ERROR: ' + e.message);
- }
- JS
-
- run_js(runner).should == expect
- end
- it "should sendFun the correct html" do
-
- view, template, partial, expect =
- load_test(__DIR__, testname, true)
-
- runner = <<-JS
- try {
- #{@mustache}
- #{view};
- var template = #{template};
- var partials = {"partial": #{partial}};
- var chunks = [];
- var sendFun = function(chunk) {
- if (chunk != "") {
- chunks.push(chunk);
- }
- }
- Mustache.to_html(template, partial_context, partials, sendFun);
- print(chunks.join("\\n"));
- } catch(e) {
- print('ERROR: ' + e.message);
- }
- JS
-
- run_js(runner).strip.should == expect.strip
- end
- end
- end
-
- def run_js(js)
- File.open("runner.js", 'w') {|f| f << js}
- `js runner.js`
- end
-end
-
diff --git a/wrappers/commonjs/mustache.js.tpl.post b/wrappers/commonjs/mustache.js.tpl.post
new file mode 100644
index 0000000..f566443
--- /dev/null
+++ b/wrappers/commonjs/mustache.js.tpl.post
@@ -0,0 +1,8 @@
+if (typeof module !== 'undefined' && module.exports) {
+ exports.name = Mustache.name;
+ exports.version = Mustache.version;
+
+ exports.to_html = function() {
+ return Mustache.to_html.apply(this, arguments);
+ };
+}
diff --git a/mustache-commonjs/mustache.js.tpl.pre b/wrappers/commonjs/mustache.js.tpl.pre
similarity index 100%
rename from mustache-commonjs/mustache.js.tpl.pre
rename to wrappers/commonjs/mustache.js.tpl.pre
diff --git a/wrappers/commonjs/package.json b/wrappers/commonjs/package.json
new file mode 100644
index 0000000..8e13993
--- /dev/null
+++ b/wrappers/commonjs/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "mustache",
+ "author": "http://mustache.github.com/",
+ "description": "Logic-less {{mustache}} templates with JavaScript",
+ "keywords": ["template", "templates", "mustache"],
+ "version": "{{version}}",
+ "main": "./mustache"
+}
diff --git a/wrappers/dojo/mustache.js.tpl.post b/wrappers/dojo/mustache.js.tpl.post
new file mode 100644
index 0000000..d64667f
--- /dev/null
+++ b/wrappers/dojo/mustache.js.tpl.post
@@ -0,0 +1,4 @@
+
+ dojox.mustache = dojo.hitch(Mustache, "to_html");
+
+})();
\ No newline at end of file
diff --git a/mustache-dojo/mustache.js.tpl.pre b/wrappers/dojo/mustache.js.tpl.pre
similarity index 71%
rename from mustache-dojo/mustache.js.tpl.pre
rename to wrappers/dojo/mustache.js.tpl.pre
index ac9a308..f87f3cd 100644
--- a/mustache-dojo/mustache.js.tpl.pre
+++ b/wrappers/dojo/mustache.js.tpl.pre
@@ -5,5 +5,5 @@ Shameless port of a shameless port
See http://github.com/defunkt/mustache for more info.
*/
-dojo.provide("dojox.string.mustache");
-;(function(d) {
+dojo.provide("dojox.mustache._base");
+(function(){
diff --git a/mustache-jquery/jquery.mustache.js.tpl.post b/wrappers/jquery/jquery.mustache.js.tpl.post
similarity index 100%
rename from mustache-jquery/jquery.mustache.js.tpl.post
rename to wrappers/jquery/jquery.mustache.js.tpl.post
diff --git a/mustache-jquery/jquery.mustache.js.tpl.pre b/wrappers/jquery/jquery.mustache.js.tpl.pre
similarity index 100%
rename from mustache-jquery/jquery.mustache.js.tpl.pre
rename to wrappers/jquery/jquery.mustache.js.tpl.pre
diff --git a/wrappers/qooxdoo/qooxdoo.mustache.js.tpl.post b/wrappers/qooxdoo/qooxdoo.mustache.js.tpl.post
new file mode 100644
index 0000000..e66f9e6
--- /dev/null
+++ b/wrappers/qooxdoo/qooxdoo.mustache.js.tpl.post
@@ -0,0 +1,9 @@
+/**
+ * Above is the original mustache code.
+ */
+
+// EXPOSE qooxdoo variant
+qx.bom.Template.version = Mustache.version;
+qx.bom.Template.toHtml = Mustache.to_html;
+
+})();
diff --git a/wrappers/qooxdoo/qooxdoo.mustache.js.tpl.pre b/wrappers/qooxdoo/qooxdoo.mustache.js.tpl.pre
new file mode 100644
index 0000000..a70d0a4
--- /dev/null
+++ b/wrappers/qooxdoo/qooxdoo.mustache.js.tpl.pre
@@ -0,0 +1,127 @@
+/* ************************************************************************
+
+ qooxdoo - the new era of web development
+
+ http://qooxdoo.org
+
+ Copyright:
+ 2004-2011 1&1 Internet AG, Germany, http://www.1und1.de
+
+ License:
+ LGPL: http://www.gnu.org/licenses/lgpl.html
+ EPL: http://www.eclipse.org/org/documents/epl-v10.php
+ See the LICENSE file in the project's top-level directory for details.
+
+ Authors:
+ * Martin Wittemann (martinwittemann)
+
+ ======================================================================
+
+ This class contains code based on the following work:
+
+ * Mustache.js version 0.4.0-dev
+
+ Code:
+ https://github.com/janl/mustache.js
+
+ Copyright:
+ (c) 2009 Chris Wanstrath (Ruby)
+ (c) 2010 Jan Lehnardt (JavaScript)
+
+ License:
+ MIT: http://www.opensource.org/licenses/mit-license.php
+
+ ----------------------------------------------------------------------
+
+ Copyright (c) 2009 Chris Wanstrath (Ruby)
+ Copyright (c) 2010 Jan Lehnardt (JavaScript)
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+************************************************************************ */
+
+/**
+ * The is a template class which can be used for HTML templating. In fact,
+ * this is a wrapper for mustache.js which is a "framework-agnostic way to
+ * render logic-free views".
+ *
+ * Here is a basic example how to use it:
+ * Template:
+ * <pre>
+ * var template = "Hi, my name is {{name}}!";
+ * var view = {name: "qooxdoo"};
+ * qx.bom.Template.toHtml(template, view);
+ * // return "Hi, my name is qooxdoo!"
+ * </pre>
+ *
+ * For further details, please visit the mustache.js documentation here:
+ * https://github.com/janl/mustache.js/blob/master/README.md
+ */
+qx.Class.define("qx.bom.Template", {
+ statics : {
+ /** Contains the mustache.js version. */
+ version: null,
+
+ /**
+ * Original and only template method of mustache.js. For further
+ * documentation, please visit https://github.com/janl/mustache.js
+ *
+ * @signature function(template, view, partials, send_fun)
+ * @param template {String} The String containing the template.
+ * @param view {Object} The object holding the data to render.
+ * @param partials {Object} Object holding parts of a template.
+ * @param send_fun {Function?} Callback function for streaming.
+ * @return {String} The parsed template.
+ */
+ toHtml: null,
+
+
+ /**
+ * Helper method which provides you with a direct access to templates
+ * stored as HTML in the DOM. The DOM node with the given ID will be reated
+ * as a template, parsed and a new DOM node will be returned containing the
+ * parsed data.
+ *
+ * @param id {String} The id of the HTML template in the DOM.
+ * @param view {Object} The object holding the data to render.
+ * @param partials {Object} Object holding parts of a template.
+ * @return {DomNode} A DOM element holding the parsed template data.
+ */
+ get : function(id, view, partials) {
+ var template = document.getElementById(id);
+ var inner = template.innerHTML;
+
+ inner = this.toHtml(inner, view, partials);
+
+ var helper = qx.bom.Element.create("div");
+ helper.innerHTML = inner;
+
+ return helper.children[0];
+ }
+ }
+});
+
+(function() {
+
+/**
+ * Below is the original mustache.js code. Snapshot date is mentioned in
+ * the head of this file.
+ */
+
\ No newline at end of file
diff --git a/wrappers/requirejs/requirejs.mustache.js.tpl.post b/wrappers/requirejs/requirejs.mustache.js.tpl.post
new file mode 100644
index 0000000..632fd2a
--- /dev/null
+++ b/wrappers/requirejs/requirejs.mustache.js.tpl.post
@@ -0,0 +1,3 @@
+
+return Mustache;
+});
\ No newline at end of file
diff --git a/wrappers/requirejs/requirejs.mustache.js.tpl.pre b/wrappers/requirejs/requirejs.mustache.js.tpl.pre
new file mode 100644
index 0000000..160286d
--- /dev/null
+++ b/wrappers/requirejs/requirejs.mustache.js.tpl.pre
@@ -0,0 +1,6 @@
+/*
+Shameless port of a shameless port ^ 2
+ at defunkt => @janl => @aq => @voodootikigod => @timruffles
+
+*/
+define(function(){
diff --git a/mustache-yui3/mustache.js.tpl.post b/wrappers/yui3/mustache.js.tpl.post
similarity index 100%
rename from mustache-yui3/mustache.js.tpl.post
rename to wrappers/yui3/mustache.js.tpl.post
diff --git a/mustache-yui3/mustache.js.tpl.pre b/wrappers/yui3/mustache.js.tpl.pre
similarity index 100%
rename from mustache-yui3/mustache.js.tpl.pre
rename to wrappers/yui3/mustache.js.tpl.pre
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/mustache.js.git
More information about the Pkg-javascript-commits
mailing list