mirror of
https://github.com/zulip/zulip.git
synced 2025-11-09 16:37:23 +00:00
Upgrade handlebars to 1.3.0.
This was "npm update handlebars" followed by copying runtime.js into the static directory and restoring the copyright header. (imported from commit 69d30cbfcb3b776cdfdcffa17a87704540eab76a)
This commit is contained in:
52
node_modules/handlebars/.jshintrc
generated
vendored
52
node_modules/handlebars/.jshintrc
generated
vendored
@@ -1,52 +0,0 @@
|
|||||||
{
|
|
||||||
"predef": [
|
|
||||||
"console",
|
|
||||||
"Ember",
|
|
||||||
"DS",
|
|
||||||
"Handlebars",
|
|
||||||
"Metamorph",
|
|
||||||
"ember_assert",
|
|
||||||
"ember_warn",
|
|
||||||
"ember_deprecate",
|
|
||||||
"ember_deprecateFunc",
|
|
||||||
"require",
|
|
||||||
"suite",
|
|
||||||
"equal",
|
|
||||||
"equals",
|
|
||||||
"test",
|
|
||||||
"testBoth",
|
|
||||||
"raises",
|
|
||||||
"deepEqual",
|
|
||||||
"start",
|
|
||||||
"stop",
|
|
||||||
"ok",
|
|
||||||
"strictEqual",
|
|
||||||
"module"
|
|
||||||
],
|
|
||||||
|
|
||||||
"node" : true,
|
|
||||||
"es5" : true,
|
|
||||||
"browser" : true,
|
|
||||||
|
|
||||||
"boss" : true,
|
|
||||||
"curly": false,
|
|
||||||
"debug": false,
|
|
||||||
"devel": false,
|
|
||||||
"eqeqeq": true,
|
|
||||||
"evil": true,
|
|
||||||
"forin": false,
|
|
||||||
"immed": false,
|
|
||||||
"laxbreak": false,
|
|
||||||
"newcap": true,
|
|
||||||
"noarg": true,
|
|
||||||
"noempty": false,
|
|
||||||
"nonew": false,
|
|
||||||
"nomen": false,
|
|
||||||
"onevar": false,
|
|
||||||
"plusplus": false,
|
|
||||||
"regexp": false,
|
|
||||||
"undef": true,
|
|
||||||
"sub": true,
|
|
||||||
"strict": false,
|
|
||||||
"white": false
|
|
||||||
}
|
|
||||||
13
node_modules/handlebars/.npmignore
generated
vendored
13
node_modules/handlebars/.npmignore
generated
vendored
@@ -1,10 +1,23 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.gitignore
|
.gitignore
|
||||||
.rvmrc
|
.rvmrc
|
||||||
|
.jshintrc
|
||||||
|
.travis.yml
|
||||||
|
.rspec
|
||||||
Gemfile
|
Gemfile
|
||||||
Gemfile.lock
|
Gemfile.lock
|
||||||
Rakefile
|
Rakefile
|
||||||
|
Gruntfile.js
|
||||||
|
*.gemspec
|
||||||
|
*.nuspec
|
||||||
bench/*
|
bench/*
|
||||||
|
configurations/*
|
||||||
|
components/*
|
||||||
|
dist/cdnjs/*
|
||||||
|
dist/components/*
|
||||||
spec/*
|
spec/*
|
||||||
src/*
|
src/*
|
||||||
|
tasks/*
|
||||||
|
tmp/*
|
||||||
|
publish/*
|
||||||
vendor/*
|
vendor/*
|
||||||
|
|||||||
1
node_modules/handlebars/.rspec
generated
vendored
1
node_modules/handlebars/.rspec
generated
vendored
@@ -1 +0,0 @@
|
|||||||
-cfs
|
|
||||||
203
node_modules/handlebars/README.markdown
generated
vendored
203
node_modules/handlebars/README.markdown
generated
vendored
@@ -1,4 +1,5 @@
|
|||||||
[](https://travis-ci.org/wycats/handlebars.js)
|
[](https://travis-ci.org/wycats/handlebars.js)
|
||||||
|
[](https://saucelabs.com/u/handlebars)
|
||||||
|
|
||||||
Handlebars.js
|
Handlebars.js
|
||||||
=============
|
=============
|
||||||
@@ -11,12 +12,20 @@ keep the view and the code separated like we all know they should be.
|
|||||||
Checkout the official Handlebars docs site at
|
Checkout the official Handlebars docs site at
|
||||||
[http://www.handlebarsjs.com](http://www.handlebarsjs.com).
|
[http://www.handlebarsjs.com](http://www.handlebarsjs.com).
|
||||||
|
|
||||||
|
|
||||||
Installing
|
Installing
|
||||||
----------
|
----------
|
||||||
Installing Handlebars is easy. Simply download the package [from the
|
Installing Handlebars is easy. Simply download the package [from the official site](http://handlebarsjs.com/) or the [bower repository][bower-repo] and add it to your web pages (you should usually use the most recent version).
|
||||||
official site](http://handlebarsjs.com/) and add it to your web pages
|
|
||||||
(you should usually use the most recent version).
|
Alternatively, if you prefer having the latest version of handlebars from
|
||||||
|
the 'master' branch, passing builds of the 'master' branch are automatically
|
||||||
|
published to S3. You may download the latest passing master build by grabbing
|
||||||
|
a `handlebars-latest.js` file from the [builds page][builds-page]. When the
|
||||||
|
build is published, it is also available as a `handlebars-gitSHA.js` file on
|
||||||
|
the builds page if you need a version to refer to others.
|
||||||
|
`handlebars-runtime.js` builds are also available.
|
||||||
|
|
||||||
|
**Note**: The S3 builds page is provided as a convenience for the community,
|
||||||
|
but you should not use it for hosting Handlebars in production.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
-----
|
-----
|
||||||
@@ -24,7 +33,7 @@ In general, the syntax of Handlebars.js templates is a superset
|
|||||||
of Mustache templates. For basic syntax, check out the [Mustache
|
of Mustache templates. For basic syntax, check out the [Mustache
|
||||||
manpage](http://mustache.github.com/mustache.5.html).
|
manpage](http://mustache.github.com/mustache.5.html).
|
||||||
|
|
||||||
Once you have a template, use the Handlebars.compile method to compile
|
Once you have a template, use the `Handlebars.compile` method to compile
|
||||||
the template into a function. The generated function takes a context
|
the template into a function. The generated function takes a context
|
||||||
argument, which will be used to render the template.
|
argument, which will be used to render the template.
|
||||||
|
|
||||||
@@ -55,12 +64,12 @@ template. Here's an example, which assumes that your objects have a URL
|
|||||||
embedded in them, as well as the text for a link:
|
embedded in them, as well as the text for a link:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
Handlebars.registerHelper('link_to', function(context) {
|
Handlebars.registerHelper('link_to', function() {
|
||||||
return "<a href='" + context.url + "'>" + context.body + "</a>";
|
return "<a href='" + this.url + "'>" + this.body + "</a>";
|
||||||
});
|
});
|
||||||
|
|
||||||
var context = { posts: [{url: "/hello-world", body: "Hello World!"}] };
|
var context = { posts: [{url: "/hello-world", body: "Hello World!"}] };
|
||||||
var source = "<ul>{{#posts}}<li>{{{link_to this}}}</li>{{/posts}}</ul>"
|
var source = "<ul>{{#posts}}<li>{{{link_to}}}</li>{{/posts}}</ul>"
|
||||||
|
|
||||||
var template = Handlebars.compile(source);
|
var template = Handlebars.compile(source);
|
||||||
template(context);
|
template(context);
|
||||||
@@ -72,6 +81,14 @@ template(context);
|
|||||||
// </ul>
|
// </ul>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Helpers take precedence over fields defined on the context. To access a field
|
||||||
|
that is masked by a helper, a path reference may be used. In the example above
|
||||||
|
a field named `link_to` on the `context` object would be referenced using:
|
||||||
|
|
||||||
|
```
|
||||||
|
{{./link_to}}
|
||||||
|
```
|
||||||
|
|
||||||
Escaping
|
Escaping
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@@ -93,17 +110,17 @@ templates easier and also changes a tiny detail of how partials work.
|
|||||||
Handlebars.js supports an extended expression syntax that we call paths.
|
Handlebars.js supports an extended expression syntax that we call paths.
|
||||||
Paths are made up of typical expressions and . characters. Expressions
|
Paths are made up of typical expressions and . characters. Expressions
|
||||||
allow you to not only display data from the current context, but to
|
allow you to not only display data from the current context, but to
|
||||||
display data from contexts that are descendents and ancestors of the
|
display data from contexts that are descendants and ancestors of the
|
||||||
current context.
|
current context.
|
||||||
|
|
||||||
To display data from descendent contexts, use the `.` character. So, for
|
To display data from descendant contexts, use the `.` character. So, for
|
||||||
example, if your data were structured like:
|
example, if your data were structured like:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var data = {"person": { "name": "Alan" }, company: {"name": "Rad, Inc." } };
|
var data = {"person": { "name": "Alan" }, "company": {"name": "Rad, Inc." } };
|
||||||
```
|
```
|
||||||
|
|
||||||
you could display the person's name from the top-level context with the
|
You could display the person's name from the top-level context with the
|
||||||
following expression:
|
following expression:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -130,12 +147,12 @@ When calling a helper, you can pass paths or Strings as parameters. For
|
|||||||
instance:
|
instance:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
Handlebars.registerHelper('link_to', function(title, context) {
|
Handlebars.registerHelper('link_to', function(title, options) {
|
||||||
return "<a href='/posts" + context.url + "'>" + title + "!</a>"
|
return "<a href='/posts" + this.url + "'>" + title + "!</a>"
|
||||||
});
|
});
|
||||||
|
|
||||||
var context = { posts: [{url: "/hello-world", body: "Hello World!"}] };
|
var context = { posts: [{url: "/hello-world", body: "Hello World!"}] };
|
||||||
var source = '<ul>{{#posts}}<li>{{{link_to "Post" this}}}</li>{{/posts}}</ul>'
|
var source = '<ul>{{#posts}}<li>{{{link_to "Post"}}}</li>{{/posts}}</ul>'
|
||||||
|
|
||||||
var template = Handlebars.compile(source);
|
var template = Handlebars.compile(source);
|
||||||
template(context);
|
template(context);
|
||||||
@@ -177,12 +194,18 @@ template(data);
|
|||||||
// </ul>
|
// </ul>
|
||||||
```
|
```
|
||||||
|
|
||||||
Whenever the block helper is called it is given two parameters, the
|
Whenever the block helper is called it is given one or more parameters,
|
||||||
argument that is passed to the helper, or the current context if no
|
any arguments that are passed in the helper in the call and an `options`
|
||||||
argument is passed and the compiled contents of the block. Inside of
|
object containing the `fn` function which executes the block's child.
|
||||||
the block helper the value of `this` is the current context, wrapped to
|
The block's current context may be accessed through `this`.
|
||||||
include a method named `__get__` that helps translate paths into values
|
|
||||||
within the helpers.
|
Block helpers have the same syntax as mustache sections but should not be
|
||||||
|
confused with one another. Sections are akin to an implicit `each` or
|
||||||
|
`with` statement depending on the input data and helpers are explicit
|
||||||
|
pieces of code that are free to implement whatever behavior they like.
|
||||||
|
The [mustache spec](http://mustache.github.io/mustache.5.html)
|
||||||
|
defines the exact behavior of sections. In the case of name conflicts,
|
||||||
|
helpers are given priority.
|
||||||
|
|
||||||
### Partials
|
### Partials
|
||||||
|
|
||||||
@@ -253,6 +276,13 @@ Options:
|
|||||||
-m, --min Minimize output [boolean]
|
-m, --min Minimize output [boolean]
|
||||||
-s, --simple Output template function only. [boolean]
|
-s, --simple Output template function only. [boolean]
|
||||||
-r, --root Template root. Base value that will be stripped from template names. [string]
|
-r, --root Template root. Base value that will be stripped from template names. [string]
|
||||||
|
-c, --commonjs Exports CommonJS style, path to Handlebars module [string]
|
||||||
|
-h, --handlebarPath Path to handlebar.js (only valid for amd-style) [string]
|
||||||
|
-n, --namespace Template namespace [string]
|
||||||
|
-p, --partial Compiling a partial template [boolean]
|
||||||
|
-d, --data Include data when compiling [boolean]
|
||||||
|
-e, --extension Template extension. [string]
|
||||||
|
-b, --bom Removes the BOM (Byte Order Mark) from the beginning of the templates. [boolean]
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
If using the precompiler's normal mode, the resulting templates will be
|
If using the precompiler's normal mode, the resulting templates will be
|
||||||
@@ -275,7 +305,25 @@ normal.
|
|||||||
helpers for size and speed.
|
helpers for size and speed.
|
||||||
- When all helpers are known in advance the `--knownOnly` argument may be used
|
- When all helpers are known in advance the `--knownOnly` argument may be used
|
||||||
to optimize all block helper references.
|
to optimize all block helper references.
|
||||||
|
- Implementations that do not use `@data` variables can improve performance of
|
||||||
|
iteration centric templates by specifying `{data: false}` in the compiler options.
|
||||||
|
|
||||||
|
Supported Environments
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Handlebars has been designed to work in any ECMAScript 3 environment. This includes
|
||||||
|
|
||||||
|
- Node.js
|
||||||
|
- Chrome
|
||||||
|
- Firefox
|
||||||
|
- Safari 5+
|
||||||
|
- Opera 11+
|
||||||
|
- IE 6+
|
||||||
|
|
||||||
|
Older versions and other runtimes are likely to work but have not been formally
|
||||||
|
tested.
|
||||||
|
|
||||||
|
[](https://saucelabs.com/u/handlebars)
|
||||||
|
|
||||||
Performance
|
Performance
|
||||||
-----------
|
-----------
|
||||||
@@ -294,28 +342,13 @@ and we will have some benchmarks in the near future.
|
|||||||
Building
|
Building
|
||||||
--------
|
--------
|
||||||
|
|
||||||
To build handlebars, just run `rake release`, and you will get two files
|
To build handlebars, just run `grunt build`, and the build will output to the `dist` directory.
|
||||||
in the `dist` directory.
|
|
||||||
|
|
||||||
|
|
||||||
Upgrading
|
Upgrading
|
||||||
---------
|
---------
|
||||||
|
|
||||||
When upgrading from the Handlebars 0.9 series, be aware that the
|
See [release-notes.md](https://github.com/wycats/handlebars.js/blob/master/release-notes.md) for upgrade notes.
|
||||||
signature for passing custom helpers or partials to templates has
|
|
||||||
changed.
|
|
||||||
|
|
||||||
Instead of:
|
|
||||||
|
|
||||||
```js
|
|
||||||
template(context, helpers, partials, [data])
|
|
||||||
```
|
|
||||||
|
|
||||||
Use:
|
|
||||||
|
|
||||||
```js
|
|
||||||
template(context, {helpers: helpers, partials: partials, data: data})
|
|
||||||
```
|
|
||||||
|
|
||||||
Known Issues
|
Known Issues
|
||||||
------------
|
------------
|
||||||
@@ -323,47 +356,103 @@ Known Issues
|
|||||||
* Using a variable, helper, or partial named `class` causes errors in IE browsers. (Instead, use `className`)
|
* Using a variable, helper, or partial named `class` causes errors in IE browsers. (Instead, use `className`)
|
||||||
|
|
||||||
Handlebars in the Wild
|
Handlebars in the Wild
|
||||||
-----------------
|
----------------------
|
||||||
|
|
||||||
|
* [Assemble](http://assemble.io), by [@jonschlinkert](https://github.com/jonschlinkert)
|
||||||
|
and [@doowb](https://github.com/doowb), is a static site generator that uses Handlebars.js
|
||||||
|
as its template engine.
|
||||||
|
* [CoSchedule](http://coschedule.com) An editorial calendar for WordPress that uses Handlebars.js
|
||||||
|
* [Ember.js](http://www.emberjs.com) makes Handlebars.js the primary way to
|
||||||
|
structure your views, also with automatic data binding support.
|
||||||
|
* [Ghost](https://ghost.org/) Just a blogging platform.
|
||||||
|
* [handlebars_assets](http://github.com/leshill/handlebars_assets): A Rails Asset Pipeline gem
|
||||||
|
from Les Hill (@leshill).
|
||||||
|
* [handlebars-helpers](https://github.com/assemble/handlebars-helpers) is an extensive library
|
||||||
|
with 100+ handlebars helpers.
|
||||||
|
* [hbs](http://github.com/donpark/hbs): An Express.js view engine adapter for Handlebars.js,
|
||||||
|
from Don Park.
|
||||||
* [jblotus](http://github.com/jblotus) created [http://tryhandlebarsjs.com](http://tryhandlebarsjs.com)
|
* [jblotus](http://github.com/jblotus) created [http://tryhandlebarsjs.com](http://tryhandlebarsjs.com)
|
||||||
for anyone who would like to try out Handlebars.js in their browser.
|
for anyone who would like to try out Handlebars.js in their browser.
|
||||||
* Don Park wrote an Express.js view engine adapter for Handlebars.js called
|
* [jQuery plugin](http://71104.github.io/jquery-handlebars/): allows you to use
|
||||||
[hbs](http://github.com/donpark/hbs).
|
Handlebars.js with [jQuery](http://jquery.com/).
|
||||||
|
* [Lumbar](http://walmartlabs.github.io/lumbar) provides easy module-based template management for
|
||||||
|
handlebars projects.
|
||||||
* [sammy.js](http://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey,
|
* [sammy.js](http://github.com/quirkey/sammy) by Aaron Quint, a.k.a. quirkey,
|
||||||
supports Handlebars.js as one of its template plugins.
|
supports Handlebars.js as one of its template plugins.
|
||||||
* [SproutCore](http://www.sproutcore.com) uses Handlebars.js as its main
|
* [SproutCore](http://www.sproutcore.com) uses Handlebars.js as its main
|
||||||
templating engine, extending it with automatic data binding support.
|
templating engine, extending it with automatic data binding support.
|
||||||
* [Ember.js](http://www.emberjs.com) makes Handlebars.js the primary way to
|
* [YUI](http://yuilibrary.com/yui/docs/handlebars/) implements a port of handlebars
|
||||||
structure your views, also with automatic data binding support.
|
* [Swag](https://github.com/elving/swag) by [@elving](https://github.com/elving) is a growing collection of helpers for handlebars.js. Give your handlebars.js templates some swag son!
|
||||||
* Les Hill (@leshill) wrote a Rails Asset Pipeline gem named
|
* [DOMBars](https://github.com/blakeembrey/dombars) is a DOM-based templating engine built on the Handlebars parser and runtime
|
||||||
handlebars_assets](http://github.com/leshill/handlebars_assets).
|
|
||||||
|
External Resources
|
||||||
|
------------------
|
||||||
|
|
||||||
* [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070)
|
* [Gist about Synchronous and asynchronous loading of external handlebars templates](https://gist.github.com/2287070)
|
||||||
|
|
||||||
|
Have a project using Handlebars? Send us a [pull request][pull-request]!
|
||||||
|
|
||||||
Helping Out
|
Helping Out
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
To build Handlebars.js you'll need a few things installed.
|
To build Handlebars.js you'll need a few things installed.
|
||||||
|
|
||||||
* Node.js
|
* Node.js
|
||||||
* Jison, for building the compiler - `npm install jison`
|
* [Grunt](http://gruntjs.com/getting-started)
|
||||||
* Ruby
|
|
||||||
* therubyracer, for running tests - `gem install therubyracer`
|
|
||||||
* rspec, for running tests - `gem install rspec`
|
|
||||||
|
|
||||||
There's a Gemfile in the repo, so you can run `bundle` to install rspec
|
Project dependencies may be installed via `npm install`.
|
||||||
and therubyracer if you've got bundler installed.
|
|
||||||
|
|
||||||
To build Handlebars.js from scratch, you'll want to run `rake compile`
|
To build Handlebars.js from scratch, you'll want to run `grunt`
|
||||||
in the root of the project. That will build Handlebars and output the
|
in the root of the project. That will build Handlebars and output the
|
||||||
results to the dist/ folder. To run tests, run `rake spec`. You can also
|
results to the dist/ folder. To re-run tests, run `grunt test` or `npm test`.
|
||||||
run our set of benchmarks with `rake bench`.
|
You can also run our set of benchmarks with `grunt bench`.
|
||||||
|
|
||||||
If you notice any problems, please report
|
The `grunt dev` implements watching for tests and allows for in browser testing at `http://localhost:9999/spec/`.
|
||||||
them to the GitHub issue tracker at
|
|
||||||
|
If you notice any problems, please report them to the GitHub issue tracker at
|
||||||
[http://github.com/wycats/handlebars.js/issues](http://github.com/wycats/handlebars.js/issues).
|
[http://github.com/wycats/handlebars.js/issues](http://github.com/wycats/handlebars.js/issues).
|
||||||
Feel free to contact commondream or wycats through GitHub with any other
|
Feel free to contact commondream or wycats through GitHub with any other
|
||||||
questions or feature requests. To submit changes fork the project and
|
questions or feature requests. To submit changes fork the project and
|
||||||
send a pull request.
|
send a pull request.
|
||||||
|
|
||||||
|
### Ember testing
|
||||||
|
|
||||||
|
The current ember distribution should be tested as part of the handlebars release process. This requires building the `handlebars-source` gem locally and then executing the ember test script.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
grunt build release
|
||||||
|
export HANDLEBARS_PATH=`pwd`
|
||||||
|
|
||||||
|
cd $emberRepoDir
|
||||||
|
bundle exec rake clean
|
||||||
|
bundle exec rake test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Releasing
|
||||||
|
|
||||||
|
Handlebars utilizes the [release yeoman generator][generator-release] to perform most release tasks.
|
||||||
|
|
||||||
|
A full release may be completed with the following:
|
||||||
|
|
||||||
|
```
|
||||||
|
yo release:notes patch
|
||||||
|
yo release:release patch
|
||||||
|
npm publish
|
||||||
|
yo release:publish cdnjs handlebars.js dist/cdnjs/
|
||||||
|
yo release:publish components handlebars.js dist/components/
|
||||||
|
|
||||||
|
cd dist/components/
|
||||||
|
gem build handlebars-source.gemspec
|
||||||
|
gem push handlebars-source-*.gem
|
||||||
|
```
|
||||||
|
|
||||||
|
After this point the handlebars site needs to be updated to point to the new version numbers.
|
||||||
|
|
||||||
License
|
License
|
||||||
-------
|
-------
|
||||||
Handlebars.js is released under the MIT license.
|
Handlebars.js is released under the MIT license.
|
||||||
|
|
||||||
|
[bower-repo]: https://github.com/components/handlebars.js
|
||||||
|
[builds-page]: http://builds.handlebarsjs.com.s3.amazonaws.com/bucket-listing.html?sort=lastmod&sortdir=desc
|
||||||
|
[generator-release]: https://github.com/walmartlabs/generator-release
|
||||||
|
[pull-request]: https://github.com/wycats/handlebars.js/pull/new/master
|
||||||
|
|||||||
30
node_modules/handlebars/bin/handlebars
generated
vendored
30
node_modules/handlebars/bin/handlebars
generated
vendored
@@ -70,6 +70,11 @@ var optimist = require('optimist')
|
|||||||
'description': 'Template extension.',
|
'description': 'Template extension.',
|
||||||
'alias': 'extension',
|
'alias': 'extension',
|
||||||
'default': 'handlebars'
|
'default': 'handlebars'
|
||||||
|
},
|
||||||
|
'b': {
|
||||||
|
'type': 'boolean',
|
||||||
|
'description': 'Removes the BOM (Byte Order Mark) from the beginning of the templates.',
|
||||||
|
'alias': 'bom'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -97,7 +102,7 @@ var optimist = require('optimist')
|
|||||||
});
|
});
|
||||||
|
|
||||||
var fs = require('fs'),
|
var fs = require('fs'),
|
||||||
handlebars = require('../lib/handlebars'),
|
handlebars = require('../lib'),
|
||||||
basename = require('path').basename,
|
basename = require('path').basename,
|
||||||
uglify = require('uglify-js');
|
uglify = require('uglify-js');
|
||||||
|
|
||||||
@@ -122,7 +127,7 @@ extension = new RegExp('\\.' + extension + '$');
|
|||||||
var output = [];
|
var output = [];
|
||||||
if (!argv.simple) {
|
if (!argv.simple) {
|
||||||
if (argv.amd) {
|
if (argv.amd) {
|
||||||
output.push('define([\'' + argv.handlebarPath + 'handlebars\'], function(Handlebars) {\n');
|
output.push('define([\'' + argv.handlebarPath + 'handlebars.runtime\'], function(Handlebars) {\n Handlebars = Handlebars["default"];');
|
||||||
} else if (argv.commonjs) {
|
} else if (argv.commonjs) {
|
||||||
output.push('var Handlebars = require("' + argv.commonjs + '");');
|
output.push('var Handlebars = require("' + argv.commonjs + '");');
|
||||||
} else {
|
} else {
|
||||||
@@ -145,9 +150,13 @@ function processTemplate(template, root) {
|
|||||||
processTemplate(path, root || template);
|
processTemplate(path, root || template);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else if (extension.test(path)) {
|
||||||
var data = fs.readFileSync(path, 'utf8');
|
var data = fs.readFileSync(path, 'utf8');
|
||||||
|
|
||||||
|
if (argv.bom && data.indexOf('\uFEFF') === 0) {
|
||||||
|
data = data.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
knownHelpers: known,
|
knownHelpers: known,
|
||||||
knownHelpersOnly: argv.o
|
knownHelpersOnly: argv.o
|
||||||
@@ -168,10 +177,14 @@ function processTemplate(template, root) {
|
|||||||
if (argv.simple) {
|
if (argv.simple) {
|
||||||
output.push(handlebars.precompile(data, options) + '\n');
|
output.push(handlebars.precompile(data, options) + '\n');
|
||||||
} else if (argv.partial) {
|
} else if (argv.partial) {
|
||||||
if(argv.amd && argv._.length == 1){ output.push('return '); }
|
if(argv.amd && (argv._.length == 1 && !fs.statSync(argv._[0]).isDirectory())) {
|
||||||
|
output.push('return ');
|
||||||
|
}
|
||||||
output.push('Handlebars.partials[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n');
|
output.push('Handlebars.partials[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n');
|
||||||
} else {
|
} else {
|
||||||
if(argv.amd && argv._.length == 1){ output.push('return '); }
|
if(argv.amd && (argv._.length == 1 && !fs.statSync(argv._[0]).isDirectory())) {
|
||||||
|
output.push('return ');
|
||||||
|
}
|
||||||
output.push('templates[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n');
|
output.push('templates[\'' + template + '\'] = template(' + handlebars.precompile(data, options) + ');\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +197,7 @@ argv._.forEach(function(template) {
|
|||||||
// Output the content
|
// Output the content
|
||||||
if (!argv.simple) {
|
if (!argv.simple) {
|
||||||
if (argv.amd) {
|
if (argv.amd) {
|
||||||
if(argv._.length > 1){
|
if(argv._.length > 1 || (argv._.length == 1 && fs.statSync(argv._[0]).isDirectory())) {
|
||||||
if(argv.partial){
|
if(argv.partial){
|
||||||
output.push('return Handlebars.partials;\n');
|
output.push('return Handlebars.partials;\n');
|
||||||
} else {
|
} else {
|
||||||
@@ -199,10 +212,7 @@ if (!argv.simple) {
|
|||||||
output = output.join('');
|
output = output.join('');
|
||||||
|
|
||||||
if (argv.min) {
|
if (argv.min) {
|
||||||
var ast = uglify.parser.parse(output);
|
output = uglify.minify(output, {fromString: true}).code;
|
||||||
ast = uglify.uglify.ast_mangle(ast);
|
|
||||||
ast = uglify.uglify.ast_squeeze(ast);
|
|
||||||
output = uglify.uglify.gen_code(ast);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argv.output) {
|
if (argv.output) {
|
||||||
|
|||||||
9
node_modules/handlebars/bower.json
generated
vendored
9
node_modules/handlebars/bower.json
generated
vendored
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "handlebars.js",
|
|
||||||
"version": "1.0.0-rc.4",
|
|
||||||
"main": "dist/handlebars.js",
|
|
||||||
"ignore": [
|
|
||||||
"node_modules",
|
|
||||||
"components"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
41
node_modules/handlebars/dist/amd/handlebars.js
generated
vendored
Normal file
41
node_modules/handlebars/dist/amd/handlebars.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
define(
|
||||||
|
["./handlebars.runtime","./handlebars/compiler/ast","./handlebars/compiler/base","./handlebars/compiler/compiler","./handlebars/compiler/javascript-compiler","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var Handlebars = __dependency1__["default"];
|
||||||
|
|
||||||
|
// Compiler imports
|
||||||
|
var AST = __dependency2__["default"];
|
||||||
|
var Parser = __dependency3__.parser;
|
||||||
|
var parse = __dependency3__.parse;
|
||||||
|
var Compiler = __dependency4__.Compiler;
|
||||||
|
var compile = __dependency4__.compile;
|
||||||
|
var precompile = __dependency4__.precompile;
|
||||||
|
var JavaScriptCompiler = __dependency5__["default"];
|
||||||
|
|
||||||
|
var _create = Handlebars.create;
|
||||||
|
var create = function() {
|
||||||
|
var hb = _create();
|
||||||
|
|
||||||
|
hb.compile = function(input, options) {
|
||||||
|
return compile(input, options, hb);
|
||||||
|
};
|
||||||
|
hb.precompile = function (input, options) {
|
||||||
|
return precompile(input, options, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
hb.AST = AST;
|
||||||
|
hb.Compiler = Compiler;
|
||||||
|
hb.JavaScriptCompiler = JavaScriptCompiler;
|
||||||
|
hb.Parser = Parser;
|
||||||
|
hb.parse = parse;
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
__exports__["default"] = Handlebars;
|
||||||
|
});
|
||||||
36
node_modules/handlebars/dist/amd/handlebars.runtime.js
generated
vendored
Normal file
36
node_modules/handlebars/dist/amd/handlebars.runtime.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
define(
|
||||||
|
["./handlebars/base","./handlebars/safe-string","./handlebars/exception","./handlebars/utils","./handlebars/runtime","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var base = __dependency1__;
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
var SafeString = __dependency2__["default"];
|
||||||
|
var Exception = __dependency3__["default"];
|
||||||
|
var Utils = __dependency4__;
|
||||||
|
var runtime = __dependency5__;
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
__exports__["default"] = Handlebars;
|
||||||
|
});
|
||||||
184
node_modules/handlebars/dist/amd/handlebars/base.js
generated
vendored
Normal file
184
node_modules/handlebars/dist/amd/handlebars/base.js
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
define(
|
||||||
|
["./utils","./exception","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
|
||||||
|
var VERSION = "1.3.0";
|
||||||
|
__exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
|
||||||
|
__exports__.COMPILER_REVISION = COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = {
|
||||||
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
|
2: '== 1.0.0-rc.3',
|
||||||
|
3: '== 1.0.0-rc.4',
|
||||||
|
4: '>= 1.0.0'
|
||||||
|
};
|
||||||
|
__exports__.REVISION_CHANGES = REVISION_CHANGES;
|
||||||
|
var isArray = Utils.isArray,
|
||||||
|
isFunction = Utils.isFunction,
|
||||||
|
toString = Utils.toString,
|
||||||
|
objectType = '[object Object]';
|
||||||
|
|
||||||
|
function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
|
Utils.extend(this.helpers, name);
|
||||||
|
} else {
|
||||||
|
if (inverse) { fn.not = inverse; }
|
||||||
|
this.helpers[name] = fn;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
registerPartial: function(name, str) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
Utils.extend(this.partials, name);
|
||||||
|
} else {
|
||||||
|
this.partials[name] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
|
if(arguments.length === 2) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if(context === true) {
|
||||||
|
return fn(this);
|
||||||
|
} else if(context === false || context == null) {
|
||||||
|
return inverse(this);
|
||||||
|
} else if (isArray(context)) {
|
||||||
|
if(context.length > 0) {
|
||||||
|
return instance.helpers.each(context, options);
|
||||||
|
} else {
|
||||||
|
return inverse(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fn(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
var fn = options.fn, inverse = options.inverse;
|
||||||
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (options.data) {
|
||||||
|
data = createFrame(options.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(context && typeof context === 'object') {
|
||||||
|
if (isArray(context)) {
|
||||||
|
for(var j = context.length; i<j; i++) {
|
||||||
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[i], { data: data });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(var key in context) {
|
||||||
|
if(context.hasOwnProperty(key)) {
|
||||||
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[key], {data: data});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i === 0){
|
||||||
|
ret = inverse(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
|
|
||||||
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
|
return options.inverse(this);
|
||||||
|
} else {
|
||||||
|
return options.fn(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('with', function(context, options) {
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('log', function(context, options) {
|
||||||
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
|
instance.log(level, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger = {
|
||||||
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
|
|
||||||
|
// State enum
|
||||||
|
DEBUG: 0,
|
||||||
|
INFO: 1,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
|
// can be overridden in the host environment
|
||||||
|
log: function(level, obj) {
|
||||||
|
if (logger.level <= level) {
|
||||||
|
var method = logger.methodMap[level];
|
||||||
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__exports__.logger = logger;
|
||||||
|
function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
__exports__.log = log;var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
__exports__.createFrame = createFrame;
|
||||||
|
});
|
||||||
231
node_modules/handlebars/dist/amd/handlebars/compiler/ast.js
generated
vendored
Normal file
231
node_modules/handlebars/dist/amd/handlebars/compiler/ast.js
generated
vendored
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
define(
|
||||||
|
["../exception","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Exception = __dependency1__["default"];
|
||||||
|
|
||||||
|
function LocationInfo(locInfo){
|
||||||
|
locInfo = locInfo || {};
|
||||||
|
this.firstLine = locInfo.first_line;
|
||||||
|
this.firstColumn = locInfo.first_column;
|
||||||
|
this.lastColumn = locInfo.last_column;
|
||||||
|
this.lastLine = locInfo.last_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
var AST = {
|
||||||
|
ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
|
||||||
|
var inverseLocationInfo, firstInverseNode;
|
||||||
|
if (arguments.length === 3) {
|
||||||
|
locInfo = inverse;
|
||||||
|
inverse = null;
|
||||||
|
} else if (arguments.length === 2) {
|
||||||
|
locInfo = inverseStrip;
|
||||||
|
inverseStrip = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "program";
|
||||||
|
this.statements = statements;
|
||||||
|
this.strip = {};
|
||||||
|
|
||||||
|
if(inverse) {
|
||||||
|
firstInverseNode = inverse[0];
|
||||||
|
if (firstInverseNode) {
|
||||||
|
inverseLocationInfo = {
|
||||||
|
first_line: firstInverseNode.firstLine,
|
||||||
|
last_line: firstInverseNode.lastLine,
|
||||||
|
last_column: firstInverseNode.lastColumn,
|
||||||
|
first_column: firstInverseNode.firstColumn
|
||||||
|
};
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
|
||||||
|
} else {
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip);
|
||||||
|
}
|
||||||
|
this.strip.right = inverseStrip.left;
|
||||||
|
} else if (inverseStrip) {
|
||||||
|
this.strip.left = inverseStrip.right;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
MustacheNode: function(rawParams, hash, open, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "mustache";
|
||||||
|
this.strip = strip;
|
||||||
|
|
||||||
|
// Open may be a string parsed from the parser or a passed boolean flag
|
||||||
|
if (open != null && open.charAt) {
|
||||||
|
// Must use charAt to support IE pre-10
|
||||||
|
var escapeFlag = open.charAt(3) || open.charAt(2);
|
||||||
|
this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
|
||||||
|
} else {
|
||||||
|
this.escaped = !!open;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawParams instanceof AST.SexprNode) {
|
||||||
|
this.sexpr = rawParams;
|
||||||
|
} else {
|
||||||
|
// Support old AST API
|
||||||
|
this.sexpr = new AST.SexprNode(rawParams, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sexpr.isRoot = true;
|
||||||
|
|
||||||
|
// Support old AST API that stored this info in MustacheNode
|
||||||
|
this.id = this.sexpr.id;
|
||||||
|
this.params = this.sexpr.params;
|
||||||
|
this.hash = this.sexpr.hash;
|
||||||
|
this.eligibleHelper = this.sexpr.eligibleHelper;
|
||||||
|
this.isHelper = this.sexpr.isHelper;
|
||||||
|
},
|
||||||
|
|
||||||
|
SexprNode: function(rawParams, hash, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
this.type = "sexpr";
|
||||||
|
this.hash = hash;
|
||||||
|
|
||||||
|
var id = this.id = rawParams[0];
|
||||||
|
var params = this.params = rawParams.slice(1);
|
||||||
|
|
||||||
|
// a mustache is an eligible helper if:
|
||||||
|
// * its id is simple (a single part, not `this` or `..`)
|
||||||
|
var eligibleHelper = this.eligibleHelper = id.isSimple;
|
||||||
|
|
||||||
|
// a mustache is definitely a helper if:
|
||||||
|
// * it is an eligible helper, and
|
||||||
|
// * it has at least one parameter or hash segment
|
||||||
|
this.isHelper = eligibleHelper && (params.length || hash);
|
||||||
|
|
||||||
|
// if a mustache is an eligible helper but not a definite
|
||||||
|
// helper, it is ambiguous, and will be resolved in a later
|
||||||
|
// pass or at runtime.
|
||||||
|
},
|
||||||
|
|
||||||
|
PartialNode: function(partialName, context, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "partial";
|
||||||
|
this.partialName = partialName;
|
||||||
|
this.context = context;
|
||||||
|
this.strip = strip;
|
||||||
|
},
|
||||||
|
|
||||||
|
BlockNode: function(mustache, program, inverse, close, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
if(mustache.sexpr.id.original !== close.path.original) {
|
||||||
|
throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.type = 'block';
|
||||||
|
this.mustache = mustache;
|
||||||
|
this.program = program;
|
||||||
|
this.inverse = inverse;
|
||||||
|
|
||||||
|
this.strip = {
|
||||||
|
left: mustache.strip.left,
|
||||||
|
right: close.strip.right
|
||||||
|
};
|
||||||
|
|
||||||
|
(program || inverse).strip.left = mustache.strip.right;
|
||||||
|
(inverse || program).strip.right = close.strip.left;
|
||||||
|
|
||||||
|
if (inverse && !program) {
|
||||||
|
this.isInverse = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ContentNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "content";
|
||||||
|
this.string = string;
|
||||||
|
},
|
||||||
|
|
||||||
|
HashNode: function(pairs, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "hash";
|
||||||
|
this.pairs = pairs;
|
||||||
|
},
|
||||||
|
|
||||||
|
IdNode: function(parts, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "ID";
|
||||||
|
|
||||||
|
var original = "",
|
||||||
|
dig = [],
|
||||||
|
depth = 0;
|
||||||
|
|
||||||
|
for(var i=0,l=parts.length; i<l; i++) {
|
||||||
|
var part = parts[i].part;
|
||||||
|
original += (parts[i].separator || '') + part;
|
||||||
|
|
||||||
|
if (part === ".." || part === "." || part === "this") {
|
||||||
|
if (dig.length > 0) {
|
||||||
|
throw new Exception("Invalid path: " + original, this);
|
||||||
|
} else if (part === "..") {
|
||||||
|
depth++;
|
||||||
|
} else {
|
||||||
|
this.isScoped = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dig.push(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.original = original;
|
||||||
|
this.parts = dig;
|
||||||
|
this.string = dig.join('.');
|
||||||
|
this.depth = depth;
|
||||||
|
|
||||||
|
// an ID is simple if it only has one part, and that part is not
|
||||||
|
// `..` or `this`.
|
||||||
|
this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
|
||||||
|
|
||||||
|
this.stringModeValue = this.string;
|
||||||
|
},
|
||||||
|
|
||||||
|
PartialNameNode: function(name, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "PARTIAL_NAME";
|
||||||
|
this.name = name.original;
|
||||||
|
},
|
||||||
|
|
||||||
|
DataNode: function(id, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "DATA";
|
||||||
|
this.id = id;
|
||||||
|
},
|
||||||
|
|
||||||
|
StringNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "STRING";
|
||||||
|
this.original =
|
||||||
|
this.string =
|
||||||
|
this.stringModeValue = string;
|
||||||
|
},
|
||||||
|
|
||||||
|
IntegerNode: function(integer, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "INTEGER";
|
||||||
|
this.original =
|
||||||
|
this.integer = integer;
|
||||||
|
this.stringModeValue = Number(integer);
|
||||||
|
},
|
||||||
|
|
||||||
|
BooleanNode: function(bool, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "BOOLEAN";
|
||||||
|
this.bool = bool;
|
||||||
|
this.stringModeValue = bool === "true";
|
||||||
|
},
|
||||||
|
|
||||||
|
CommentNode: function(comment, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "comment";
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Must be exported as an object rather than the root of the module as the jison lexer
|
||||||
|
// most modify the object to operate properly.
|
||||||
|
__exports__["default"] = AST;
|
||||||
|
});
|
||||||
19
node_modules/handlebars/dist/amd/handlebars/compiler/base.js
generated
vendored
Normal file
19
node_modules/handlebars/dist/amd/handlebars/compiler/base.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
define(
|
||||||
|
["./parser","./ast","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var parser = __dependency1__["default"];
|
||||||
|
var AST = __dependency2__["default"];
|
||||||
|
|
||||||
|
__exports__.parser = parser;
|
||||||
|
|
||||||
|
function parse(input) {
|
||||||
|
// Just return if an already-compile AST was passed in.
|
||||||
|
if(input.constructor === AST.ProgramNode) { return input; }
|
||||||
|
|
||||||
|
parser.yy = AST;
|
||||||
|
return parser.parse(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.parse = parse;
|
||||||
|
});
|
||||||
473
node_modules/handlebars/dist/amd/handlebars/compiler/compiler.js
generated
vendored
Normal file
473
node_modules/handlebars/dist/amd/handlebars/compiler/compiler.js
generated
vendored
Normal file
@@ -0,0 +1,473 @@
|
|||||||
|
define(
|
||||||
|
["../exception","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Exception = __dependency1__["default"];
|
||||||
|
|
||||||
|
function Compiler() {}
|
||||||
|
|
||||||
|
__exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
|
||||||
|
// function in a context. This is necessary for mustache compatibility, which
|
||||||
|
// requires that context functions in blocks are evaluated by blockHelperMissing,
|
||||||
|
// and then proceed as if the resulting value was provided to blockHelperMissing.
|
||||||
|
|
||||||
|
Compiler.prototype = {
|
||||||
|
compiler: Compiler,
|
||||||
|
|
||||||
|
disassemble: function() {
|
||||||
|
var opcodes = this.opcodes, opcode, out = [], params, param;
|
||||||
|
|
||||||
|
for (var i=0, l=opcodes.length; i<l; i++) {
|
||||||
|
opcode = opcodes[i];
|
||||||
|
|
||||||
|
if (opcode.opcode === 'DECLARE') {
|
||||||
|
out.push("DECLARE " + opcode.name + "=" + opcode.value);
|
||||||
|
} else {
|
||||||
|
params = [];
|
||||||
|
for (var j=0; j<opcode.args.length; j++) {
|
||||||
|
param = opcode.args[j];
|
||||||
|
if (typeof param === "string") {
|
||||||
|
param = "\"" + param.replace("\n", "\\n") + "\"";
|
||||||
|
}
|
||||||
|
params.push(param);
|
||||||
|
}
|
||||||
|
out.push(opcode.opcode + " " + params.join(" "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.join("\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
equals: function(other) {
|
||||||
|
var len = this.opcodes.length;
|
||||||
|
if (other.opcodes.length !== len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
var opcode = this.opcodes[i],
|
||||||
|
otherOpcode = other.opcodes[i];
|
||||||
|
if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (var j = 0; j < opcode.args.length; j++) {
|
||||||
|
if (opcode.args[j] !== otherOpcode.args[j]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = this.children.length;
|
||||||
|
if (other.children.length !== len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (!this.children[i].equals(other.children[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
guid: 0,
|
||||||
|
|
||||||
|
compile: function(program, options) {
|
||||||
|
this.opcodes = [];
|
||||||
|
this.children = [];
|
||||||
|
this.depths = {list: []};
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
// These changes will propagate to the other compiler components
|
||||||
|
var knownHelpers = this.options.knownHelpers;
|
||||||
|
this.options.knownHelpers = {
|
||||||
|
'helperMissing': true,
|
||||||
|
'blockHelperMissing': true,
|
||||||
|
'each': true,
|
||||||
|
'if': true,
|
||||||
|
'unless': true,
|
||||||
|
'with': true,
|
||||||
|
'log': true
|
||||||
|
};
|
||||||
|
if (knownHelpers) {
|
||||||
|
for (var name in knownHelpers) {
|
||||||
|
this.options.knownHelpers[name] = knownHelpers[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.accept(program);
|
||||||
|
},
|
||||||
|
|
||||||
|
accept: function(node) {
|
||||||
|
var strip = node.strip || {},
|
||||||
|
ret;
|
||||||
|
if (strip.left) {
|
||||||
|
this.opcode('strip');
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = this[node.type](node);
|
||||||
|
|
||||||
|
if (strip.right) {
|
||||||
|
this.opcode('strip');
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
|
||||||
|
program: function(program) {
|
||||||
|
var statements = program.statements;
|
||||||
|
|
||||||
|
for(var i=0, l=statements.length; i<l; i++) {
|
||||||
|
this.accept(statements[i]);
|
||||||
|
}
|
||||||
|
this.isSimple = l === 1;
|
||||||
|
|
||||||
|
this.depths.list = this.depths.list.sort(function(a, b) {
|
||||||
|
return a - b;
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
compileProgram: function(program) {
|
||||||
|
var result = new this.compiler().compile(program, this.options);
|
||||||
|
var guid = this.guid++, depth;
|
||||||
|
|
||||||
|
this.usePartial = this.usePartial || result.usePartial;
|
||||||
|
|
||||||
|
this.children[guid] = result;
|
||||||
|
|
||||||
|
for(var i=0, l=result.depths.list.length; i<l; i++) {
|
||||||
|
depth = result.depths.list[i];
|
||||||
|
|
||||||
|
if(depth < 2) { continue; }
|
||||||
|
else { this.addDepth(depth - 1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return guid;
|
||||||
|
},
|
||||||
|
|
||||||
|
block: function(block) {
|
||||||
|
var mustache = block.mustache,
|
||||||
|
program = block.program,
|
||||||
|
inverse = block.inverse;
|
||||||
|
|
||||||
|
if (program) {
|
||||||
|
program = this.compileProgram(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inverse) {
|
||||||
|
inverse = this.compileProgram(inverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sexpr = mustache.sexpr;
|
||||||
|
var type = this.classifySexpr(sexpr);
|
||||||
|
|
||||||
|
if (type === "helper") {
|
||||||
|
this.helperSexpr(sexpr, program, inverse);
|
||||||
|
} else if (type === "simple") {
|
||||||
|
this.simpleSexpr(sexpr);
|
||||||
|
|
||||||
|
// now that the simple mustache is resolved, we need to
|
||||||
|
// evaluate it by executing `blockHelperMissing`
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
this.opcode('blockValue');
|
||||||
|
} else {
|
||||||
|
this.ambiguousSexpr(sexpr, program, inverse);
|
||||||
|
|
||||||
|
// now that the simple mustache is resolved, we need to
|
||||||
|
// evaluate it by executing `blockHelperMissing`
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
this.opcode('ambiguousBlockValue');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('append');
|
||||||
|
},
|
||||||
|
|
||||||
|
hash: function(hash) {
|
||||||
|
var pairs = hash.pairs, pair, val;
|
||||||
|
|
||||||
|
this.opcode('pushHash');
|
||||||
|
|
||||||
|
for(var i=0, l=pairs.length; i<l; i++) {
|
||||||
|
pair = pairs[i];
|
||||||
|
val = pair[1];
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
if(val.depth) {
|
||||||
|
this.addDepth(val.depth);
|
||||||
|
}
|
||||||
|
this.opcode('getContext', val.depth || 0);
|
||||||
|
this.opcode('pushStringParam', val.stringModeValue, val.type);
|
||||||
|
|
||||||
|
if (val.type === 'sexpr') {
|
||||||
|
// Subexpressions get evaluated and passed in
|
||||||
|
// in string params mode.
|
||||||
|
this.sexpr(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.accept(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('assignToHash', pair[0]);
|
||||||
|
}
|
||||||
|
this.opcode('popHash');
|
||||||
|
},
|
||||||
|
|
||||||
|
partial: function(partial) {
|
||||||
|
var partialName = partial.partialName;
|
||||||
|
this.usePartial = true;
|
||||||
|
|
||||||
|
if(partial.context) {
|
||||||
|
this.ID(partial.context);
|
||||||
|
} else {
|
||||||
|
this.opcode('push', 'depth0');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('invokePartial', partialName.name);
|
||||||
|
this.opcode('append');
|
||||||
|
},
|
||||||
|
|
||||||
|
content: function(content) {
|
||||||
|
this.opcode('appendContent', content.string);
|
||||||
|
},
|
||||||
|
|
||||||
|
mustache: function(mustache) {
|
||||||
|
this.sexpr(mustache.sexpr);
|
||||||
|
|
||||||
|
if(mustache.escaped && !this.options.noEscape) {
|
||||||
|
this.opcode('appendEscaped');
|
||||||
|
} else {
|
||||||
|
this.opcode('append');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ambiguousSexpr: function(sexpr, program, inverse) {
|
||||||
|
var id = sexpr.id,
|
||||||
|
name = id.parts[0],
|
||||||
|
isBlock = program != null || inverse != null;
|
||||||
|
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
|
||||||
|
this.opcode('invokeAmbiguous', name, isBlock);
|
||||||
|
},
|
||||||
|
|
||||||
|
simpleSexpr: function(sexpr) {
|
||||||
|
var id = sexpr.id;
|
||||||
|
|
||||||
|
if (id.type === 'DATA') {
|
||||||
|
this.DATA(id);
|
||||||
|
} else if (id.parts.length) {
|
||||||
|
this.ID(id);
|
||||||
|
} else {
|
||||||
|
// Simplified ID for `this`
|
||||||
|
this.addDepth(id.depth);
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
this.opcode('pushContext');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('resolvePossibleLambda');
|
||||||
|
},
|
||||||
|
|
||||||
|
helperSexpr: function(sexpr, program, inverse) {
|
||||||
|
var params = this.setupFullMustacheParams(sexpr, program, inverse),
|
||||||
|
name = sexpr.id.parts[0];
|
||||||
|
|
||||||
|
if (this.options.knownHelpers[name]) {
|
||||||
|
this.opcode('invokeKnownHelper', params.length, name);
|
||||||
|
} else if (this.options.knownHelpersOnly) {
|
||||||
|
throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
|
||||||
|
} else {
|
||||||
|
this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sexpr: function(sexpr) {
|
||||||
|
var type = this.classifySexpr(sexpr);
|
||||||
|
|
||||||
|
if (type === "simple") {
|
||||||
|
this.simpleSexpr(sexpr);
|
||||||
|
} else if (type === "helper") {
|
||||||
|
this.helperSexpr(sexpr);
|
||||||
|
} else {
|
||||||
|
this.ambiguousSexpr(sexpr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ID: function(id) {
|
||||||
|
this.addDepth(id.depth);
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
|
||||||
|
var name = id.parts[0];
|
||||||
|
if (!name) {
|
||||||
|
this.opcode('pushContext');
|
||||||
|
} else {
|
||||||
|
this.opcode('lookupOnContext', id.parts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=1, l=id.parts.length; i<l; i++) {
|
||||||
|
this.opcode('lookup', id.parts[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DATA: function(data) {
|
||||||
|
this.options.data = true;
|
||||||
|
if (data.id.isScoped || data.id.depth) {
|
||||||
|
throw new Exception('Scoped data references are not supported: ' + data.original, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('lookupData');
|
||||||
|
var parts = data.id.parts;
|
||||||
|
for(var i=0, l=parts.length; i<l; i++) {
|
||||||
|
this.opcode('lookup', parts[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
STRING: function(string) {
|
||||||
|
this.opcode('pushString', string.string);
|
||||||
|
},
|
||||||
|
|
||||||
|
INTEGER: function(integer) {
|
||||||
|
this.opcode('pushLiteral', integer.integer);
|
||||||
|
},
|
||||||
|
|
||||||
|
BOOLEAN: function(bool) {
|
||||||
|
this.opcode('pushLiteral', bool.bool);
|
||||||
|
},
|
||||||
|
|
||||||
|
comment: function() {},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
opcode: function(name) {
|
||||||
|
this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
|
||||||
|
},
|
||||||
|
|
||||||
|
declare: function(name, value) {
|
||||||
|
this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
|
||||||
|
},
|
||||||
|
|
||||||
|
addDepth: function(depth) {
|
||||||
|
if(depth === 0) { return; }
|
||||||
|
|
||||||
|
if(!this.depths[depth]) {
|
||||||
|
this.depths[depth] = true;
|
||||||
|
this.depths.list.push(depth);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
classifySexpr: function(sexpr) {
|
||||||
|
var isHelper = sexpr.isHelper;
|
||||||
|
var isEligible = sexpr.eligibleHelper;
|
||||||
|
var options = this.options;
|
||||||
|
|
||||||
|
// if ambiguous, we can possibly resolve the ambiguity now
|
||||||
|
if (isEligible && !isHelper) {
|
||||||
|
var name = sexpr.id.parts[0];
|
||||||
|
|
||||||
|
if (options.knownHelpers[name]) {
|
||||||
|
isHelper = true;
|
||||||
|
} else if (options.knownHelpersOnly) {
|
||||||
|
isEligible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHelper) { return "helper"; }
|
||||||
|
else if (isEligible) { return "ambiguous"; }
|
||||||
|
else { return "simple"; }
|
||||||
|
},
|
||||||
|
|
||||||
|
pushParams: function(params) {
|
||||||
|
var i = params.length, param;
|
||||||
|
|
||||||
|
while(i--) {
|
||||||
|
param = params[i];
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
if(param.depth) {
|
||||||
|
this.addDepth(param.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('getContext', param.depth || 0);
|
||||||
|
this.opcode('pushStringParam', param.stringModeValue, param.type);
|
||||||
|
|
||||||
|
if (param.type === 'sexpr') {
|
||||||
|
// Subexpressions get evaluated and passed in
|
||||||
|
// in string params mode.
|
||||||
|
this.sexpr(param);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this[param.type](param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setupFullMustacheParams: function(sexpr, program, inverse) {
|
||||||
|
var params = sexpr.params;
|
||||||
|
this.pushParams(params);
|
||||||
|
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
|
||||||
|
if (sexpr.hash) {
|
||||||
|
this.hash(sexpr.hash);
|
||||||
|
} else {
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function precompile(input, options, env) {
|
||||||
|
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
||||||
|
throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
if (!('data' in options)) {
|
||||||
|
options.data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ast = env.parse(input);
|
||||||
|
var environment = new env.Compiler().compile(ast, options);
|
||||||
|
return new env.JavaScriptCompiler().compile(environment, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.precompile = precompile;function compile(input, options, env) {
|
||||||
|
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
||||||
|
throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
if (!('data' in options)) {
|
||||||
|
options.data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var compiled;
|
||||||
|
|
||||||
|
function compileInput() {
|
||||||
|
var ast = env.parse(input);
|
||||||
|
var environment = new env.Compiler().compile(ast, options);
|
||||||
|
var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
|
||||||
|
return env.template(templateSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Template is only compiled on first use and cached after that point.
|
||||||
|
return function(context, options) {
|
||||||
|
if (!compiled) {
|
||||||
|
compiled = compileInput();
|
||||||
|
}
|
||||||
|
return compiled.call(this, context, options);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.compile = compile;
|
||||||
|
});
|
||||||
946
node_modules/handlebars/dist/amd/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
946
node_modules/handlebars/dist/amd/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
@@ -0,0 +1,946 @@
|
|||||||
|
define(
|
||||||
|
["../base","../exception","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
|
||||||
|
var log = __dependency1__.log;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
|
||||||
|
function Literal(value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function JavaScriptCompiler() {}
|
||||||
|
|
||||||
|
JavaScriptCompiler.prototype = {
|
||||||
|
// PUBLIC API: You can override these methods in a subclass to provide
|
||||||
|
// alternative compiled forms for name lookup and buffering semantics
|
||||||
|
nameLookup: function(parent, name /* , type*/) {
|
||||||
|
var wrap,
|
||||||
|
ret;
|
||||||
|
if (parent.indexOf('depth') === 0) {
|
||||||
|
wrap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^[0-9]+$/.test(name)) {
|
||||||
|
ret = parent + "[" + name + "]";
|
||||||
|
} else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
||||||
|
ret = parent + "." + name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = parent + "['" + name + "']";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrap) {
|
||||||
|
return '(' + parent + ' && ' + ret + ')';
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
compilerInfo: function() {
|
||||||
|
var revision = COMPILER_REVISION,
|
||||||
|
versions = REVISION_CHANGES[revision];
|
||||||
|
return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
|
||||||
|
},
|
||||||
|
|
||||||
|
appendToBuffer: function(string) {
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
return "return " + string + ";";
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
appendToBuffer: true,
|
||||||
|
content: string,
|
||||||
|
toString: function() { return "buffer += " + string + ";"; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
initializeBuffer: function() {
|
||||||
|
return this.quotedString("");
|
||||||
|
},
|
||||||
|
|
||||||
|
namespace: "Handlebars",
|
||||||
|
// END PUBLIC API
|
||||||
|
|
||||||
|
compile: function(environment, options, context, asObject) {
|
||||||
|
this.environment = environment;
|
||||||
|
this.options = options || {};
|
||||||
|
|
||||||
|
log('debug', this.environment.disassemble() + "\n\n");
|
||||||
|
|
||||||
|
this.name = this.environment.name;
|
||||||
|
this.isChild = !!context;
|
||||||
|
this.context = context || {
|
||||||
|
programs: [],
|
||||||
|
environments: [],
|
||||||
|
aliases: { }
|
||||||
|
};
|
||||||
|
|
||||||
|
this.preamble();
|
||||||
|
|
||||||
|
this.stackSlot = 0;
|
||||||
|
this.stackVars = [];
|
||||||
|
this.registers = { list: [] };
|
||||||
|
this.hashes = [];
|
||||||
|
this.compileStack = [];
|
||||||
|
this.inlineStack = [];
|
||||||
|
|
||||||
|
this.compileChildren(environment, options);
|
||||||
|
|
||||||
|
var opcodes = environment.opcodes, opcode;
|
||||||
|
|
||||||
|
this.i = 0;
|
||||||
|
|
||||||
|
for(var l=opcodes.length; this.i<l; this.i++) {
|
||||||
|
opcode = opcodes[this.i];
|
||||||
|
|
||||||
|
if(opcode.opcode === 'DECLARE') {
|
||||||
|
this[opcode.name] = opcode.value;
|
||||||
|
} else {
|
||||||
|
this[opcode.opcode].apply(this, opcode.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the stripNext flag if it was not set by this operation.
|
||||||
|
if (opcode.opcode !== this.stripNext) {
|
||||||
|
this.stripNext = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush any trailing content that might be pending.
|
||||||
|
this.pushSource('');
|
||||||
|
|
||||||
|
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
|
||||||
|
throw new Exception('Compile completed with content left on stack');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createFunctionContext(asObject);
|
||||||
|
},
|
||||||
|
|
||||||
|
preamble: function() {
|
||||||
|
var out = [];
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
var namespace = this.namespace;
|
||||||
|
|
||||||
|
var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
|
||||||
|
if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
|
||||||
|
if (this.options.data) { copies = copies + " data = data || {};"; }
|
||||||
|
out.push(copies);
|
||||||
|
} else {
|
||||||
|
out.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
out.push(", buffer = " + this.initializeBuffer());
|
||||||
|
} else {
|
||||||
|
out.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// track the last context pushed into place to allow skipping the
|
||||||
|
// getContext opcode when it would be a noop
|
||||||
|
this.lastContext = 0;
|
||||||
|
this.source = out;
|
||||||
|
},
|
||||||
|
|
||||||
|
createFunctionContext: function(asObject) {
|
||||||
|
var locals = this.stackVars.concat(this.registers.list);
|
||||||
|
|
||||||
|
if(locals.length > 0) {
|
||||||
|
this.source[1] = this.source[1] + ", " + locals.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate minimizer alias mappings
|
||||||
|
if (!this.isChild) {
|
||||||
|
for (var alias in this.context.aliases) {
|
||||||
|
if (this.context.aliases.hasOwnProperty(alias)) {
|
||||||
|
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.source[1]) {
|
||||||
|
this.source[1] = "var " + this.source[1].substring(2) + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge children
|
||||||
|
if (!this.isChild) {
|
||||||
|
this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
this.pushSource("return buffer;");
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
|
||||||
|
|
||||||
|
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
||||||
|
params.push("depth" + this.environment.depths.list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a second pass over the output to merge content when possible
|
||||||
|
var source = this.mergeSource();
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
source = this.compilerInfo()+source;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asObject) {
|
||||||
|
params.push(source);
|
||||||
|
|
||||||
|
return Function.apply(this, params);
|
||||||
|
} else {
|
||||||
|
var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
|
||||||
|
log('debug', functionSource + "\n\n");
|
||||||
|
return functionSource;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mergeSource: function() {
|
||||||
|
// WARN: We are not handling the case where buffer is still populated as the source should
|
||||||
|
// not have buffer append operations as their final action.
|
||||||
|
var source = '',
|
||||||
|
buffer;
|
||||||
|
for (var i = 0, len = this.source.length; i < len; i++) {
|
||||||
|
var line = this.source[i];
|
||||||
|
if (line.appendToBuffer) {
|
||||||
|
if (buffer) {
|
||||||
|
buffer = buffer + '\n + ' + line.content;
|
||||||
|
} else {
|
||||||
|
buffer = line.content;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (buffer) {
|
||||||
|
source += 'buffer += ' + buffer + ';\n ';
|
||||||
|
buffer = undefined;
|
||||||
|
}
|
||||||
|
source += line + '\n ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return source;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [blockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// On stack, after: return value of blockHelperMissing
|
||||||
|
//
|
||||||
|
// The purpose of this opcode is to take a block of the form
|
||||||
|
// `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
|
||||||
|
// replace it on the stack with the result of properly
|
||||||
|
// invoking blockHelperMissing.
|
||||||
|
blockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
return "blockHelperMissing.call(" + params.join(", ") + ")";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [ambiguousBlockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// Compiler value, before: lastHelper=value of last found helper, if any
|
||||||
|
// On stack, after, if no lastHelper: same as [blockValue]
|
||||||
|
// On stack, after, if lastHelper: value
|
||||||
|
ambiguousBlockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
var current = this.topStack();
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
|
||||||
|
this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendContent]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Appends the string value of `content` to the current buffer
|
||||||
|
appendContent: function(content) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
content = this.pendingContent + content;
|
||||||
|
}
|
||||||
|
if (this.stripNext) {
|
||||||
|
content = content.replace(/^\s+/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingContent = content;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [strip]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Removes any trailing whitespace from the prior content node and flags
|
||||||
|
// the next operation for stripping if it is a content node.
|
||||||
|
strip: function() {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.pendingContent = this.pendingContent.replace(/\s+$/, '');
|
||||||
|
}
|
||||||
|
this.stripNext = 'strip';
|
||||||
|
},
|
||||||
|
|
||||||
|
// [append]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Coerces `value` to a String and appends it to the current buffer.
|
||||||
|
//
|
||||||
|
// If `value` is truthy, or 0, it is coerced into a string and appended
|
||||||
|
// Otherwise, the empty string is appended
|
||||||
|
append: function() {
|
||||||
|
// Force anything that is inlined onto the stack so we don't have duplication
|
||||||
|
// when we examine local
|
||||||
|
this.flushInline();
|
||||||
|
var local = this.popStack();
|
||||||
|
this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
this.pushSource("else { " + this.appendToBuffer("''") + " }");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendEscaped]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Escape `value` and append it to the buffer
|
||||||
|
appendEscaped: function() {
|
||||||
|
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
||||||
|
|
||||||
|
this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [getContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
// Compiler value, after: lastContext=depth
|
||||||
|
//
|
||||||
|
// Set the value of the `lastContext` compiler value to the depth
|
||||||
|
getContext: function(depth) {
|
||||||
|
if(this.lastContext !== depth) {
|
||||||
|
this.lastContext = depth;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupOnContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext[name], ...
|
||||||
|
//
|
||||||
|
// Looks up the value of `name` on the current context and pushes
|
||||||
|
// it onto the stack.
|
||||||
|
lookupOnContext: function(name) {
|
||||||
|
this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext, ...
|
||||||
|
//
|
||||||
|
// Pushes the value of the current context onto the stack.
|
||||||
|
pushContext: function() {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [resolvePossibleLambda]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: resolved value, ...
|
||||||
|
//
|
||||||
|
// If the `value` is a lambda, replace it on the stack by
|
||||||
|
// the return value of the lambda
|
||||||
|
resolvePossibleLambda: function() {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookup]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: value[name], ...
|
||||||
|
//
|
||||||
|
// Replace the value on the stack with the result of looking
|
||||||
|
// up `name` on `value`
|
||||||
|
lookup: function(name) {
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupData]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: data, ...
|
||||||
|
//
|
||||||
|
// Push the data lookup operator
|
||||||
|
lookupData: function() {
|
||||||
|
this.pushStackLiteral('data');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushStringParam]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: string, currentContext, ...
|
||||||
|
//
|
||||||
|
// This opcode is designed for use in string mode, which
|
||||||
|
// provides the string value of a parameter along with its
|
||||||
|
// depth rather than resolving it immediately.
|
||||||
|
pushStringParam: function(string, type) {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
|
||||||
|
this.pushString(type);
|
||||||
|
|
||||||
|
// If it's a subexpression, the string result
|
||||||
|
// will be pushed after this opcode.
|
||||||
|
if (type !== 'sexpr') {
|
||||||
|
if (typeof string === 'string') {
|
||||||
|
this.pushString(string);
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emptyHash: function() {
|
||||||
|
this.pushStackLiteral('{}');
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{}'); // hashContexts
|
||||||
|
this.push('{}'); // hashTypes
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pushHash: function() {
|
||||||
|
if (this.hash) {
|
||||||
|
this.hashes.push(this.hash);
|
||||||
|
}
|
||||||
|
this.hash = {values: [], types: [], contexts: []};
|
||||||
|
},
|
||||||
|
popHash: function() {
|
||||||
|
var hash = this.hash;
|
||||||
|
this.hash = this.hashes.pop();
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{' + hash.contexts.join(',') + '}');
|
||||||
|
this.push('{' + hash.types.join(',') + '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push('{\n ' + hash.values.join(',\n ') + '\n }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushString]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: quotedString(string), ...
|
||||||
|
//
|
||||||
|
// Push a quoted version of `string` onto the stack
|
||||||
|
pushString: function(string) {
|
||||||
|
this.pushStackLiteral(this.quotedString(string));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [push]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: expr, ...
|
||||||
|
//
|
||||||
|
// Push an expression onto the stack
|
||||||
|
push: function(expr) {
|
||||||
|
this.inlineStack.push(expr);
|
||||||
|
return expr;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushLiteral]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: value, ...
|
||||||
|
//
|
||||||
|
// Pushes a value onto the stack. This operation prevents
|
||||||
|
// the compiler from creating a temporary variable to hold
|
||||||
|
// it.
|
||||||
|
pushLiteral: function(value) {
|
||||||
|
this.pushStackLiteral(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushProgram]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: program(guid), ...
|
||||||
|
//
|
||||||
|
// Push a program expression onto the stack. This takes
|
||||||
|
// a compile-time guid and converts it into a runtime-accessible
|
||||||
|
// expression.
|
||||||
|
pushProgram: function(guid) {
|
||||||
|
if (guid != null) {
|
||||||
|
this.pushStackLiteral(this.programExpression(guid));
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// Pops off the helper's parameters, invokes the helper,
|
||||||
|
// and pushes the helper's return value onto the stack.
|
||||||
|
//
|
||||||
|
// If the helper is not found, `helperMissing` is called.
|
||||||
|
invokeHelper: function(paramSize, name, isRoot) {
|
||||||
|
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
|
||||||
|
var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
lookup += ',' + helper.paramsInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push(
|
||||||
|
'('
|
||||||
|
+ lookup
|
||||||
|
+ ',helper '
|
||||||
|
+ '? helper.call(' + helper.callParams + ') '
|
||||||
|
+ ': helperMissing.call(' + helper.helperMissingParams + '))');
|
||||||
|
|
||||||
|
// Always flush subexpressions. This is both to prevent the compounding size issue that
|
||||||
|
// occurs when the code has to be duplicated for inlining and also to prevent errors
|
||||||
|
// due to the incorrect options object being passed due to the shared register.
|
||||||
|
if (!isRoot) {
|
||||||
|
this.flushInline();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeKnownHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// This operation is used when the helper is known to exist,
|
||||||
|
// so a `helperMissing` fallback is not required.
|
||||||
|
invokeKnownHelper: function(paramSize, name) {
|
||||||
|
var helper = this.setupHelper(paramSize, name);
|
||||||
|
this.push(helper.name + ".call(" + helper.callParams + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeAmbiguous]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of disambiguation
|
||||||
|
//
|
||||||
|
// This operation is used when an expression like `{{foo}}`
|
||||||
|
// is provided, but we don't know at compile-time whether it
|
||||||
|
// is a helper or a path.
|
||||||
|
//
|
||||||
|
// This operation emits more code than the other options,
|
||||||
|
// and can be avoided by passing the `knownHelpers` and
|
||||||
|
// `knownHelpersOnly` flags at compile-time.
|
||||||
|
invokeAmbiguous: function(name, helperCall) {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
this.emptyHash();
|
||||||
|
var helper = this.setupHelper(0, name, helperCall);
|
||||||
|
|
||||||
|
var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
var nextStack = this.nextStack();
|
||||||
|
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
this.pushSource(helper.paramsInit);
|
||||||
|
}
|
||||||
|
this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
|
||||||
|
this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokePartial]
|
||||||
|
//
|
||||||
|
// On stack, before: context, ...
|
||||||
|
// On stack after: result of partial invocation
|
||||||
|
//
|
||||||
|
// This operation pops off a context, invokes a partial with that context,
|
||||||
|
// and pushes the result of the invocation back.
|
||||||
|
invokePartial: function(name) {
|
||||||
|
var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
|
||||||
|
|
||||||
|
if (this.options.data) {
|
||||||
|
params.push("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
this.push("self.invokePartial(" + params.join(", ") + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [assignToHash]
|
||||||
|
//
|
||||||
|
// On stack, before: value, hash, ...
|
||||||
|
// On stack, after: hash, ...
|
||||||
|
//
|
||||||
|
// Pops a value and hash off the stack, assigns `hash[key] = value`
|
||||||
|
// and pushes the hash back onto the stack.
|
||||||
|
assignToHash: function(key) {
|
||||||
|
var value = this.popStack(),
|
||||||
|
context,
|
||||||
|
type;
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
type = this.popStack();
|
||||||
|
context = this.popStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = this.hash;
|
||||||
|
if (context) {
|
||||||
|
hash.contexts.push("'" + key + "': " + context);
|
||||||
|
}
|
||||||
|
if (type) {
|
||||||
|
hash.types.push("'" + key + "': " + type);
|
||||||
|
}
|
||||||
|
hash.values.push("'" + key + "': (" + value + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
|
||||||
|
compiler: JavaScriptCompiler,
|
||||||
|
|
||||||
|
compileChildren: function(environment, options) {
|
||||||
|
var children = environment.children, child, compiler;
|
||||||
|
|
||||||
|
for(var i=0, l=children.length; i<l; i++) {
|
||||||
|
child = children[i];
|
||||||
|
compiler = new this.compiler();
|
||||||
|
|
||||||
|
var index = this.matchExistingProgram(child);
|
||||||
|
|
||||||
|
if (index == null) {
|
||||||
|
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
|
||||||
|
index = this.context.programs.length;
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
this.context.programs[index] = compiler.compile(child, options, this.context);
|
||||||
|
this.context.environments[index] = child;
|
||||||
|
} else {
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matchExistingProgram: function(child) {
|
||||||
|
for (var i = 0, len = this.context.environments.length; i < len; i++) {
|
||||||
|
var environment = this.context.environments[i];
|
||||||
|
if (environment && environment.equals(child)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
programExpression: function(guid) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
|
||||||
|
if(guid == null) {
|
||||||
|
return "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
var child = this.environment.children[guid],
|
||||||
|
depths = child.depths.list, depth;
|
||||||
|
|
||||||
|
var programParams = [child.index, child.name, "data"];
|
||||||
|
|
||||||
|
for(var i=0, l = depths.length; i<l; i++) {
|
||||||
|
depth = depths[i];
|
||||||
|
|
||||||
|
if(depth === 1) { programParams.push("depth0"); }
|
||||||
|
else { programParams.push("depth" + (depth - 1)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
|
||||||
|
},
|
||||||
|
|
||||||
|
register: function(name, val) {
|
||||||
|
this.useRegister(name);
|
||||||
|
this.pushSource(name + " = " + val + ";");
|
||||||
|
},
|
||||||
|
|
||||||
|
useRegister: function(name) {
|
||||||
|
if(!this.registers[name]) {
|
||||||
|
this.registers[name] = true;
|
||||||
|
this.registers.list.push(name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStackLiteral: function(item) {
|
||||||
|
return this.push(new Literal(item));
|
||||||
|
},
|
||||||
|
|
||||||
|
pushSource: function(source) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
|
||||||
|
this.pendingContent = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source) {
|
||||||
|
this.source.push(source);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStack: function(item) {
|
||||||
|
this.flushInline();
|
||||||
|
|
||||||
|
var stack = this.incrStack();
|
||||||
|
if (item) {
|
||||||
|
this.pushSource(stack + " = " + item + ";");
|
||||||
|
}
|
||||||
|
this.compileStack.push(stack);
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
replaceStack: function(callback) {
|
||||||
|
var prefix = '',
|
||||||
|
inline = this.isInline(),
|
||||||
|
stack,
|
||||||
|
createdStack,
|
||||||
|
usedLiteral;
|
||||||
|
|
||||||
|
// If we are currently inline then we want to merge the inline statement into the
|
||||||
|
// replacement statement via ','
|
||||||
|
if (inline) {
|
||||||
|
var top = this.popStack(true);
|
||||||
|
|
||||||
|
if (top instanceof Literal) {
|
||||||
|
// Literals do not need to be inlined
|
||||||
|
stack = top.value;
|
||||||
|
usedLiteral = true;
|
||||||
|
} else {
|
||||||
|
// Get or create the current stack name for use by the inline
|
||||||
|
createdStack = !this.stackSlot;
|
||||||
|
var name = !createdStack ? this.topStackName() : this.incrStack();
|
||||||
|
|
||||||
|
prefix = '(' + this.push(name) + ' = ' + top + '),';
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = callback.call(this, stack);
|
||||||
|
|
||||||
|
if (inline) {
|
||||||
|
if (!usedLiteral) {
|
||||||
|
this.popStack();
|
||||||
|
}
|
||||||
|
if (createdStack) {
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
this.push('(' + prefix + item + ')');
|
||||||
|
} else {
|
||||||
|
// Prevent modification of the context depth variable. Through replaceStack
|
||||||
|
if (!/^stack/.test(stack)) {
|
||||||
|
stack = this.nextStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pushSource(stack + " = (" + prefix + item + ");");
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
nextStack: function() {
|
||||||
|
return this.pushStack();
|
||||||
|
},
|
||||||
|
|
||||||
|
incrStack: function() {
|
||||||
|
this.stackSlot++;
|
||||||
|
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
|
||||||
|
return this.topStackName();
|
||||||
|
},
|
||||||
|
topStackName: function() {
|
||||||
|
return "stack" + this.stackSlot;
|
||||||
|
},
|
||||||
|
flushInline: function() {
|
||||||
|
var inlineStack = this.inlineStack;
|
||||||
|
if (inlineStack.length) {
|
||||||
|
this.inlineStack = [];
|
||||||
|
for (var i = 0, len = inlineStack.length; i < len; i++) {
|
||||||
|
var entry = inlineStack[i];
|
||||||
|
if (entry instanceof Literal) {
|
||||||
|
this.compileStack.push(entry);
|
||||||
|
} else {
|
||||||
|
this.pushStack(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isInline: function() {
|
||||||
|
return this.inlineStack.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
popStack: function(wrapped) {
|
||||||
|
var inline = this.isInline(),
|
||||||
|
item = (inline ? this.inlineStack : this.compileStack).pop();
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
if (!inline) {
|
||||||
|
if (!this.stackSlot) {
|
||||||
|
throw new Exception('Invalid stack pop');
|
||||||
|
}
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
topStack: function(wrapped) {
|
||||||
|
var stack = (this.isInline() ? this.inlineStack : this.compileStack),
|
||||||
|
item = stack[stack.length - 1];
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
quotedString: function(str) {
|
||||||
|
return '"' + str
|
||||||
|
.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/"/g, '\\"')
|
||||||
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\r/g, '\\r')
|
||||||
|
.replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
|
||||||
|
.replace(/\u2029/g, '\\u2029') + '"';
|
||||||
|
},
|
||||||
|
|
||||||
|
setupHelper: function(paramSize, name, missingParams) {
|
||||||
|
var params = [],
|
||||||
|
paramsInit = this.setupParams(paramSize, params, missingParams);
|
||||||
|
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
return {
|
||||||
|
params: params,
|
||||||
|
paramsInit: paramsInit,
|
||||||
|
name: foundHelper,
|
||||||
|
callParams: ["depth0"].concat(params).join(", "),
|
||||||
|
helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
setupOptions: function(paramSize, params) {
|
||||||
|
var options = [], contexts = [], types = [], param, inverse, program;
|
||||||
|
|
||||||
|
options.push("hash:" + this.popStack());
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("hashTypes:" + this.popStack());
|
||||||
|
options.push("hashContexts:" + this.popStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse = this.popStack();
|
||||||
|
program = this.popStack();
|
||||||
|
|
||||||
|
// Avoid setting fn and inverse if neither are set. This allows
|
||||||
|
// helpers to do a check for `if (options.fn)`
|
||||||
|
if (program || inverse) {
|
||||||
|
if (!program) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
program = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inverse) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
inverse = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
options.push("inverse:" + inverse);
|
||||||
|
options.push("fn:" + program);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=0; i<paramSize; i++) {
|
||||||
|
param = this.popStack();
|
||||||
|
params.push(param);
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
types.push(this.popStack());
|
||||||
|
contexts.push(this.popStack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("contexts:[" + contexts.join(",") + "]");
|
||||||
|
options.push("types:[" + types.join(",") + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.data) {
|
||||||
|
options.push("data:data");
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
|
||||||
|
// the params and contexts arguments are passed in arrays
|
||||||
|
// to fill in
|
||||||
|
setupParams: function(paramSize, params, useRegister) {
|
||||||
|
var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
|
||||||
|
|
||||||
|
if (useRegister) {
|
||||||
|
this.useRegister('options');
|
||||||
|
params.push('options');
|
||||||
|
return 'options=' + options;
|
||||||
|
} else {
|
||||||
|
params.push(options);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var reservedWords = (
|
||||||
|
"break else new var" +
|
||||||
|
" case finally return void" +
|
||||||
|
" catch for switch while" +
|
||||||
|
" continue function this with" +
|
||||||
|
" default if throw" +
|
||||||
|
" delete in try" +
|
||||||
|
" do instanceof typeof" +
|
||||||
|
" abstract enum int short" +
|
||||||
|
" boolean export interface static" +
|
||||||
|
" byte extends long super" +
|
||||||
|
" char final native synchronized" +
|
||||||
|
" class float package throws" +
|
||||||
|
" const goto private transient" +
|
||||||
|
" debugger implements protected volatile" +
|
||||||
|
" double import public let yield"
|
||||||
|
).split(" ");
|
||||||
|
|
||||||
|
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
|
||||||
|
|
||||||
|
for(var i=0, l=reservedWords.length; i<l; i++) {
|
||||||
|
compilerWords[reservedWords[i]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
||||||
|
if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
__exports__["default"] = JavaScriptCompiler;
|
||||||
|
});
|
||||||
494
node_modules/handlebars/dist/amd/handlebars/compiler/parser.js
generated
vendored
Normal file
494
node_modules/handlebars/dist/amd/handlebars/compiler/parser.js
generated
vendored
Normal file
@@ -0,0 +1,494 @@
|
|||||||
|
define(
|
||||||
|
["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
"use strict";
|
||||||
|
/* jshint ignore:start */
|
||||||
|
/* Jison generated parser */
|
||||||
|
var handlebars = (function(){
|
||||||
|
var parser = {trace: function trace() { },
|
||||||
|
yy: {},
|
||||||
|
symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
|
||||||
|
terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
|
||||||
|
productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
|
||||||
|
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
||||||
|
|
||||||
|
var $0 = $$.length - 1;
|
||||||
|
switch (yystate) {
|
||||||
|
case 1: return new yy.ProgramNode($$[$0-1], this._$);
|
||||||
|
break;
|
||||||
|
case 2: return new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
|
||||||
|
break;
|
||||||
|
case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 7:this.$ = new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 8:this.$ = new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 9:this.$ = [$$[$0]];
|
||||||
|
break;
|
||||||
|
case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
||||||
|
break;
|
||||||
|
case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 13:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 14:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 15:this.$ = new yy.ContentNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 16:this.$ = new yy.CommentNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
|
||||||
|
break;
|
||||||
|
case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
|
||||||
|
break;
|
||||||
|
case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
|
||||||
|
break;
|
||||||
|
case 26:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 27:this.$ = new yy.StringNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 30:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
|
||||||
|
break;
|
||||||
|
case 32:this.$ = new yy.HashNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 33:this.$ = [$$[$0-2], $$[$0]];
|
||||||
|
break;
|
||||||
|
case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
|
||||||
|
break;
|
||||||
|
case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
|
||||||
|
break;
|
||||||
|
case 37:this.$ = new yy.DataNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 38:this.$ = new yy.IdNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
|
||||||
|
break;
|
||||||
|
case 40:this.$ = [{part: $$[$0]}];
|
||||||
|
break;
|
||||||
|
case 43:this.$ = [];
|
||||||
|
break;
|
||||||
|
case 44:$$[$0-1].push($$[$0]);
|
||||||
|
break;
|
||||||
|
case 47:this.$ = [$$[$0]];
|
||||||
|
break;
|
||||||
|
case 48:$$[$0-1].push($$[$0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
|
||||||
|
defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
|
||||||
|
parseError: function parseError(str, hash) {
|
||||||
|
throw new Error(str);
|
||||||
|
},
|
||||||
|
parse: function parse(input) {
|
||||||
|
var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
|
||||||
|
this.lexer.setInput(input);
|
||||||
|
this.lexer.yy = this.yy;
|
||||||
|
this.yy.lexer = this.lexer;
|
||||||
|
this.yy.parser = this;
|
||||||
|
if (typeof this.lexer.yylloc == "undefined")
|
||||||
|
this.lexer.yylloc = {};
|
||||||
|
var yyloc = this.lexer.yylloc;
|
||||||
|
lstack.push(yyloc);
|
||||||
|
var ranges = this.lexer.options && this.lexer.options.ranges;
|
||||||
|
if (typeof this.yy.parseError === "function")
|
||||||
|
this.parseError = this.yy.parseError;
|
||||||
|
function popStack(n) {
|
||||||
|
stack.length = stack.length - 2 * n;
|
||||||
|
vstack.length = vstack.length - n;
|
||||||
|
lstack.length = lstack.length - n;
|
||||||
|
}
|
||||||
|
function lex() {
|
||||||
|
var token;
|
||||||
|
token = self.lexer.lex() || 1;
|
||||||
|
if (typeof token !== "number") {
|
||||||
|
token = self.symbols_[token] || token;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
|
||||||
|
while (true) {
|
||||||
|
state = stack[stack.length - 1];
|
||||||
|
if (this.defaultActions[state]) {
|
||||||
|
action = this.defaultActions[state];
|
||||||
|
} else {
|
||||||
|
if (symbol === null || typeof symbol == "undefined") {
|
||||||
|
symbol = lex();
|
||||||
|
}
|
||||||
|
action = table[state] && table[state][symbol];
|
||||||
|
}
|
||||||
|
if (typeof action === "undefined" || !action.length || !action[0]) {
|
||||||
|
var errStr = "";
|
||||||
|
if (!recovering) {
|
||||||
|
expected = [];
|
||||||
|
for (p in table[state])
|
||||||
|
if (this.terminals_[p] && p > 2) {
|
||||||
|
expected.push("'" + this.terminals_[p] + "'");
|
||||||
|
}
|
||||||
|
if (this.lexer.showPosition) {
|
||||||
|
errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
|
||||||
|
} else {
|
||||||
|
errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
|
||||||
|
}
|
||||||
|
this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action[0] instanceof Array && action.length > 1) {
|
||||||
|
throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
|
||||||
|
}
|
||||||
|
switch (action[0]) {
|
||||||
|
case 1:
|
||||||
|
stack.push(symbol);
|
||||||
|
vstack.push(this.lexer.yytext);
|
||||||
|
lstack.push(this.lexer.yylloc);
|
||||||
|
stack.push(action[1]);
|
||||||
|
symbol = null;
|
||||||
|
if (!preErrorSymbol) {
|
||||||
|
yyleng = this.lexer.yyleng;
|
||||||
|
yytext = this.lexer.yytext;
|
||||||
|
yylineno = this.lexer.yylineno;
|
||||||
|
yyloc = this.lexer.yylloc;
|
||||||
|
if (recovering > 0)
|
||||||
|
recovering--;
|
||||||
|
} else {
|
||||||
|
symbol = preErrorSymbol;
|
||||||
|
preErrorSymbol = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
len = this.productions_[action[1]][1];
|
||||||
|
yyval.$ = vstack[vstack.length - len];
|
||||||
|
yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
|
||||||
|
if (ranges) {
|
||||||
|
yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
|
||||||
|
}
|
||||||
|
r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
|
||||||
|
if (typeof r !== "undefined") {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
if (len) {
|
||||||
|
stack = stack.slice(0, -1 * len * 2);
|
||||||
|
vstack = vstack.slice(0, -1 * len);
|
||||||
|
lstack = lstack.slice(0, -1 * len);
|
||||||
|
}
|
||||||
|
stack.push(this.productions_[action[1]][0]);
|
||||||
|
vstack.push(yyval.$);
|
||||||
|
lstack.push(yyval._$);
|
||||||
|
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
|
||||||
|
stack.push(newState);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function stripFlags(open, close) {
|
||||||
|
return {
|
||||||
|
left: open.charAt(2) === '~',
|
||||||
|
right: close.charAt(0) === '~' || close.charAt(1) === '~'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jison generated lexer */
|
||||||
|
var lexer = (function(){
|
||||||
|
var lexer = ({EOF:1,
|
||||||
|
parseError:function parseError(str, hash) {
|
||||||
|
if (this.yy.parser) {
|
||||||
|
this.yy.parser.parseError(str, hash);
|
||||||
|
} else {
|
||||||
|
throw new Error(str);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setInput:function (input) {
|
||||||
|
this._input = input;
|
||||||
|
this._more = this._less = this.done = false;
|
||||||
|
this.yylineno = this.yyleng = 0;
|
||||||
|
this.yytext = this.matched = this.match = '';
|
||||||
|
this.conditionStack = ['INITIAL'];
|
||||||
|
this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
|
||||||
|
if (this.options.ranges) this.yylloc.range = [0,0];
|
||||||
|
this.offset = 0;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
input:function () {
|
||||||
|
var ch = this._input[0];
|
||||||
|
this.yytext += ch;
|
||||||
|
this.yyleng++;
|
||||||
|
this.offset++;
|
||||||
|
this.match += ch;
|
||||||
|
this.matched += ch;
|
||||||
|
var lines = ch.match(/(?:\r\n?|\n).*/g);
|
||||||
|
if (lines) {
|
||||||
|
this.yylineno++;
|
||||||
|
this.yylloc.last_line++;
|
||||||
|
} else {
|
||||||
|
this.yylloc.last_column++;
|
||||||
|
}
|
||||||
|
if (this.options.ranges) this.yylloc.range[1]++;
|
||||||
|
|
||||||
|
this._input = this._input.slice(1);
|
||||||
|
return ch;
|
||||||
|
},
|
||||||
|
unput:function (ch) {
|
||||||
|
var len = ch.length;
|
||||||
|
var lines = ch.split(/(?:\r\n?|\n)/g);
|
||||||
|
|
||||||
|
this._input = ch + this._input;
|
||||||
|
this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
|
||||||
|
//this.yyleng -= len;
|
||||||
|
this.offset -= len;
|
||||||
|
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
|
||||||
|
this.match = this.match.substr(0, this.match.length-1);
|
||||||
|
this.matched = this.matched.substr(0, this.matched.length-1);
|
||||||
|
|
||||||
|
if (lines.length-1) this.yylineno -= lines.length-1;
|
||||||
|
var r = this.yylloc.range;
|
||||||
|
|
||||||
|
this.yylloc = {first_line: this.yylloc.first_line,
|
||||||
|
last_line: this.yylineno+1,
|
||||||
|
first_column: this.yylloc.first_column,
|
||||||
|
last_column: lines ?
|
||||||
|
(lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
|
||||||
|
this.yylloc.first_column - len
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.options.ranges) {
|
||||||
|
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
more:function () {
|
||||||
|
this._more = true;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
less:function (n) {
|
||||||
|
this.unput(this.match.slice(n));
|
||||||
|
},
|
||||||
|
pastInput:function () {
|
||||||
|
var past = this.matched.substr(0, this.matched.length - this.match.length);
|
||||||
|
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
|
||||||
|
},
|
||||||
|
upcomingInput:function () {
|
||||||
|
var next = this.match;
|
||||||
|
if (next.length < 20) {
|
||||||
|
next += this._input.substr(0, 20-next.length);
|
||||||
|
}
|
||||||
|
return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
|
||||||
|
},
|
||||||
|
showPosition:function () {
|
||||||
|
var pre = this.pastInput();
|
||||||
|
var c = new Array(pre.length + 1).join("-");
|
||||||
|
return pre + this.upcomingInput() + "\n" + c+"^";
|
||||||
|
},
|
||||||
|
next:function () {
|
||||||
|
if (this.done) {
|
||||||
|
return this.EOF;
|
||||||
|
}
|
||||||
|
if (!this._input) this.done = true;
|
||||||
|
|
||||||
|
var token,
|
||||||
|
match,
|
||||||
|
tempMatch,
|
||||||
|
index,
|
||||||
|
col,
|
||||||
|
lines;
|
||||||
|
if (!this._more) {
|
||||||
|
this.yytext = '';
|
||||||
|
this.match = '';
|
||||||
|
}
|
||||||
|
var rules = this._currentRules();
|
||||||
|
for (var i=0;i < rules.length; i++) {
|
||||||
|
tempMatch = this._input.match(this.rules[rules[i]]);
|
||||||
|
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
|
||||||
|
match = tempMatch;
|
||||||
|
index = i;
|
||||||
|
if (!this.options.flex) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (match) {
|
||||||
|
lines = match[0].match(/(?:\r\n?|\n).*/g);
|
||||||
|
if (lines) this.yylineno += lines.length;
|
||||||
|
this.yylloc = {first_line: this.yylloc.last_line,
|
||||||
|
last_line: this.yylineno+1,
|
||||||
|
first_column: this.yylloc.last_column,
|
||||||
|
last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
|
||||||
|
this.yytext += match[0];
|
||||||
|
this.match += match[0];
|
||||||
|
this.matches = match;
|
||||||
|
this.yyleng = this.yytext.length;
|
||||||
|
if (this.options.ranges) {
|
||||||
|
this.yylloc.range = [this.offset, this.offset += this.yyleng];
|
||||||
|
}
|
||||||
|
this._more = false;
|
||||||
|
this._input = this._input.slice(match[0].length);
|
||||||
|
this.matched += match[0];
|
||||||
|
token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
|
||||||
|
if (this.done && this._input) this.done = false;
|
||||||
|
if (token) return token;
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
if (this._input === "") {
|
||||||
|
return this.EOF;
|
||||||
|
} else {
|
||||||
|
return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
|
||||||
|
{text: "", token: null, line: this.yylineno});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lex:function lex() {
|
||||||
|
var r = this.next();
|
||||||
|
if (typeof r !== 'undefined') {
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
return this.lex();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
begin:function begin(condition) {
|
||||||
|
this.conditionStack.push(condition);
|
||||||
|
},
|
||||||
|
popState:function popState() {
|
||||||
|
return this.conditionStack.pop();
|
||||||
|
},
|
||||||
|
_currentRules:function _currentRules() {
|
||||||
|
return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
|
||||||
|
},
|
||||||
|
topState:function () {
|
||||||
|
return this.conditionStack[this.conditionStack.length-2];
|
||||||
|
},
|
||||||
|
pushState:function begin(condition) {
|
||||||
|
this.begin(condition);
|
||||||
|
}});
|
||||||
|
lexer.options = {};
|
||||||
|
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
||||||
|
|
||||||
|
|
||||||
|
function strip(start, end) {
|
||||||
|
return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var YYSTATE=YY_START
|
||||||
|
switch($avoiding_name_collisions) {
|
||||||
|
case 0:
|
||||||
|
if(yy_.yytext.slice(-2) === "\\\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("mu");
|
||||||
|
} else if(yy_.yytext.slice(-1) === "\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("emu");
|
||||||
|
} else {
|
||||||
|
this.begin("mu");
|
||||||
|
}
|
||||||
|
if(yy_.yytext) return 14;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 1:return 14;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.popState();
|
||||||
|
return 14;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 3:strip(0,4); this.popState(); return 15;
|
||||||
|
break;
|
||||||
|
case 4:return 35;
|
||||||
|
break;
|
||||||
|
case 5:return 36;
|
||||||
|
break;
|
||||||
|
case 6:return 25;
|
||||||
|
break;
|
||||||
|
case 7:return 16;
|
||||||
|
break;
|
||||||
|
case 8:return 20;
|
||||||
|
break;
|
||||||
|
case 9:return 19;
|
||||||
|
break;
|
||||||
|
case 10:return 19;
|
||||||
|
break;
|
||||||
|
case 11:return 23;
|
||||||
|
break;
|
||||||
|
case 12:return 22;
|
||||||
|
break;
|
||||||
|
case 13:this.popState(); this.begin('com');
|
||||||
|
break;
|
||||||
|
case 14:strip(3,5); this.popState(); return 15;
|
||||||
|
break;
|
||||||
|
case 15:return 22;
|
||||||
|
break;
|
||||||
|
case 16:return 41;
|
||||||
|
break;
|
||||||
|
case 17:return 40;
|
||||||
|
break;
|
||||||
|
case 18:return 40;
|
||||||
|
break;
|
||||||
|
case 19:return 44;
|
||||||
|
break;
|
||||||
|
case 20:// ignore whitespace
|
||||||
|
break;
|
||||||
|
case 21:this.popState(); return 24;
|
||||||
|
break;
|
||||||
|
case 22:this.popState(); return 18;
|
||||||
|
break;
|
||||||
|
case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
|
||||||
|
break;
|
||||||
|
case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
|
||||||
|
break;
|
||||||
|
case 25:return 42;
|
||||||
|
break;
|
||||||
|
case 26:return 34;
|
||||||
|
break;
|
||||||
|
case 27:return 34;
|
||||||
|
break;
|
||||||
|
case 28:return 33;
|
||||||
|
break;
|
||||||
|
case 29:return 40;
|
||||||
|
break;
|
||||||
|
case 30:yy_.yytext = strip(1,2); return 40;
|
||||||
|
break;
|
||||||
|
case 31:return 'INVALID';
|
||||||
|
break;
|
||||||
|
case 32:return 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
|
||||||
|
lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
|
||||||
|
return lexer;})()
|
||||||
|
parser.lexer = lexer;
|
||||||
|
function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
|
||||||
|
return new Parser;
|
||||||
|
})();__exports__["default"] = handlebars;
|
||||||
|
/* jshint ignore:end */
|
||||||
|
});
|
||||||
142
node_modules/handlebars/dist/amd/handlebars/compiler/printer.js
generated
vendored
Normal file
142
node_modules/handlebars/dist/amd/handlebars/compiler/printer.js
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
define(
|
||||||
|
["./visitor","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Visitor = __dependency1__["default"];
|
||||||
|
|
||||||
|
function print(ast) {
|
||||||
|
return new PrintVisitor().accept(ast);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.print = print;function PrintVisitor() {
|
||||||
|
this.padding = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.PrintVisitor = PrintVisitor;PrintVisitor.prototype = new Visitor();
|
||||||
|
|
||||||
|
PrintVisitor.prototype.pad = function(string, newline) {
|
||||||
|
var out = "";
|
||||||
|
|
||||||
|
for(var i=0,l=this.padding; i<l; i++) {
|
||||||
|
out = out + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
out = out + string;
|
||||||
|
|
||||||
|
if(newline !== false) { out = out + "\n"; }
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.program = function(program) {
|
||||||
|
var out = "",
|
||||||
|
statements = program.statements,
|
||||||
|
i, l;
|
||||||
|
|
||||||
|
for(i=0, l=statements.length; i<l; i++) {
|
||||||
|
out = out + this.accept(statements[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.padding--;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.block = function(block) {
|
||||||
|
var out = "";
|
||||||
|
|
||||||
|
out = out + this.pad("BLOCK:");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.mustache);
|
||||||
|
if (block.program) {
|
||||||
|
out = out + this.pad("PROGRAM:");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.program);
|
||||||
|
this.padding--;
|
||||||
|
}
|
||||||
|
if (block.inverse) {
|
||||||
|
if (block.program) { this.padding++; }
|
||||||
|
out = out + this.pad("{{^}}");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.inverse);
|
||||||
|
this.padding--;
|
||||||
|
if (block.program) { this.padding--; }
|
||||||
|
}
|
||||||
|
this.padding--;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.sexpr = function(sexpr) {
|
||||||
|
var params = sexpr.params, paramStrings = [], hash;
|
||||||
|
|
||||||
|
for(var i=0, l=params.length; i<l; i++) {
|
||||||
|
paramStrings.push(this.accept(params[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
params = "[" + paramStrings.join(", ") + "]";
|
||||||
|
|
||||||
|
hash = sexpr.hash ? " " + this.accept(sexpr.hash) : "";
|
||||||
|
|
||||||
|
return this.accept(sexpr.id) + " " + params + hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.mustache = function(mustache) {
|
||||||
|
return this.pad("{{ " + this.accept(mustache.sexpr) + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.partial = function(partial) {
|
||||||
|
var content = this.accept(partial.partialName);
|
||||||
|
if(partial.context) { content = content + " " + this.accept(partial.context); }
|
||||||
|
return this.pad("{{> " + content + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.hash = function(hash) {
|
||||||
|
var pairs = hash.pairs;
|
||||||
|
var joinedPairs = [], left, right;
|
||||||
|
|
||||||
|
for(var i=0, l=pairs.length; i<l; i++) {
|
||||||
|
left = pairs[i][0];
|
||||||
|
right = this.accept(pairs[i][1]);
|
||||||
|
joinedPairs.push( left + "=" + right );
|
||||||
|
}
|
||||||
|
|
||||||
|
return "HASH{" + joinedPairs.join(", ") + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.STRING = function(string) {
|
||||||
|
return '"' + string.string + '"';
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.INTEGER = function(integer) {
|
||||||
|
return "INTEGER{" + integer.integer + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.BOOLEAN = function(bool) {
|
||||||
|
return "BOOLEAN{" + bool.bool + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.ID = function(id) {
|
||||||
|
var path = id.parts.join("/");
|
||||||
|
if(id.parts.length > 1) {
|
||||||
|
return "PATH:" + path;
|
||||||
|
} else {
|
||||||
|
return "ID:" + path;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.PARTIAL_NAME = function(partialName) {
|
||||||
|
return "PARTIAL:" + partialName.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.DATA = function(data) {
|
||||||
|
return "@" + this.accept(data.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.content = function(content) {
|
||||||
|
return this.pad("CONTENT[ '" + content.string + "' ]");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.comment = function(comment) {
|
||||||
|
return this.pad("{{! '" + comment.comment + "' }}");
|
||||||
|
};
|
||||||
|
});
|
||||||
16
node_modules/handlebars/dist/amd/handlebars/compiler/visitor.js
generated
vendored
Normal file
16
node_modules/handlebars/dist/amd/handlebars/compiler/visitor.js
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
define(
|
||||||
|
["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
"use strict";
|
||||||
|
function Visitor() {}
|
||||||
|
|
||||||
|
Visitor.prototype = {
|
||||||
|
constructor: Visitor,
|
||||||
|
|
||||||
|
accept: function(object) {
|
||||||
|
return this[object.type](object);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
__exports__["default"] = Visitor;
|
||||||
|
});
|
||||||
32
node_modules/handlebars/dist/amd/handlebars/exception.js
generated
vendored
Normal file
32
node_modules/handlebars/dist/amd/handlebars/exception.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
define(
|
||||||
|
["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
__exports__["default"] = Exception;
|
||||||
|
});
|
||||||
141
node_modules/handlebars/dist/amd/handlebars/runtime.js
generated
vendored
Normal file
141
node_modules/handlebars/dist/amd/handlebars/runtime.js
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
define(
|
||||||
|
["./utils","./exception","./base","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
|
||||||
|
|
||||||
|
function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
|
} else {
|
||||||
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
|
||||||
|
|
||||||
|
function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Just add water
|
||||||
|
var container = {
|
||||||
|
escapeExpression: Utils.escapeExpression,
|
||||||
|
invokePartial: invokePartialWrapper,
|
||||||
|
programs: [],
|
||||||
|
program: function(i, fn, data) {
|
||||||
|
var programWrapper = this.programs[i];
|
||||||
|
if(data) {
|
||||||
|
programWrapper = program(i, fn, data);
|
||||||
|
} else if (!programWrapper) {
|
||||||
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
|
}
|
||||||
|
return programWrapper;
|
||||||
|
},
|
||||||
|
merge: function(param, common) {
|
||||||
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
|
compilerInfo: null
|
||||||
|
};
|
||||||
|
|
||||||
|
return function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
helpers = options.helpers;
|
||||||
|
partials = options.partials;
|
||||||
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = args.length;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn(context, options.data || data);
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = 0;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
|
if(partial === undefined) {
|
||||||
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
|
} else if(partial instanceof Function) {
|
||||||
|
return partial(context, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.invokePartial = invokePartial;function noop() { return ""; }
|
||||||
|
|
||||||
|
__exports__.noop = noop;
|
||||||
|
});
|
||||||
15
node_modules/handlebars/dist/amd/handlebars/safe-string.js
generated
vendored
Normal file
15
node_modules/handlebars/dist/amd/handlebars/safe-string.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
define(
|
||||||
|
["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
"use strict";
|
||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeString.prototype.toString = function() {
|
||||||
|
return "" + this.string;
|
||||||
|
};
|
||||||
|
|
||||||
|
__exports__["default"] = SafeString;
|
||||||
|
});
|
||||||
80
node_modules/handlebars/dist/amd/handlebars/utils.js
generated
vendored
Normal file
80
node_modules/handlebars/dist/amd/handlebars/utils.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
define(
|
||||||
|
["./safe-string","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
"use strict";
|
||||||
|
/*jshint -W004 */
|
||||||
|
var SafeString = __dependency1__["default"];
|
||||||
|
|
||||||
|
var escape = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': """,
|
||||||
|
"'": "'",
|
||||||
|
"`": "`"
|
||||||
|
};
|
||||||
|
|
||||||
|
var badChars = /[&<>"'`]/g;
|
||||||
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
|
function escapeChar(chr) {
|
||||||
|
return escape[chr] || "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
function extend(obj, value) {
|
||||||
|
for(var key in value) {
|
||||||
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
obj[key] = value[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.extend = extend;var toString = Object.prototype.toString;
|
||||||
|
__exports__.toString = toString;
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var isFunction;
|
||||||
|
__exports__.isFunction = isFunction;
|
||||||
|
var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
|
};
|
||||||
|
__exports__.isArray = isArray;
|
||||||
|
|
||||||
|
function escapeExpression(string) {
|
||||||
|
// don't escape SafeStrings, since they're already safe
|
||||||
|
if (string instanceof SafeString) {
|
||||||
|
return string.toString();
|
||||||
|
} else if (!string && string !== 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
|
// an object's to string has escaped characters in it.
|
||||||
|
string = "" + string;
|
||||||
|
|
||||||
|
if(!possible.test(string)) { return string; }
|
||||||
|
return string.replace(badChars, escapeChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.escapeExpression = escapeExpression;function isEmpty(value) {
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
return true;
|
||||||
|
} else if (isArray(value) && value.length === 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.isEmpty = isEmpty;
|
||||||
|
});
|
||||||
37
node_modules/handlebars/dist/cjs/handlebars.js
generated
vendored
Normal file
37
node_modules/handlebars/dist/cjs/handlebars.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
"use strict";
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var Handlebars = require("./handlebars.runtime")["default"];
|
||||||
|
|
||||||
|
// Compiler imports
|
||||||
|
var AST = require("./handlebars/compiler/ast")["default"];
|
||||||
|
var Parser = require("./handlebars/compiler/base").parser;
|
||||||
|
var parse = require("./handlebars/compiler/base").parse;
|
||||||
|
var Compiler = require("./handlebars/compiler/compiler").Compiler;
|
||||||
|
var compile = require("./handlebars/compiler/compiler").compile;
|
||||||
|
var precompile = require("./handlebars/compiler/compiler").precompile;
|
||||||
|
var JavaScriptCompiler = require("./handlebars/compiler/javascript-compiler")["default"];
|
||||||
|
|
||||||
|
var _create = Handlebars.create;
|
||||||
|
var create = function() {
|
||||||
|
var hb = _create();
|
||||||
|
|
||||||
|
hb.compile = function(input, options) {
|
||||||
|
return compile(input, options, hb);
|
||||||
|
};
|
||||||
|
hb.precompile = function (input, options) {
|
||||||
|
return precompile(input, options, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
hb.AST = AST;
|
||||||
|
hb.Compiler = Compiler;
|
||||||
|
hb.JavaScriptCompiler = JavaScriptCompiler;
|
||||||
|
hb.Parser = Parser;
|
||||||
|
hb.parse = parse;
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
exports["default"] = Handlebars;
|
||||||
32
node_modules/handlebars/dist/cjs/handlebars.runtime.js
generated
vendored
Normal file
32
node_modules/handlebars/dist/cjs/handlebars.runtime.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
"use strict";
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var base = require("./handlebars/base");
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
var SafeString = require("./handlebars/safe-string")["default"];
|
||||||
|
var Exception = require("./handlebars/exception")["default"];
|
||||||
|
var Utils = require("./handlebars/utils");
|
||||||
|
var runtime = require("./handlebars/runtime");
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
exports["default"] = Handlebars;
|
||||||
180
node_modules/handlebars/dist/cjs/handlebars/base.js
generated
vendored
Normal file
180
node_modules/handlebars/dist/cjs/handlebars/base.js
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
"use strict";
|
||||||
|
var Utils = require("./utils");
|
||||||
|
var Exception = require("./exception")["default"];
|
||||||
|
|
||||||
|
var VERSION = "1.3.0";
|
||||||
|
exports.VERSION = VERSION;var COMPILER_REVISION = 4;
|
||||||
|
exports.COMPILER_REVISION = COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = {
|
||||||
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
|
2: '== 1.0.0-rc.3',
|
||||||
|
3: '== 1.0.0-rc.4',
|
||||||
|
4: '>= 1.0.0'
|
||||||
|
};
|
||||||
|
exports.REVISION_CHANGES = REVISION_CHANGES;
|
||||||
|
var isArray = Utils.isArray,
|
||||||
|
isFunction = Utils.isFunction,
|
||||||
|
toString = Utils.toString,
|
||||||
|
objectType = '[object Object]';
|
||||||
|
|
||||||
|
function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
|
Utils.extend(this.helpers, name);
|
||||||
|
} else {
|
||||||
|
if (inverse) { fn.not = inverse; }
|
||||||
|
this.helpers[name] = fn;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
registerPartial: function(name, str) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
Utils.extend(this.partials, name);
|
||||||
|
} else {
|
||||||
|
this.partials[name] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
|
if(arguments.length === 2) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if(context === true) {
|
||||||
|
return fn(this);
|
||||||
|
} else if(context === false || context == null) {
|
||||||
|
return inverse(this);
|
||||||
|
} else if (isArray(context)) {
|
||||||
|
if(context.length > 0) {
|
||||||
|
return instance.helpers.each(context, options);
|
||||||
|
} else {
|
||||||
|
return inverse(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fn(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
var fn = options.fn, inverse = options.inverse;
|
||||||
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (options.data) {
|
||||||
|
data = createFrame(options.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(context && typeof context === 'object') {
|
||||||
|
if (isArray(context)) {
|
||||||
|
for(var j = context.length; i<j; i++) {
|
||||||
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[i], { data: data });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(var key in context) {
|
||||||
|
if(context.hasOwnProperty(key)) {
|
||||||
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[key], {data: data});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i === 0){
|
||||||
|
ret = inverse(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
|
|
||||||
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
|
return options.inverse(this);
|
||||||
|
} else {
|
||||||
|
return options.fn(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('with', function(context, options) {
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('log', function(context, options) {
|
||||||
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
|
instance.log(level, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger = {
|
||||||
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
|
|
||||||
|
// State enum
|
||||||
|
DEBUG: 0,
|
||||||
|
INFO: 1,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
|
// can be overridden in the host environment
|
||||||
|
log: function(level, obj) {
|
||||||
|
if (logger.level <= level) {
|
||||||
|
var method = logger.methodMap[level];
|
||||||
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
exports.logger = logger;
|
||||||
|
function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
exports.log = log;var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
exports.createFrame = createFrame;
|
||||||
227
node_modules/handlebars/dist/cjs/handlebars/compiler/ast.js
generated
vendored
Normal file
227
node_modules/handlebars/dist/cjs/handlebars/compiler/ast.js
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
"use strict";
|
||||||
|
var Exception = require("../exception")["default"];
|
||||||
|
|
||||||
|
function LocationInfo(locInfo){
|
||||||
|
locInfo = locInfo || {};
|
||||||
|
this.firstLine = locInfo.first_line;
|
||||||
|
this.firstColumn = locInfo.first_column;
|
||||||
|
this.lastColumn = locInfo.last_column;
|
||||||
|
this.lastLine = locInfo.last_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
var AST = {
|
||||||
|
ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
|
||||||
|
var inverseLocationInfo, firstInverseNode;
|
||||||
|
if (arguments.length === 3) {
|
||||||
|
locInfo = inverse;
|
||||||
|
inverse = null;
|
||||||
|
} else if (arguments.length === 2) {
|
||||||
|
locInfo = inverseStrip;
|
||||||
|
inverseStrip = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "program";
|
||||||
|
this.statements = statements;
|
||||||
|
this.strip = {};
|
||||||
|
|
||||||
|
if(inverse) {
|
||||||
|
firstInverseNode = inverse[0];
|
||||||
|
if (firstInverseNode) {
|
||||||
|
inverseLocationInfo = {
|
||||||
|
first_line: firstInverseNode.firstLine,
|
||||||
|
last_line: firstInverseNode.lastLine,
|
||||||
|
last_column: firstInverseNode.lastColumn,
|
||||||
|
first_column: firstInverseNode.firstColumn
|
||||||
|
};
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
|
||||||
|
} else {
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip);
|
||||||
|
}
|
||||||
|
this.strip.right = inverseStrip.left;
|
||||||
|
} else if (inverseStrip) {
|
||||||
|
this.strip.left = inverseStrip.right;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
MustacheNode: function(rawParams, hash, open, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "mustache";
|
||||||
|
this.strip = strip;
|
||||||
|
|
||||||
|
// Open may be a string parsed from the parser or a passed boolean flag
|
||||||
|
if (open != null && open.charAt) {
|
||||||
|
// Must use charAt to support IE pre-10
|
||||||
|
var escapeFlag = open.charAt(3) || open.charAt(2);
|
||||||
|
this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
|
||||||
|
} else {
|
||||||
|
this.escaped = !!open;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawParams instanceof AST.SexprNode) {
|
||||||
|
this.sexpr = rawParams;
|
||||||
|
} else {
|
||||||
|
// Support old AST API
|
||||||
|
this.sexpr = new AST.SexprNode(rawParams, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sexpr.isRoot = true;
|
||||||
|
|
||||||
|
// Support old AST API that stored this info in MustacheNode
|
||||||
|
this.id = this.sexpr.id;
|
||||||
|
this.params = this.sexpr.params;
|
||||||
|
this.hash = this.sexpr.hash;
|
||||||
|
this.eligibleHelper = this.sexpr.eligibleHelper;
|
||||||
|
this.isHelper = this.sexpr.isHelper;
|
||||||
|
},
|
||||||
|
|
||||||
|
SexprNode: function(rawParams, hash, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
this.type = "sexpr";
|
||||||
|
this.hash = hash;
|
||||||
|
|
||||||
|
var id = this.id = rawParams[0];
|
||||||
|
var params = this.params = rawParams.slice(1);
|
||||||
|
|
||||||
|
// a mustache is an eligible helper if:
|
||||||
|
// * its id is simple (a single part, not `this` or `..`)
|
||||||
|
var eligibleHelper = this.eligibleHelper = id.isSimple;
|
||||||
|
|
||||||
|
// a mustache is definitely a helper if:
|
||||||
|
// * it is an eligible helper, and
|
||||||
|
// * it has at least one parameter or hash segment
|
||||||
|
this.isHelper = eligibleHelper && (params.length || hash);
|
||||||
|
|
||||||
|
// if a mustache is an eligible helper but not a definite
|
||||||
|
// helper, it is ambiguous, and will be resolved in a later
|
||||||
|
// pass or at runtime.
|
||||||
|
},
|
||||||
|
|
||||||
|
PartialNode: function(partialName, context, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "partial";
|
||||||
|
this.partialName = partialName;
|
||||||
|
this.context = context;
|
||||||
|
this.strip = strip;
|
||||||
|
},
|
||||||
|
|
||||||
|
BlockNode: function(mustache, program, inverse, close, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
if(mustache.sexpr.id.original !== close.path.original) {
|
||||||
|
throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.type = 'block';
|
||||||
|
this.mustache = mustache;
|
||||||
|
this.program = program;
|
||||||
|
this.inverse = inverse;
|
||||||
|
|
||||||
|
this.strip = {
|
||||||
|
left: mustache.strip.left,
|
||||||
|
right: close.strip.right
|
||||||
|
};
|
||||||
|
|
||||||
|
(program || inverse).strip.left = mustache.strip.right;
|
||||||
|
(inverse || program).strip.right = close.strip.left;
|
||||||
|
|
||||||
|
if (inverse && !program) {
|
||||||
|
this.isInverse = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ContentNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "content";
|
||||||
|
this.string = string;
|
||||||
|
},
|
||||||
|
|
||||||
|
HashNode: function(pairs, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "hash";
|
||||||
|
this.pairs = pairs;
|
||||||
|
},
|
||||||
|
|
||||||
|
IdNode: function(parts, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "ID";
|
||||||
|
|
||||||
|
var original = "",
|
||||||
|
dig = [],
|
||||||
|
depth = 0;
|
||||||
|
|
||||||
|
for(var i=0,l=parts.length; i<l; i++) {
|
||||||
|
var part = parts[i].part;
|
||||||
|
original += (parts[i].separator || '') + part;
|
||||||
|
|
||||||
|
if (part === ".." || part === "." || part === "this") {
|
||||||
|
if (dig.length > 0) {
|
||||||
|
throw new Exception("Invalid path: " + original, this);
|
||||||
|
} else if (part === "..") {
|
||||||
|
depth++;
|
||||||
|
} else {
|
||||||
|
this.isScoped = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dig.push(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.original = original;
|
||||||
|
this.parts = dig;
|
||||||
|
this.string = dig.join('.');
|
||||||
|
this.depth = depth;
|
||||||
|
|
||||||
|
// an ID is simple if it only has one part, and that part is not
|
||||||
|
// `..` or `this`.
|
||||||
|
this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
|
||||||
|
|
||||||
|
this.stringModeValue = this.string;
|
||||||
|
},
|
||||||
|
|
||||||
|
PartialNameNode: function(name, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "PARTIAL_NAME";
|
||||||
|
this.name = name.original;
|
||||||
|
},
|
||||||
|
|
||||||
|
DataNode: function(id, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "DATA";
|
||||||
|
this.id = id;
|
||||||
|
},
|
||||||
|
|
||||||
|
StringNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "STRING";
|
||||||
|
this.original =
|
||||||
|
this.string =
|
||||||
|
this.stringModeValue = string;
|
||||||
|
},
|
||||||
|
|
||||||
|
IntegerNode: function(integer, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "INTEGER";
|
||||||
|
this.original =
|
||||||
|
this.integer = integer;
|
||||||
|
this.stringModeValue = Number(integer);
|
||||||
|
},
|
||||||
|
|
||||||
|
BooleanNode: function(bool, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "BOOLEAN";
|
||||||
|
this.bool = bool;
|
||||||
|
this.stringModeValue = bool === "true";
|
||||||
|
},
|
||||||
|
|
||||||
|
CommentNode: function(comment, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
this.type = "comment";
|
||||||
|
this.comment = comment;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Must be exported as an object rather than the root of the module as the jison lexer
|
||||||
|
// most modify the object to operate properly.
|
||||||
|
exports["default"] = AST;
|
||||||
15
node_modules/handlebars/dist/cjs/handlebars/compiler/base.js
generated
vendored
Normal file
15
node_modules/handlebars/dist/cjs/handlebars/compiler/base.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
"use strict";
|
||||||
|
var parser = require("./parser")["default"];
|
||||||
|
var AST = require("./ast")["default"];
|
||||||
|
|
||||||
|
exports.parser = parser;
|
||||||
|
|
||||||
|
function parse(input) {
|
||||||
|
// Just return if an already-compile AST was passed in.
|
||||||
|
if(input.constructor === AST.ProgramNode) { return input; }
|
||||||
|
|
||||||
|
parser.yy = AST;
|
||||||
|
return parser.parse(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.parse = parse;
|
||||||
469
node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js
generated
vendored
Normal file
469
node_modules/handlebars/dist/cjs/handlebars/compiler/compiler.js
generated
vendored
Normal file
@@ -0,0 +1,469 @@
|
|||||||
|
"use strict";
|
||||||
|
var Exception = require("../exception")["default"];
|
||||||
|
|
||||||
|
function Compiler() {}
|
||||||
|
|
||||||
|
exports.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
|
||||||
|
// function in a context. This is necessary for mustache compatibility, which
|
||||||
|
// requires that context functions in blocks are evaluated by blockHelperMissing,
|
||||||
|
// and then proceed as if the resulting value was provided to blockHelperMissing.
|
||||||
|
|
||||||
|
Compiler.prototype = {
|
||||||
|
compiler: Compiler,
|
||||||
|
|
||||||
|
disassemble: function() {
|
||||||
|
var opcodes = this.opcodes, opcode, out = [], params, param;
|
||||||
|
|
||||||
|
for (var i=0, l=opcodes.length; i<l; i++) {
|
||||||
|
opcode = opcodes[i];
|
||||||
|
|
||||||
|
if (opcode.opcode === 'DECLARE') {
|
||||||
|
out.push("DECLARE " + opcode.name + "=" + opcode.value);
|
||||||
|
} else {
|
||||||
|
params = [];
|
||||||
|
for (var j=0; j<opcode.args.length; j++) {
|
||||||
|
param = opcode.args[j];
|
||||||
|
if (typeof param === "string") {
|
||||||
|
param = "\"" + param.replace("\n", "\\n") + "\"";
|
||||||
|
}
|
||||||
|
params.push(param);
|
||||||
|
}
|
||||||
|
out.push(opcode.opcode + " " + params.join(" "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out.join("\n");
|
||||||
|
},
|
||||||
|
|
||||||
|
equals: function(other) {
|
||||||
|
var len = this.opcodes.length;
|
||||||
|
if (other.opcodes.length !== len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
var opcode = this.opcodes[i],
|
||||||
|
otherOpcode = other.opcodes[i];
|
||||||
|
if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (var j = 0; j < opcode.args.length; j++) {
|
||||||
|
if (opcode.args[j] !== otherOpcode.args[j]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
len = this.children.length;
|
||||||
|
if (other.children.length !== len) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (!this.children[i].equals(other.children[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
guid: 0,
|
||||||
|
|
||||||
|
compile: function(program, options) {
|
||||||
|
this.opcodes = [];
|
||||||
|
this.children = [];
|
||||||
|
this.depths = {list: []};
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
// These changes will propagate to the other compiler components
|
||||||
|
var knownHelpers = this.options.knownHelpers;
|
||||||
|
this.options.knownHelpers = {
|
||||||
|
'helperMissing': true,
|
||||||
|
'blockHelperMissing': true,
|
||||||
|
'each': true,
|
||||||
|
'if': true,
|
||||||
|
'unless': true,
|
||||||
|
'with': true,
|
||||||
|
'log': true
|
||||||
|
};
|
||||||
|
if (knownHelpers) {
|
||||||
|
for (var name in knownHelpers) {
|
||||||
|
this.options.knownHelpers[name] = knownHelpers[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.accept(program);
|
||||||
|
},
|
||||||
|
|
||||||
|
accept: function(node) {
|
||||||
|
var strip = node.strip || {},
|
||||||
|
ret;
|
||||||
|
if (strip.left) {
|
||||||
|
this.opcode('strip');
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = this[node.type](node);
|
||||||
|
|
||||||
|
if (strip.right) {
|
||||||
|
this.opcode('strip');
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
|
||||||
|
program: function(program) {
|
||||||
|
var statements = program.statements;
|
||||||
|
|
||||||
|
for(var i=0, l=statements.length; i<l; i++) {
|
||||||
|
this.accept(statements[i]);
|
||||||
|
}
|
||||||
|
this.isSimple = l === 1;
|
||||||
|
|
||||||
|
this.depths.list = this.depths.list.sort(function(a, b) {
|
||||||
|
return a - b;
|
||||||
|
});
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
compileProgram: function(program) {
|
||||||
|
var result = new this.compiler().compile(program, this.options);
|
||||||
|
var guid = this.guid++, depth;
|
||||||
|
|
||||||
|
this.usePartial = this.usePartial || result.usePartial;
|
||||||
|
|
||||||
|
this.children[guid] = result;
|
||||||
|
|
||||||
|
for(var i=0, l=result.depths.list.length; i<l; i++) {
|
||||||
|
depth = result.depths.list[i];
|
||||||
|
|
||||||
|
if(depth < 2) { continue; }
|
||||||
|
else { this.addDepth(depth - 1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return guid;
|
||||||
|
},
|
||||||
|
|
||||||
|
block: function(block) {
|
||||||
|
var mustache = block.mustache,
|
||||||
|
program = block.program,
|
||||||
|
inverse = block.inverse;
|
||||||
|
|
||||||
|
if (program) {
|
||||||
|
program = this.compileProgram(program);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inverse) {
|
||||||
|
inverse = this.compileProgram(inverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
var sexpr = mustache.sexpr;
|
||||||
|
var type = this.classifySexpr(sexpr);
|
||||||
|
|
||||||
|
if (type === "helper") {
|
||||||
|
this.helperSexpr(sexpr, program, inverse);
|
||||||
|
} else if (type === "simple") {
|
||||||
|
this.simpleSexpr(sexpr);
|
||||||
|
|
||||||
|
// now that the simple mustache is resolved, we need to
|
||||||
|
// evaluate it by executing `blockHelperMissing`
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
this.opcode('blockValue');
|
||||||
|
} else {
|
||||||
|
this.ambiguousSexpr(sexpr, program, inverse);
|
||||||
|
|
||||||
|
// now that the simple mustache is resolved, we need to
|
||||||
|
// evaluate it by executing `blockHelperMissing`
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
this.opcode('ambiguousBlockValue');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('append');
|
||||||
|
},
|
||||||
|
|
||||||
|
hash: function(hash) {
|
||||||
|
var pairs = hash.pairs, pair, val;
|
||||||
|
|
||||||
|
this.opcode('pushHash');
|
||||||
|
|
||||||
|
for(var i=0, l=pairs.length; i<l; i++) {
|
||||||
|
pair = pairs[i];
|
||||||
|
val = pair[1];
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
if(val.depth) {
|
||||||
|
this.addDepth(val.depth);
|
||||||
|
}
|
||||||
|
this.opcode('getContext', val.depth || 0);
|
||||||
|
this.opcode('pushStringParam', val.stringModeValue, val.type);
|
||||||
|
|
||||||
|
if (val.type === 'sexpr') {
|
||||||
|
// Subexpressions get evaluated and passed in
|
||||||
|
// in string params mode.
|
||||||
|
this.sexpr(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.accept(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('assignToHash', pair[0]);
|
||||||
|
}
|
||||||
|
this.opcode('popHash');
|
||||||
|
},
|
||||||
|
|
||||||
|
partial: function(partial) {
|
||||||
|
var partialName = partial.partialName;
|
||||||
|
this.usePartial = true;
|
||||||
|
|
||||||
|
if(partial.context) {
|
||||||
|
this.ID(partial.context);
|
||||||
|
} else {
|
||||||
|
this.opcode('push', 'depth0');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('invokePartial', partialName.name);
|
||||||
|
this.opcode('append');
|
||||||
|
},
|
||||||
|
|
||||||
|
content: function(content) {
|
||||||
|
this.opcode('appendContent', content.string);
|
||||||
|
},
|
||||||
|
|
||||||
|
mustache: function(mustache) {
|
||||||
|
this.sexpr(mustache.sexpr);
|
||||||
|
|
||||||
|
if(mustache.escaped && !this.options.noEscape) {
|
||||||
|
this.opcode('appendEscaped');
|
||||||
|
} else {
|
||||||
|
this.opcode('append');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ambiguousSexpr: function(sexpr, program, inverse) {
|
||||||
|
var id = sexpr.id,
|
||||||
|
name = id.parts[0],
|
||||||
|
isBlock = program != null || inverse != null;
|
||||||
|
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
|
||||||
|
this.opcode('invokeAmbiguous', name, isBlock);
|
||||||
|
},
|
||||||
|
|
||||||
|
simpleSexpr: function(sexpr) {
|
||||||
|
var id = sexpr.id;
|
||||||
|
|
||||||
|
if (id.type === 'DATA') {
|
||||||
|
this.DATA(id);
|
||||||
|
} else if (id.parts.length) {
|
||||||
|
this.ID(id);
|
||||||
|
} else {
|
||||||
|
// Simplified ID for `this`
|
||||||
|
this.addDepth(id.depth);
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
this.opcode('pushContext');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('resolvePossibleLambda');
|
||||||
|
},
|
||||||
|
|
||||||
|
helperSexpr: function(sexpr, program, inverse) {
|
||||||
|
var params = this.setupFullMustacheParams(sexpr, program, inverse),
|
||||||
|
name = sexpr.id.parts[0];
|
||||||
|
|
||||||
|
if (this.options.knownHelpers[name]) {
|
||||||
|
this.opcode('invokeKnownHelper', params.length, name);
|
||||||
|
} else if (this.options.knownHelpersOnly) {
|
||||||
|
throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
|
||||||
|
} else {
|
||||||
|
this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
sexpr: function(sexpr) {
|
||||||
|
var type = this.classifySexpr(sexpr);
|
||||||
|
|
||||||
|
if (type === "simple") {
|
||||||
|
this.simpleSexpr(sexpr);
|
||||||
|
} else if (type === "helper") {
|
||||||
|
this.helperSexpr(sexpr);
|
||||||
|
} else {
|
||||||
|
this.ambiguousSexpr(sexpr);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
ID: function(id) {
|
||||||
|
this.addDepth(id.depth);
|
||||||
|
this.opcode('getContext', id.depth);
|
||||||
|
|
||||||
|
var name = id.parts[0];
|
||||||
|
if (!name) {
|
||||||
|
this.opcode('pushContext');
|
||||||
|
} else {
|
||||||
|
this.opcode('lookupOnContext', id.parts[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=1, l=id.parts.length; i<l; i++) {
|
||||||
|
this.opcode('lookup', id.parts[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
DATA: function(data) {
|
||||||
|
this.options.data = true;
|
||||||
|
if (data.id.isScoped || data.id.depth) {
|
||||||
|
throw new Exception('Scoped data references are not supported: ' + data.original, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('lookupData');
|
||||||
|
var parts = data.id.parts;
|
||||||
|
for(var i=0, l=parts.length; i<l; i++) {
|
||||||
|
this.opcode('lookup', parts[i]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
STRING: function(string) {
|
||||||
|
this.opcode('pushString', string.string);
|
||||||
|
},
|
||||||
|
|
||||||
|
INTEGER: function(integer) {
|
||||||
|
this.opcode('pushLiteral', integer.integer);
|
||||||
|
},
|
||||||
|
|
||||||
|
BOOLEAN: function(bool) {
|
||||||
|
this.opcode('pushLiteral', bool.bool);
|
||||||
|
},
|
||||||
|
|
||||||
|
comment: function() {},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
opcode: function(name) {
|
||||||
|
this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
|
||||||
|
},
|
||||||
|
|
||||||
|
declare: function(name, value) {
|
||||||
|
this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
|
||||||
|
},
|
||||||
|
|
||||||
|
addDepth: function(depth) {
|
||||||
|
if(depth === 0) { return; }
|
||||||
|
|
||||||
|
if(!this.depths[depth]) {
|
||||||
|
this.depths[depth] = true;
|
||||||
|
this.depths.list.push(depth);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
classifySexpr: function(sexpr) {
|
||||||
|
var isHelper = sexpr.isHelper;
|
||||||
|
var isEligible = sexpr.eligibleHelper;
|
||||||
|
var options = this.options;
|
||||||
|
|
||||||
|
// if ambiguous, we can possibly resolve the ambiguity now
|
||||||
|
if (isEligible && !isHelper) {
|
||||||
|
var name = sexpr.id.parts[0];
|
||||||
|
|
||||||
|
if (options.knownHelpers[name]) {
|
||||||
|
isHelper = true;
|
||||||
|
} else if (options.knownHelpersOnly) {
|
||||||
|
isEligible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHelper) { return "helper"; }
|
||||||
|
else if (isEligible) { return "ambiguous"; }
|
||||||
|
else { return "simple"; }
|
||||||
|
},
|
||||||
|
|
||||||
|
pushParams: function(params) {
|
||||||
|
var i = params.length, param;
|
||||||
|
|
||||||
|
while(i--) {
|
||||||
|
param = params[i];
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
if(param.depth) {
|
||||||
|
this.addDepth(param.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.opcode('getContext', param.depth || 0);
|
||||||
|
this.opcode('pushStringParam', param.stringModeValue, param.type);
|
||||||
|
|
||||||
|
if (param.type === 'sexpr') {
|
||||||
|
// Subexpressions get evaluated and passed in
|
||||||
|
// in string params mode.
|
||||||
|
this.sexpr(param);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this[param.type](param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setupFullMustacheParams: function(sexpr, program, inverse) {
|
||||||
|
var params = sexpr.params;
|
||||||
|
this.pushParams(params);
|
||||||
|
|
||||||
|
this.opcode('pushProgram', program);
|
||||||
|
this.opcode('pushProgram', inverse);
|
||||||
|
|
||||||
|
if (sexpr.hash) {
|
||||||
|
this.hash(sexpr.hash);
|
||||||
|
} else {
|
||||||
|
this.opcode('emptyHash');
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function precompile(input, options, env) {
|
||||||
|
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
||||||
|
throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
if (!('data' in options)) {
|
||||||
|
options.data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ast = env.parse(input);
|
||||||
|
var environment = new env.Compiler().compile(ast, options);
|
||||||
|
return new env.JavaScriptCompiler().compile(environment, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.precompile = precompile;function compile(input, options, env) {
|
||||||
|
if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
|
||||||
|
throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
|
||||||
|
}
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
if (!('data' in options)) {
|
||||||
|
options.data = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var compiled;
|
||||||
|
|
||||||
|
function compileInput() {
|
||||||
|
var ast = env.parse(input);
|
||||||
|
var environment = new env.Compiler().compile(ast, options);
|
||||||
|
var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
|
||||||
|
return env.template(templateSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Template is only compiled on first use and cached after that point.
|
||||||
|
return function(context, options) {
|
||||||
|
if (!compiled) {
|
||||||
|
compiled = compileInput();
|
||||||
|
}
|
||||||
|
return compiled.call(this, context, options);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.compile = compile;
|
||||||
942
node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
942
node_modules/handlebars/dist/cjs/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
@@ -0,0 +1,942 @@
|
|||||||
|
"use strict";
|
||||||
|
var COMPILER_REVISION = require("../base").COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = require("../base").REVISION_CHANGES;
|
||||||
|
var log = require("../base").log;
|
||||||
|
var Exception = require("../exception")["default"];
|
||||||
|
|
||||||
|
function Literal(value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function JavaScriptCompiler() {}
|
||||||
|
|
||||||
|
JavaScriptCompiler.prototype = {
|
||||||
|
// PUBLIC API: You can override these methods in a subclass to provide
|
||||||
|
// alternative compiled forms for name lookup and buffering semantics
|
||||||
|
nameLookup: function(parent, name /* , type*/) {
|
||||||
|
var wrap,
|
||||||
|
ret;
|
||||||
|
if (parent.indexOf('depth') === 0) {
|
||||||
|
wrap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^[0-9]+$/.test(name)) {
|
||||||
|
ret = parent + "[" + name + "]";
|
||||||
|
} else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
||||||
|
ret = parent + "." + name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = parent + "['" + name + "']";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrap) {
|
||||||
|
return '(' + parent + ' && ' + ret + ')';
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
compilerInfo: function() {
|
||||||
|
var revision = COMPILER_REVISION,
|
||||||
|
versions = REVISION_CHANGES[revision];
|
||||||
|
return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
|
||||||
|
},
|
||||||
|
|
||||||
|
appendToBuffer: function(string) {
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
return "return " + string + ";";
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
appendToBuffer: true,
|
||||||
|
content: string,
|
||||||
|
toString: function() { return "buffer += " + string + ";"; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
initializeBuffer: function() {
|
||||||
|
return this.quotedString("");
|
||||||
|
},
|
||||||
|
|
||||||
|
namespace: "Handlebars",
|
||||||
|
// END PUBLIC API
|
||||||
|
|
||||||
|
compile: function(environment, options, context, asObject) {
|
||||||
|
this.environment = environment;
|
||||||
|
this.options = options || {};
|
||||||
|
|
||||||
|
log('debug', this.environment.disassemble() + "\n\n");
|
||||||
|
|
||||||
|
this.name = this.environment.name;
|
||||||
|
this.isChild = !!context;
|
||||||
|
this.context = context || {
|
||||||
|
programs: [],
|
||||||
|
environments: [],
|
||||||
|
aliases: { }
|
||||||
|
};
|
||||||
|
|
||||||
|
this.preamble();
|
||||||
|
|
||||||
|
this.stackSlot = 0;
|
||||||
|
this.stackVars = [];
|
||||||
|
this.registers = { list: [] };
|
||||||
|
this.hashes = [];
|
||||||
|
this.compileStack = [];
|
||||||
|
this.inlineStack = [];
|
||||||
|
|
||||||
|
this.compileChildren(environment, options);
|
||||||
|
|
||||||
|
var opcodes = environment.opcodes, opcode;
|
||||||
|
|
||||||
|
this.i = 0;
|
||||||
|
|
||||||
|
for(var l=opcodes.length; this.i<l; this.i++) {
|
||||||
|
opcode = opcodes[this.i];
|
||||||
|
|
||||||
|
if(opcode.opcode === 'DECLARE') {
|
||||||
|
this[opcode.name] = opcode.value;
|
||||||
|
} else {
|
||||||
|
this[opcode.opcode].apply(this, opcode.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the stripNext flag if it was not set by this operation.
|
||||||
|
if (opcode.opcode !== this.stripNext) {
|
||||||
|
this.stripNext = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush any trailing content that might be pending.
|
||||||
|
this.pushSource('');
|
||||||
|
|
||||||
|
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
|
||||||
|
throw new Exception('Compile completed with content left on stack');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createFunctionContext(asObject);
|
||||||
|
},
|
||||||
|
|
||||||
|
preamble: function() {
|
||||||
|
var out = [];
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
var namespace = this.namespace;
|
||||||
|
|
||||||
|
var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
|
||||||
|
if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
|
||||||
|
if (this.options.data) { copies = copies + " data = data || {};"; }
|
||||||
|
out.push(copies);
|
||||||
|
} else {
|
||||||
|
out.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
out.push(", buffer = " + this.initializeBuffer());
|
||||||
|
} else {
|
||||||
|
out.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// track the last context pushed into place to allow skipping the
|
||||||
|
// getContext opcode when it would be a noop
|
||||||
|
this.lastContext = 0;
|
||||||
|
this.source = out;
|
||||||
|
},
|
||||||
|
|
||||||
|
createFunctionContext: function(asObject) {
|
||||||
|
var locals = this.stackVars.concat(this.registers.list);
|
||||||
|
|
||||||
|
if(locals.length > 0) {
|
||||||
|
this.source[1] = this.source[1] + ", " + locals.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate minimizer alias mappings
|
||||||
|
if (!this.isChild) {
|
||||||
|
for (var alias in this.context.aliases) {
|
||||||
|
if (this.context.aliases.hasOwnProperty(alias)) {
|
||||||
|
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.source[1]) {
|
||||||
|
this.source[1] = "var " + this.source[1].substring(2) + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge children
|
||||||
|
if (!this.isChild) {
|
||||||
|
this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
this.pushSource("return buffer;");
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
|
||||||
|
|
||||||
|
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
||||||
|
params.push("depth" + this.environment.depths.list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a second pass over the output to merge content when possible
|
||||||
|
var source = this.mergeSource();
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
source = this.compilerInfo()+source;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asObject) {
|
||||||
|
params.push(source);
|
||||||
|
|
||||||
|
return Function.apply(this, params);
|
||||||
|
} else {
|
||||||
|
var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
|
||||||
|
log('debug', functionSource + "\n\n");
|
||||||
|
return functionSource;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mergeSource: function() {
|
||||||
|
// WARN: We are not handling the case where buffer is still populated as the source should
|
||||||
|
// not have buffer append operations as their final action.
|
||||||
|
var source = '',
|
||||||
|
buffer;
|
||||||
|
for (var i = 0, len = this.source.length; i < len; i++) {
|
||||||
|
var line = this.source[i];
|
||||||
|
if (line.appendToBuffer) {
|
||||||
|
if (buffer) {
|
||||||
|
buffer = buffer + '\n + ' + line.content;
|
||||||
|
} else {
|
||||||
|
buffer = line.content;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (buffer) {
|
||||||
|
source += 'buffer += ' + buffer + ';\n ';
|
||||||
|
buffer = undefined;
|
||||||
|
}
|
||||||
|
source += line + '\n ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return source;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [blockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// On stack, after: return value of blockHelperMissing
|
||||||
|
//
|
||||||
|
// The purpose of this opcode is to take a block of the form
|
||||||
|
// `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
|
||||||
|
// replace it on the stack with the result of properly
|
||||||
|
// invoking blockHelperMissing.
|
||||||
|
blockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
return "blockHelperMissing.call(" + params.join(", ") + ")";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [ambiguousBlockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// Compiler value, before: lastHelper=value of last found helper, if any
|
||||||
|
// On stack, after, if no lastHelper: same as [blockValue]
|
||||||
|
// On stack, after, if lastHelper: value
|
||||||
|
ambiguousBlockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
var current = this.topStack();
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
|
||||||
|
this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendContent]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Appends the string value of `content` to the current buffer
|
||||||
|
appendContent: function(content) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
content = this.pendingContent + content;
|
||||||
|
}
|
||||||
|
if (this.stripNext) {
|
||||||
|
content = content.replace(/^\s+/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingContent = content;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [strip]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Removes any trailing whitespace from the prior content node and flags
|
||||||
|
// the next operation for stripping if it is a content node.
|
||||||
|
strip: function() {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.pendingContent = this.pendingContent.replace(/\s+$/, '');
|
||||||
|
}
|
||||||
|
this.stripNext = 'strip';
|
||||||
|
},
|
||||||
|
|
||||||
|
// [append]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Coerces `value` to a String and appends it to the current buffer.
|
||||||
|
//
|
||||||
|
// If `value` is truthy, or 0, it is coerced into a string and appended
|
||||||
|
// Otherwise, the empty string is appended
|
||||||
|
append: function() {
|
||||||
|
// Force anything that is inlined onto the stack so we don't have duplication
|
||||||
|
// when we examine local
|
||||||
|
this.flushInline();
|
||||||
|
var local = this.popStack();
|
||||||
|
this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
this.pushSource("else { " + this.appendToBuffer("''") + " }");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendEscaped]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Escape `value` and append it to the buffer
|
||||||
|
appendEscaped: function() {
|
||||||
|
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
||||||
|
|
||||||
|
this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [getContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
// Compiler value, after: lastContext=depth
|
||||||
|
//
|
||||||
|
// Set the value of the `lastContext` compiler value to the depth
|
||||||
|
getContext: function(depth) {
|
||||||
|
if(this.lastContext !== depth) {
|
||||||
|
this.lastContext = depth;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupOnContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext[name], ...
|
||||||
|
//
|
||||||
|
// Looks up the value of `name` on the current context and pushes
|
||||||
|
// it onto the stack.
|
||||||
|
lookupOnContext: function(name) {
|
||||||
|
this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext, ...
|
||||||
|
//
|
||||||
|
// Pushes the value of the current context onto the stack.
|
||||||
|
pushContext: function() {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [resolvePossibleLambda]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: resolved value, ...
|
||||||
|
//
|
||||||
|
// If the `value` is a lambda, replace it on the stack by
|
||||||
|
// the return value of the lambda
|
||||||
|
resolvePossibleLambda: function() {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookup]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: value[name], ...
|
||||||
|
//
|
||||||
|
// Replace the value on the stack with the result of looking
|
||||||
|
// up `name` on `value`
|
||||||
|
lookup: function(name) {
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupData]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: data, ...
|
||||||
|
//
|
||||||
|
// Push the data lookup operator
|
||||||
|
lookupData: function() {
|
||||||
|
this.pushStackLiteral('data');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushStringParam]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: string, currentContext, ...
|
||||||
|
//
|
||||||
|
// This opcode is designed for use in string mode, which
|
||||||
|
// provides the string value of a parameter along with its
|
||||||
|
// depth rather than resolving it immediately.
|
||||||
|
pushStringParam: function(string, type) {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
|
||||||
|
this.pushString(type);
|
||||||
|
|
||||||
|
// If it's a subexpression, the string result
|
||||||
|
// will be pushed after this opcode.
|
||||||
|
if (type !== 'sexpr') {
|
||||||
|
if (typeof string === 'string') {
|
||||||
|
this.pushString(string);
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emptyHash: function() {
|
||||||
|
this.pushStackLiteral('{}');
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{}'); // hashContexts
|
||||||
|
this.push('{}'); // hashTypes
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pushHash: function() {
|
||||||
|
if (this.hash) {
|
||||||
|
this.hashes.push(this.hash);
|
||||||
|
}
|
||||||
|
this.hash = {values: [], types: [], contexts: []};
|
||||||
|
},
|
||||||
|
popHash: function() {
|
||||||
|
var hash = this.hash;
|
||||||
|
this.hash = this.hashes.pop();
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{' + hash.contexts.join(',') + '}');
|
||||||
|
this.push('{' + hash.types.join(',') + '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push('{\n ' + hash.values.join(',\n ') + '\n }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushString]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: quotedString(string), ...
|
||||||
|
//
|
||||||
|
// Push a quoted version of `string` onto the stack
|
||||||
|
pushString: function(string) {
|
||||||
|
this.pushStackLiteral(this.quotedString(string));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [push]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: expr, ...
|
||||||
|
//
|
||||||
|
// Push an expression onto the stack
|
||||||
|
push: function(expr) {
|
||||||
|
this.inlineStack.push(expr);
|
||||||
|
return expr;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushLiteral]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: value, ...
|
||||||
|
//
|
||||||
|
// Pushes a value onto the stack. This operation prevents
|
||||||
|
// the compiler from creating a temporary variable to hold
|
||||||
|
// it.
|
||||||
|
pushLiteral: function(value) {
|
||||||
|
this.pushStackLiteral(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushProgram]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: program(guid), ...
|
||||||
|
//
|
||||||
|
// Push a program expression onto the stack. This takes
|
||||||
|
// a compile-time guid and converts it into a runtime-accessible
|
||||||
|
// expression.
|
||||||
|
pushProgram: function(guid) {
|
||||||
|
if (guid != null) {
|
||||||
|
this.pushStackLiteral(this.programExpression(guid));
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// Pops off the helper's parameters, invokes the helper,
|
||||||
|
// and pushes the helper's return value onto the stack.
|
||||||
|
//
|
||||||
|
// If the helper is not found, `helperMissing` is called.
|
||||||
|
invokeHelper: function(paramSize, name, isRoot) {
|
||||||
|
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
|
||||||
|
var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
lookup += ',' + helper.paramsInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push(
|
||||||
|
'('
|
||||||
|
+ lookup
|
||||||
|
+ ',helper '
|
||||||
|
+ '? helper.call(' + helper.callParams + ') '
|
||||||
|
+ ': helperMissing.call(' + helper.helperMissingParams + '))');
|
||||||
|
|
||||||
|
// Always flush subexpressions. This is both to prevent the compounding size issue that
|
||||||
|
// occurs when the code has to be duplicated for inlining and also to prevent errors
|
||||||
|
// due to the incorrect options object being passed due to the shared register.
|
||||||
|
if (!isRoot) {
|
||||||
|
this.flushInline();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeKnownHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// This operation is used when the helper is known to exist,
|
||||||
|
// so a `helperMissing` fallback is not required.
|
||||||
|
invokeKnownHelper: function(paramSize, name) {
|
||||||
|
var helper = this.setupHelper(paramSize, name);
|
||||||
|
this.push(helper.name + ".call(" + helper.callParams + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeAmbiguous]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of disambiguation
|
||||||
|
//
|
||||||
|
// This operation is used when an expression like `{{foo}}`
|
||||||
|
// is provided, but we don't know at compile-time whether it
|
||||||
|
// is a helper or a path.
|
||||||
|
//
|
||||||
|
// This operation emits more code than the other options,
|
||||||
|
// and can be avoided by passing the `knownHelpers` and
|
||||||
|
// `knownHelpersOnly` flags at compile-time.
|
||||||
|
invokeAmbiguous: function(name, helperCall) {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
this.emptyHash();
|
||||||
|
var helper = this.setupHelper(0, name, helperCall);
|
||||||
|
|
||||||
|
var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
var nextStack = this.nextStack();
|
||||||
|
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
this.pushSource(helper.paramsInit);
|
||||||
|
}
|
||||||
|
this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
|
||||||
|
this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokePartial]
|
||||||
|
//
|
||||||
|
// On stack, before: context, ...
|
||||||
|
// On stack after: result of partial invocation
|
||||||
|
//
|
||||||
|
// This operation pops off a context, invokes a partial with that context,
|
||||||
|
// and pushes the result of the invocation back.
|
||||||
|
invokePartial: function(name) {
|
||||||
|
var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
|
||||||
|
|
||||||
|
if (this.options.data) {
|
||||||
|
params.push("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
this.push("self.invokePartial(" + params.join(", ") + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [assignToHash]
|
||||||
|
//
|
||||||
|
// On stack, before: value, hash, ...
|
||||||
|
// On stack, after: hash, ...
|
||||||
|
//
|
||||||
|
// Pops a value and hash off the stack, assigns `hash[key] = value`
|
||||||
|
// and pushes the hash back onto the stack.
|
||||||
|
assignToHash: function(key) {
|
||||||
|
var value = this.popStack(),
|
||||||
|
context,
|
||||||
|
type;
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
type = this.popStack();
|
||||||
|
context = this.popStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = this.hash;
|
||||||
|
if (context) {
|
||||||
|
hash.contexts.push("'" + key + "': " + context);
|
||||||
|
}
|
||||||
|
if (type) {
|
||||||
|
hash.types.push("'" + key + "': " + type);
|
||||||
|
}
|
||||||
|
hash.values.push("'" + key + "': (" + value + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
|
||||||
|
compiler: JavaScriptCompiler,
|
||||||
|
|
||||||
|
compileChildren: function(environment, options) {
|
||||||
|
var children = environment.children, child, compiler;
|
||||||
|
|
||||||
|
for(var i=0, l=children.length; i<l; i++) {
|
||||||
|
child = children[i];
|
||||||
|
compiler = new this.compiler();
|
||||||
|
|
||||||
|
var index = this.matchExistingProgram(child);
|
||||||
|
|
||||||
|
if (index == null) {
|
||||||
|
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
|
||||||
|
index = this.context.programs.length;
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
this.context.programs[index] = compiler.compile(child, options, this.context);
|
||||||
|
this.context.environments[index] = child;
|
||||||
|
} else {
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matchExistingProgram: function(child) {
|
||||||
|
for (var i = 0, len = this.context.environments.length; i < len; i++) {
|
||||||
|
var environment = this.context.environments[i];
|
||||||
|
if (environment && environment.equals(child)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
programExpression: function(guid) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
|
||||||
|
if(guid == null) {
|
||||||
|
return "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
var child = this.environment.children[guid],
|
||||||
|
depths = child.depths.list, depth;
|
||||||
|
|
||||||
|
var programParams = [child.index, child.name, "data"];
|
||||||
|
|
||||||
|
for(var i=0, l = depths.length; i<l; i++) {
|
||||||
|
depth = depths[i];
|
||||||
|
|
||||||
|
if(depth === 1) { programParams.push("depth0"); }
|
||||||
|
else { programParams.push("depth" + (depth - 1)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
|
||||||
|
},
|
||||||
|
|
||||||
|
register: function(name, val) {
|
||||||
|
this.useRegister(name);
|
||||||
|
this.pushSource(name + " = " + val + ";");
|
||||||
|
},
|
||||||
|
|
||||||
|
useRegister: function(name) {
|
||||||
|
if(!this.registers[name]) {
|
||||||
|
this.registers[name] = true;
|
||||||
|
this.registers.list.push(name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStackLiteral: function(item) {
|
||||||
|
return this.push(new Literal(item));
|
||||||
|
},
|
||||||
|
|
||||||
|
pushSource: function(source) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
|
||||||
|
this.pendingContent = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source) {
|
||||||
|
this.source.push(source);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStack: function(item) {
|
||||||
|
this.flushInline();
|
||||||
|
|
||||||
|
var stack = this.incrStack();
|
||||||
|
if (item) {
|
||||||
|
this.pushSource(stack + " = " + item + ";");
|
||||||
|
}
|
||||||
|
this.compileStack.push(stack);
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
replaceStack: function(callback) {
|
||||||
|
var prefix = '',
|
||||||
|
inline = this.isInline(),
|
||||||
|
stack,
|
||||||
|
createdStack,
|
||||||
|
usedLiteral;
|
||||||
|
|
||||||
|
// If we are currently inline then we want to merge the inline statement into the
|
||||||
|
// replacement statement via ','
|
||||||
|
if (inline) {
|
||||||
|
var top = this.popStack(true);
|
||||||
|
|
||||||
|
if (top instanceof Literal) {
|
||||||
|
// Literals do not need to be inlined
|
||||||
|
stack = top.value;
|
||||||
|
usedLiteral = true;
|
||||||
|
} else {
|
||||||
|
// Get or create the current stack name for use by the inline
|
||||||
|
createdStack = !this.stackSlot;
|
||||||
|
var name = !createdStack ? this.topStackName() : this.incrStack();
|
||||||
|
|
||||||
|
prefix = '(' + this.push(name) + ' = ' + top + '),';
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = callback.call(this, stack);
|
||||||
|
|
||||||
|
if (inline) {
|
||||||
|
if (!usedLiteral) {
|
||||||
|
this.popStack();
|
||||||
|
}
|
||||||
|
if (createdStack) {
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
this.push('(' + prefix + item + ')');
|
||||||
|
} else {
|
||||||
|
// Prevent modification of the context depth variable. Through replaceStack
|
||||||
|
if (!/^stack/.test(stack)) {
|
||||||
|
stack = this.nextStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pushSource(stack + " = (" + prefix + item + ");");
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
nextStack: function() {
|
||||||
|
return this.pushStack();
|
||||||
|
},
|
||||||
|
|
||||||
|
incrStack: function() {
|
||||||
|
this.stackSlot++;
|
||||||
|
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
|
||||||
|
return this.topStackName();
|
||||||
|
},
|
||||||
|
topStackName: function() {
|
||||||
|
return "stack" + this.stackSlot;
|
||||||
|
},
|
||||||
|
flushInline: function() {
|
||||||
|
var inlineStack = this.inlineStack;
|
||||||
|
if (inlineStack.length) {
|
||||||
|
this.inlineStack = [];
|
||||||
|
for (var i = 0, len = inlineStack.length; i < len; i++) {
|
||||||
|
var entry = inlineStack[i];
|
||||||
|
if (entry instanceof Literal) {
|
||||||
|
this.compileStack.push(entry);
|
||||||
|
} else {
|
||||||
|
this.pushStack(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isInline: function() {
|
||||||
|
return this.inlineStack.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
popStack: function(wrapped) {
|
||||||
|
var inline = this.isInline(),
|
||||||
|
item = (inline ? this.inlineStack : this.compileStack).pop();
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
if (!inline) {
|
||||||
|
if (!this.stackSlot) {
|
||||||
|
throw new Exception('Invalid stack pop');
|
||||||
|
}
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
topStack: function(wrapped) {
|
||||||
|
var stack = (this.isInline() ? this.inlineStack : this.compileStack),
|
||||||
|
item = stack[stack.length - 1];
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
quotedString: function(str) {
|
||||||
|
return '"' + str
|
||||||
|
.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/"/g, '\\"')
|
||||||
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\r/g, '\\r')
|
||||||
|
.replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
|
||||||
|
.replace(/\u2029/g, '\\u2029') + '"';
|
||||||
|
},
|
||||||
|
|
||||||
|
setupHelper: function(paramSize, name, missingParams) {
|
||||||
|
var params = [],
|
||||||
|
paramsInit = this.setupParams(paramSize, params, missingParams);
|
||||||
|
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
return {
|
||||||
|
params: params,
|
||||||
|
paramsInit: paramsInit,
|
||||||
|
name: foundHelper,
|
||||||
|
callParams: ["depth0"].concat(params).join(", "),
|
||||||
|
helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
setupOptions: function(paramSize, params) {
|
||||||
|
var options = [], contexts = [], types = [], param, inverse, program;
|
||||||
|
|
||||||
|
options.push("hash:" + this.popStack());
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("hashTypes:" + this.popStack());
|
||||||
|
options.push("hashContexts:" + this.popStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse = this.popStack();
|
||||||
|
program = this.popStack();
|
||||||
|
|
||||||
|
// Avoid setting fn and inverse if neither are set. This allows
|
||||||
|
// helpers to do a check for `if (options.fn)`
|
||||||
|
if (program || inverse) {
|
||||||
|
if (!program) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
program = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inverse) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
inverse = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
options.push("inverse:" + inverse);
|
||||||
|
options.push("fn:" + program);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=0; i<paramSize; i++) {
|
||||||
|
param = this.popStack();
|
||||||
|
params.push(param);
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
types.push(this.popStack());
|
||||||
|
contexts.push(this.popStack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("contexts:[" + contexts.join(",") + "]");
|
||||||
|
options.push("types:[" + types.join(",") + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.data) {
|
||||||
|
options.push("data:data");
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
|
||||||
|
// the params and contexts arguments are passed in arrays
|
||||||
|
// to fill in
|
||||||
|
setupParams: function(paramSize, params, useRegister) {
|
||||||
|
var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
|
||||||
|
|
||||||
|
if (useRegister) {
|
||||||
|
this.useRegister('options');
|
||||||
|
params.push('options');
|
||||||
|
return 'options=' + options;
|
||||||
|
} else {
|
||||||
|
params.push(options);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var reservedWords = (
|
||||||
|
"break else new var" +
|
||||||
|
" case finally return void" +
|
||||||
|
" catch for switch while" +
|
||||||
|
" continue function this with" +
|
||||||
|
" default if throw" +
|
||||||
|
" delete in try" +
|
||||||
|
" do instanceof typeof" +
|
||||||
|
" abstract enum int short" +
|
||||||
|
" boolean export interface static" +
|
||||||
|
" byte extends long super" +
|
||||||
|
" char final native synchronized" +
|
||||||
|
" class float package throws" +
|
||||||
|
" const goto private transient" +
|
||||||
|
" debugger implements protected volatile" +
|
||||||
|
" double import public let yield"
|
||||||
|
).split(" ");
|
||||||
|
|
||||||
|
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
|
||||||
|
|
||||||
|
for(var i=0, l=reservedWords.length; i<l; i++) {
|
||||||
|
compilerWords[reservedWords[i]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
||||||
|
if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports["default"] = JavaScriptCompiler;
|
||||||
490
node_modules/handlebars/dist/cjs/handlebars/compiler/parser.js
generated
vendored
Normal file
490
node_modules/handlebars/dist/cjs/handlebars/compiler/parser.js
generated
vendored
Normal file
@@ -0,0 +1,490 @@
|
|||||||
|
"use strict";
|
||||||
|
/* jshint ignore:start */
|
||||||
|
/* Jison generated parser */
|
||||||
|
var handlebars = (function(){
|
||||||
|
var parser = {trace: function trace() { },
|
||||||
|
yy: {},
|
||||||
|
symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
|
||||||
|
terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
|
||||||
|
productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
|
||||||
|
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
||||||
|
|
||||||
|
var $0 = $$.length - 1;
|
||||||
|
switch (yystate) {
|
||||||
|
case 1: return new yy.ProgramNode($$[$0-1], this._$);
|
||||||
|
break;
|
||||||
|
case 2: return new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
|
||||||
|
break;
|
||||||
|
case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 7:this.$ = new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 8:this.$ = new yy.ProgramNode([], this._$);
|
||||||
|
break;
|
||||||
|
case 9:this.$ = [$$[$0]];
|
||||||
|
break;
|
||||||
|
case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
||||||
|
break;
|
||||||
|
case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 13:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 14:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 15:this.$ = new yy.ContentNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 16:this.$ = new yy.CommentNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
|
||||||
|
break;
|
||||||
|
case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
|
||||||
|
break;
|
||||||
|
case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
|
||||||
|
break;
|
||||||
|
case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
|
||||||
|
break;
|
||||||
|
case 26:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 27:this.$ = new yy.StringNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 30:this.$ = $$[$0];
|
||||||
|
break;
|
||||||
|
case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
|
||||||
|
break;
|
||||||
|
case 32:this.$ = new yy.HashNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 33:this.$ = [$$[$0-2], $$[$0]];
|
||||||
|
break;
|
||||||
|
case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
|
||||||
|
break;
|
||||||
|
case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
|
||||||
|
break;
|
||||||
|
case 37:this.$ = new yy.DataNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 38:this.$ = new yy.IdNode($$[$0], this._$);
|
||||||
|
break;
|
||||||
|
case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
|
||||||
|
break;
|
||||||
|
case 40:this.$ = [{part: $$[$0]}];
|
||||||
|
break;
|
||||||
|
case 43:this.$ = [];
|
||||||
|
break;
|
||||||
|
case 44:$$[$0-1].push($$[$0]);
|
||||||
|
break;
|
||||||
|
case 47:this.$ = [$$[$0]];
|
||||||
|
break;
|
||||||
|
case 48:$$[$0-1].push($$[$0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
|
||||||
|
defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
|
||||||
|
parseError: function parseError(str, hash) {
|
||||||
|
throw new Error(str);
|
||||||
|
},
|
||||||
|
parse: function parse(input) {
|
||||||
|
var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
|
||||||
|
this.lexer.setInput(input);
|
||||||
|
this.lexer.yy = this.yy;
|
||||||
|
this.yy.lexer = this.lexer;
|
||||||
|
this.yy.parser = this;
|
||||||
|
if (typeof this.lexer.yylloc == "undefined")
|
||||||
|
this.lexer.yylloc = {};
|
||||||
|
var yyloc = this.lexer.yylloc;
|
||||||
|
lstack.push(yyloc);
|
||||||
|
var ranges = this.lexer.options && this.lexer.options.ranges;
|
||||||
|
if (typeof this.yy.parseError === "function")
|
||||||
|
this.parseError = this.yy.parseError;
|
||||||
|
function popStack(n) {
|
||||||
|
stack.length = stack.length - 2 * n;
|
||||||
|
vstack.length = vstack.length - n;
|
||||||
|
lstack.length = lstack.length - n;
|
||||||
|
}
|
||||||
|
function lex() {
|
||||||
|
var token;
|
||||||
|
token = self.lexer.lex() || 1;
|
||||||
|
if (typeof token !== "number") {
|
||||||
|
token = self.symbols_[token] || token;
|
||||||
|
}
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
|
||||||
|
while (true) {
|
||||||
|
state = stack[stack.length - 1];
|
||||||
|
if (this.defaultActions[state]) {
|
||||||
|
action = this.defaultActions[state];
|
||||||
|
} else {
|
||||||
|
if (symbol === null || typeof symbol == "undefined") {
|
||||||
|
symbol = lex();
|
||||||
|
}
|
||||||
|
action = table[state] && table[state][symbol];
|
||||||
|
}
|
||||||
|
if (typeof action === "undefined" || !action.length || !action[0]) {
|
||||||
|
var errStr = "";
|
||||||
|
if (!recovering) {
|
||||||
|
expected = [];
|
||||||
|
for (p in table[state])
|
||||||
|
if (this.terminals_[p] && p > 2) {
|
||||||
|
expected.push("'" + this.terminals_[p] + "'");
|
||||||
|
}
|
||||||
|
if (this.lexer.showPosition) {
|
||||||
|
errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
|
||||||
|
} else {
|
||||||
|
errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
|
||||||
|
}
|
||||||
|
this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (action[0] instanceof Array && action.length > 1) {
|
||||||
|
throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
|
||||||
|
}
|
||||||
|
switch (action[0]) {
|
||||||
|
case 1:
|
||||||
|
stack.push(symbol);
|
||||||
|
vstack.push(this.lexer.yytext);
|
||||||
|
lstack.push(this.lexer.yylloc);
|
||||||
|
stack.push(action[1]);
|
||||||
|
symbol = null;
|
||||||
|
if (!preErrorSymbol) {
|
||||||
|
yyleng = this.lexer.yyleng;
|
||||||
|
yytext = this.lexer.yytext;
|
||||||
|
yylineno = this.lexer.yylineno;
|
||||||
|
yyloc = this.lexer.yylloc;
|
||||||
|
if (recovering > 0)
|
||||||
|
recovering--;
|
||||||
|
} else {
|
||||||
|
symbol = preErrorSymbol;
|
||||||
|
preErrorSymbol = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
len = this.productions_[action[1]][1];
|
||||||
|
yyval.$ = vstack[vstack.length - len];
|
||||||
|
yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
|
||||||
|
if (ranges) {
|
||||||
|
yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
|
||||||
|
}
|
||||||
|
r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
|
||||||
|
if (typeof r !== "undefined") {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
if (len) {
|
||||||
|
stack = stack.slice(0, -1 * len * 2);
|
||||||
|
vstack = vstack.slice(0, -1 * len);
|
||||||
|
lstack = lstack.slice(0, -1 * len);
|
||||||
|
}
|
||||||
|
stack.push(this.productions_[action[1]][0]);
|
||||||
|
vstack.push(yyval.$);
|
||||||
|
lstack.push(yyval._$);
|
||||||
|
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
|
||||||
|
stack.push(newState);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function stripFlags(open, close) {
|
||||||
|
return {
|
||||||
|
left: open.charAt(2) === '~',
|
||||||
|
right: close.charAt(0) === '~' || close.charAt(1) === '~'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Jison generated lexer */
|
||||||
|
var lexer = (function(){
|
||||||
|
var lexer = ({EOF:1,
|
||||||
|
parseError:function parseError(str, hash) {
|
||||||
|
if (this.yy.parser) {
|
||||||
|
this.yy.parser.parseError(str, hash);
|
||||||
|
} else {
|
||||||
|
throw new Error(str);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setInput:function (input) {
|
||||||
|
this._input = input;
|
||||||
|
this._more = this._less = this.done = false;
|
||||||
|
this.yylineno = this.yyleng = 0;
|
||||||
|
this.yytext = this.matched = this.match = '';
|
||||||
|
this.conditionStack = ['INITIAL'];
|
||||||
|
this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
|
||||||
|
if (this.options.ranges) this.yylloc.range = [0,0];
|
||||||
|
this.offset = 0;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
input:function () {
|
||||||
|
var ch = this._input[0];
|
||||||
|
this.yytext += ch;
|
||||||
|
this.yyleng++;
|
||||||
|
this.offset++;
|
||||||
|
this.match += ch;
|
||||||
|
this.matched += ch;
|
||||||
|
var lines = ch.match(/(?:\r\n?|\n).*/g);
|
||||||
|
if (lines) {
|
||||||
|
this.yylineno++;
|
||||||
|
this.yylloc.last_line++;
|
||||||
|
} else {
|
||||||
|
this.yylloc.last_column++;
|
||||||
|
}
|
||||||
|
if (this.options.ranges) this.yylloc.range[1]++;
|
||||||
|
|
||||||
|
this._input = this._input.slice(1);
|
||||||
|
return ch;
|
||||||
|
},
|
||||||
|
unput:function (ch) {
|
||||||
|
var len = ch.length;
|
||||||
|
var lines = ch.split(/(?:\r\n?|\n)/g);
|
||||||
|
|
||||||
|
this._input = ch + this._input;
|
||||||
|
this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
|
||||||
|
//this.yyleng -= len;
|
||||||
|
this.offset -= len;
|
||||||
|
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
|
||||||
|
this.match = this.match.substr(0, this.match.length-1);
|
||||||
|
this.matched = this.matched.substr(0, this.matched.length-1);
|
||||||
|
|
||||||
|
if (lines.length-1) this.yylineno -= lines.length-1;
|
||||||
|
var r = this.yylloc.range;
|
||||||
|
|
||||||
|
this.yylloc = {first_line: this.yylloc.first_line,
|
||||||
|
last_line: this.yylineno+1,
|
||||||
|
first_column: this.yylloc.first_column,
|
||||||
|
last_column: lines ?
|
||||||
|
(lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
|
||||||
|
this.yylloc.first_column - len
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.options.ranges) {
|
||||||
|
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
more:function () {
|
||||||
|
this._more = true;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
less:function (n) {
|
||||||
|
this.unput(this.match.slice(n));
|
||||||
|
},
|
||||||
|
pastInput:function () {
|
||||||
|
var past = this.matched.substr(0, this.matched.length - this.match.length);
|
||||||
|
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
|
||||||
|
},
|
||||||
|
upcomingInput:function () {
|
||||||
|
var next = this.match;
|
||||||
|
if (next.length < 20) {
|
||||||
|
next += this._input.substr(0, 20-next.length);
|
||||||
|
}
|
||||||
|
return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
|
||||||
|
},
|
||||||
|
showPosition:function () {
|
||||||
|
var pre = this.pastInput();
|
||||||
|
var c = new Array(pre.length + 1).join("-");
|
||||||
|
return pre + this.upcomingInput() + "\n" + c+"^";
|
||||||
|
},
|
||||||
|
next:function () {
|
||||||
|
if (this.done) {
|
||||||
|
return this.EOF;
|
||||||
|
}
|
||||||
|
if (!this._input) this.done = true;
|
||||||
|
|
||||||
|
var token,
|
||||||
|
match,
|
||||||
|
tempMatch,
|
||||||
|
index,
|
||||||
|
col,
|
||||||
|
lines;
|
||||||
|
if (!this._more) {
|
||||||
|
this.yytext = '';
|
||||||
|
this.match = '';
|
||||||
|
}
|
||||||
|
var rules = this._currentRules();
|
||||||
|
for (var i=0;i < rules.length; i++) {
|
||||||
|
tempMatch = this._input.match(this.rules[rules[i]]);
|
||||||
|
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
|
||||||
|
match = tempMatch;
|
||||||
|
index = i;
|
||||||
|
if (!this.options.flex) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (match) {
|
||||||
|
lines = match[0].match(/(?:\r\n?|\n).*/g);
|
||||||
|
if (lines) this.yylineno += lines.length;
|
||||||
|
this.yylloc = {first_line: this.yylloc.last_line,
|
||||||
|
last_line: this.yylineno+1,
|
||||||
|
first_column: this.yylloc.last_column,
|
||||||
|
last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
|
||||||
|
this.yytext += match[0];
|
||||||
|
this.match += match[0];
|
||||||
|
this.matches = match;
|
||||||
|
this.yyleng = this.yytext.length;
|
||||||
|
if (this.options.ranges) {
|
||||||
|
this.yylloc.range = [this.offset, this.offset += this.yyleng];
|
||||||
|
}
|
||||||
|
this._more = false;
|
||||||
|
this._input = this._input.slice(match[0].length);
|
||||||
|
this.matched += match[0];
|
||||||
|
token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
|
||||||
|
if (this.done && this._input) this.done = false;
|
||||||
|
if (token) return token;
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
if (this._input === "") {
|
||||||
|
return this.EOF;
|
||||||
|
} else {
|
||||||
|
return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
|
||||||
|
{text: "", token: null, line: this.yylineno});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lex:function lex() {
|
||||||
|
var r = this.next();
|
||||||
|
if (typeof r !== 'undefined') {
|
||||||
|
return r;
|
||||||
|
} else {
|
||||||
|
return this.lex();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
begin:function begin(condition) {
|
||||||
|
this.conditionStack.push(condition);
|
||||||
|
},
|
||||||
|
popState:function popState() {
|
||||||
|
return this.conditionStack.pop();
|
||||||
|
},
|
||||||
|
_currentRules:function _currentRules() {
|
||||||
|
return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
|
||||||
|
},
|
||||||
|
topState:function () {
|
||||||
|
return this.conditionStack[this.conditionStack.length-2];
|
||||||
|
},
|
||||||
|
pushState:function begin(condition) {
|
||||||
|
this.begin(condition);
|
||||||
|
}});
|
||||||
|
lexer.options = {};
|
||||||
|
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
||||||
|
|
||||||
|
|
||||||
|
function strip(start, end) {
|
||||||
|
return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var YYSTATE=YY_START
|
||||||
|
switch($avoiding_name_collisions) {
|
||||||
|
case 0:
|
||||||
|
if(yy_.yytext.slice(-2) === "\\\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("mu");
|
||||||
|
} else if(yy_.yytext.slice(-1) === "\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("emu");
|
||||||
|
} else {
|
||||||
|
this.begin("mu");
|
||||||
|
}
|
||||||
|
if(yy_.yytext) return 14;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 1:return 14;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this.popState();
|
||||||
|
return 14;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 3:strip(0,4); this.popState(); return 15;
|
||||||
|
break;
|
||||||
|
case 4:return 35;
|
||||||
|
break;
|
||||||
|
case 5:return 36;
|
||||||
|
break;
|
||||||
|
case 6:return 25;
|
||||||
|
break;
|
||||||
|
case 7:return 16;
|
||||||
|
break;
|
||||||
|
case 8:return 20;
|
||||||
|
break;
|
||||||
|
case 9:return 19;
|
||||||
|
break;
|
||||||
|
case 10:return 19;
|
||||||
|
break;
|
||||||
|
case 11:return 23;
|
||||||
|
break;
|
||||||
|
case 12:return 22;
|
||||||
|
break;
|
||||||
|
case 13:this.popState(); this.begin('com');
|
||||||
|
break;
|
||||||
|
case 14:strip(3,5); this.popState(); return 15;
|
||||||
|
break;
|
||||||
|
case 15:return 22;
|
||||||
|
break;
|
||||||
|
case 16:return 41;
|
||||||
|
break;
|
||||||
|
case 17:return 40;
|
||||||
|
break;
|
||||||
|
case 18:return 40;
|
||||||
|
break;
|
||||||
|
case 19:return 44;
|
||||||
|
break;
|
||||||
|
case 20:// ignore whitespace
|
||||||
|
break;
|
||||||
|
case 21:this.popState(); return 24;
|
||||||
|
break;
|
||||||
|
case 22:this.popState(); return 18;
|
||||||
|
break;
|
||||||
|
case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
|
||||||
|
break;
|
||||||
|
case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
|
||||||
|
break;
|
||||||
|
case 25:return 42;
|
||||||
|
break;
|
||||||
|
case 26:return 34;
|
||||||
|
break;
|
||||||
|
case 27:return 34;
|
||||||
|
break;
|
||||||
|
case 28:return 33;
|
||||||
|
break;
|
||||||
|
case 29:return 40;
|
||||||
|
break;
|
||||||
|
case 30:yy_.yytext = strip(1,2); return 40;
|
||||||
|
break;
|
||||||
|
case 31:return 'INVALID';
|
||||||
|
break;
|
||||||
|
case 32:return 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
|
||||||
|
lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
|
||||||
|
return lexer;})()
|
||||||
|
parser.lexer = lexer;
|
||||||
|
function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
|
||||||
|
return new Parser;
|
||||||
|
})();exports["default"] = handlebars;
|
||||||
|
/* jshint ignore:end */
|
||||||
138
node_modules/handlebars/dist/cjs/handlebars/compiler/printer.js
generated
vendored
Normal file
138
node_modules/handlebars/dist/cjs/handlebars/compiler/printer.js
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
"use strict";
|
||||||
|
var Visitor = require("./visitor")["default"];
|
||||||
|
|
||||||
|
function print(ast) {
|
||||||
|
return new PrintVisitor().accept(ast);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.print = print;function PrintVisitor() {
|
||||||
|
this.padding = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.PrintVisitor = PrintVisitor;PrintVisitor.prototype = new Visitor();
|
||||||
|
|
||||||
|
PrintVisitor.prototype.pad = function(string, newline) {
|
||||||
|
var out = "";
|
||||||
|
|
||||||
|
for(var i=0,l=this.padding; i<l; i++) {
|
||||||
|
out = out + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
out = out + string;
|
||||||
|
|
||||||
|
if(newline !== false) { out = out + "\n"; }
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.program = function(program) {
|
||||||
|
var out = "",
|
||||||
|
statements = program.statements,
|
||||||
|
i, l;
|
||||||
|
|
||||||
|
for(i=0, l=statements.length; i<l; i++) {
|
||||||
|
out = out + this.accept(statements[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.padding--;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.block = function(block) {
|
||||||
|
var out = "";
|
||||||
|
|
||||||
|
out = out + this.pad("BLOCK:");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.mustache);
|
||||||
|
if (block.program) {
|
||||||
|
out = out + this.pad("PROGRAM:");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.program);
|
||||||
|
this.padding--;
|
||||||
|
}
|
||||||
|
if (block.inverse) {
|
||||||
|
if (block.program) { this.padding++; }
|
||||||
|
out = out + this.pad("{{^}}");
|
||||||
|
this.padding++;
|
||||||
|
out = out + this.accept(block.inverse);
|
||||||
|
this.padding--;
|
||||||
|
if (block.program) { this.padding--; }
|
||||||
|
}
|
||||||
|
this.padding--;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.sexpr = function(sexpr) {
|
||||||
|
var params = sexpr.params, paramStrings = [], hash;
|
||||||
|
|
||||||
|
for(var i=0, l=params.length; i<l; i++) {
|
||||||
|
paramStrings.push(this.accept(params[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
params = "[" + paramStrings.join(", ") + "]";
|
||||||
|
|
||||||
|
hash = sexpr.hash ? " " + this.accept(sexpr.hash) : "";
|
||||||
|
|
||||||
|
return this.accept(sexpr.id) + " " + params + hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.mustache = function(mustache) {
|
||||||
|
return this.pad("{{ " + this.accept(mustache.sexpr) + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.partial = function(partial) {
|
||||||
|
var content = this.accept(partial.partialName);
|
||||||
|
if(partial.context) { content = content + " " + this.accept(partial.context); }
|
||||||
|
return this.pad("{{> " + content + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.hash = function(hash) {
|
||||||
|
var pairs = hash.pairs;
|
||||||
|
var joinedPairs = [], left, right;
|
||||||
|
|
||||||
|
for(var i=0, l=pairs.length; i<l; i++) {
|
||||||
|
left = pairs[i][0];
|
||||||
|
right = this.accept(pairs[i][1]);
|
||||||
|
joinedPairs.push( left + "=" + right );
|
||||||
|
}
|
||||||
|
|
||||||
|
return "HASH{" + joinedPairs.join(", ") + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.STRING = function(string) {
|
||||||
|
return '"' + string.string + '"';
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.INTEGER = function(integer) {
|
||||||
|
return "INTEGER{" + integer.integer + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.BOOLEAN = function(bool) {
|
||||||
|
return "BOOLEAN{" + bool.bool + "}";
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.ID = function(id) {
|
||||||
|
var path = id.parts.join("/");
|
||||||
|
if(id.parts.length > 1) {
|
||||||
|
return "PATH:" + path;
|
||||||
|
} else {
|
||||||
|
return "ID:" + path;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.PARTIAL_NAME = function(partialName) {
|
||||||
|
return "PARTIAL:" + partialName.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.DATA = function(data) {
|
||||||
|
return "@" + this.accept(data.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.content = function(content) {
|
||||||
|
return this.pad("CONTENT[ '" + content.string + "' ]");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.comment = function(comment) {
|
||||||
|
return this.pad("{{! '" + comment.comment + "' }}");
|
||||||
|
};
|
||||||
12
node_modules/handlebars/dist/cjs/handlebars/compiler/visitor.js
generated
vendored
Normal file
12
node_modules/handlebars/dist/cjs/handlebars/compiler/visitor.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
"use strict";
|
||||||
|
function Visitor() {}
|
||||||
|
|
||||||
|
Visitor.prototype = {
|
||||||
|
constructor: Visitor,
|
||||||
|
|
||||||
|
accept: function(object) {
|
||||||
|
return this[object.type](object);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports["default"] = Visitor;
|
||||||
28
node_modules/handlebars/dist/cjs/handlebars/exception.js
generated
vendored
Normal file
28
node_modules/handlebars/dist/cjs/handlebars/exception.js
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
exports["default"] = Exception;
|
||||||
137
node_modules/handlebars/dist/cjs/handlebars/runtime.js
generated
vendored
Normal file
137
node_modules/handlebars/dist/cjs/handlebars/runtime.js
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
"use strict";
|
||||||
|
var Utils = require("./utils");
|
||||||
|
var Exception = require("./exception")["default"];
|
||||||
|
var COMPILER_REVISION = require("./base").COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = require("./base").REVISION_CHANGES;
|
||||||
|
|
||||||
|
function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
|
} else {
|
||||||
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
|
||||||
|
|
||||||
|
function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Just add water
|
||||||
|
var container = {
|
||||||
|
escapeExpression: Utils.escapeExpression,
|
||||||
|
invokePartial: invokePartialWrapper,
|
||||||
|
programs: [],
|
||||||
|
program: function(i, fn, data) {
|
||||||
|
var programWrapper = this.programs[i];
|
||||||
|
if(data) {
|
||||||
|
programWrapper = program(i, fn, data);
|
||||||
|
} else if (!programWrapper) {
|
||||||
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
|
}
|
||||||
|
return programWrapper;
|
||||||
|
},
|
||||||
|
merge: function(param, common) {
|
||||||
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
|
compilerInfo: null
|
||||||
|
};
|
||||||
|
|
||||||
|
return function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
helpers = options.helpers;
|
||||||
|
partials = options.partials;
|
||||||
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.template = template;function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = args.length;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.programWithDepth = programWithDepth;function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn(context, options.data || data);
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = 0;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
|
if(partial === undefined) {
|
||||||
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
|
} else if(partial instanceof Function) {
|
||||||
|
return partial(context, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.invokePartial = invokePartial;function noop() { return ""; }
|
||||||
|
|
||||||
|
exports.noop = noop;
|
||||||
11
node_modules/handlebars/dist/cjs/handlebars/safe-string.js
generated
vendored
Normal file
11
node_modules/handlebars/dist/cjs/handlebars/safe-string.js
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
"use strict";
|
||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeString.prototype.toString = function() {
|
||||||
|
return "" + this.string;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports["default"] = SafeString;
|
||||||
76
node_modules/handlebars/dist/cjs/handlebars/utils.js
generated
vendored
Normal file
76
node_modules/handlebars/dist/cjs/handlebars/utils.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
"use strict";
|
||||||
|
/*jshint -W004 */
|
||||||
|
var SafeString = require("./safe-string")["default"];
|
||||||
|
|
||||||
|
var escape = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': """,
|
||||||
|
"'": "'",
|
||||||
|
"`": "`"
|
||||||
|
};
|
||||||
|
|
||||||
|
var badChars = /[&<>"'`]/g;
|
||||||
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
|
function escapeChar(chr) {
|
||||||
|
return escape[chr] || "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
function extend(obj, value) {
|
||||||
|
for(var key in value) {
|
||||||
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
obj[key] = value[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.extend = extend;var toString = Object.prototype.toString;
|
||||||
|
exports.toString = toString;
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var isFunction;
|
||||||
|
exports.isFunction = isFunction;
|
||||||
|
var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
|
};
|
||||||
|
exports.isArray = isArray;
|
||||||
|
|
||||||
|
function escapeExpression(string) {
|
||||||
|
// don't escape SafeStrings, since they're already safe
|
||||||
|
if (string instanceof SafeString) {
|
||||||
|
return string.toString();
|
||||||
|
} else if (!string && string !== 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
|
// an object's to string has escaped characters in it.
|
||||||
|
string = "" + string;
|
||||||
|
|
||||||
|
if(!possible.test(string)) { return string; }
|
||||||
|
return string.replace(badChars, escapeChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.escapeExpression = escapeExpression;function isEmpty(value) {
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
return true;
|
||||||
|
} else if (isArray(value) && value.length === 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.isEmpty = isEmpty;
|
||||||
2719
node_modules/handlebars/dist/handlebars.amd.js
generated
vendored
Normal file
2719
node_modules/handlebars/dist/handlebars.amd.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
28
node_modules/handlebars/dist/handlebars.amd.min.js
generated
vendored
Normal file
28
node_modules/handlebars/dist/handlebars.amd.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2043
node_modules/handlebars/dist/handlebars.js
generated
vendored
2043
node_modules/handlebars/dist/handlebars.js
generated
vendored
File diff suppressed because it is too large
Load Diff
28
node_modules/handlebars/dist/handlebars.min.js
generated
vendored
Normal file
28
node_modules/handlebars/dist/handlebars.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
515
node_modules/handlebars/dist/handlebars.runtime.amd.js
generated
vendored
Normal file
515
node_modules/handlebars/dist/handlebars.runtime.amd.js
generated
vendored
Normal file
@@ -0,0 +1,515 @@
|
|||||||
|
/*!
|
||||||
|
|
||||||
|
handlebars v1.3.0
|
||||||
|
|
||||||
|
Copyright (C) 2011 by Yehuda Katz
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
@license
|
||||||
|
*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
'handlebars/safe-string',["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
|
||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeString.prototype.toString = function() {
|
||||||
|
return "" + this.string;
|
||||||
|
};
|
||||||
|
|
||||||
|
__exports__["default"] = SafeString;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars/utils',["./safe-string","exports"],
|
||||||
|
function(__dependency1__, __exports__) {
|
||||||
|
|
||||||
|
/*jshint -W004 */
|
||||||
|
var SafeString = __dependency1__["default"];
|
||||||
|
|
||||||
|
var escape = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': """,
|
||||||
|
"'": "'",
|
||||||
|
"`": "`"
|
||||||
|
};
|
||||||
|
|
||||||
|
var badChars = /[&<>"'`]/g;
|
||||||
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
|
function escapeChar(chr) {
|
||||||
|
return escape[chr] || "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
function extend(obj, value) {
|
||||||
|
for(var key in value) {
|
||||||
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
obj[key] = value[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.extend = extend;var toString = Object.prototype.toString;
|
||||||
|
__exports__.toString = toString;
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var isFunction;
|
||||||
|
__exports__.isFunction = isFunction;
|
||||||
|
var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
|
};
|
||||||
|
__exports__.isArray = isArray;
|
||||||
|
|
||||||
|
function escapeExpression(string) {
|
||||||
|
// don't escape SafeStrings, since they're already safe
|
||||||
|
if (string instanceof SafeString) {
|
||||||
|
return string.toString();
|
||||||
|
} else if (!string && string !== 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
|
// an object's to string has escaped characters in it.
|
||||||
|
string = "" + string;
|
||||||
|
|
||||||
|
if(!possible.test(string)) { return string; }
|
||||||
|
return string.replace(badChars, escapeChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.escapeExpression = escapeExpression;function isEmpty(value) {
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
return true;
|
||||||
|
} else if (isArray(value) && value.length === 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.isEmpty = isEmpty;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars/exception',["exports"],
|
||||||
|
function(__exports__) {
|
||||||
|
|
||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
__exports__["default"] = Exception;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars/base',["./utils","./exception","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __exports__) {
|
||||||
|
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
|
||||||
|
var VERSION = "1.3.0";
|
||||||
|
__exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
|
||||||
|
__exports__.COMPILER_REVISION = COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = {
|
||||||
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
|
2: '== 1.0.0-rc.3',
|
||||||
|
3: '== 1.0.0-rc.4',
|
||||||
|
4: '>= 1.0.0'
|
||||||
|
};
|
||||||
|
__exports__.REVISION_CHANGES = REVISION_CHANGES;
|
||||||
|
var isArray = Utils.isArray,
|
||||||
|
isFunction = Utils.isFunction,
|
||||||
|
toString = Utils.toString,
|
||||||
|
objectType = '[object Object]';
|
||||||
|
|
||||||
|
function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
|
Utils.extend(this.helpers, name);
|
||||||
|
} else {
|
||||||
|
if (inverse) { fn.not = inverse; }
|
||||||
|
this.helpers[name] = fn;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
registerPartial: function(name, str) {
|
||||||
|
if (toString.call(name) === objectType) {
|
||||||
|
Utils.extend(this.partials, name);
|
||||||
|
} else {
|
||||||
|
this.partials[name] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
|
if(arguments.length === 2) {
|
||||||
|
return undefined;
|
||||||
|
} else {
|
||||||
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if(context === true) {
|
||||||
|
return fn(this);
|
||||||
|
} else if(context === false || context == null) {
|
||||||
|
return inverse(this);
|
||||||
|
} else if (isArray(context)) {
|
||||||
|
if(context.length > 0) {
|
||||||
|
return instance.helpers.each(context, options);
|
||||||
|
} else {
|
||||||
|
return inverse(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fn(context);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
var fn = options.fn, inverse = options.inverse;
|
||||||
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (options.data) {
|
||||||
|
data = createFrame(options.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(context && typeof context === 'object') {
|
||||||
|
if (isArray(context)) {
|
||||||
|
for(var j = context.length; i<j; i++) {
|
||||||
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[i], { data: data });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(var key in context) {
|
||||||
|
if(context.hasOwnProperty(key)) {
|
||||||
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
|
ret = ret + fn(context[key], {data: data});
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i === 0){
|
||||||
|
ret = inverse(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
|
|
||||||
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
|
return options.inverse(this);
|
||||||
|
} else {
|
||||||
|
return options.fn(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('with', function(context, options) {
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('log', function(context, options) {
|
||||||
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
|
instance.log(level, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var logger = {
|
||||||
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
|
|
||||||
|
// State enum
|
||||||
|
DEBUG: 0,
|
||||||
|
INFO: 1,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
|
// can be overridden in the host environment
|
||||||
|
log: function(level, obj) {
|
||||||
|
if (logger.level <= level) {
|
||||||
|
var method = logger.methodMap[level];
|
||||||
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__exports__.logger = logger;
|
||||||
|
function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
__exports__.log = log;var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
__exports__.createFrame = createFrame;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars/runtime',["./utils","./exception","./base","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __exports__) {
|
||||||
|
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__["default"];
|
||||||
|
var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
|
||||||
|
|
||||||
|
function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
|
} else {
|
||||||
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
|
||||||
|
|
||||||
|
function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Just add water
|
||||||
|
var container = {
|
||||||
|
escapeExpression: Utils.escapeExpression,
|
||||||
|
invokePartial: invokePartialWrapper,
|
||||||
|
programs: [],
|
||||||
|
program: function(i, fn, data) {
|
||||||
|
var programWrapper = this.programs[i];
|
||||||
|
if(data) {
|
||||||
|
programWrapper = program(i, fn, data);
|
||||||
|
} else if (!programWrapper) {
|
||||||
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
|
}
|
||||||
|
return programWrapper;
|
||||||
|
},
|
||||||
|
merge: function(param, common) {
|
||||||
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
|
compilerInfo: null
|
||||||
|
};
|
||||||
|
|
||||||
|
return function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
helpers = options.helpers;
|
||||||
|
partials = options.partials;
|
||||||
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = args.length;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
return fn(context, options.data || data);
|
||||||
|
};
|
||||||
|
prog.program = i;
|
||||||
|
prog.depth = 0;
|
||||||
|
return prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
|
if(partial === undefined) {
|
||||||
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
|
} else if(partial instanceof Function) {
|
||||||
|
return partial(context, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.invokePartial = invokePartial;function noop() { return ""; }
|
||||||
|
|
||||||
|
__exports__.noop = noop;
|
||||||
|
});
|
||||||
|
define(
|
||||||
|
'handlebars.runtime',["./handlebars/base","./handlebars/safe-string","./handlebars/exception","./handlebars/utils","./handlebars/runtime","exports"],
|
||||||
|
function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
|
||||||
|
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var base = __dependency1__;
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
var SafeString = __dependency2__["default"];
|
||||||
|
var Exception = __dependency3__["default"];
|
||||||
|
var Utils = __dependency4__;
|
||||||
|
var runtime = __dependency5__;
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
__exports__["default"] = Handlebars;
|
||||||
|
});
|
||||||
27
node_modules/handlebars/dist/handlebars.runtime.amd.min.js
generated
vendored
Normal file
27
node_modules/handlebars/dist/handlebars.runtime.amd.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
589
node_modules/handlebars/dist/handlebars.runtime.js
generated
vendored
589
node_modules/handlebars/dist/handlebars.runtime.js
generated
vendored
@@ -1,4 +1,6 @@
|
|||||||
/*
|
/*!
|
||||||
|
|
||||||
|
handlebars v1.3.0
|
||||||
|
|
||||||
Copyright (C) 2011 by Yehuda Katz
|
Copyright (C) 2011 by Yehuda Katz
|
||||||
|
|
||||||
@@ -20,124 +22,254 @@ 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
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
@license
|
||||||
*/
|
*/
|
||||||
|
/* exported Handlebars */
|
||||||
|
var Handlebars = (function() {
|
||||||
|
// handlebars/safe-string.js
|
||||||
|
var __module3__ = (function() {
|
||||||
|
"use strict";
|
||||||
|
var __exports__;
|
||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
// lib/handlebars/browser-prefix.js
|
SafeString.prototype.toString = function() {
|
||||||
var Handlebars = {};
|
return "" + this.string;
|
||||||
|
};
|
||||||
|
|
||||||
(function(Handlebars, undefined) {
|
__exports__ = SafeString;
|
||||||
;
|
return __exports__;
|
||||||
// lib/handlebars/base.js
|
})();
|
||||||
|
|
||||||
Handlebars.VERSION = "1.0.0-rc.4";
|
// handlebars/utils.js
|
||||||
Handlebars.COMPILER_REVISION = 3;
|
var __module2__ = (function(__dependency1__) {
|
||||||
|
"use strict";
|
||||||
|
var __exports__ = {};
|
||||||
|
/*jshint -W004 */
|
||||||
|
var SafeString = __dependency1__;
|
||||||
|
|
||||||
Handlebars.REVISION_CHANGES = {
|
var escape = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': """,
|
||||||
|
"'": "'",
|
||||||
|
"`": "`"
|
||||||
|
};
|
||||||
|
|
||||||
|
var badChars = /[&<>"'`]/g;
|
||||||
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
|
function escapeChar(chr) {
|
||||||
|
return escape[chr] || "&";
|
||||||
|
}
|
||||||
|
|
||||||
|
function extend(obj, value) {
|
||||||
|
for(var key in value) {
|
||||||
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
|
obj[key] = value[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.extend = extend;var toString = Object.prototype.toString;
|
||||||
|
__exports__.toString = toString;
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var isFunction;
|
||||||
|
__exports__.isFunction = isFunction;
|
||||||
|
var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
|
};
|
||||||
|
__exports__.isArray = isArray;
|
||||||
|
|
||||||
|
function escapeExpression(string) {
|
||||||
|
// don't escape SafeStrings, since they're already safe
|
||||||
|
if (string instanceof SafeString) {
|
||||||
|
return string.toString();
|
||||||
|
} else if (!string && string !== 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
|
// an object's to string has escaped characters in it.
|
||||||
|
string = "" + string;
|
||||||
|
|
||||||
|
if(!possible.test(string)) { return string; }
|
||||||
|
return string.replace(badChars, escapeChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.escapeExpression = escapeExpression;function isEmpty(value) {
|
||||||
|
if (!value && value !== 0) {
|
||||||
|
return true;
|
||||||
|
} else if (isArray(value) && value.length === 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.isEmpty = isEmpty;
|
||||||
|
return __exports__;
|
||||||
|
})(__module3__);
|
||||||
|
|
||||||
|
// handlebars/exception.js
|
||||||
|
var __module4__ = (function() {
|
||||||
|
"use strict";
|
||||||
|
var __exports__;
|
||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
__exports__ = Exception;
|
||||||
|
return __exports__;
|
||||||
|
})();
|
||||||
|
|
||||||
|
// handlebars/base.js
|
||||||
|
var __module1__ = (function(__dependency1__, __dependency2__) {
|
||||||
|
"use strict";
|
||||||
|
var __exports__ = {};
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__;
|
||||||
|
|
||||||
|
var VERSION = "1.3.0";
|
||||||
|
__exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
|
||||||
|
__exports__.COMPILER_REVISION = COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = {
|
||||||
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
2: '== 1.0.0-rc.3',
|
2: '== 1.0.0-rc.3',
|
||||||
3: '>= 1.0.0-rc.4'
|
3: '== 1.0.0-rc.4',
|
||||||
};
|
4: '>= 1.0.0'
|
||||||
|
};
|
||||||
Handlebars.helpers = {};
|
__exports__.REVISION_CHANGES = REVISION_CHANGES;
|
||||||
Handlebars.partials = {};
|
var isArray = Utils.isArray,
|
||||||
|
isFunction = Utils.isFunction,
|
||||||
var toString = Object.prototype.toString,
|
toString = Utils.toString,
|
||||||
functionType = '[object Function]',
|
|
||||||
objectType = '[object Object]';
|
objectType = '[object Object]';
|
||||||
|
|
||||||
Handlebars.registerHelper = function(name, fn, inverse) {
|
function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
__exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
if (toString.call(name) === objectType) {
|
if (toString.call(name) === objectType) {
|
||||||
if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); }
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
Handlebars.Utils.extend(this.helpers, name);
|
Utils.extend(this.helpers, name);
|
||||||
} else {
|
} else {
|
||||||
if (inverse) { fn.not = inverse; }
|
if (inverse) { fn.not = inverse; }
|
||||||
this.helpers[name] = fn;
|
this.helpers[name] = fn;
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.registerPartial = function(name, str) {
|
registerPartial: function(name, str) {
|
||||||
if (toString.call(name) === objectType) {
|
if (toString.call(name) === objectType) {
|
||||||
Handlebars.Utils.extend(this.partials, name);
|
Utils.extend(this.partials, name);
|
||||||
} else {
|
} else {
|
||||||
this.partials[name] = str;
|
this.partials[name] = str;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Handlebars.registerHelper('helperMissing', function(arg) {
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
if(arguments.length === 2) {
|
if(arguments.length === 2) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Could not find property '" + arg + "'");
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('blockHelperMissing', function(context, options) {
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
var inverse = options.inverse || function() {}, fn = options.fn;
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
var type = toString.call(context);
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
if(type === functionType) { context = context.call(this); }
|
|
||||||
|
|
||||||
if(context === true) {
|
if(context === true) {
|
||||||
return fn(this);
|
return fn(this);
|
||||||
} else if(context === false || context == null) {
|
} else if(context === false || context == null) {
|
||||||
return inverse(this);
|
return inverse(this);
|
||||||
} else if(type === "[object Array]") {
|
} else if (isArray(context)) {
|
||||||
if(context.length > 0) {
|
if(context.length > 0) {
|
||||||
return Handlebars.helpers.each(context, options);
|
return instance.helpers.each(context, options);
|
||||||
} else {
|
} else {
|
||||||
return inverse(this);
|
return inverse(this);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fn(context);
|
return fn(context);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.K = function() {};
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
|
||||||
Handlebars.createFrame = Object.create || function(object) {
|
|
||||||
Handlebars.K.prototype = object;
|
|
||||||
var obj = new Handlebars.K();
|
|
||||||
Handlebars.K.prototype = null;
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.logger = {
|
|
||||||
DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
|
|
||||||
|
|
||||||
methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
|
|
||||||
|
|
||||||
// can be overridden in the host environment
|
|
||||||
log: function(level, obj) {
|
|
||||||
if (Handlebars.logger.level <= level) {
|
|
||||||
var method = Handlebars.logger.methodMap[level];
|
|
||||||
if (typeof console !== 'undefined' && console[method]) {
|
|
||||||
console[method].call(console, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
|
|
||||||
|
|
||||||
Handlebars.registerHelper('each', function(context, options) {
|
|
||||||
var fn = options.fn, inverse = options.inverse;
|
var fn = options.fn, inverse = options.inverse;
|
||||||
var i = 0, ret = "", data;
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
if (options.data) {
|
if (options.data) {
|
||||||
data = Handlebars.createFrame(options.data);
|
data = createFrame(options.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(context && typeof context === 'object') {
|
if(context && typeof context === 'object') {
|
||||||
if(context instanceof Array){
|
if (isArray(context)) {
|
||||||
for(var j = context.length; i<j; i++) {
|
for(var j = context.length; i<j; i++) {
|
||||||
if (data) { data.index = i; }
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
ret = ret + fn(context[i], { data: data });
|
ret = ret + fn(context[i], { data: data });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for(var key in context) {
|
for(var key in context) {
|
||||||
if(context.hasOwnProperty(key)) {
|
if(context.hasOwnProperty(key)) {
|
||||||
if(data) { data.key = key; }
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
ret = ret + fn(context[key], {data: data});
|
ret = ret + fn(context[key], {data: data});
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -150,196 +282,249 @@ Handlebars.registerHelper('each', function(context, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('if', function(context, options) {
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
var type = toString.call(context);
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
if(type === functionType) { context = context.call(this); }
|
|
||||||
|
|
||||||
if(!context || Handlebars.Utils.isEmpty(context)) {
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
return options.inverse(this);
|
return options.inverse(this);
|
||||||
} else {
|
} else {
|
||||||
return options.fn(this);
|
return options.fn(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('unless', function(context, options) {
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
return Handlebars.helpers['if'].call(this, context, {fn: options.inverse, inverse: options.fn});
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('with', function(context, options) {
|
instance.registerHelper('with', function(context, options) {
|
||||||
if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('log', function(context, options) {
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('log', function(context, options) {
|
||||||
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
Handlebars.log(level, context);
|
instance.log(level, context);
|
||||||
});
|
});
|
||||||
;
|
|
||||||
// lib/handlebars/utils.js
|
|
||||||
|
|
||||||
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
|
||||||
|
|
||||||
Handlebars.Exception = function(message) {
|
|
||||||
var tmp = Error.prototype.constructor.apply(this, arguments);
|
|
||||||
|
|
||||||
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
|
||||||
for (var idx = 0; idx < errorProps.length; idx++) {
|
|
||||||
this[errorProps[idx]] = tmp[errorProps[idx]];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Handlebars.Exception.prototype = new Error();
|
|
||||||
|
|
||||||
// Build out our basic SafeString type
|
|
||||||
Handlebars.SafeString = function(string) {
|
|
||||||
this.string = string;
|
|
||||||
};
|
|
||||||
Handlebars.SafeString.prototype.toString = function() {
|
|
||||||
return this.string.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
var escape = {
|
|
||||||
"&": "&",
|
|
||||||
"<": "<",
|
|
||||||
">": ">",
|
|
||||||
'"': """,
|
|
||||||
"'": "'",
|
|
||||||
"`": "`"
|
|
||||||
};
|
|
||||||
|
|
||||||
var badChars = /[&<>"'`]/g;
|
|
||||||
var possible = /[&<>"'`]/;
|
|
||||||
|
|
||||||
var escapeChar = function(chr) {
|
|
||||||
return escape[chr] || "&";
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.Utils = {
|
|
||||||
extend: function(obj, value) {
|
|
||||||
for(var key in value) {
|
|
||||||
if(value.hasOwnProperty(key)) {
|
|
||||||
obj[key] = value[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
escapeExpression: function(string) {
|
|
||||||
// don't escape SafeStrings, since they're already safe
|
|
||||||
if (string instanceof Handlebars.SafeString) {
|
|
||||||
return string.toString();
|
|
||||||
} else if (string == null || string === false) {
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force a string conversion as this will be done by the append regardless and
|
var logger = {
|
||||||
// the regex test will do this transparently behind the scenes, causing issues if
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
// an object's to string has escaped characters in it.
|
|
||||||
string = string.toString();
|
|
||||||
|
|
||||||
if(!possible.test(string)) { return string; }
|
// State enum
|
||||||
return string.replace(badChars, escapeChar);
|
DEBUG: 0,
|
||||||
},
|
INFO: 1,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
isEmpty: function(value) {
|
// can be overridden in the host environment
|
||||||
if (!value && value !== 0) {
|
log: function(level, obj) {
|
||||||
return true;
|
if (logger.level <= level) {
|
||||||
} else if(toString.call(value) === "[object Array]" && value.length === 0) {
|
var method = logger.methodMap[level];
|
||||||
return true;
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
__exports__.logger = logger;
|
||||||
|
function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
__exports__.log = log;var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
__exports__.createFrame = createFrame;
|
||||||
|
return __exports__;
|
||||||
|
})(__module2__, __module4__);
|
||||||
|
|
||||||
|
// handlebars/runtime.js
|
||||||
|
var __module5__ = (function(__dependency1__, __dependency2__, __dependency3__) {
|
||||||
|
"use strict";
|
||||||
|
var __exports__ = {};
|
||||||
|
var Utils = __dependency1__;
|
||||||
|
var Exception = __dependency2__;
|
||||||
|
var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
|
||||||
|
var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
|
||||||
|
|
||||||
|
function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
} else {
|
} else {
|
||||||
return false;
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
;
|
|
||||||
// lib/handlebars/runtime.js
|
|
||||||
|
|
||||||
Handlebars.VM = {
|
__exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
|
||||||
template: function(templateSpec) {
|
|
||||||
|
function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Just add water
|
// Just add water
|
||||||
var container = {
|
var container = {
|
||||||
escapeExpression: Handlebars.Utils.escapeExpression,
|
escapeExpression: Utils.escapeExpression,
|
||||||
invokePartial: Handlebars.VM.invokePartial,
|
invokePartial: invokePartialWrapper,
|
||||||
programs: [],
|
programs: [],
|
||||||
program: function(i, fn, data) {
|
program: function(i, fn, data) {
|
||||||
var programWrapper = this.programs[i];
|
var programWrapper = this.programs[i];
|
||||||
if(data) {
|
if(data) {
|
||||||
programWrapper = Handlebars.VM.program(i, fn, data);
|
programWrapper = program(i, fn, data);
|
||||||
} else if (!programWrapper) {
|
} else if (!programWrapper) {
|
||||||
programWrapper = this.programs[i] = Handlebars.VM.program(i, fn);
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
}
|
}
|
||||||
return programWrapper;
|
return programWrapper;
|
||||||
},
|
},
|
||||||
programWithDepth: Handlebars.VM.programWithDepth,
|
merge: function(param, common) {
|
||||||
noop: Handlebars.VM.noop,
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
compilerInfo: null
|
compilerInfo: null
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(context, options) {
|
return function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
var compilerInfo = container.compilerInfo || [],
|
if (!options.partial) {
|
||||||
compilerRevision = compilerInfo[0] || 1,
|
helpers = options.helpers;
|
||||||
currentRevision = Handlebars.COMPILER_REVISION;
|
partials = options.partials;
|
||||||
|
|
||||||
if (compilerRevision !== currentRevision) {
|
|
||||||
if (compilerRevision < currentRevision) {
|
|
||||||
var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
|
|
||||||
compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
|
|
||||||
throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
|
|
||||||
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
|
|
||||||
} else {
|
|
||||||
// Use the embedded version info since the runtime doesn't know about this revision yet
|
|
||||||
throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
|
||||||
"Please update your runtime to a newer version ("+compilerInfo[1]+").";
|
|
||||||
}
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
|
|
||||||
programWithDepth: function(i, fn, data /*, $depth */) {
|
__exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
var args = Array.prototype.slice.call(arguments, 3);
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
var program = function(context, options) {
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn.apply(this, [context, options.data || data].concat(args));
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
};
|
};
|
||||||
program.program = i;
|
prog.program = i;
|
||||||
program.depth = args.length;
|
prog.depth = args.length;
|
||||||
return program;
|
return prog;
|
||||||
},
|
}
|
||||||
program: function(i, fn, data) {
|
|
||||||
var program = function(context, options) {
|
__exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn(context, options.data || data);
|
return fn(context, options.data || data);
|
||||||
};
|
};
|
||||||
program.program = i;
|
prog.program = i;
|
||||||
program.depth = 0;
|
prog.depth = 0;
|
||||||
return program;
|
return prog;
|
||||||
},
|
}
|
||||||
noop: function() { return ""; },
|
|
||||||
invokePartial: function(partial, name, context, helpers, partials, data) {
|
__exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
var options = { helpers: helpers, partials: partials, data: data };
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
if(partial === undefined) {
|
if(partial === undefined) {
|
||||||
throw new Handlebars.Exception("The partial " + name + " could not be found");
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
} else if(partial instanceof Function) {
|
} else if(partial instanceof Function) {
|
||||||
return partial(context, options);
|
return partial(context, options);
|
||||||
} else if (!Handlebars.compile) {
|
|
||||||
throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
|
||||||
} else {
|
|
||||||
partials[name] = Handlebars.compile(partial, {data: data !== undefined});
|
|
||||||
return partials[name](context, options);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.template = Handlebars.VM.template;
|
__exports__.invokePartial = invokePartial;function noop() { return ""; }
|
||||||
;
|
|
||||||
// lib/handlebars/browser-suffix.js
|
__exports__.noop = noop;
|
||||||
})(Handlebars);
|
return __exports__;
|
||||||
;
|
})(__module2__, __module4__, __module1__);
|
||||||
|
|
||||||
|
// handlebars.runtime.js
|
||||||
|
var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
|
||||||
|
"use strict";
|
||||||
|
var __exports__;
|
||||||
|
/*globals Handlebars: true */
|
||||||
|
var base = __dependency1__;
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
var SafeString = __dependency2__;
|
||||||
|
var Exception = __dependency3__;
|
||||||
|
var Utils = __dependency4__;
|
||||||
|
var runtime = __dependency5__;
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
__exports__ = Handlebars;
|
||||||
|
return __exports__;
|
||||||
|
})(__module1__, __module3__, __module4__, __module2__, __module5__);
|
||||||
|
|
||||||
|
return __module0__;
|
||||||
|
})();
|
||||||
|
|||||||
27
node_modules/handlebars/dist/handlebars.runtime.min.js
generated
vendored
Normal file
27
node_modules/handlebars/dist/handlebars.runtime.min.js
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
18
node_modules/handlebars/global-test.js
generated
vendored
18
node_modules/handlebars/global-test.js
generated
vendored
@@ -1,18 +0,0 @@
|
|||||||
var Handlebars = require('./lib/handlebars');
|
|
||||||
|
|
||||||
Handlebars.registerHelper('test_helper', function() { return 'found it!' });
|
|
||||||
Handlebars.registerPartial('global_test', '{{another_dude}}');
|
|
||||||
|
|
||||||
//var template = Handlebars.compile('{{test_helper}} {{#if cruel}}Goodbye {{cruel}} {{world}}!{{/if}}');
|
|
||||||
var template = Handlebars.precompile("Dudes: {{#if foo}} {{#if nested}} {{> shared/dude}} {{/if}} {{> global_test}} {{/if}}");
|
|
||||||
console.log(template);
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
template({cruel: "cruel", name:"Jeepers", another_dude:"Creepers"}, {
|
|
||||||
helpers: {world: function() { return "world!"; }},
|
|
||||||
partials: {'shared/dude':"{{name}}"}
|
|
||||||
}));
|
|
||||||
|
|
||||||
console.log(template);
|
|
||||||
21
node_modules/handlebars/handlebars-source.gemspec
generated
vendored
21
node_modules/handlebars/handlebars-source.gemspec
generated
vendored
@@ -1,21 +0,0 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
|
||||||
require 'json'
|
|
||||||
|
|
||||||
package = JSON.parse(File.read('package.json'))
|
|
||||||
|
|
||||||
Gem::Specification.new do |gem|
|
|
||||||
gem.name = "handlebars-source"
|
|
||||||
gem.authors = ["Yehuda Katz"]
|
|
||||||
gem.email = ["wycats@gmail.com"]
|
|
||||||
gem.date = Time.now.strftime("%Y-%m-%d")
|
|
||||||
gem.description = %q{Handlebars.js source code wrapper for (pre)compilation gems.}
|
|
||||||
gem.summary = %q{Handlebars.js source code wrapper}
|
|
||||||
gem.homepage = "https://github.com/wycats/handlebars.js/"
|
|
||||||
gem.version = package["version"]
|
|
||||||
|
|
||||||
gem.files = [
|
|
||||||
'dist/handlebars.js',
|
|
||||||
'dist/handlebars.runtime.js',
|
|
||||||
'lib/handlebars/source.rb'
|
|
||||||
]
|
|
||||||
end
|
|
||||||
17
node_modules/handlebars/handlebars.js.nuspec
generated
vendored
17
node_modules/handlebars/handlebars.js.nuspec
generated
vendored
@@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<package>
|
|
||||||
<metadata>
|
|
||||||
<id>handlebars.js</id>
|
|
||||||
<version>1.0.0-rc.4</version>
|
|
||||||
<authors>handlebars.js Authors</authors>
|
|
||||||
<licenseUrl>https://github.com/wycats/handlebars.js/blob/master/LICENSE</licenseUrl>
|
|
||||||
<projectUrl>https://github.com/wycats/handlebars.js/</projectUrl>
|
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
|
||||||
<description>Extension of the Mustache logicless template language</description>
|
|
||||||
<releaseNotes></releaseNotes>
|
|
||||||
<tags>handlebars mustache template html</tags>
|
|
||||||
</metadata>
|
|
||||||
<files>
|
|
||||||
<file src="dist\handlebars.js" target="Content\Scripts" />
|
|
||||||
</files>
|
|
||||||
</package>
|
|
||||||
45
node_modules/handlebars/lib/handlebars.js
generated
vendored
45
node_modules/handlebars/lib/handlebars.js
generated
vendored
@@ -1,32 +1,33 @@
|
|||||||
var handlebars = require("./handlebars/base"),
|
/*globals Handlebars: true */
|
||||||
|
import Handlebars from "./handlebars.runtime";
|
||||||
|
|
||||||
// Each of these augment the Handlebars object. No need to setup here.
|
// Compiler imports
|
||||||
// (This is done to easily share code between commonjs and browse envs)
|
import AST from "./handlebars/compiler/ast";
|
||||||
utils = require("./handlebars/utils"),
|
import { parser as Parser, parse } from "./handlebars/compiler/base";
|
||||||
compiler = require("./handlebars/compiler"),
|
import { Compiler, compile, precompile } from "./handlebars/compiler/compiler";
|
||||||
runtime = require("./handlebars/runtime");
|
import JavaScriptCompiler from "./handlebars/compiler/javascript-compiler";
|
||||||
|
|
||||||
|
var _create = Handlebars.create;
|
||||||
var create = function() {
|
var create = function() {
|
||||||
var hb = handlebars.create();
|
var hb = _create();
|
||||||
|
|
||||||
utils.attach(hb);
|
hb.compile = function(input, options) {
|
||||||
compiler.attach(hb);
|
return compile(input, options, hb);
|
||||||
runtime.attach(hb);
|
};
|
||||||
|
hb.precompile = function (input, options) {
|
||||||
|
return precompile(input, options, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
hb.AST = AST;
|
||||||
|
hb.Compiler = Compiler;
|
||||||
|
hb.JavaScriptCompiler = JavaScriptCompiler;
|
||||||
|
hb.Parser = Parser;
|
||||||
|
hb.parse = parse;
|
||||||
|
|
||||||
return hb;
|
return hb;
|
||||||
};
|
};
|
||||||
|
|
||||||
var Handlebars = create();
|
Handlebars = create();
|
||||||
Handlebars.create = create;
|
Handlebars.create = create;
|
||||||
|
|
||||||
module.exports = Handlebars; // instantiate an instance
|
export default Handlebars;
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
|
||||||
|
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
// USAGE:
|
|
||||||
// var handlebars = require('handlebars');
|
|
||||||
|
|
||||||
// var singleton = handlebars.Handlebars,
|
|
||||||
// local = handlebars.create();
|
|
||||||
|
|||||||
31
node_modules/handlebars/lib/handlebars.runtime.js
generated
vendored
Normal file
31
node_modules/handlebars/lib/handlebars.runtime.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/*globals Handlebars: true */
|
||||||
|
module base from "./handlebars/base";
|
||||||
|
|
||||||
|
// Each of these augment the Handlebars object. No need to setup here.
|
||||||
|
// (This is done to easily share code between commonjs and browse envs)
|
||||||
|
import SafeString from "./handlebars/safe-string";
|
||||||
|
import Exception from "./handlebars/exception";
|
||||||
|
module Utils from "./handlebars/utils";
|
||||||
|
module runtime from "./handlebars/runtime";
|
||||||
|
|
||||||
|
// For compatibility and usage outside of module systems, make the Handlebars object a namespace
|
||||||
|
var create = function() {
|
||||||
|
var hb = new base.HandlebarsEnvironment();
|
||||||
|
|
||||||
|
Utils.extend(hb, base);
|
||||||
|
hb.SafeString = SafeString;
|
||||||
|
hb.Exception = Exception;
|
||||||
|
hb.Utils = Utils;
|
||||||
|
|
||||||
|
hb.VM = runtime;
|
||||||
|
hb.template = function(spec) {
|
||||||
|
return runtime.template(spec, hb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return hb;
|
||||||
|
};
|
||||||
|
|
||||||
|
var Handlebars = create();
|
||||||
|
Handlebars.create = create;
|
||||||
|
|
||||||
|
export default Handlebars;
|
||||||
181
node_modules/handlebars/lib/handlebars/base.js
generated
vendored
181
node_modules/handlebars/lib/handlebars/base.js
generated
vendored
@@ -1,120 +1,110 @@
|
|||||||
/*jshint eqnull: true */
|
module Utils from "./utils";
|
||||||
|
import Exception from "./exception";
|
||||||
|
|
||||||
module.exports.create = function() {
|
export var VERSION = "1.3.0";
|
||||||
|
export var COMPILER_REVISION = 4;
|
||||||
|
|
||||||
var Handlebars = {};
|
export var REVISION_CHANGES = {
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
|
||||||
|
|
||||||
Handlebars.VERSION = "1.0.0-rc.4";
|
|
||||||
Handlebars.COMPILER_REVISION = 3;
|
|
||||||
|
|
||||||
Handlebars.REVISION_CHANGES = {
|
|
||||||
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
|
||||||
2: '== 1.0.0-rc.3',
|
2: '== 1.0.0-rc.3',
|
||||||
3: '>= 1.0.0-rc.4'
|
3: '== 1.0.0-rc.4',
|
||||||
|
4: '>= 1.0.0'
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.helpers = {};
|
var isArray = Utils.isArray,
|
||||||
Handlebars.partials = {};
|
isFunction = Utils.isFunction,
|
||||||
|
toString = Utils.toString,
|
||||||
var toString = Object.prototype.toString,
|
|
||||||
functionType = '[object Function]',
|
|
||||||
objectType = '[object Object]';
|
objectType = '[object Object]';
|
||||||
|
|
||||||
Handlebars.registerHelper = function(name, fn, inverse) {
|
export function HandlebarsEnvironment(helpers, partials) {
|
||||||
|
this.helpers = helpers || {};
|
||||||
|
this.partials = partials || {};
|
||||||
|
|
||||||
|
registerDefaultHelpers(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
HandlebarsEnvironment.prototype = {
|
||||||
|
constructor: HandlebarsEnvironment,
|
||||||
|
|
||||||
|
logger: logger,
|
||||||
|
log: log,
|
||||||
|
|
||||||
|
registerHelper: function(name, fn, inverse) {
|
||||||
if (toString.call(name) === objectType) {
|
if (toString.call(name) === objectType) {
|
||||||
if (inverse || fn) { throw new Handlebars.Exception('Arg not supported with multiple helpers'); }
|
if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
|
||||||
Handlebars.Utils.extend(this.helpers, name);
|
Utils.extend(this.helpers, name);
|
||||||
} else {
|
} else {
|
||||||
if (inverse) { fn.not = inverse; }
|
if (inverse) { fn.not = inverse; }
|
||||||
this.helpers[name] = fn;
|
this.helpers[name] = fn;
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.registerPartial = function(name, str) {
|
registerPartial: function(name, str) {
|
||||||
if (toString.call(name) === objectType) {
|
if (toString.call(name) === objectType) {
|
||||||
Handlebars.Utils.extend(this.partials, name);
|
Utils.extend(this.partials, name);
|
||||||
} else {
|
} else {
|
||||||
this.partials[name] = str;
|
this.partials[name] = str;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.registerHelper('helperMissing', function(arg) {
|
function registerDefaultHelpers(instance) {
|
||||||
|
instance.registerHelper('helperMissing', function(arg) {
|
||||||
if(arguments.length === 2) {
|
if(arguments.length === 2) {
|
||||||
return undefined;
|
return undefined;
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Could not find property '" + arg + "'");
|
throw new Exception("Missing helper: '" + arg + "'");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('blockHelperMissing', function(context, options) {
|
instance.registerHelper('blockHelperMissing', function(context, options) {
|
||||||
var inverse = options.inverse || function() {}, fn = options.fn;
|
var inverse = options.inverse || function() {}, fn = options.fn;
|
||||||
|
|
||||||
var type = toString.call(context);
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
if(type === functionType) { context = context.call(this); }
|
|
||||||
|
|
||||||
if(context === true) {
|
if(context === true) {
|
||||||
return fn(this);
|
return fn(this);
|
||||||
} else if(context === false || context == null) {
|
} else if(context === false || context == null) {
|
||||||
return inverse(this);
|
return inverse(this);
|
||||||
} else if(type === "[object Array]") {
|
} else if (isArray(context)) {
|
||||||
if(context.length > 0) {
|
if(context.length > 0) {
|
||||||
return Handlebars.helpers.each(context, options);
|
return instance.helpers.each(context, options);
|
||||||
} else {
|
} else {
|
||||||
return inverse(this);
|
return inverse(this);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fn(context);
|
return fn(context);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.K = function() {};
|
instance.registerHelper('each', function(context, options) {
|
||||||
|
|
||||||
Handlebars.createFrame = Object.create || function(object) {
|
|
||||||
Handlebars.K.prototype = object;
|
|
||||||
var obj = new Handlebars.K();
|
|
||||||
Handlebars.K.prototype = null;
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.logger = {
|
|
||||||
DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
|
|
||||||
|
|
||||||
methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
|
|
||||||
|
|
||||||
// can be overridden in the host environment
|
|
||||||
log: function(level, obj) {
|
|
||||||
if (Handlebars.logger.level <= level) {
|
|
||||||
var method = Handlebars.logger.methodMap[level];
|
|
||||||
if (typeof console !== 'undefined' && console[method]) {
|
|
||||||
console[method].call(console, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
|
|
||||||
|
|
||||||
Handlebars.registerHelper('each', function(context, options) {
|
|
||||||
var fn = options.fn, inverse = options.inverse;
|
var fn = options.fn, inverse = options.inverse;
|
||||||
var i = 0, ret = "", data;
|
var i = 0, ret = "", data;
|
||||||
|
|
||||||
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
|
|
||||||
if (options.data) {
|
if (options.data) {
|
||||||
data = Handlebars.createFrame(options.data);
|
data = createFrame(options.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(context && typeof context === 'object') {
|
if(context && typeof context === 'object') {
|
||||||
if(context instanceof Array){
|
if (isArray(context)) {
|
||||||
for(var j = context.length; i<j; i++) {
|
for(var j = context.length; i<j; i++) {
|
||||||
if (data) { data.index = i; }
|
if (data) {
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
data.last = (i === (context.length-1));
|
||||||
|
}
|
||||||
ret = ret + fn(context[i], { data: data });
|
ret = ret + fn(context[i], { data: data });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for(var key in context) {
|
for(var key in context) {
|
||||||
if(context.hasOwnProperty(key)) {
|
if(context.hasOwnProperty(key)) {
|
||||||
if(data) { data.key = key; }
|
if(data) {
|
||||||
|
data.key = key;
|
||||||
|
data.index = i;
|
||||||
|
data.first = (i === 0);
|
||||||
|
}
|
||||||
ret = ret + fn(context[key], {data: data});
|
ret = ret + fn(context[key], {data: data});
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@@ -127,33 +117,62 @@ Handlebars.registerHelper('each', function(context, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('if', function(context, options) {
|
instance.registerHelper('if', function(conditional, options) {
|
||||||
var type = toString.call(context);
|
if (isFunction(conditional)) { conditional = conditional.call(this); }
|
||||||
if(type === functionType) { context = context.call(this); }
|
|
||||||
|
|
||||||
if(!context || Handlebars.Utils.isEmpty(context)) {
|
// Default behavior is to render the positive path if the value is truthy and not empty.
|
||||||
|
// The `includeZero` option may be set to treat the condtional as purely not empty based on the
|
||||||
|
// behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
|
||||||
|
if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
|
||||||
return options.inverse(this);
|
return options.inverse(this);
|
||||||
} else {
|
} else {
|
||||||
return options.fn(this);
|
return options.fn(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('unless', function(context, options) {
|
instance.registerHelper('unless', function(conditional, options) {
|
||||||
return Handlebars.helpers['if'].call(this, context, {fn: options.inverse, inverse: options.fn});
|
return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
|
||||||
});
|
});
|
||||||
|
|
||||||
Handlebars.registerHelper('with', function(context, options) {
|
instance.registerHelper('with', function(context, options) {
|
||||||
if (!Handlebars.Utils.isEmpty(context)) return options.fn(context);
|
if (isFunction(context)) { context = context.call(this); }
|
||||||
});
|
|
||||||
|
|
||||||
Handlebars.registerHelper('log', function(context, options) {
|
if (!Utils.isEmpty(context)) return options.fn(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
instance.registerHelper('log', function(context, options) {
|
||||||
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
|
||||||
Handlebars.log(level, context);
|
instance.log(level, context);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// END(BROWSER)
|
export var logger = {
|
||||||
|
methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
|
||||||
|
|
||||||
return Handlebars;
|
// State enum
|
||||||
|
DEBUG: 0,
|
||||||
|
INFO: 1,
|
||||||
|
WARN: 2,
|
||||||
|
ERROR: 3,
|
||||||
|
level: 3,
|
||||||
|
|
||||||
|
// can be overridden in the host environment
|
||||||
|
log: function(level, obj) {
|
||||||
|
if (logger.level <= level) {
|
||||||
|
var method = logger.methodMap[level];
|
||||||
|
if (typeof console !== 'undefined' && console[method]) {
|
||||||
|
console[method].call(console, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export function log(level, obj) { logger.log(level, obj); }
|
||||||
|
|
||||||
|
export var createFrame = function(object) {
|
||||||
|
var obj = {};
|
||||||
|
Utils.extend(obj, object);
|
||||||
|
return obj;
|
||||||
};
|
};
|
||||||
|
|||||||
3
node_modules/handlebars/lib/handlebars/browser-prefix.js
generated
vendored
3
node_modules/handlebars/lib/handlebars/browser-prefix.js
generated
vendored
@@ -1,3 +0,0 @@
|
|||||||
var Handlebars = {};
|
|
||||||
|
|
||||||
(function(Handlebars, undefined) {
|
|
||||||
1
node_modules/handlebars/lib/handlebars/browser-suffix.js
generated
vendored
1
node_modules/handlebars/lib/handlebars/browser-suffix.js
generated
vendored
@@ -1 +0,0 @@
|
|||||||
})(Handlebars);
|
|
||||||
195
node_modules/handlebars/lib/handlebars/compiler/ast.js
generated
vendored
195
node_modules/handlebars/lib/handlebars/compiler/ast.js
generated
vendored
@@ -1,17 +1,83 @@
|
|||||||
exports.attach = function(Handlebars) {
|
import Exception from "../exception";
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
function LocationInfo(locInfo){
|
||||||
Handlebars.AST = {};
|
locInfo = locInfo || {};
|
||||||
|
this.firstLine = locInfo.first_line;
|
||||||
|
this.firstColumn = locInfo.first_column;
|
||||||
|
this.lastColumn = locInfo.last_column;
|
||||||
|
this.lastLine = locInfo.last_line;
|
||||||
|
}
|
||||||
|
|
||||||
Handlebars.AST.ProgramNode = function(statements, inverse) {
|
var AST = {
|
||||||
|
ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
|
||||||
|
var inverseLocationInfo, firstInverseNode;
|
||||||
|
if (arguments.length === 3) {
|
||||||
|
locInfo = inverse;
|
||||||
|
inverse = null;
|
||||||
|
} else if (arguments.length === 2) {
|
||||||
|
locInfo = inverseStrip;
|
||||||
|
inverseStrip = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "program";
|
this.type = "program";
|
||||||
this.statements = statements;
|
this.statements = statements;
|
||||||
if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
|
this.strip = {};
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
|
if(inverse) {
|
||||||
|
firstInverseNode = inverse[0];
|
||||||
|
if (firstInverseNode) {
|
||||||
|
inverseLocationInfo = {
|
||||||
|
first_line: firstInverseNode.firstLine,
|
||||||
|
last_line: firstInverseNode.lastLine,
|
||||||
|
last_column: firstInverseNode.lastColumn,
|
||||||
|
first_column: firstInverseNode.firstColumn
|
||||||
|
};
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
|
||||||
|
} else {
|
||||||
|
this.inverse = new AST.ProgramNode(inverse, inverseStrip);
|
||||||
|
}
|
||||||
|
this.strip.right = inverseStrip.left;
|
||||||
|
} else if (inverseStrip) {
|
||||||
|
this.strip.left = inverseStrip.right;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
MustacheNode: function(rawParams, hash, open, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "mustache";
|
this.type = "mustache";
|
||||||
this.escaped = !unescaped;
|
this.strip = strip;
|
||||||
|
|
||||||
|
// Open may be a string parsed from the parser or a passed boolean flag
|
||||||
|
if (open != null && open.charAt) {
|
||||||
|
// Must use charAt to support IE pre-10
|
||||||
|
var escapeFlag = open.charAt(3) || open.charAt(2);
|
||||||
|
this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
|
||||||
|
} else {
|
||||||
|
this.escaped = !!open;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rawParams instanceof AST.SexprNode) {
|
||||||
|
this.sexpr = rawParams;
|
||||||
|
} else {
|
||||||
|
// Support old AST API
|
||||||
|
this.sexpr = new AST.SexprNode(rawParams, hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sexpr.isRoot = true;
|
||||||
|
|
||||||
|
// Support old AST API that stored this info in MustacheNode
|
||||||
|
this.id = this.sexpr.id;
|
||||||
|
this.params = this.sexpr.params;
|
||||||
|
this.hash = this.sexpr.hash;
|
||||||
|
this.eligibleHelper = this.sexpr.eligibleHelper;
|
||||||
|
this.isHelper = this.sexpr.isHelper;
|
||||||
|
},
|
||||||
|
|
||||||
|
SexprNode: function(rawParams, hash, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
|
|
||||||
|
this.type = "sexpr";
|
||||||
this.hash = hash;
|
this.hash = hash;
|
||||||
|
|
||||||
var id = this.id = rawParams[0];
|
var id = this.id = rawParams[0];
|
||||||
@@ -29,59 +95,79 @@ Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
|
|||||||
// if a mustache is an eligible helper but not a definite
|
// if a mustache is an eligible helper but not a definite
|
||||||
// helper, it is ambiguous, and will be resolved in a later
|
// helper, it is ambiguous, and will be resolved in a later
|
||||||
// pass or at runtime.
|
// pass or at runtime.
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.PartialNode = function(partialName, context) {
|
PartialNode: function(partialName, context, strip, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "partial";
|
this.type = "partial";
|
||||||
this.partialName = partialName;
|
this.partialName = partialName;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
};
|
this.strip = strip;
|
||||||
|
},
|
||||||
|
|
||||||
Handlebars.AST.BlockNode = function(mustache, program, inverse, close) {
|
BlockNode: function(mustache, program, inverse, close, locInfo) {
|
||||||
var verifyMatch = function(open, close) {
|
LocationInfo.call(this, locInfo);
|
||||||
if(open.original !== close.original) {
|
|
||||||
throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
|
if(mustache.sexpr.id.original !== close.path.original) {
|
||||||
|
throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
verifyMatch(mustache.id, close);
|
this.type = 'block';
|
||||||
this.type = "block";
|
|
||||||
this.mustache = mustache;
|
this.mustache = mustache;
|
||||||
this.program = program;
|
this.program = program;
|
||||||
this.inverse = inverse;
|
this.inverse = inverse;
|
||||||
|
|
||||||
if (this.inverse && !this.program) {
|
this.strip = {
|
||||||
|
left: mustache.strip.left,
|
||||||
|
right: close.strip.right
|
||||||
|
};
|
||||||
|
|
||||||
|
(program || inverse).strip.left = mustache.strip.right;
|
||||||
|
(inverse || program).strip.right = close.strip.left;
|
||||||
|
|
||||||
|
if (inverse && !program) {
|
||||||
this.isInverse = true;
|
this.isInverse = true;
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.ContentNode = function(string) {
|
ContentNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "content";
|
this.type = "content";
|
||||||
this.string = string;
|
this.string = string;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.HashNode = function(pairs) {
|
HashNode: function(pairs, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "hash";
|
this.type = "hash";
|
||||||
this.pairs = pairs;
|
this.pairs = pairs;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.IdNode = function(parts) {
|
IdNode: function(parts, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "ID";
|
this.type = "ID";
|
||||||
this.original = parts.join(".");
|
|
||||||
|
|
||||||
var dig = [], depth = 0;
|
var original = "",
|
||||||
|
dig = [],
|
||||||
|
depth = 0;
|
||||||
|
|
||||||
for(var i=0,l=parts.length; i<l; i++) {
|
for(var i=0,l=parts.length; i<l; i++) {
|
||||||
var part = parts[i];
|
var part = parts[i].part;
|
||||||
|
original += (parts[i].separator || '') + part;
|
||||||
|
|
||||||
if (part === ".." || part === "." || part === "this") {
|
if (part === ".." || part === "." || part === "this") {
|
||||||
if (dig.length > 0) { throw new Handlebars.Exception("Invalid path: " + this.original); }
|
if (dig.length > 0) {
|
||||||
else if (part === "..") { depth++; }
|
throw new Exception("Invalid path: " + original, this);
|
||||||
else { this.isScoped = true; }
|
} else if (part === "..") {
|
||||||
|
depth++;
|
||||||
|
} else {
|
||||||
|
this.isScoped = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dig.push(part);
|
||||||
}
|
}
|
||||||
else { dig.push(part); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.original = original;
|
||||||
this.parts = dig;
|
this.parts = dig;
|
||||||
this.string = dig.join('.');
|
this.string = dig.join('.');
|
||||||
this.depth = depth;
|
this.depth = depth;
|
||||||
@@ -91,43 +177,50 @@ Handlebars.AST.IdNode = function(parts) {
|
|||||||
this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
|
this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
|
||||||
|
|
||||||
this.stringModeValue = this.string;
|
this.stringModeValue = this.string;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.PartialNameNode = function(name) {
|
PartialNameNode: function(name, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "PARTIAL_NAME";
|
this.type = "PARTIAL_NAME";
|
||||||
this.name = name;
|
this.name = name.original;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.DataNode = function(id) {
|
DataNode: function(id, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "DATA";
|
this.type = "DATA";
|
||||||
this.id = id;
|
this.id = id;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.StringNode = function(string) {
|
StringNode: function(string, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "STRING";
|
this.type = "STRING";
|
||||||
this.string = string;
|
this.original =
|
||||||
|
this.string =
|
||||||
this.stringModeValue = string;
|
this.stringModeValue = string;
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.IntegerNode = function(integer) {
|
IntegerNode: function(integer, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "INTEGER";
|
this.type = "INTEGER";
|
||||||
|
this.original =
|
||||||
this.integer = integer;
|
this.integer = integer;
|
||||||
this.stringModeValue = Number(integer);
|
this.stringModeValue = Number(integer);
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.BooleanNode = function(bool) {
|
BooleanNode: function(bool, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "BOOLEAN";
|
this.type = "BOOLEAN";
|
||||||
this.bool = bool;
|
this.bool = bool;
|
||||||
this.stringModeValue = bool === "true";
|
this.stringModeValue = bool === "true";
|
||||||
};
|
},
|
||||||
|
|
||||||
Handlebars.AST.CommentNode = function(comment) {
|
CommentNode: function(comment, locInfo) {
|
||||||
|
LocationInfo.call(this, locInfo);
|
||||||
this.type = "comment";
|
this.type = "comment";
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// END(BROWSER)
|
// Must be exported as an object rather than the root of the module as the jison lexer
|
||||||
|
// most modify the object to operate properly.
|
||||||
return Handlebars;
|
export default AST;
|
||||||
};
|
|
||||||
|
|
||||||
|
|||||||
25
node_modules/handlebars/lib/handlebars/compiler/base.js
generated
vendored
25
node_modules/handlebars/lib/handlebars/compiler/base.js
generated
vendored
@@ -1,21 +1,12 @@
|
|||||||
var handlebars = require("./parser");
|
import parser from "./parser";
|
||||||
|
import AST from "./ast";
|
||||||
|
|
||||||
exports.attach = function(Handlebars) {
|
export { parser };
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
|
||||||
|
|
||||||
Handlebars.Parser = handlebars;
|
|
||||||
|
|
||||||
Handlebars.parse = function(input) {
|
|
||||||
|
|
||||||
|
export function parse(input) {
|
||||||
// Just return if an already-compile AST was passed in.
|
// Just return if an already-compile AST was passed in.
|
||||||
if(input.constructor === Handlebars.AST.ProgramNode) { return input; }
|
if(input.constructor === AST.ProgramNode) { return input; }
|
||||||
|
|
||||||
Handlebars.Parser.yy = Handlebars.AST;
|
parser.yy = AST;
|
||||||
return Handlebars.Parser.parse(input);
|
return parser.parse(input);
|
||||||
};
|
}
|
||||||
|
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
};
|
|
||||||
|
|||||||
1023
node_modules/handlebars/lib/handlebars/compiler/compiler.js
generated
vendored
1023
node_modules/handlebars/lib/handlebars/compiler/compiler.js
generated
vendored
File diff suppressed because it is too large
Load Diff
16
node_modules/handlebars/lib/handlebars/compiler/index.js
generated
vendored
16
node_modules/handlebars/lib/handlebars/compiler/index.js
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
// Each of these module will augment the Handlebars object as it loads. No need to perform addition operations
|
|
||||||
module.exports.attach = function(Handlebars) {
|
|
||||||
|
|
||||||
var visitor = require("./visitor"),
|
|
||||||
printer = require("./printer"),
|
|
||||||
ast = require("./ast"),
|
|
||||||
compiler = require("./compiler");
|
|
||||||
|
|
||||||
visitor.attach(Handlebars);
|
|
||||||
printer.attach(Handlebars);
|
|
||||||
ast.attach(Handlebars);
|
|
||||||
compiler.attach(Handlebars);
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
|
|
||||||
};
|
|
||||||
939
node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
939
node_modules/handlebars/lib/handlebars/compiler/javascript-compiler.js
generated
vendored
Normal file
@@ -0,0 +1,939 @@
|
|||||||
|
import { COMPILER_REVISION, REVISION_CHANGES, log } from "../base";
|
||||||
|
import Exception from "../exception";
|
||||||
|
|
||||||
|
function Literal(value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function JavaScriptCompiler() {}
|
||||||
|
|
||||||
|
JavaScriptCompiler.prototype = {
|
||||||
|
// PUBLIC API: You can override these methods in a subclass to provide
|
||||||
|
// alternative compiled forms for name lookup and buffering semantics
|
||||||
|
nameLookup: function(parent, name /* , type*/) {
|
||||||
|
var wrap,
|
||||||
|
ret;
|
||||||
|
if (parent.indexOf('depth') === 0) {
|
||||||
|
wrap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (/^[0-9]+$/.test(name)) {
|
||||||
|
ret = parent + "[" + name + "]";
|
||||||
|
} else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
|
||||||
|
ret = parent + "." + name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = parent + "['" + name + "']";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wrap) {
|
||||||
|
return '(' + parent + ' && ' + ret + ')';
|
||||||
|
} else {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
compilerInfo: function() {
|
||||||
|
var revision = COMPILER_REVISION,
|
||||||
|
versions = REVISION_CHANGES[revision];
|
||||||
|
return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
|
||||||
|
},
|
||||||
|
|
||||||
|
appendToBuffer: function(string) {
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
return "return " + string + ";";
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
appendToBuffer: true,
|
||||||
|
content: string,
|
||||||
|
toString: function() { return "buffer += " + string + ";"; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
initializeBuffer: function() {
|
||||||
|
return this.quotedString("");
|
||||||
|
},
|
||||||
|
|
||||||
|
namespace: "Handlebars",
|
||||||
|
// END PUBLIC API
|
||||||
|
|
||||||
|
compile: function(environment, options, context, asObject) {
|
||||||
|
this.environment = environment;
|
||||||
|
this.options = options || {};
|
||||||
|
|
||||||
|
log('debug', this.environment.disassemble() + "\n\n");
|
||||||
|
|
||||||
|
this.name = this.environment.name;
|
||||||
|
this.isChild = !!context;
|
||||||
|
this.context = context || {
|
||||||
|
programs: [],
|
||||||
|
environments: [],
|
||||||
|
aliases: { }
|
||||||
|
};
|
||||||
|
|
||||||
|
this.preamble();
|
||||||
|
|
||||||
|
this.stackSlot = 0;
|
||||||
|
this.stackVars = [];
|
||||||
|
this.registers = { list: [] };
|
||||||
|
this.hashes = [];
|
||||||
|
this.compileStack = [];
|
||||||
|
this.inlineStack = [];
|
||||||
|
|
||||||
|
this.compileChildren(environment, options);
|
||||||
|
|
||||||
|
var opcodes = environment.opcodes, opcode;
|
||||||
|
|
||||||
|
this.i = 0;
|
||||||
|
|
||||||
|
for(var l=opcodes.length; this.i<l; this.i++) {
|
||||||
|
opcode = opcodes[this.i];
|
||||||
|
|
||||||
|
if(opcode.opcode === 'DECLARE') {
|
||||||
|
this[opcode.name] = opcode.value;
|
||||||
|
} else {
|
||||||
|
this[opcode.opcode].apply(this, opcode.args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the stripNext flag if it was not set by this operation.
|
||||||
|
if (opcode.opcode !== this.stripNext) {
|
||||||
|
this.stripNext = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush any trailing content that might be pending.
|
||||||
|
this.pushSource('');
|
||||||
|
|
||||||
|
if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
|
||||||
|
throw new Exception('Compile completed with content left on stack');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.createFunctionContext(asObject);
|
||||||
|
},
|
||||||
|
|
||||||
|
preamble: function() {
|
||||||
|
var out = [];
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
var namespace = this.namespace;
|
||||||
|
|
||||||
|
var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
|
||||||
|
if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
|
||||||
|
if (this.options.data) { copies = copies + " data = data || {};"; }
|
||||||
|
out.push(copies);
|
||||||
|
} else {
|
||||||
|
out.push('');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
out.push(", buffer = " + this.initializeBuffer());
|
||||||
|
} else {
|
||||||
|
out.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// track the last context pushed into place to allow skipping the
|
||||||
|
// getContext opcode when it would be a noop
|
||||||
|
this.lastContext = 0;
|
||||||
|
this.source = out;
|
||||||
|
},
|
||||||
|
|
||||||
|
createFunctionContext: function(asObject) {
|
||||||
|
var locals = this.stackVars.concat(this.registers.list);
|
||||||
|
|
||||||
|
if(locals.length > 0) {
|
||||||
|
this.source[1] = this.source[1] + ", " + locals.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate minimizer alias mappings
|
||||||
|
if (!this.isChild) {
|
||||||
|
for (var alias in this.context.aliases) {
|
||||||
|
if (this.context.aliases.hasOwnProperty(alias)) {
|
||||||
|
this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.source[1]) {
|
||||||
|
this.source[1] = "var " + this.source[1].substring(2) + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge children
|
||||||
|
if (!this.isChild) {
|
||||||
|
this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.environment.isSimple) {
|
||||||
|
this.pushSource("return buffer;");
|
||||||
|
}
|
||||||
|
|
||||||
|
var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
|
||||||
|
|
||||||
|
for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
|
||||||
|
params.push("depth" + this.environment.depths.list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform a second pass over the output to merge content when possible
|
||||||
|
var source = this.mergeSource();
|
||||||
|
|
||||||
|
if (!this.isChild) {
|
||||||
|
source = this.compilerInfo()+source;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (asObject) {
|
||||||
|
params.push(source);
|
||||||
|
|
||||||
|
return Function.apply(this, params);
|
||||||
|
} else {
|
||||||
|
var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
|
||||||
|
log('debug', functionSource + "\n\n");
|
||||||
|
return functionSource;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mergeSource: function() {
|
||||||
|
// WARN: We are not handling the case where buffer is still populated as the source should
|
||||||
|
// not have buffer append operations as their final action.
|
||||||
|
var source = '',
|
||||||
|
buffer;
|
||||||
|
for (var i = 0, len = this.source.length; i < len; i++) {
|
||||||
|
var line = this.source[i];
|
||||||
|
if (line.appendToBuffer) {
|
||||||
|
if (buffer) {
|
||||||
|
buffer = buffer + '\n + ' + line.content;
|
||||||
|
} else {
|
||||||
|
buffer = line.content;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (buffer) {
|
||||||
|
source += 'buffer += ' + buffer + ';\n ';
|
||||||
|
buffer = undefined;
|
||||||
|
}
|
||||||
|
source += line + '\n ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return source;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [blockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// On stack, after: return value of blockHelperMissing
|
||||||
|
//
|
||||||
|
// The purpose of this opcode is to take a block of the form
|
||||||
|
// `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
|
||||||
|
// replace it on the stack with the result of properly
|
||||||
|
// invoking blockHelperMissing.
|
||||||
|
blockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
return "blockHelperMissing.call(" + params.join(", ") + ")";
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [ambiguousBlockValue]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, value
|
||||||
|
// Compiler value, before: lastHelper=value of last found helper, if any
|
||||||
|
// On stack, after, if no lastHelper: same as [blockValue]
|
||||||
|
// On stack, after, if lastHelper: value
|
||||||
|
ambiguousBlockValue: function() {
|
||||||
|
this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
|
||||||
|
|
||||||
|
var params = ["depth0"];
|
||||||
|
this.setupParams(0, params);
|
||||||
|
|
||||||
|
var current = this.topStack();
|
||||||
|
params.splice(1, 0, current);
|
||||||
|
|
||||||
|
this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendContent]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Appends the string value of `content` to the current buffer
|
||||||
|
appendContent: function(content) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
content = this.pendingContent + content;
|
||||||
|
}
|
||||||
|
if (this.stripNext) {
|
||||||
|
content = content.replace(/^\s+/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pendingContent = content;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [strip]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Removes any trailing whitespace from the prior content node and flags
|
||||||
|
// the next operation for stripping if it is a content node.
|
||||||
|
strip: function() {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.pendingContent = this.pendingContent.replace(/\s+$/, '');
|
||||||
|
}
|
||||||
|
this.stripNext = 'strip';
|
||||||
|
},
|
||||||
|
|
||||||
|
// [append]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Coerces `value` to a String and appends it to the current buffer.
|
||||||
|
//
|
||||||
|
// If `value` is truthy, or 0, it is coerced into a string and appended
|
||||||
|
// Otherwise, the empty string is appended
|
||||||
|
append: function() {
|
||||||
|
// Force anything that is inlined onto the stack so we don't have duplication
|
||||||
|
// when we examine local
|
||||||
|
this.flushInline();
|
||||||
|
var local = this.popStack();
|
||||||
|
this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
|
||||||
|
if (this.environment.isSimple) {
|
||||||
|
this.pushSource("else { " + this.appendToBuffer("''") + " }");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [appendEscaped]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: ...
|
||||||
|
//
|
||||||
|
// Escape `value` and append it to the buffer
|
||||||
|
appendEscaped: function() {
|
||||||
|
this.context.aliases.escapeExpression = 'this.escapeExpression';
|
||||||
|
|
||||||
|
this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [getContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: ...
|
||||||
|
// Compiler value, after: lastContext=depth
|
||||||
|
//
|
||||||
|
// Set the value of the `lastContext` compiler value to the depth
|
||||||
|
getContext: function(depth) {
|
||||||
|
if(this.lastContext !== depth) {
|
||||||
|
this.lastContext = depth;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupOnContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext[name], ...
|
||||||
|
//
|
||||||
|
// Looks up the value of `name` on the current context and pushes
|
||||||
|
// it onto the stack.
|
||||||
|
lookupOnContext: function(name) {
|
||||||
|
this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushContext]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: currentContext, ...
|
||||||
|
//
|
||||||
|
// Pushes the value of the current context onto the stack.
|
||||||
|
pushContext: function() {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [resolvePossibleLambda]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: resolved value, ...
|
||||||
|
//
|
||||||
|
// If the `value` is a lambda, replace it on the stack by
|
||||||
|
// the return value of the lambda
|
||||||
|
resolvePossibleLambda: function() {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookup]
|
||||||
|
//
|
||||||
|
// On stack, before: value, ...
|
||||||
|
// On stack, after: value[name], ...
|
||||||
|
//
|
||||||
|
// Replace the value on the stack with the result of looking
|
||||||
|
// up `name` on `value`
|
||||||
|
lookup: function(name) {
|
||||||
|
this.replaceStack(function(current) {
|
||||||
|
return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// [lookupData]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: data, ...
|
||||||
|
//
|
||||||
|
// Push the data lookup operator
|
||||||
|
lookupData: function() {
|
||||||
|
this.pushStackLiteral('data');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushStringParam]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: string, currentContext, ...
|
||||||
|
//
|
||||||
|
// This opcode is designed for use in string mode, which
|
||||||
|
// provides the string value of a parameter along with its
|
||||||
|
// depth rather than resolving it immediately.
|
||||||
|
pushStringParam: function(string, type) {
|
||||||
|
this.pushStackLiteral('depth' + this.lastContext);
|
||||||
|
|
||||||
|
this.pushString(type);
|
||||||
|
|
||||||
|
// If it's a subexpression, the string result
|
||||||
|
// will be pushed after this opcode.
|
||||||
|
if (type !== 'sexpr') {
|
||||||
|
if (typeof string === 'string') {
|
||||||
|
this.pushString(string);
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(string);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
emptyHash: function() {
|
||||||
|
this.pushStackLiteral('{}');
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{}'); // hashContexts
|
||||||
|
this.push('{}'); // hashTypes
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pushHash: function() {
|
||||||
|
if (this.hash) {
|
||||||
|
this.hashes.push(this.hash);
|
||||||
|
}
|
||||||
|
this.hash = {values: [], types: [], contexts: []};
|
||||||
|
},
|
||||||
|
popHash: function() {
|
||||||
|
var hash = this.hash;
|
||||||
|
this.hash = this.hashes.pop();
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
this.push('{' + hash.contexts.join(',') + '}');
|
||||||
|
this.push('{' + hash.types.join(',') + '}');
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push('{\n ' + hash.values.join(',\n ') + '\n }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushString]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: quotedString(string), ...
|
||||||
|
//
|
||||||
|
// Push a quoted version of `string` onto the stack
|
||||||
|
pushString: function(string) {
|
||||||
|
this.pushStackLiteral(this.quotedString(string));
|
||||||
|
},
|
||||||
|
|
||||||
|
// [push]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: expr, ...
|
||||||
|
//
|
||||||
|
// Push an expression onto the stack
|
||||||
|
push: function(expr) {
|
||||||
|
this.inlineStack.push(expr);
|
||||||
|
return expr;
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushLiteral]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: value, ...
|
||||||
|
//
|
||||||
|
// Pushes a value onto the stack. This operation prevents
|
||||||
|
// the compiler from creating a temporary variable to hold
|
||||||
|
// it.
|
||||||
|
pushLiteral: function(value) {
|
||||||
|
this.pushStackLiteral(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
// [pushProgram]
|
||||||
|
//
|
||||||
|
// On stack, before: ...
|
||||||
|
// On stack, after: program(guid), ...
|
||||||
|
//
|
||||||
|
// Push a program expression onto the stack. This takes
|
||||||
|
// a compile-time guid and converts it into a runtime-accessible
|
||||||
|
// expression.
|
||||||
|
pushProgram: function(guid) {
|
||||||
|
if (guid != null) {
|
||||||
|
this.pushStackLiteral(this.programExpression(guid));
|
||||||
|
} else {
|
||||||
|
this.pushStackLiteral(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// Pops off the helper's parameters, invokes the helper,
|
||||||
|
// and pushes the helper's return value onto the stack.
|
||||||
|
//
|
||||||
|
// If the helper is not found, `helperMissing` is called.
|
||||||
|
invokeHelper: function(paramSize, name, isRoot) {
|
||||||
|
this.context.aliases.helperMissing = 'helpers.helperMissing';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
|
||||||
|
var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
lookup += ',' + helper.paramsInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.push(
|
||||||
|
'('
|
||||||
|
+ lookup
|
||||||
|
+ ',helper '
|
||||||
|
+ '? helper.call(' + helper.callParams + ') '
|
||||||
|
+ ': helperMissing.call(' + helper.helperMissingParams + '))');
|
||||||
|
|
||||||
|
// Always flush subexpressions. This is both to prevent the compounding size issue that
|
||||||
|
// occurs when the code has to be duplicated for inlining and also to prevent errors
|
||||||
|
// due to the incorrect options object being passed due to the shared register.
|
||||||
|
if (!isRoot) {
|
||||||
|
this.flushInline();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeKnownHelper]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of helper invocation
|
||||||
|
//
|
||||||
|
// This operation is used when the helper is known to exist,
|
||||||
|
// so a `helperMissing` fallback is not required.
|
||||||
|
invokeKnownHelper: function(paramSize, name) {
|
||||||
|
var helper = this.setupHelper(paramSize, name);
|
||||||
|
this.push(helper.name + ".call(" + helper.callParams + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokeAmbiguous]
|
||||||
|
//
|
||||||
|
// On stack, before: hash, inverse, program, params..., ...
|
||||||
|
// On stack, after: result of disambiguation
|
||||||
|
//
|
||||||
|
// This operation is used when an expression like `{{foo}}`
|
||||||
|
// is provided, but we don't know at compile-time whether it
|
||||||
|
// is a helper or a path.
|
||||||
|
//
|
||||||
|
// This operation emits more code than the other options,
|
||||||
|
// and can be avoided by passing the `knownHelpers` and
|
||||||
|
// `knownHelpersOnly` flags at compile-time.
|
||||||
|
invokeAmbiguous: function(name, helperCall) {
|
||||||
|
this.context.aliases.functionType = '"function"';
|
||||||
|
this.useRegister('helper');
|
||||||
|
|
||||||
|
this.emptyHash();
|
||||||
|
var helper = this.setupHelper(0, name, helperCall);
|
||||||
|
|
||||||
|
var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
|
||||||
|
var nextStack = this.nextStack();
|
||||||
|
|
||||||
|
if (helper.paramsInit) {
|
||||||
|
this.pushSource(helper.paramsInit);
|
||||||
|
}
|
||||||
|
this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
|
||||||
|
this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
|
||||||
|
},
|
||||||
|
|
||||||
|
// [invokePartial]
|
||||||
|
//
|
||||||
|
// On stack, before: context, ...
|
||||||
|
// On stack after: result of partial invocation
|
||||||
|
//
|
||||||
|
// This operation pops off a context, invokes a partial with that context,
|
||||||
|
// and pushes the result of the invocation back.
|
||||||
|
invokePartial: function(name) {
|
||||||
|
var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
|
||||||
|
|
||||||
|
if (this.options.data) {
|
||||||
|
params.push("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
this.push("self.invokePartial(" + params.join(", ") + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// [assignToHash]
|
||||||
|
//
|
||||||
|
// On stack, before: value, hash, ...
|
||||||
|
// On stack, after: hash, ...
|
||||||
|
//
|
||||||
|
// Pops a value and hash off the stack, assigns `hash[key] = value`
|
||||||
|
// and pushes the hash back onto the stack.
|
||||||
|
assignToHash: function(key) {
|
||||||
|
var value = this.popStack(),
|
||||||
|
context,
|
||||||
|
type;
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
type = this.popStack();
|
||||||
|
context = this.popStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = this.hash;
|
||||||
|
if (context) {
|
||||||
|
hash.contexts.push("'" + key + "': " + context);
|
||||||
|
}
|
||||||
|
if (type) {
|
||||||
|
hash.types.push("'" + key + "': " + type);
|
||||||
|
}
|
||||||
|
hash.values.push("'" + key + "': (" + value + ")");
|
||||||
|
},
|
||||||
|
|
||||||
|
// HELPERS
|
||||||
|
|
||||||
|
compiler: JavaScriptCompiler,
|
||||||
|
|
||||||
|
compileChildren: function(environment, options) {
|
||||||
|
var children = environment.children, child, compiler;
|
||||||
|
|
||||||
|
for(var i=0, l=children.length; i<l; i++) {
|
||||||
|
child = children[i];
|
||||||
|
compiler = new this.compiler();
|
||||||
|
|
||||||
|
var index = this.matchExistingProgram(child);
|
||||||
|
|
||||||
|
if (index == null) {
|
||||||
|
this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
|
||||||
|
index = this.context.programs.length;
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
this.context.programs[index] = compiler.compile(child, options, this.context);
|
||||||
|
this.context.environments[index] = child;
|
||||||
|
} else {
|
||||||
|
child.index = index;
|
||||||
|
child.name = 'program' + index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matchExistingProgram: function(child) {
|
||||||
|
for (var i = 0, len = this.context.environments.length; i < len; i++) {
|
||||||
|
var environment = this.context.environments[i];
|
||||||
|
if (environment && environment.equals(child)) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
programExpression: function(guid) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
|
||||||
|
if(guid == null) {
|
||||||
|
return "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
var child = this.environment.children[guid],
|
||||||
|
depths = child.depths.list, depth;
|
||||||
|
|
||||||
|
var programParams = [child.index, child.name, "data"];
|
||||||
|
|
||||||
|
for(var i=0, l = depths.length; i<l; i++) {
|
||||||
|
depth = depths[i];
|
||||||
|
|
||||||
|
if(depth === 1) { programParams.push("depth0"); }
|
||||||
|
else { programParams.push("depth" + (depth - 1)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
|
||||||
|
},
|
||||||
|
|
||||||
|
register: function(name, val) {
|
||||||
|
this.useRegister(name);
|
||||||
|
this.pushSource(name + " = " + val + ";");
|
||||||
|
},
|
||||||
|
|
||||||
|
useRegister: function(name) {
|
||||||
|
if(!this.registers[name]) {
|
||||||
|
this.registers[name] = true;
|
||||||
|
this.registers.list.push(name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStackLiteral: function(item) {
|
||||||
|
return this.push(new Literal(item));
|
||||||
|
},
|
||||||
|
|
||||||
|
pushSource: function(source) {
|
||||||
|
if (this.pendingContent) {
|
||||||
|
this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
|
||||||
|
this.pendingContent = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source) {
|
||||||
|
this.source.push(source);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
pushStack: function(item) {
|
||||||
|
this.flushInline();
|
||||||
|
|
||||||
|
var stack = this.incrStack();
|
||||||
|
if (item) {
|
||||||
|
this.pushSource(stack + " = " + item + ";");
|
||||||
|
}
|
||||||
|
this.compileStack.push(stack);
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
replaceStack: function(callback) {
|
||||||
|
var prefix = '',
|
||||||
|
inline = this.isInline(),
|
||||||
|
stack,
|
||||||
|
createdStack,
|
||||||
|
usedLiteral;
|
||||||
|
|
||||||
|
// If we are currently inline then we want to merge the inline statement into the
|
||||||
|
// replacement statement via ','
|
||||||
|
if (inline) {
|
||||||
|
var top = this.popStack(true);
|
||||||
|
|
||||||
|
if (top instanceof Literal) {
|
||||||
|
// Literals do not need to be inlined
|
||||||
|
stack = top.value;
|
||||||
|
usedLiteral = true;
|
||||||
|
} else {
|
||||||
|
// Get or create the current stack name for use by the inline
|
||||||
|
createdStack = !this.stackSlot;
|
||||||
|
var name = !createdStack ? this.topStackName() : this.incrStack();
|
||||||
|
|
||||||
|
prefix = '(' + this.push(name) + ' = ' + top + '),';
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stack = this.topStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
var item = callback.call(this, stack);
|
||||||
|
|
||||||
|
if (inline) {
|
||||||
|
if (!usedLiteral) {
|
||||||
|
this.popStack();
|
||||||
|
}
|
||||||
|
if (createdStack) {
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
this.push('(' + prefix + item + ')');
|
||||||
|
} else {
|
||||||
|
// Prevent modification of the context depth variable. Through replaceStack
|
||||||
|
if (!/^stack/.test(stack)) {
|
||||||
|
stack = this.nextStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pushSource(stack + " = (" + prefix + item + ");");
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
},
|
||||||
|
|
||||||
|
nextStack: function() {
|
||||||
|
return this.pushStack();
|
||||||
|
},
|
||||||
|
|
||||||
|
incrStack: function() {
|
||||||
|
this.stackSlot++;
|
||||||
|
if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
|
||||||
|
return this.topStackName();
|
||||||
|
},
|
||||||
|
topStackName: function() {
|
||||||
|
return "stack" + this.stackSlot;
|
||||||
|
},
|
||||||
|
flushInline: function() {
|
||||||
|
var inlineStack = this.inlineStack;
|
||||||
|
if (inlineStack.length) {
|
||||||
|
this.inlineStack = [];
|
||||||
|
for (var i = 0, len = inlineStack.length; i < len; i++) {
|
||||||
|
var entry = inlineStack[i];
|
||||||
|
if (entry instanceof Literal) {
|
||||||
|
this.compileStack.push(entry);
|
||||||
|
} else {
|
||||||
|
this.pushStack(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isInline: function() {
|
||||||
|
return this.inlineStack.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
popStack: function(wrapped) {
|
||||||
|
var inline = this.isInline(),
|
||||||
|
item = (inline ? this.inlineStack : this.compileStack).pop();
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
if (!inline) {
|
||||||
|
if (!this.stackSlot) {
|
||||||
|
throw new Exception('Invalid stack pop');
|
||||||
|
}
|
||||||
|
this.stackSlot--;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
topStack: function(wrapped) {
|
||||||
|
var stack = (this.isInline() ? this.inlineStack : this.compileStack),
|
||||||
|
item = stack[stack.length - 1];
|
||||||
|
|
||||||
|
if (!wrapped && (item instanceof Literal)) {
|
||||||
|
return item.value;
|
||||||
|
} else {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
quotedString: function(str) {
|
||||||
|
return '"' + str
|
||||||
|
.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/"/g, '\\"')
|
||||||
|
.replace(/\n/g, '\\n')
|
||||||
|
.replace(/\r/g, '\\r')
|
||||||
|
.replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
|
||||||
|
.replace(/\u2029/g, '\\u2029') + '"';
|
||||||
|
},
|
||||||
|
|
||||||
|
setupHelper: function(paramSize, name, missingParams) {
|
||||||
|
var params = [],
|
||||||
|
paramsInit = this.setupParams(paramSize, params, missingParams);
|
||||||
|
var foundHelper = this.nameLookup('helpers', name, 'helper');
|
||||||
|
|
||||||
|
return {
|
||||||
|
params: params,
|
||||||
|
paramsInit: paramsInit,
|
||||||
|
name: foundHelper,
|
||||||
|
callParams: ["depth0"].concat(params).join(", "),
|
||||||
|
helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
setupOptions: function(paramSize, params) {
|
||||||
|
var options = [], contexts = [], types = [], param, inverse, program;
|
||||||
|
|
||||||
|
options.push("hash:" + this.popStack());
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("hashTypes:" + this.popStack());
|
||||||
|
options.push("hashContexts:" + this.popStack());
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse = this.popStack();
|
||||||
|
program = this.popStack();
|
||||||
|
|
||||||
|
// Avoid setting fn and inverse if neither are set. This allows
|
||||||
|
// helpers to do a check for `if (options.fn)`
|
||||||
|
if (program || inverse) {
|
||||||
|
if (!program) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
program = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inverse) {
|
||||||
|
this.context.aliases.self = "this";
|
||||||
|
inverse = "self.noop";
|
||||||
|
}
|
||||||
|
|
||||||
|
options.push("inverse:" + inverse);
|
||||||
|
options.push("fn:" + program);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var i=0; i<paramSize; i++) {
|
||||||
|
param = this.popStack();
|
||||||
|
params.push(param);
|
||||||
|
|
||||||
|
if(this.options.stringParams) {
|
||||||
|
types.push(this.popStack());
|
||||||
|
contexts.push(this.popStack());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.stringParams) {
|
||||||
|
options.push("contexts:[" + contexts.join(",") + "]");
|
||||||
|
options.push("types:[" + types.join(",") + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.data) {
|
||||||
|
options.push("data:data");
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
|
},
|
||||||
|
|
||||||
|
// the params and contexts arguments are passed in arrays
|
||||||
|
// to fill in
|
||||||
|
setupParams: function(paramSize, params, useRegister) {
|
||||||
|
var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
|
||||||
|
|
||||||
|
if (useRegister) {
|
||||||
|
this.useRegister('options');
|
||||||
|
params.push('options');
|
||||||
|
return 'options=' + options;
|
||||||
|
} else {
|
||||||
|
params.push(options);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var reservedWords = (
|
||||||
|
"break else new var" +
|
||||||
|
" case finally return void" +
|
||||||
|
" catch for switch while" +
|
||||||
|
" continue function this with" +
|
||||||
|
" default if throw" +
|
||||||
|
" delete in try" +
|
||||||
|
" do instanceof typeof" +
|
||||||
|
" abstract enum int short" +
|
||||||
|
" boolean export interface static" +
|
||||||
|
" byte extends long super" +
|
||||||
|
" char final native synchronized" +
|
||||||
|
" class float package throws" +
|
||||||
|
" const goto private transient" +
|
||||||
|
" debugger implements protected volatile" +
|
||||||
|
" double import public let yield"
|
||||||
|
).split(" ");
|
||||||
|
|
||||||
|
var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
|
||||||
|
|
||||||
|
for(var i=0, l=reservedWords.length; i<l; i++) {
|
||||||
|
compilerWords[reservedWords[i]] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
|
||||||
|
if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default JavaScriptCompiler;
|
||||||
213
node_modules/handlebars/lib/handlebars/compiler/parser.js
generated
vendored
213
node_modules/handlebars/lib/handlebars/compiler/parser.js
generated
vendored
@@ -1,113 +1,107 @@
|
|||||||
// BEGIN(BROWSER)
|
/* jshint ignore:start */
|
||||||
/* Jison generated parser */
|
/* Jison generated parser */
|
||||||
var handlebars = (function(){
|
var handlebars = (function(){
|
||||||
var parser = {trace: function trace() { },
|
var parser = {trace: function trace() { },
|
||||||
yy: {},
|
yy: {},
|
||||||
symbols_: {"error":2,"root":3,"program":4,"EOF":5,"simpleInverse":6,"statements":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"partialName":25,"params":26,"hash":27,"DATA":28,"param":29,"STRING":30,"INTEGER":31,"BOOLEAN":32,"hashSegments":33,"hashSegment":34,"ID":35,"EQUALS":36,"PARTIAL_NAME":37,"pathSegments":38,"SEP":39,"$accept":0,"$end":1},
|
symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
|
||||||
terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"DATA",30:"STRING",31:"INTEGER",32:"BOOLEAN",35:"ID",36:"EQUALS",37:"PARTIAL_NAME",39:"SEP"},
|
terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
|
||||||
productions_: [0,[3,2],[4,2],[4,3],[4,2],[4,1],[4,1],[4,0],[7,1],[7,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[6,2],[17,3],[17,2],[17,2],[17,1],[17,1],[26,2],[26,1],[29,1],[29,1],[29,1],[29,1],[29,1],[27,1],[33,2],[33,1],[34,3],[34,3],[34,3],[34,3],[34,3],[25,1],[21,1],[38,3],[38,1]],
|
productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
|
||||||
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
|
||||||
|
|
||||||
var $0 = $$.length - 1;
|
var $0 = $$.length - 1;
|
||||||
switch (yystate) {
|
switch (yystate) {
|
||||||
case 1: return $$[$0-1];
|
case 1: return new yy.ProgramNode($$[$0-1], this._$);
|
||||||
break;
|
break;
|
||||||
case 2: this.$ = new yy.ProgramNode([], $$[$0]);
|
case 2: return new yy.ProgramNode([], this._$);
|
||||||
break;
|
break;
|
||||||
case 3: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]);
|
case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 4: this.$ = new yy.ProgramNode($$[$0-1], []);
|
case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 5: this.$ = new yy.ProgramNode($$[$0]);
|
case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
|
||||||
break;
|
break;
|
||||||
case 6: this.$ = new yy.ProgramNode([], []);
|
case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 7: this.$ = new yy.ProgramNode([]);
|
case 7:this.$ = new yy.ProgramNode([], this._$);
|
||||||
break;
|
break;
|
||||||
case 8: this.$ = [$$[$0]];
|
case 8:this.$ = new yy.ProgramNode([], this._$);
|
||||||
break;
|
break;
|
||||||
case 9: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
case 9:this.$ = [$$[$0]];
|
||||||
break;
|
break;
|
||||||
case 10: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
|
case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
||||||
break;
|
break;
|
||||||
case 11: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
|
case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 12: this.$ = $$[$0];
|
case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 13: this.$ = $$[$0];
|
case 13:this.$ = $$[$0];
|
||||||
break;
|
break;
|
||||||
case 14: this.$ = new yy.ContentNode($$[$0]);
|
case 14:this.$ = $$[$0];
|
||||||
break;
|
break;
|
||||||
case 15: this.$ = new yy.CommentNode($$[$0]);
|
case 15:this.$ = new yy.ContentNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
|
case 16:this.$ = new yy.CommentNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
|
case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 18: this.$ = $$[$0-1];
|
case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 19: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
|
case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
|
||||||
break;
|
break;
|
||||||
case 20: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true);
|
case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 21: this.$ = new yy.PartialNode($$[$0-1]);
|
case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 22: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]);
|
case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
|
||||||
break;
|
break;
|
||||||
case 23:
|
case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
|
||||||
break;
|
break;
|
||||||
case 24: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]];
|
case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 25: this.$ = [[$$[$0-1]].concat($$[$0]), null];
|
case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
|
||||||
break;
|
break;
|
||||||
case 26: this.$ = [[$$[$0-1]], $$[$0]];
|
case 26:this.$ = $$[$0];
|
||||||
break;
|
break;
|
||||||
case 27: this.$ = [[$$[$0]], null];
|
case 27:this.$ = new yy.StringNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 28: this.$ = [[new yy.DataNode($$[$0])], null];
|
case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 29: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 30: this.$ = [$$[$0]];
|
case 30:this.$ = $$[$0];
|
||||||
break;
|
break;
|
||||||
case 31: this.$ = $$[$0];
|
case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
|
||||||
break;
|
break;
|
||||||
case 32: this.$ = new yy.StringNode($$[$0]);
|
case 32:this.$ = new yy.HashNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 33: this.$ = new yy.IntegerNode($$[$0]);
|
case 33:this.$ = [$$[$0-2], $$[$0]];
|
||||||
break;
|
break;
|
||||||
case 34: this.$ = new yy.BooleanNode($$[$0]);
|
case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 35: this.$ = new yy.DataNode($$[$0]);
|
case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
|
||||||
break;
|
break;
|
||||||
case 36: this.$ = new yy.HashNode($$[$0]);
|
case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
|
||||||
break;
|
break;
|
||||||
case 37: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
|
case 37:this.$ = new yy.DataNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 38: this.$ = [$$[$0]];
|
case 38:this.$ = new yy.IdNode($$[$0], this._$);
|
||||||
break;
|
break;
|
||||||
case 39: this.$ = [$$[$0-2], $$[$0]];
|
case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
|
||||||
break;
|
break;
|
||||||
case 40: this.$ = [$$[$0-2], new yy.StringNode($$[$0])];
|
case 40:this.$ = [{part: $$[$0]}];
|
||||||
break;
|
break;
|
||||||
case 41: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])];
|
case 43:this.$ = [];
|
||||||
break;
|
break;
|
||||||
case 42: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])];
|
case 44:$$[$0-1].push($$[$0]);
|
||||||
break;
|
break;
|
||||||
case 43: this.$ = [$$[$0-2], new yy.DataNode($$[$0])];
|
case 47:this.$ = [$$[$0]];
|
||||||
break;
|
break;
|
||||||
case 44: this.$ = new yy.PartialNameNode($$[$0]);
|
case 48:$$[$0-1].push($$[$0]);
|
||||||
break;
|
|
||||||
case 45: this.$ = new yy.IdNode($$[$0]);
|
|
||||||
break;
|
|
||||||
case 46: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
|
|
||||||
break;
|
|
||||||
case 47: this.$ = [$$[$0]];
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
table: [{3:1,4:2,5:[2,7],6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],22:[1,14],23:[1,15],24:[1,16]},{1:[3]},{5:[1,17]},{5:[2,6],7:18,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,6],22:[1,14],23:[1,15],24:[1,16]},{5:[2,5],6:20,8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,5],22:[1,14],23:[1,15],24:[1,16]},{17:23,18:[1,22],21:24,28:[1,25],35:[1,27],38:26},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{4:28,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],24:[1,16]},{4:29,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],24:[1,16]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{17:30,21:24,28:[1,25],35:[1,27],38:26},{17:31,21:24,28:[1,25],35:[1,27],38:26},{17:32,21:24,28:[1,25],35:[1,27],38:26},{25:33,37:[1,34]},{1:[2,1]},{5:[2,2],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,2],22:[1,14],23:[1,15],24:[1,16]},{17:23,21:24,28:[1,25],35:[1,27],38:26},{5:[2,4],7:35,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,4],22:[1,14],23:[1,15],24:[1,16]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,23],14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],24:[2,23]},{18:[1,36]},{18:[2,27],21:41,26:37,27:38,28:[1,45],29:39,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,28]},{18:[2,45],28:[2,45],30:[2,45],31:[2,45],32:[2,45],35:[2,45],39:[1,48]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],39:[2,47]},{10:49,20:[1,50]},{10:51,20:[1,50]},{18:[1,52]},{18:[1,53]},{18:[1,54]},{18:[1,55],21:56,35:[1,27],38:26},{18:[2,44],35:[2,44]},{5:[2,3],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,3],22:[1,14],23:[1,15],24:[1,16]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{18:[2,25],21:41,27:57,28:[1,45],29:58,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,26]},{18:[2,30],28:[2,30],30:[2,30],31:[2,30],32:[2,30],35:[2,30]},{18:[2,36],34:59,35:[1,60]},{18:[2,31],28:[2,31],30:[2,31],31:[2,31],32:[2,31],35:[2,31]},{18:[2,32],28:[2,32],30:[2,32],31:[2,32],32:[2,32],35:[2,32]},{18:[2,33],28:[2,33],30:[2,33],31:[2,33],32:[2,33],35:[2,33]},{18:[2,34],28:[2,34],30:[2,34],31:[2,34],32:[2,34],35:[2,34]},{18:[2,35],28:[2,35],30:[2,35],31:[2,35],32:[2,35],35:[2,35]},{18:[2,38],35:[2,38]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],36:[1,61],39:[2,47]},{35:[1,62]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{21:63,35:[1,27],38:26},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],24:[2,21]},{18:[1,64]},{18:[2,24]},{18:[2,29],28:[2,29],30:[2,29],31:[2,29],32:[2,29],35:[2,29]},{18:[2,37],35:[2,37]},{36:[1,61]},{21:65,28:[1,69],30:[1,66],31:[1,67],32:[1,68],35:[1,27],38:26},{18:[2,46],28:[2,46],30:[2,46],31:[2,46],32:[2,46],35:[2,46],39:[2,46]},{18:[1,70]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],24:[2,22]},{18:[2,39],35:[2,39]},{18:[2,40],35:[2,40]},{18:[2,41],35:[2,41]},{18:[2,42],35:[2,42]},{18:[2,43],35:[2,43]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]}],
|
table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
|
||||||
defaultActions: {17:[2,1],25:[2,28],38:[2,26],57:[2,24]},
|
defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
|
||||||
parseError: function parseError(str, hash) {
|
parseError: function parseError(str, hash) {
|
||||||
throw new Error(str);
|
throw new Error(str);
|
||||||
},
|
},
|
||||||
@@ -215,6 +209,15 @@ parse: function parse(input) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function stripFlags(open, close) {
|
||||||
|
return {
|
||||||
|
left: open.charAt(2) === '~',
|
||||||
|
right: close.charAt(0) === '~' || close.charAt(1) === '~'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/* Jison generated lexer */
|
/* Jison generated lexer */
|
||||||
var lexer = (function(){
|
var lexer = (function(){
|
||||||
var lexer = ({EOF:1,
|
var lexer = ({EOF:1,
|
||||||
@@ -386,93 +389,101 @@ pushState:function begin(condition) {
|
|||||||
lexer.options = {};
|
lexer.options = {};
|
||||||
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
|
||||||
|
|
||||||
|
|
||||||
|
function strip(start, end) {
|
||||||
|
return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var YYSTATE=YY_START
|
var YYSTATE=YY_START
|
||||||
switch($avoiding_name_collisions) {
|
switch($avoiding_name_collisions) {
|
||||||
case 0: yy_.yytext = "\\"; return 14;
|
case 0:
|
||||||
break;
|
if(yy_.yytext.slice(-2) === "\\\\") {
|
||||||
case 1:
|
strip(0,1);
|
||||||
if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
|
this.begin("mu");
|
||||||
if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
|
} else if(yy_.yytext.slice(-1) === "\\") {
|
||||||
|
strip(0,1);
|
||||||
|
this.begin("emu");
|
||||||
|
} else {
|
||||||
|
this.begin("mu");
|
||||||
|
}
|
||||||
if(yy_.yytext) return 14;
|
if(yy_.yytext) return 14;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 2: return 14;
|
case 1:return 14;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 2:
|
||||||
if(yy_.yytext.slice(-1) !== "\\") this.popState();
|
this.popState();
|
||||||
if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1);
|
|
||||||
return 14;
|
return 14;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 4: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15;
|
case 3:strip(0,4); this.popState(); return 15;
|
||||||
break;
|
break;
|
||||||
case 5: this.begin("par"); return 24;
|
case 4:return 35;
|
||||||
break;
|
break;
|
||||||
case 6: return 16;
|
case 5:return 36;
|
||||||
break;
|
break;
|
||||||
case 7: return 20;
|
case 6:return 25;
|
||||||
break;
|
break;
|
||||||
case 8: return 19;
|
case 7:return 16;
|
||||||
break;
|
break;
|
||||||
case 9: return 19;
|
case 8:return 20;
|
||||||
break;
|
break;
|
||||||
case 10: return 23;
|
case 9:return 19;
|
||||||
break;
|
break;
|
||||||
case 11: return 23;
|
case 10:return 19;
|
||||||
break;
|
break;
|
||||||
case 12: this.popState(); this.begin('com');
|
case 11:return 23;
|
||||||
break;
|
break;
|
||||||
case 13: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
|
case 12:return 22;
|
||||||
break;
|
break;
|
||||||
case 14: return 22;
|
case 13:this.popState(); this.begin('com');
|
||||||
break;
|
break;
|
||||||
case 15: return 36;
|
case 14:strip(3,5); this.popState(); return 15;
|
||||||
break;
|
break;
|
||||||
case 16: return 35;
|
case 15:return 22;
|
||||||
break;
|
break;
|
||||||
case 17: return 35;
|
case 16:return 41;
|
||||||
break;
|
break;
|
||||||
case 18: return 39;
|
case 17:return 40;
|
||||||
break;
|
break;
|
||||||
case 19: /*ignore whitespace*/
|
case 18:return 40;
|
||||||
break;
|
break;
|
||||||
case 20: this.popState(); return 18;
|
case 19:return 44;
|
||||||
break;
|
break;
|
||||||
case 21: this.popState(); return 18;
|
case 20:// ignore whitespace
|
||||||
break;
|
break;
|
||||||
case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 30;
|
case 21:this.popState(); return 24;
|
||||||
break;
|
break;
|
||||||
case 23: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'"); return 30;
|
case 22:this.popState(); return 18;
|
||||||
break;
|
break;
|
||||||
case 24: yy_.yytext = yy_.yytext.substr(1); return 28;
|
case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
|
||||||
break;
|
break;
|
||||||
case 25: return 32;
|
case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
|
||||||
break;
|
break;
|
||||||
case 26: return 32;
|
case 25:return 42;
|
||||||
break;
|
break;
|
||||||
case 27: return 31;
|
case 26:return 34;
|
||||||
break;
|
break;
|
||||||
case 28: return 35;
|
case 27:return 34;
|
||||||
break;
|
break;
|
||||||
case 29: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 35;
|
case 28:return 33;
|
||||||
break;
|
break;
|
||||||
case 30: return 'INVALID';
|
case 29:return 40;
|
||||||
break;
|
break;
|
||||||
case 31: /*ignore whitespace*/
|
case 30:yy_.yytext = strip(1,2); return 40;
|
||||||
break;
|
break;
|
||||||
case 32: this.popState(); return 37;
|
case 31:return 'INVALID';
|
||||||
break;
|
break;
|
||||||
case 33: return 5;
|
case 32:return 5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
lexer.rules = [/^(?:\\\\(?=(\{\{)))/,/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[}/ ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:-?[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$:\-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$\-\/]+)/,/^(?:$)/];
|
lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
|
||||||
lexer.conditions = {"mu":{"rules":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,33],"inclusive":false},"emu":{"rules":[3],"inclusive":false},"com":{"rules":[4],"inclusive":false},"par":{"rules":[31,32],"inclusive":false},"INITIAL":{"rules":[0,1,2,33],"inclusive":true}};
|
lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
|
||||||
return lexer;})()
|
return lexer;})()
|
||||||
parser.lexer = lexer;
|
parser.lexer = lexer;
|
||||||
function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
|
function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
|
||||||
return new Parser;
|
return new Parser;
|
||||||
})();
|
})();export default handlebars;
|
||||||
// END(BROWSER)
|
/* jshint ignore:end */
|
||||||
|
|
||||||
module.exports = handlebars;
|
|
||||||
|
|||||||
60
node_modules/handlebars/lib/handlebars/compiler/printer.js
generated
vendored
60
node_modules/handlebars/lib/handlebars/compiler/printer.js
generated
vendored
@@ -1,15 +1,16 @@
|
|||||||
exports.attach = function(Handlebars) {
|
import Visitor from "./visitor";
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
export function print(ast) {
|
||||||
|
return new PrintVisitor().accept(ast);
|
||||||
|
}
|
||||||
|
|
||||||
Handlebars.print = function(ast) {
|
export function PrintVisitor() {
|
||||||
return new Handlebars.PrintVisitor().accept(ast);
|
this.padding = 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
Handlebars.PrintVisitor = function() { this.padding = 0; };
|
PrintVisitor.prototype = new Visitor();
|
||||||
Handlebars.PrintVisitor.prototype = new Handlebars.Visitor();
|
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.pad = function(string, newline) {
|
PrintVisitor.prototype.pad = function(string, newline) {
|
||||||
var out = "";
|
var out = "";
|
||||||
|
|
||||||
for(var i=0,l=this.padding; i<l; i++) {
|
for(var i=0,l=this.padding; i<l; i++) {
|
||||||
@@ -22,10 +23,9 @@ Handlebars.PrintVisitor.prototype.pad = function(string, newline) {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.program = function(program) {
|
PrintVisitor.prototype.program = function(program) {
|
||||||
var out = "",
|
var out = "",
|
||||||
statements = program.statements,
|
statements = program.statements,
|
||||||
inverse = program.inverse,
|
|
||||||
i, l;
|
i, l;
|
||||||
|
|
||||||
for(i=0, l=statements.length; i<l; i++) {
|
for(i=0, l=statements.length; i<l; i++) {
|
||||||
@@ -37,7 +37,7 @@ Handlebars.PrintVisitor.prototype.program = function(program) {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.block = function(block) {
|
PrintVisitor.prototype.block = function(block) {
|
||||||
var out = "";
|
var out = "";
|
||||||
|
|
||||||
out = out + this.pad("BLOCK:");
|
out = out + this.pad("BLOCK:");
|
||||||
@@ -62,8 +62,8 @@ Handlebars.PrintVisitor.prototype.block = function(block) {
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.mustache = function(mustache) {
|
PrintVisitor.prototype.sexpr = function(sexpr) {
|
||||||
var params = mustache.params, paramStrings = [], hash;
|
var params = sexpr.params, paramStrings = [], hash;
|
||||||
|
|
||||||
for(var i=0, l=params.length; i<l; i++) {
|
for(var i=0, l=params.length; i<l; i++) {
|
||||||
paramStrings.push(this.accept(params[i]));
|
paramStrings.push(this.accept(params[i]));
|
||||||
@@ -71,18 +71,22 @@ Handlebars.PrintVisitor.prototype.mustache = function(mustache) {
|
|||||||
|
|
||||||
params = "[" + paramStrings.join(", ") + "]";
|
params = "[" + paramStrings.join(", ") + "]";
|
||||||
|
|
||||||
hash = mustache.hash ? " " + this.accept(mustache.hash) : "";
|
hash = sexpr.hash ? " " + this.accept(sexpr.hash) : "";
|
||||||
|
|
||||||
return this.pad("{{ " + this.accept(mustache.id) + " " + params + hash + " }}");
|
return this.accept(sexpr.id) + " " + params + hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.partial = function(partial) {
|
PrintVisitor.prototype.mustache = function(mustache) {
|
||||||
|
return this.pad("{{ " + this.accept(mustache.sexpr) + " }}");
|
||||||
|
};
|
||||||
|
|
||||||
|
PrintVisitor.prototype.partial = function(partial) {
|
||||||
var content = this.accept(partial.partialName);
|
var content = this.accept(partial.partialName);
|
||||||
if(partial.context) { content = content + " " + this.accept(partial.context); }
|
if(partial.context) { content = content + " " + this.accept(partial.context); }
|
||||||
return this.pad("{{> " + content + " }}");
|
return this.pad("{{> " + content + " }}");
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.hash = function(hash) {
|
PrintVisitor.prototype.hash = function(hash) {
|
||||||
var pairs = hash.pairs;
|
var pairs = hash.pairs;
|
||||||
var joinedPairs = [], left, right;
|
var joinedPairs = [], left, right;
|
||||||
|
|
||||||
@@ -95,19 +99,19 @@ Handlebars.PrintVisitor.prototype.hash = function(hash) {
|
|||||||
return "HASH{" + joinedPairs.join(", ") + "}";
|
return "HASH{" + joinedPairs.join(", ") + "}";
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.STRING = function(string) {
|
PrintVisitor.prototype.STRING = function(string) {
|
||||||
return '"' + string.string + '"';
|
return '"' + string.string + '"';
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.INTEGER = function(integer) {
|
PrintVisitor.prototype.INTEGER = function(integer) {
|
||||||
return "INTEGER{" + integer.integer + "}";
|
return "INTEGER{" + integer.integer + "}";
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.BOOLEAN = function(bool) {
|
PrintVisitor.prototype.BOOLEAN = function(bool) {
|
||||||
return "BOOLEAN{" + bool.bool + "}";
|
return "BOOLEAN{" + bool.bool + "}";
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.ID = function(id) {
|
PrintVisitor.prototype.ID = function(id) {
|
||||||
var path = id.parts.join("/");
|
var path = id.parts.join("/");
|
||||||
if(id.parts.length > 1) {
|
if(id.parts.length > 1) {
|
||||||
return "PATH:" + path;
|
return "PATH:" + path;
|
||||||
@@ -116,23 +120,19 @@ Handlebars.PrintVisitor.prototype.ID = function(id) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.PARTIAL_NAME = function(partialName) {
|
PrintVisitor.prototype.PARTIAL_NAME = function(partialName) {
|
||||||
return "PARTIAL:" + partialName.name;
|
return "PARTIAL:" + partialName.name;
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.DATA = function(data) {
|
PrintVisitor.prototype.DATA = function(data) {
|
||||||
return "@" + data.id;
|
return "@" + this.accept(data.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.content = function(content) {
|
PrintVisitor.prototype.content = function(content) {
|
||||||
return this.pad("CONTENT[ '" + content.string + "' ]");
|
return this.pad("CONTENT[ '" + content.string + "' ]");
|
||||||
};
|
};
|
||||||
|
|
||||||
Handlebars.PrintVisitor.prototype.comment = function(comment) {
|
PrintVisitor.prototype.comment = function(comment) {
|
||||||
return this.pad("{{! '" + comment.comment + "' }}");
|
return this.pad("{{! '" + comment.comment + "' }}");
|
||||||
};
|
};
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|||||||
15
node_modules/handlebars/lib/handlebars/compiler/visitor.js
generated
vendored
15
node_modules/handlebars/lib/handlebars/compiler/visitor.js
generated
vendored
@@ -1,18 +1,11 @@
|
|||||||
exports.attach = function(Handlebars) {
|
function Visitor() {}
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
Visitor.prototype = {
|
||||||
|
constructor: Visitor,
|
||||||
|
|
||||||
Handlebars.Visitor = function() {};
|
|
||||||
|
|
||||||
Handlebars.Visitor.prototype = {
|
|
||||||
accept: function(object) {
|
accept: function(object) {
|
||||||
return this[object.type](object);
|
return this[object.type](object);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// END(BROWSER)
|
export default Visitor;
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
27
node_modules/handlebars/lib/handlebars/exception.js
generated
vendored
Normal file
27
node_modules/handlebars/lib/handlebars/exception.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
||||||
|
|
||||||
|
function Exception(message, node) {
|
||||||
|
var line;
|
||||||
|
if (node && node.firstLine) {
|
||||||
|
line = node.firstLine;
|
||||||
|
|
||||||
|
message += ' - ' + line + ':' + node.firstColumn;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tmp = Error.prototype.constructor.call(this, message);
|
||||||
|
|
||||||
|
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
||||||
|
for (var idx = 0; idx < errorProps.length; idx++) {
|
||||||
|
this[errorProps[idx]] = tmp[errorProps[idx]];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line) {
|
||||||
|
this.lineNumber = line;
|
||||||
|
this.column = node.firstColumn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Exception.prototype = new Error();
|
||||||
|
|
||||||
|
export default Exception;
|
||||||
149
node_modules/handlebars/lib/handlebars/runtime.js
generated
vendored
149
node_modules/handlebars/lib/handlebars/runtime.js
generated
vendored
@@ -1,96 +1,133 @@
|
|||||||
exports.attach = function(Handlebars) {
|
module Utils from "./utils";
|
||||||
|
import Exception from "./exception";
|
||||||
|
import { COMPILER_REVISION, REVISION_CHANGES } from "./base";
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
export function checkRevision(compilerInfo) {
|
||||||
|
var compilerRevision = compilerInfo && compilerInfo[0] || 1,
|
||||||
|
currentRevision = COMPILER_REVISION;
|
||||||
|
|
||||||
|
if (compilerRevision !== currentRevision) {
|
||||||
|
if (compilerRevision < currentRevision) {
|
||||||
|
var runtimeVersions = REVISION_CHANGES[currentRevision],
|
||||||
|
compilerVersions = REVISION_CHANGES[compilerRevision];
|
||||||
|
throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
|
||||||
|
} else {
|
||||||
|
// Use the embedded version info since the runtime doesn't know about this revision yet
|
||||||
|
throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
||||||
|
"Please update your runtime to a newer version ("+compilerInfo[1]+").");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Remove this line and break up compilePartial
|
||||||
|
|
||||||
|
export function template(templateSpec, env) {
|
||||||
|
if (!env) {
|
||||||
|
throw new Exception("No environment passed to template");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Using env.VM references rather than local var references throughout this section to allow
|
||||||
|
// for external users to override these as psuedo-supported APIs.
|
||||||
|
var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
|
||||||
|
var result = env.VM.invokePartial.apply(this, arguments);
|
||||||
|
if (result != null) { return result; }
|
||||||
|
|
||||||
|
if (env.compile) {
|
||||||
|
var options = { helpers: helpers, partials: partials, data: data };
|
||||||
|
partials[name] = env.compile(partial, { data: data !== undefined }, env);
|
||||||
|
return partials[name](context, options);
|
||||||
|
} else {
|
||||||
|
throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Handlebars.VM = {
|
|
||||||
template: function(templateSpec) {
|
|
||||||
// Just add water
|
// Just add water
|
||||||
var container = {
|
var container = {
|
||||||
escapeExpression: Handlebars.Utils.escapeExpression,
|
escapeExpression: Utils.escapeExpression,
|
||||||
invokePartial: Handlebars.VM.invokePartial,
|
invokePartial: invokePartialWrapper,
|
||||||
programs: [],
|
programs: [],
|
||||||
program: function(i, fn, data) {
|
program: function(i, fn, data) {
|
||||||
var programWrapper = this.programs[i];
|
var programWrapper = this.programs[i];
|
||||||
if(data) {
|
if(data) {
|
||||||
programWrapper = Handlebars.VM.program(i, fn, data);
|
programWrapper = program(i, fn, data);
|
||||||
} else if (!programWrapper) {
|
} else if (!programWrapper) {
|
||||||
programWrapper = this.programs[i] = Handlebars.VM.program(i, fn);
|
programWrapper = this.programs[i] = program(i, fn);
|
||||||
}
|
}
|
||||||
return programWrapper;
|
return programWrapper;
|
||||||
},
|
},
|
||||||
programWithDepth: Handlebars.VM.programWithDepth,
|
merge: function(param, common) {
|
||||||
noop: Handlebars.VM.noop,
|
var ret = param || common;
|
||||||
|
|
||||||
|
if (param && common && (param !== common)) {
|
||||||
|
ret = {};
|
||||||
|
Utils.extend(ret, common);
|
||||||
|
Utils.extend(ret, param);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
programWithDepth: env.VM.programWithDepth,
|
||||||
|
noop: env.VM.noop,
|
||||||
compilerInfo: null
|
compilerInfo: null
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(context, options) {
|
return function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var result = templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
|
var namespace = options.partial ? options : env,
|
||||||
|
helpers,
|
||||||
|
partials;
|
||||||
|
|
||||||
var compilerInfo = container.compilerInfo || [],
|
if (!options.partial) {
|
||||||
compilerRevision = compilerInfo[0] || 1,
|
helpers = options.helpers;
|
||||||
currentRevision = Handlebars.COMPILER_REVISION;
|
partials = options.partials;
|
||||||
|
|
||||||
if (compilerRevision !== currentRevision) {
|
|
||||||
if (compilerRevision < currentRevision) {
|
|
||||||
var runtimeVersions = Handlebars.REVISION_CHANGES[currentRevision],
|
|
||||||
compilerVersions = Handlebars.REVISION_CHANGES[compilerRevision];
|
|
||||||
throw "Template was precompiled with an older version of Handlebars than the current runtime. "+
|
|
||||||
"Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").";
|
|
||||||
} else {
|
|
||||||
// Use the embedded version info since the runtime doesn't know about this revision yet
|
|
||||||
throw "Template was precompiled with a newer version of Handlebars than the current runtime. "+
|
|
||||||
"Please update your runtime to a newer version ("+compilerInfo[1]+").";
|
|
||||||
}
|
}
|
||||||
|
var result = templateSpec.call(
|
||||||
|
container,
|
||||||
|
namespace, context,
|
||||||
|
helpers,
|
||||||
|
partials,
|
||||||
|
options.data);
|
||||||
|
|
||||||
|
if (!options.partial) {
|
||||||
|
env.VM.checkRevision(container.compilerInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
|
|
||||||
programWithDepth: function(i, fn, data /*, $depth */) {
|
export function programWithDepth(i, fn, data /*, $depth */) {
|
||||||
var args = Array.prototype.slice.call(arguments, 3);
|
var args = Array.prototype.slice.call(arguments, 3);
|
||||||
|
|
||||||
var program = function(context, options) {
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn.apply(this, [context, options.data || data].concat(args));
|
return fn.apply(this, [context, options.data || data].concat(args));
|
||||||
};
|
};
|
||||||
program.program = i;
|
prog.program = i;
|
||||||
program.depth = args.length;
|
prog.depth = args.length;
|
||||||
return program;
|
return prog;
|
||||||
},
|
}
|
||||||
program: function(i, fn, data) {
|
|
||||||
var program = function(context, options) {
|
export function program(i, fn, data) {
|
||||||
|
var prog = function(context, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return fn(context, options.data || data);
|
return fn(context, options.data || data);
|
||||||
};
|
};
|
||||||
program.program = i;
|
prog.program = i;
|
||||||
program.depth = 0;
|
prog.depth = 0;
|
||||||
return program;
|
return prog;
|
||||||
},
|
}
|
||||||
noop: function() { return ""; },
|
|
||||||
invokePartial: function(partial, name, context, helpers, partials, data) {
|
export function invokePartial(partial, name, context, helpers, partials, data) {
|
||||||
var options = { helpers: helpers, partials: partials, data: data };
|
var options = { partial: true, helpers: helpers, partials: partials, data: data };
|
||||||
|
|
||||||
if(partial === undefined) {
|
if(partial === undefined) {
|
||||||
throw new Handlebars.Exception("The partial " + name + " could not be found");
|
throw new Exception("The partial " + name + " could not be found");
|
||||||
} else if(partial instanceof Function) {
|
} else if(partial instanceof Function) {
|
||||||
return partial(context, options);
|
return partial(context, options);
|
||||||
} else if (!Handlebars.compile) {
|
|
||||||
throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
|
|
||||||
} else {
|
|
||||||
partials[name] = Handlebars.compile(partial, {data: data !== undefined});
|
|
||||||
return partials[name](context, options);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
Handlebars.template = Handlebars.VM.template;
|
export function noop() { return ""; }
|
||||||
|
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|||||||
10
node_modules/handlebars/lib/handlebars/safe-string.js
generated
vendored
Normal file
10
node_modules/handlebars/lib/handlebars/safe-string.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// Build out our basic SafeString type
|
||||||
|
function SafeString(string) {
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeString.prototype.toString = function() {
|
||||||
|
return "" + this.string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SafeString;
|
||||||
11
node_modules/handlebars/lib/handlebars/source.rb
generated
vendored
11
node_modules/handlebars/lib/handlebars/source.rb
generated
vendored
@@ -1,11 +0,0 @@
|
|||||||
module Handlebars
|
|
||||||
module Source
|
|
||||||
def self.bundled_path
|
|
||||||
File.expand_path("../../../dist/handlebars.js", __FILE__)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.runtime_bundled_path
|
|
||||||
File.expand_path("../../../dist/handlebars.runtime.js", __FILE__)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
80
node_modules/handlebars/lib/handlebars/utils.js
generated
vendored
80
node_modules/handlebars/lib/handlebars/utils.js
generated
vendored
@@ -1,28 +1,5 @@
|
|||||||
exports.attach = function(Handlebars) {
|
/*jshint -W004 */
|
||||||
|
import SafeString from "./safe-string";
|
||||||
var toString = Object.prototype.toString;
|
|
||||||
|
|
||||||
// BEGIN(BROWSER)
|
|
||||||
|
|
||||||
var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
|
|
||||||
|
|
||||||
Handlebars.Exception = function(message) {
|
|
||||||
var tmp = Error.prototype.constructor.apply(this, arguments);
|
|
||||||
|
|
||||||
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
|
|
||||||
for (var idx = 0; idx < errorProps.length; idx++) {
|
|
||||||
this[errorProps[idx]] = tmp[errorProps[idx]];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Handlebars.Exception.prototype = new Error();
|
|
||||||
|
|
||||||
// Build out our basic SafeString type
|
|
||||||
Handlebars.SafeString = function(string) {
|
|
||||||
this.string = string;
|
|
||||||
};
|
|
||||||
Handlebars.SafeString.prototype.toString = function() {
|
|
||||||
return this.string.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
var escape = {
|
var escape = {
|
||||||
"&": "&",
|
"&": "&",
|
||||||
@@ -36,48 +13,61 @@ var escape = {
|
|||||||
var badChars = /[&<>"'`]/g;
|
var badChars = /[&<>"'`]/g;
|
||||||
var possible = /[&<>"'`]/;
|
var possible = /[&<>"'`]/;
|
||||||
|
|
||||||
var escapeChar = function(chr) {
|
function escapeChar(chr) {
|
||||||
return escape[chr] || "&";
|
return escape[chr] || "&";
|
||||||
};
|
}
|
||||||
|
|
||||||
Handlebars.Utils = {
|
export function extend(obj, value) {
|
||||||
extend: function(obj, value) {
|
|
||||||
for(var key in value) {
|
for(var key in value) {
|
||||||
if(value.hasOwnProperty(key)) {
|
if(Object.prototype.hasOwnProperty.call(value, key)) {
|
||||||
obj[key] = value[key];
|
obj[key] = value[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
escapeExpression: function(string) {
|
export var toString = Object.prototype.toString;
|
||||||
|
|
||||||
|
// Sourced from lodash
|
||||||
|
// https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
|
||||||
|
var isFunction = function(value) {
|
||||||
|
return typeof value === 'function';
|
||||||
|
};
|
||||||
|
// fallback for older versions of Chrome and Safari
|
||||||
|
if (isFunction(/x/)) {
|
||||||
|
isFunction = function(value) {
|
||||||
|
return typeof value === 'function' && toString.call(value) === '[object Function]';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
export var isFunction;
|
||||||
|
|
||||||
|
export var isArray = Array.isArray || function(value) {
|
||||||
|
return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export function escapeExpression(string) {
|
||||||
// don't escape SafeStrings, since they're already safe
|
// don't escape SafeStrings, since they're already safe
|
||||||
if (string instanceof Handlebars.SafeString) {
|
if (string instanceof SafeString) {
|
||||||
return string.toString();
|
return string.toString();
|
||||||
} else if (string == null || string === false) {
|
} else if (!string && string !== 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force a string conversion as this will be done by the append regardless and
|
// Force a string conversion as this will be done by the append regardless and
|
||||||
// the regex test will do this transparently behind the scenes, causing issues if
|
// the regex test will do this transparently behind the scenes, causing issues if
|
||||||
// an object's to string has escaped characters in it.
|
// an object's to string has escaped characters in it.
|
||||||
string = string.toString();
|
string = "" + string;
|
||||||
|
|
||||||
if(!possible.test(string)) { return string; }
|
if(!possible.test(string)) { return string; }
|
||||||
return string.replace(badChars, escapeChar);
|
return string.replace(badChars, escapeChar);
|
||||||
},
|
}
|
||||||
|
|
||||||
isEmpty: function(value) {
|
export function isEmpty(value) {
|
||||||
if (!value && value !== 0) {
|
if (!value && value !== 0) {
|
||||||
return true;
|
return true;
|
||||||
} else if(toString.call(value) === "[object Array]" && value.length === 0) {
|
} else if (isArray(value) && value.length === 0) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// END(BROWSER)
|
|
||||||
|
|
||||||
return Handlebars;
|
|
||||||
};
|
|
||||||
|
|||||||
25
node_modules/handlebars/lib/index.js
generated
vendored
Normal file
25
node_modules/handlebars/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// USAGE:
|
||||||
|
// var handlebars = require('handlebars');
|
||||||
|
|
||||||
|
// var local = handlebars.create();
|
||||||
|
|
||||||
|
var handlebars = require('../dist/cjs/handlebars')["default"];
|
||||||
|
|
||||||
|
handlebars.Visitor = require('../dist/cjs/handlebars/compiler/visitor')["default"];
|
||||||
|
|
||||||
|
var printer = require('../dist/cjs/handlebars/compiler/printer');
|
||||||
|
handlebars.PrintVisitor = printer.PrintVisitor;
|
||||||
|
handlebars.print = printer.print;
|
||||||
|
|
||||||
|
module.exports = handlebars;
|
||||||
|
|
||||||
|
// Publish a Node.js require() handler for .handlebars and .hbs files
|
||||||
|
if (typeof require !== 'undefined' && require.extensions) {
|
||||||
|
var extension = function(module, filename) {
|
||||||
|
var fs = require("fs");
|
||||||
|
var templateString = fs.readFileSync(filename, "utf8");
|
||||||
|
module.exports = handlebars.compile(templateString);
|
||||||
|
};
|
||||||
|
require.extensions[".handlebars"] = extension;
|
||||||
|
require.extensions[".hbs"] = extension;
|
||||||
|
}
|
||||||
11
node_modules/handlebars/min.sh
generated
vendored
11
node_modules/handlebars/min.sh
generated
vendored
@@ -1,11 +0,0 @@
|
|||||||
rm dist/*
|
|
||||||
|
|
||||||
rake
|
|
||||||
|
|
||||||
for x in dist/*.js; do
|
|
||||||
x=${x%.*}
|
|
||||||
uglifyjs -c -m -- $x.js > $x.min.js
|
|
||||||
gzip -c $x.min.js > $x.min.js.gz
|
|
||||||
done
|
|
||||||
|
|
||||||
ls -l dist | awk '{ print $9 " " $5 }'
|
|
||||||
6
node_modules/handlebars/node_modules/uglify-js/.npmignore
generated
vendored
6
node_modules/handlebars/node_modules/uglify-js/.npmignore
generated
vendored
@@ -1,4 +1,2 @@
|
|||||||
.DS_Store
|
tmp/
|
||||||
.tmp*~
|
node_modules/
|
||||||
*.local.*
|
|
||||||
.pinf-*
|
|
||||||
|
|||||||
7
node_modules/handlebars/node_modules/uglify-js/.travis.yml
generated
vendored
Normal file
7
node_modules/handlebars/node_modules/uglify-js/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "0.4"
|
||||||
|
- "0.6"
|
||||||
|
- "0.8"
|
||||||
|
- "0.10"
|
||||||
|
- "0.11"
|
||||||
29
node_modules/handlebars/node_modules/uglify-js/LICENSE
generated
vendored
Normal file
29
node_modules/handlebars/node_modules/uglify-js/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
UglifyJS is released under the BSD license:
|
||||||
|
|
||||||
|
Copyright 2012-2013 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials
|
||||||
|
provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||||
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
981
node_modules/handlebars/node_modules/uglify-js/README.html
generated
vendored
981
node_modules/handlebars/node_modules/uglify-js/README.html
generated
vendored
@@ -1,981 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
|
||||||
lang="en" xml:lang="en">
|
|
||||||
<head>
|
|
||||||
<title>UglifyJS – a JavaScript parser/compressor/beautifier</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
|
|
||||||
<meta name="generator" content="Org-mode"/>
|
|
||||||
<meta name="generated" content="2011-12-09 14:59:08 EET"/>
|
|
||||||
<meta name="author" content="Mihai Bazon"/>
|
|
||||||
<meta name="description" content="a JavaScript parser/compressor/beautifier in JavaScript"/>
|
|
||||||
<meta name="keywords" content="javascript, js, parser, compiler, compressor, mangle, minify, minifier"/>
|
|
||||||
<style type="text/css">
|
|
||||||
<!--/*--><![CDATA[/*><!--*/
|
|
||||||
html { font-family: Times, serif; font-size: 12pt; }
|
|
||||||
.title { text-align: center; }
|
|
||||||
.todo { color: red; }
|
|
||||||
.done { color: green; }
|
|
||||||
.tag { background-color: #add8e6; font-weight:normal }
|
|
||||||
.target { }
|
|
||||||
.timestamp { color: #bebebe; }
|
|
||||||
.timestamp-kwd { color: #5f9ea0; }
|
|
||||||
.right {margin-left:auto; margin-right:0px; text-align:right;}
|
|
||||||
.left {margin-left:0px; margin-right:auto; text-align:left;}
|
|
||||||
.center {margin-left:auto; margin-right:auto; text-align:center;}
|
|
||||||
p.verse { margin-left: 3% }
|
|
||||||
pre {
|
|
||||||
border: 1pt solid #AEBDCC;
|
|
||||||
background-color: #F3F5F7;
|
|
||||||
padding: 5pt;
|
|
||||||
font-family: courier, monospace;
|
|
||||||
font-size: 90%;
|
|
||||||
overflow:auto;
|
|
||||||
}
|
|
||||||
table { border-collapse: collapse; }
|
|
||||||
td, th { vertical-align: top; }
|
|
||||||
th.right { text-align:center; }
|
|
||||||
th.left { text-align:center; }
|
|
||||||
th.center { text-align:center; }
|
|
||||||
td.right { text-align:right; }
|
|
||||||
td.left { text-align:left; }
|
|
||||||
td.center { text-align:center; }
|
|
||||||
dt { font-weight: bold; }
|
|
||||||
div.figure { padding: 0.5em; }
|
|
||||||
div.figure p { text-align: center; }
|
|
||||||
div.inlinetask {
|
|
||||||
padding:10px;
|
|
||||||
border:2px solid gray;
|
|
||||||
margin:10px;
|
|
||||||
background: #ffffcc;
|
|
||||||
}
|
|
||||||
textarea { overflow-x: auto; }
|
|
||||||
.linenr { font-size:smaller }
|
|
||||||
.code-highlighted {background-color:#ffff00;}
|
|
||||||
.org-info-js_info-navigation { border-style:none; }
|
|
||||||
#org-info-js_console-label { font-size:10px; font-weight:bold;
|
|
||||||
white-space:nowrap; }
|
|
||||||
.org-info-js_search-highlight {background-color:#ffff00; color:#000000;
|
|
||||||
font-weight:bold; }
|
|
||||||
/*]]>*/-->
|
|
||||||
</style>
|
|
||||||
<link rel="stylesheet" type="text/css" href="docstyle.css" />
|
|
||||||
<script type="text/javascript">
|
|
||||||
<!--/*--><![CDATA[/*><!--*/
|
|
||||||
function CodeHighlightOn(elem, id)
|
|
||||||
{
|
|
||||||
var target = document.getElementById(id);
|
|
||||||
if(null != target) {
|
|
||||||
elem.cacheClassElem = elem.className;
|
|
||||||
elem.cacheClassTarget = target.className;
|
|
||||||
target.className = "code-highlighted";
|
|
||||||
elem.className = "code-highlighted";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function CodeHighlightOff(elem, id)
|
|
||||||
{
|
|
||||||
var target = document.getElementById(id);
|
|
||||||
if(elem.cacheClassElem)
|
|
||||||
elem.className = elem.cacheClassElem;
|
|
||||||
if(elem.cacheClassTarget)
|
|
||||||
target.className = elem.cacheClassTarget;
|
|
||||||
}
|
|
||||||
/*]]>*///-->
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div id="preamble">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="content">
|
|
||||||
<h1 class="title">UglifyJS – a JavaScript parser/compressor/beautifier</h1>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="table-of-contents">
|
|
||||||
<h2>Table of Contents</h2>
|
|
||||||
<div id="text-table-of-contents">
|
|
||||||
<ul>
|
|
||||||
<li><a href="#sec-1">1 UglifyJS — a JavaScript parser/compressor/beautifier </a>
|
|
||||||
<ul>
|
|
||||||
<li><a href="#sec-1-1">1.1 Unsafe transformations </a>
|
|
||||||
<ul>
|
|
||||||
<li><a href="#sec-1-1-1">1.1.1 Calls involving the global Array constructor </a></li>
|
|
||||||
<li><a href="#sec-1-1-2">1.1.2 <code>obj.toString()</code> ==> <code>obj+“”</code> </a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><a href="#sec-1-2">1.2 Install (NPM) </a></li>
|
|
||||||
<li><a href="#sec-1-3">1.3 Install latest code from GitHub </a></li>
|
|
||||||
<li><a href="#sec-1-4">1.4 Usage </a>
|
|
||||||
<ul>
|
|
||||||
<li><a href="#sec-1-4-1">1.4.1 API </a></li>
|
|
||||||
<li><a href="#sec-1-4-2">1.4.2 Beautifier shortcoming – no more comments </a></li>
|
|
||||||
<li><a href="#sec-1-4-3">1.4.3 Use as a code pre-processor </a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><a href="#sec-1-5">1.5 Compression – how good is it? </a></li>
|
|
||||||
<li><a href="#sec-1-6">1.6 Bugs? </a></li>
|
|
||||||
<li><a href="#sec-1-7">1.7 Links </a></li>
|
|
||||||
<li><a href="#sec-1-8">1.8 License </a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1" class="outline-2">
|
|
||||||
<h2 id="sec-1"><span class="section-number-2">1</span> UglifyJS — a JavaScript parser/compressor/beautifier </h2>
|
|
||||||
<div class="outline-text-2" id="text-1">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This package implements a general-purpose JavaScript
|
|
||||||
parser/compressor/beautifier toolkit. It is developed on <a href="http://nodejs.org/">NodeJS</a>, but it
|
|
||||||
should work on any JavaScript platform supporting the CommonJS module system
|
|
||||||
(and if your platform of choice doesn't support CommonJS, you can easily
|
|
||||||
implement it, or discard the <code>exports.*</code> lines from UglifyJS sources).
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The tokenizer/parser generates an abstract syntax tree from JS code. You
|
|
||||||
can then traverse the AST to learn more about the code, or do various
|
|
||||||
manipulations on it. This part is implemented in <a href="../lib/parse-js.js">parse-js.js</a> and it's a
|
|
||||||
port to JavaScript of the excellent <a href="http://marijn.haverbeke.nl/parse-js/">parse-js</a> Common Lisp library from <a href="http://marijn.haverbeke.nl/">Marijn Haverbeke</a>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
( See <a href="http://github.com/mishoo/cl-uglify-js">cl-uglify-js</a> if you're looking for the Common Lisp version of
|
|
||||||
UglifyJS. )
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The second part of this package, implemented in <a href="../lib/process.js">process.js</a>, inspects and
|
|
||||||
manipulates the AST generated by the parser to provide the following:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li>ability to re-generate JavaScript code from the AST. Optionally
|
|
||||||
indented—you can use this if you want to “beautify” a program that has
|
|
||||||
been compressed, so that you can inspect the source. But you can also run
|
|
||||||
our code generator to print out an AST without any whitespace, so you
|
|
||||||
achieve compression as well.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>shorten variable names (usually to single characters). Our mangler will
|
|
||||||
analyze the code and generate proper variable names, depending on scope
|
|
||||||
and usage, and is smart enough to deal with globals defined elsewhere, or
|
|
||||||
with <code>eval()</code> calls or <code>with{}</code> statements. In short, if <code>eval()</code> or
|
|
||||||
<code>with{}</code> are used in some scope, then all variables in that scope and any
|
|
||||||
variables in the parent scopes will remain unmangled, and any references
|
|
||||||
to such variables remain unmangled as well.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>various small optimizations that may lead to faster code but certainly
|
|
||||||
lead to smaller code. Where possible, we do the following:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>foo["bar"] ==> foo.bar
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>remove block brackets <code>{}</code>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>join consecutive var declarations:
|
|
||||||
var a = 10; var b = 20; ==> var a=10,b=20;
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>resolve simple constant expressions: 1 +2 * 3 ==> 7. We only do the
|
|
||||||
replacement if the result occupies less bytes; for example 1/3 would
|
|
||||||
translate to 0.333333333333, so in this case we don't replace it.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>consecutive statements in blocks are merged into a sequence; in many
|
|
||||||
cases, this leaves blocks with a single statement, so then we can remove
|
|
||||||
the block brackets.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>various optimizations for IF statements:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>if (foo) bar(); else baz(); ==> foo?bar():baz();
|
|
||||||
</li>
|
|
||||||
<li>if (!foo) bar(); else baz(); ==> foo?baz():bar();
|
|
||||||
</li>
|
|
||||||
<li>if (foo) bar(); ==> foo&&bar();
|
|
||||||
</li>
|
|
||||||
<li>if (!foo) bar(); ==> foo||bar();
|
|
||||||
</li>
|
|
||||||
<li>if (foo) return bar(); else return baz(); ==> return foo?bar():baz();
|
|
||||||
</li>
|
|
||||||
<li>if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>remove some unreachable code and warn about it (code that follows a
|
|
||||||
<code>return</code>, <code>throw</code>, <code>break</code> or <code>continue</code> statement, except
|
|
||||||
function/variable declarations).
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li>act a limited version of a pre-processor (c.f. the pre-processor of
|
|
||||||
C/C++) to allow you to safely replace selected global symbols with
|
|
||||||
specified values. When combined with the optimisations above this can
|
|
||||||
make UglifyJS operate slightly more like a compilation process, in
|
|
||||||
that when certain symbols are replaced by constant values, entire code
|
|
||||||
blocks may be optimised away as unreachable.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-1" class="outline-3">
|
|
||||||
<h3 id="sec-1-1"><span class="section-number-3">1.1</span> <span class="target">Unsafe transformations</span> </h3>
|
|
||||||
<div class="outline-text-3" id="text-1-1">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The following transformations can in theory break code, although they're
|
|
||||||
probably safe in most practical cases. To enable them you need to pass the
|
|
||||||
<code>--unsafe</code> flag.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-1-1" class="outline-4">
|
|
||||||
<h4 id="sec-1-1-1"><span class="section-number-4">1.1.1</span> Calls involving the global Array constructor </h4>
|
|
||||||
<div class="outline-text-4" id="text-1-1-1">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The following transformations occur:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<pre class="src src-js"><span class="org-keyword">new</span> <span class="org-type">Array</span>(1, 2, 3, 4) => [1,2,3,4]
|
|
||||||
Array(a, b, c) => [a,b,c]
|
|
||||||
<span class="org-keyword">new</span> <span class="org-type">Array</span>(5) => Array(5)
|
|
||||||
<span class="org-keyword">new</span> <span class="org-type">Array</span>(a) => Array(a)
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
These are all safe if the Array name isn't redefined. JavaScript does allow
|
|
||||||
one to globally redefine Array (and pretty much everything, in fact) but I
|
|
||||||
personally don't see why would anyone do that.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
UglifyJS does handle the case where Array is redefined locally, or even
|
|
||||||
globally but with a <code>function</code> or <code>var</code> declaration. Therefore, in the
|
|
||||||
following cases UglifyJS <b>doesn't touch</b> calls or instantiations of Array:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<pre class="src src-js"><span class="org-comment-delimiter">// </span><span class="org-comment">case 1. globally declared variable</span>
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">Array</span>;
|
|
||||||
<span class="org-keyword">new</span> <span class="org-type">Array</span>(1, 2, 3);
|
|
||||||
Array(a, b);
|
|
||||||
|
|
||||||
<span class="org-comment-delimiter">// </span><span class="org-comment">or (can be declared later)</span>
|
|
||||||
<span class="org-keyword">new</span> <span class="org-type">Array</span>(1, 2, 3);
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">Array</span>;
|
|
||||||
|
|
||||||
<span class="org-comment-delimiter">// </span><span class="org-comment">or (can be a function)</span>
|
|
||||||
<span class="org-keyword">new</span> <span class="org-type">Array</span>(1, 2, 3);
|
|
||||||
<span class="org-keyword">function</span> <span class="org-function-name">Array</span>() { ... }
|
|
||||||
|
|
||||||
<span class="org-comment-delimiter">// </span><span class="org-comment">case 2. declared in a function</span>
|
|
||||||
(<span class="org-keyword">function</span>(){
|
|
||||||
a = <span class="org-keyword">new</span> <span class="org-type">Array</span>(1, 2, 3);
|
|
||||||
b = Array(5, 6);
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">Array</span>;
|
|
||||||
})();
|
|
||||||
|
|
||||||
<span class="org-comment-delimiter">// </span><span class="org-comment">or</span>
|
|
||||||
(<span class="org-keyword">function</span>(<span class="org-variable-name">Array</span>){
|
|
||||||
<span class="org-keyword">return</span> Array(5, 6, 7);
|
|
||||||
})();
|
|
||||||
|
|
||||||
<span class="org-comment-delimiter">// </span><span class="org-comment">or</span>
|
|
||||||
(<span class="org-keyword">function</span>(){
|
|
||||||
<span class="org-keyword">return</span> <span class="org-keyword">new</span> <span class="org-type">Array</span>(1, 2, 3, 4);
|
|
||||||
<span class="org-keyword">function</span> <span class="org-function-name">Array</span>() { ... }
|
|
||||||
})();
|
|
||||||
|
|
||||||
<span class="org-comment-delimiter">// </span><span class="org-comment">etc.</span>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-1-2" class="outline-4">
|
|
||||||
<h4 id="sec-1-1-2"><span class="section-number-4">1.1.2</span> <code>obj.toString()</code> ==> <code>obj+“”</code> </h4>
|
|
||||||
<div class="outline-text-4" id="text-1-1-2">
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-2" class="outline-3">
|
|
||||||
<h3 id="sec-1-2"><span class="section-number-3">1.2</span> Install (NPM) </h3>
|
|
||||||
<div class="outline-text-3" id="text-1-2">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
UglifyJS is now available through NPM — <code>npm install uglify-js</code> should do
|
|
||||||
the job.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-3" class="outline-3">
|
|
||||||
<h3 id="sec-1-3"><span class="section-number-3">1.3</span> Install latest code from GitHub </h3>
|
|
||||||
<div class="outline-text-3" id="text-1-3">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<pre class="src src-sh"><span class="org-comment-delimiter">## </span><span class="org-comment">clone the repository</span>
|
|
||||||
mkdir -p /where/you/wanna/put/it
|
|
||||||
<span class="org-builtin">cd</span> /where/you/wanna/put/it
|
|
||||||
git clone git://github.com/mishoo/UglifyJS.git
|
|
||||||
|
|
||||||
<span class="org-comment-delimiter">## </span><span class="org-comment">make the module available to Node</span>
|
|
||||||
mkdir -p ~/.node_libraries/
|
|
||||||
<span class="org-builtin">cd</span> ~/.node_libraries/
|
|
||||||
ln -s /where/you/wanna/put/it/UglifyJS/uglify-js.js
|
|
||||||
|
|
||||||
<span class="org-comment-delimiter">## </span><span class="org-comment">and if you want the CLI script too:</span>
|
|
||||||
mkdir -p ~/bin
|
|
||||||
<span class="org-builtin">cd</span> ~/bin
|
|
||||||
ln -s /where/you/wanna/put/it/UglifyJS/bin/uglifyjs
|
|
||||||
<span class="org-comment-delimiter"># </span><span class="org-comment">(then add ~/bin to your $PATH if it's not there already)</span>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-4" class="outline-3">
|
|
||||||
<h3 id="sec-1-4"><span class="section-number-3">1.4</span> Usage </h3>
|
|
||||||
<div class="outline-text-3" id="text-1-4">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
There is a command-line tool that exposes the functionality of this library
|
|
||||||
for your shell-scripting needs:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<pre class="src src-sh">uglifyjs [ options... ] [ filename ]
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<code>filename</code> should be the last argument and should name the file from which
|
|
||||||
to read the JavaScript code. If you don't specify it, it will read code
|
|
||||||
from STDIN.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Supported options:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li><code>-b</code> or <code>--beautify</code> — output indented code; when passed, additional
|
|
||||||
options control the beautifier:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><code>-i N</code> or <code>--indent N</code> — indentation level (number of spaces)
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-q</code> or <code>--quote-keys</code> — quote keys in literal objects (by default,
|
|
||||||
only keys that cannot be identifier names will be quotes).
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--ascii</code> — pass this argument to encode non-ASCII characters as
|
|
||||||
<code>\uXXXX</code> sequences. By default UglifyJS won't bother to do it and will
|
|
||||||
output Unicode characters instead. (the output is always encoded in UTF8,
|
|
||||||
but if you pass this option you'll only get ASCII).
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-nm</code> or <code>--no-mangle</code> — don't mangle names.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-nmf</code> or <code>--no-mangle-functions</code> – in case you want to mangle variable
|
|
||||||
names, but not touch function names.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-ns</code> or <code>--no-squeeze</code> — don't call <code>ast_squeeze()</code> (which does various
|
|
||||||
optimizations that result in smaller, less readable code).
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-mt</code> or <code>--mangle-toplevel</code> — mangle names in the toplevel scope too
|
|
||||||
(by default we don't do this).
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--no-seqs</code> — when <code>ast_squeeze()</code> is called (thus, unless you pass
|
|
||||||
<code>--no-squeeze</code>) it will reduce consecutive statements in blocks into a
|
|
||||||
sequence. For example, "a = 10; b = 20; foo();" will be written as
|
|
||||||
"a=10,b=20,foo();". In various occasions, this allows us to discard the
|
|
||||||
block brackets (since the block becomes a single statement). This is ON
|
|
||||||
by default because it seems safe and saves a few hundred bytes on some
|
|
||||||
libs that I tested it on, but pass <code>--no-seqs</code> to disable it.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--no-dead-code</code> — by default, UglifyJS will remove code that is
|
|
||||||
obviously unreachable (code that follows a <code>return</code>, <code>throw</code>, <code>break</code> or
|
|
||||||
<code>continue</code> statement and is not a function/variable declaration). Pass
|
|
||||||
this option to disable this optimization.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-nc</code> or <code>--no-copyright</code> — by default, <code>uglifyjs</code> will keep the initial
|
|
||||||
comment tokens in the generated code (assumed to be copyright information
|
|
||||||
etc.). If you pass this it will discard it.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-o filename</code> or <code>--output filename</code> — put the result in <code>filename</code>. If
|
|
||||||
this isn't given, the result goes to standard output (or see next one).
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--overwrite</code> — if the code is read from a file (not from STDIN) and you
|
|
||||||
pass <code>--overwrite</code> then the output will be written in the same file.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--ast</code> — pass this if you want to get the Abstract Syntax Tree instead
|
|
||||||
of JavaScript as output. Useful for debugging or learning more about the
|
|
||||||
internals.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-v</code> or <code>--verbose</code> — output some notes on STDERR (for now just how long
|
|
||||||
each operation takes).
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-d SYMBOL[=VALUE]</code> or <code>--define SYMBOL[=VALUE]</code> — will replace
|
|
||||||
all instances of the specified symbol where used as an identifier
|
|
||||||
(except where symbol has properly declared by a var declaration or
|
|
||||||
use as function parameter or similar) with the specified value. This
|
|
||||||
argument may be specified multiple times to define multiple
|
|
||||||
symbols - if no value is specified the symbol will be replaced with
|
|
||||||
the value <code>true</code>, or you can specify a numeric value (such as
|
|
||||||
<code>1024</code>), a quoted string value (such as ="object"= or
|
|
||||||
='https://github.com'<code>), or the name of another symbol or keyword (such as =null</code> or <code>document</code>).
|
|
||||||
This allows you, for example, to assign meaningful names to key
|
|
||||||
constant values but discard the symbolic names in the uglified
|
|
||||||
version for brevity/efficiency, or when used wth care, allows
|
|
||||||
UglifyJS to operate as a form of <b>conditional compilation</b>
|
|
||||||
whereby defining appropriate values may, by dint of the constant
|
|
||||||
folding and dead code removal features above, remove entire
|
|
||||||
superfluous code blocks (e.g. completely remove instrumentation or
|
|
||||||
trace code for production use).
|
|
||||||
Where string values are being defined, the handling of quotes are
|
|
||||||
likely to be subject to the specifics of your command shell
|
|
||||||
environment, so you may need to experiment with quoting styles
|
|
||||||
depending on your platform, or you may find the option
|
|
||||||
<code>--define-from-module</code> more suitable for use.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>-define-from-module SOMEMODULE</code> — will load the named module (as
|
|
||||||
per the NodeJS <code>require()</code> function) and iterate all the exported
|
|
||||||
properties of the module defining them as symbol names to be defined
|
|
||||||
(as if by the <code>--define</code> option) per the name of each property
|
|
||||||
(i.e. without the module name prefix) and given the value of the
|
|
||||||
property. This is a much easier way to handle and document groups of
|
|
||||||
symbols to be defined rather than a large number of <code>--define</code>
|
|
||||||
options.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--unsafe</code> — enable other additional optimizations that are known to be
|
|
||||||
unsafe in some contrived situations, but could still be generally useful.
|
|
||||||
For now only these:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>foo.toString() ==> foo+""
|
|
||||||
</li>
|
|
||||||
<li>new Array(x,…) ==> [x,…]
|
|
||||||
</li>
|
|
||||||
<li>new Array(x) ==> Array(x)
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--max-line-len</code> (default 32K characters) — add a newline after around
|
|
||||||
32K characters. I've seen both FF and Chrome croak when all the code was
|
|
||||||
on a single line of around 670K. Pass –max-line-len 0 to disable this
|
|
||||||
safety feature.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--reserved-names</code> — some libraries rely on certain names to be used, as
|
|
||||||
pointed out in issue #92 and #81, so this option allow you to exclude such
|
|
||||||
names from the mangler. For example, to keep names <code>require</code> and <code>$super</code>
|
|
||||||
intact you'd specify –reserved-names "require,$super".
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--inline-script</code> – when you want to include the output literally in an
|
|
||||||
HTML <code><script></code> tag you can use this option to prevent <code></script</code> from
|
|
||||||
showing up in the output.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>--lift-vars</code> – when you pass this, UglifyJS will apply the following
|
|
||||||
transformations (see the notes in API, <code>ast_lift_variables</code>):
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>put all <code>var</code> declarations at the start of the scope
|
|
||||||
</li>
|
|
||||||
<li>make sure a variable is declared only once
|
|
||||||
</li>
|
|
||||||
<li>discard unused function arguments
|
|
||||||
</li>
|
|
||||||
<li>discard unused inner (named) functions
|
|
||||||
</li>
|
|
||||||
<li>finally, try to merge assignments into that one <code>var</code> declaration, if
|
|
||||||
possible.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-4-1" class="outline-4">
|
|
||||||
<h4 id="sec-1-4-1"><span class="section-number-4">1.4.1</span> API </h4>
|
|
||||||
<div class="outline-text-4" id="text-1-4-1">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
To use the library from JavaScript, you'd do the following (example for
|
|
||||||
NodeJS):
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<pre class="src src-js"><span class="org-keyword">var</span> <span class="org-variable-name">jsp</span> = require(<span class="org-string">"uglify-js"</span>).parser;
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">pro</span> = require(<span class="org-string">"uglify-js"</span>).uglify;
|
|
||||||
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">orig_code</span> = <span class="org-string">"... JS code here"</span>;
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">ast</span> = jsp.parse(orig_code); <span class="org-comment-delimiter">// </span><span class="org-comment">parse code and get the initial AST</span>
|
|
||||||
ast = pro.ast_mangle(ast); <span class="org-comment-delimiter">// </span><span class="org-comment">get a new AST with mangled names</span>
|
|
||||||
ast = pro.ast_squeeze(ast); <span class="org-comment-delimiter">// </span><span class="org-comment">get an AST with compression optimizations</span>
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">final_code</span> = pro.gen_code(ast); <span class="org-comment-delimiter">// </span><span class="org-comment">compressed code here</span>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The above performs the full compression that is possible right now. As you
|
|
||||||
can see, there are a sequence of steps which you can apply. For example if
|
|
||||||
you want compressed output but for some reason you don't want to mangle
|
|
||||||
variable names, you would simply skip the line that calls
|
|
||||||
<code>pro.ast_mangle(ast)</code>.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Some of these functions take optional arguments. Here's a description:
|
|
||||||
</p>
|
|
||||||
<ul>
|
|
||||||
<li><code>jsp.parse(code, strict_semicolons)</code> – parses JS code and returns an AST.
|
|
||||||
<code>strict_semicolons</code> is optional and defaults to <code>false</code>. If you pass
|
|
||||||
<code>true</code> then the parser will throw an error when it expects a semicolon and
|
|
||||||
it doesn't find it. For most JS code you don't want that, but it's useful
|
|
||||||
if you want to strictly sanitize your code.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>pro.ast_lift_variables(ast)</code> – merge and move <code>var</code> declarations to the
|
|
||||||
scop of the scope; discard unused function arguments or variables; discard
|
|
||||||
unused (named) inner functions. It also tries to merge assignments
|
|
||||||
following the <code>var</code> declaration into it.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
If your code is very hand-optimized concerning <code>var</code> declarations, this
|
|
||||||
lifting variable declarations might actually increase size. For me it
|
|
||||||
helps out. On jQuery it adds 865 bytes (243 after gzip). YMMV. Also
|
|
||||||
note that (since it's not enabled by default) this operation isn't yet
|
|
||||||
heavily tested (please report if you find issues!).
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Note that although it might increase the image size (on jQuery it gains
|
|
||||||
865 bytes, 243 after gzip) it's technically more correct: in certain
|
|
||||||
situations, dead code removal might drop variable declarations, which
|
|
||||||
would not happen if the variables are lifted in advance.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Here's an example of what it does:
|
|
||||||
</p></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<pre class="src src-js"><span class="org-keyword">function</span> <span class="org-function-name">f</span>(<span class="org-variable-name">a</span>, <span class="org-variable-name">b</span>, <span class="org-variable-name">c</span>, <span class="org-variable-name">d</span>, <span class="org-variable-name">e</span>) {
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">q</span>;
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">w</span>;
|
|
||||||
w = 10;
|
|
||||||
q = 20;
|
|
||||||
<span class="org-keyword">for</span> (<span class="org-keyword">var</span> <span class="org-variable-name">i</span> = 1; i < 10; ++i) {
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">boo</span> = foo(a);
|
|
||||||
}
|
|
||||||
<span class="org-keyword">for</span> (<span class="org-keyword">var</span> <span class="org-variable-name">i</span> = 0; i < 1; ++i) {
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">boo</span> = bar(c);
|
|
||||||
}
|
|
||||||
<span class="org-keyword">function</span> <span class="org-function-name">foo</span>(){ ... }
|
|
||||||
<span class="org-keyword">function</span> <span class="org-function-name">bar</span>(){ ... }
|
|
||||||
<span class="org-keyword">function</span> <span class="org-function-name">baz</span>(){ ... }
|
|
||||||
}
|
|
||||||
|
|
||||||
<span class="org-comment-delimiter">// </span><span class="org-comment">transforms into ==></span>
|
|
||||||
|
|
||||||
<span class="org-keyword">function</span> <span class="org-function-name">f</span>(<span class="org-variable-name">a</span>, <span class="org-variable-name">b</span>, <span class="org-variable-name">c</span>) {
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">i</span>, <span class="org-variable-name">boo</span>, <span class="org-variable-name">w</span> = 10, <span class="org-variable-name">q</span> = 20;
|
|
||||||
<span class="org-keyword">for</span> (i = 1; i < 10; ++i) {
|
|
||||||
boo = foo(a);
|
|
||||||
}
|
|
||||||
<span class="org-keyword">for</span> (i = 0; i < 1; ++i) {
|
|
||||||
boo = bar(c);
|
|
||||||
}
|
|
||||||
<span class="org-keyword">function</span> <span class="org-function-name">foo</span>() { ... }
|
|
||||||
<span class="org-keyword">function</span> <span class="org-function-name">bar</span>() { ... }
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><code>pro.ast_mangle(ast, options)</code> – generates a new AST containing mangled
|
|
||||||
(compressed) variable and function names. It supports the following
|
|
||||||
options:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><code>toplevel</code> – mangle toplevel names (by default we don't touch them).
|
|
||||||
</li>
|
|
||||||
<li><code>except</code> – an array of names to exclude from compression.
|
|
||||||
</li>
|
|
||||||
<li><code>defines</code> – an object with properties named after symbols to
|
|
||||||
replace (see the <code>--define</code> option for the script) and the values
|
|
||||||
representing the AST replacement value.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>pro.ast_squeeze(ast, options)</code> – employs further optimizations designed
|
|
||||||
to reduce the size of the code that <code>gen_code</code> would generate from the
|
|
||||||
AST. Returns a new AST. <code>options</code> can be a hash; the supported options
|
|
||||||
are:
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><code>make_seqs</code> (default true) which will cause consecutive statements in a
|
|
||||||
block to be merged using the "sequence" (comma) operator
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>dead_code</code> (default true) which will remove unreachable code.
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
<li><code>pro.gen_code(ast, options)</code> – generates JS code from the AST. By
|
|
||||||
default it's minified, but using the <code>options</code> argument you can get nicely
|
|
||||||
formatted output. <code>options</code> is, well, optional :-) and if you pass it it
|
|
||||||
must be an object and supports the following properties (below you can see
|
|
||||||
the default values):
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><code>beautify: false</code> – pass <code>true</code> if you want indented output
|
|
||||||
</li>
|
|
||||||
<li><code>indent_start: 0</code> (only applies when <code>beautify</code> is <code>true</code>) – initial
|
|
||||||
indentation in spaces
|
|
||||||
</li>
|
|
||||||
<li><code>indent_level: 4</code> (only applies when <code>beautify</code> is <code>true</code>) --
|
|
||||||
indentation level, in spaces (pass an even number)
|
|
||||||
</li>
|
|
||||||
<li><code>quote_keys: false</code> – if you pass <code>true</code> it will quote all keys in
|
|
||||||
literal objects
|
|
||||||
</li>
|
|
||||||
<li><code>space_colon: false</code> (only applies when <code>beautify</code> is <code>true</code>) – wether
|
|
||||||
to put a space before the colon in object literals
|
|
||||||
</li>
|
|
||||||
<li><code>ascii_only: false</code> – pass <code>true</code> if you want to encode non-ASCII
|
|
||||||
characters as <code>\uXXXX</code>.
|
|
||||||
</li>
|
|
||||||
<li><code>inline_script: false</code> – pass <code>true</code> to escape occurrences of
|
|
||||||
<code></script</code> in strings
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-4-2" class="outline-4">
|
|
||||||
<h4 id="sec-1-4-2"><span class="section-number-4">1.4.2</span> Beautifier shortcoming – no more comments </h4>
|
|
||||||
<div class="outline-text-4" id="text-1-4-2">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The beautifier can be used as a general purpose indentation tool. It's
|
|
||||||
useful when you want to make a minified file readable. One limitation,
|
|
||||||
though, is that it discards all comments, so you don't really want to use it
|
|
||||||
to reformat your code, unless you don't have, or don't care about, comments.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In fact it's not the beautifier who discards comments — they are dumped at
|
|
||||||
the parsing stage, when we build the initial AST. Comments don't really
|
|
||||||
make sense in the AST, and while we could add nodes for them, it would be
|
|
||||||
inconvenient because we'd have to add special rules to ignore them at all
|
|
||||||
the processing stages.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-4-3" class="outline-4">
|
|
||||||
<h4 id="sec-1-4-3"><span class="section-number-4">1.4.3</span> Use as a code pre-processor </h4>
|
|
||||||
<div class="outline-text-4" id="text-1-4-3">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <code>--define</code> option can be used, particularly when combined with the
|
|
||||||
constant folding logic, as a form of pre-processor to enable or remove
|
|
||||||
particular constructions, such as might be used for instrumenting
|
|
||||||
development code, or to produce variations aimed at a specific
|
|
||||||
platform.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The code below illustrates the way this can be done, and how the
|
|
||||||
symbol replacement is performed.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<pre class="src src-js">CLAUSE1: <span class="org-keyword">if</span> (<span class="org-keyword">typeof</span> DEVMODE === <span class="org-string">'undefined'</span>) {
|
|
||||||
DEVMODE = <span class="org-constant">true</span>;
|
|
||||||
}
|
|
||||||
|
|
||||||
<span class="org-function-name">CLAUSE2</span>: <span class="org-keyword">function</span> init() {
|
|
||||||
<span class="org-keyword">if</span> (DEVMODE) {
|
|
||||||
console.log(<span class="org-string">"init() called"</span>);
|
|
||||||
}
|
|
||||||
....
|
|
||||||
DEVMODE &amp;&amp; console.log(<span class="org-string">"init() complete"</span>);
|
|
||||||
}
|
|
||||||
|
|
||||||
<span class="org-function-name">CLAUSE3</span>: <span class="org-keyword">function</span> reportDeviceStatus(<span class="org-variable-name">device</span>) {
|
|
||||||
<span class="org-keyword">var</span> <span class="org-variable-name">DEVMODE</span> = device.mode, <span class="org-variable-name">DEVNAME</span> = device.name;
|
|
||||||
<span class="org-keyword">if</span> (DEVMODE === <span class="org-string">'open'</span>) {
|
|
||||||
....
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
When the above code is normally executed, the undeclared global
|
|
||||||
variable <code>DEVMODE</code> will be assigned the value <b>true</b> (see <code>CLAUSE1</code>)
|
|
||||||
and so the <code>init()</code> function (<code>CLAUSE2</code>) will write messages to the
|
|
||||||
console log when executed, but in <code>CLAUSE3</code> a locally declared
|
|
||||||
variable will mask access to the <code>DEVMODE</code> global symbol.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
If the above code is processed by UglifyJS with an argument of
|
|
||||||
<code>--define DEVMODE=false</code> then UglifyJS will replace <code>DEVMODE</code> with the
|
|
||||||
boolean constant value <b>false</b> within <code>CLAUSE1</code> and <code>CLAUSE2</code>, but it
|
|
||||||
will leave <code>CLAUSE3</code> as it stands because there <code>DEVMODE</code> resolves to
|
|
||||||
a validly declared variable.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
And more so, the constant-folding features of UglifyJS will recognise
|
|
||||||
that the <code>if</code> condition of <code>CLAUSE1</code> is thus always false, and so will
|
|
||||||
remove the test and body of <code>CLAUSE1</code> altogether (including the
|
|
||||||
otherwise slightly problematical statement <code>false = true;</code> which it
|
|
||||||
will have formed by replacing <code>DEVMODE</code> in the body). Similarly,
|
|
||||||
within <code>CLAUSE2</code> both calls to <code>console.log()</code> will be removed
|
|
||||||
altogether.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
In this way you can mimic, to a limited degree, the functionality of
|
|
||||||
the C/C++ pre-processor to enable or completely remove blocks
|
|
||||||
depending on how certain symbols are defined - perhaps using UglifyJS
|
|
||||||
to generate different versions of source aimed at different
|
|
||||||
environments
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
It is recommmended (but not made mandatory) that symbols designed for
|
|
||||||
this purpose are given names consisting of <code>UPPER_CASE_LETTERS</code> to
|
|
||||||
distinguish them from other (normal) symbols and avoid the sort of
|
|
||||||
clash that <code>CLAUSE3</code> above illustrates.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-5" class="outline-3">
|
|
||||||
<h3 id="sec-1-5"><span class="section-number-3">1.5</span> Compression – how good is it? </h3>
|
|
||||||
<div class="outline-text-3" id="text-1-5">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Here are updated statistics. (I also updated my Google Closure and YUI
|
|
||||||
installations).
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
We're still a lot better than YUI in terms of compression, though slightly
|
|
||||||
slower. We're still a lot faster than Closure, and compression after gzip
|
|
||||||
is comparable.
|
|
||||||
</p>
|
|
||||||
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
|
|
||||||
<caption></caption>
|
|
||||||
<colgroup><col class="left" /><col class="left" /><col class="right" /><col class="left" /><col class="right" /><col class="left" /><col class="right" />
|
|
||||||
</colgroup>
|
|
||||||
<thead>
|
|
||||||
<tr><th scope="col" class="left">File</th><th scope="col" class="left">UglifyJS</th><th scope="col" class="right">UglifyJS+gzip</th><th scope="col" class="left">Closure</th><th scope="col" class="right">Closure+gzip</th><th scope="col" class="left">YUI</th><th scope="col" class="right">YUI+gzip</th></tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr><td class="left">jquery-1.6.2.js</td><td class="left">91001 (0:01.59)</td><td class="right">31896</td><td class="left">90678 (0:07.40)</td><td class="right">31979</td><td class="left">101527 (0:01.82)</td><td class="right">34646</td></tr>
|
|
||||||
<tr><td class="left">paper.js</td><td class="left">142023 (0:01.65)</td><td class="right">43334</td><td class="left">134301 (0:07.42)</td><td class="right">42495</td><td class="left">173383 (0:01.58)</td><td class="right">48785</td></tr>
|
|
||||||
<tr><td class="left">prototype.js</td><td class="left">88544 (0:01.09)</td><td class="right">26680</td><td class="left">86955 (0:06.97)</td><td class="right">26326</td><td class="left">92130 (0:00.79)</td><td class="right">28624</td></tr>
|
|
||||||
<tr><td class="left">thelib-full.js (DynarchLIB)</td><td class="left">251939 (0:02.55)</td><td class="right">72535</td><td class="left">249911 (0:09.05)</td><td class="right">72696</td><td class="left">258869 (0:01.94)</td><td class="right">76584</td></tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-6" class="outline-3">
|
|
||||||
<h3 id="sec-1-6"><span class="section-number-3">1.6</span> Bugs? </h3>
|
|
||||||
<div class="outline-text-3" id="text-1-6">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Unfortunately, for the time being there is no automated test suite. But I
|
|
||||||
ran the compressor manually on non-trivial code, and then I tested that the
|
|
||||||
generated code works as expected. A few hundred times.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
DynarchLIB was started in times when there was no good JS minifier.
|
|
||||||
Therefore I was quite religious about trying to write short code manually,
|
|
||||||
and as such DL contains a lot of syntactic hacks<sup><a class="footref" name="fnr.1" href="#fn.1">1</a></sup> such as “foo == bar ? a
|
|
||||||
= 10 : b = 20”, though the more readable version would clearly be to use
|
|
||||||
“if/else”.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Since the parser/compressor runs fine on DL and jQuery, I'm quite confident
|
|
||||||
that it's solid enough for production use. If you can identify any bugs,
|
|
||||||
I'd love to hear about them (<a href="http://groups.google.com/group/uglifyjs">use the Google Group</a> or email me directly).
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-7" class="outline-3">
|
|
||||||
<h3 id="sec-1-7"><span class="section-number-3">1.7</span> Links </h3>
|
|
||||||
<div class="outline-text-3" id="text-1-7">
|
|
||||||
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>Twitter: <a href="http://twitter.com/UglifyJS">@UglifyJS</a>
|
|
||||||
</li>
|
|
||||||
<li>Project at GitHub: <a href="http://github.com/mishoo/UglifyJS">http://github.com/mishoo/UglifyJS</a>
|
|
||||||
</li>
|
|
||||||
<li>Google Group: <a href="http://groups.google.com/group/uglifyjs">http://groups.google.com/group/uglifyjs</a>
|
|
||||||
</li>
|
|
||||||
<li>Common Lisp JS parser: <a href="http://marijn.haverbeke.nl/parse-js/">http://marijn.haverbeke.nl/parse-js/</a>
|
|
||||||
</li>
|
|
||||||
<li>JS-to-Lisp compiler: <a href="http://github.com/marijnh/js">http://github.com/marijnh/js</a>
|
|
||||||
</li>
|
|
||||||
<li>Common Lisp JS uglifier: <a href="http://github.com/mishoo/cl-uglify-js">http://github.com/mishoo/cl-uglify-js</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="outline-container-1-8" class="outline-3">
|
|
||||||
<h3 id="sec-1-8"><span class="section-number-3">1.8</span> License </h3>
|
|
||||||
<div class="outline-text-3" id="text-1-8">
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
UglifyJS is released under the BSD license:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<pre class="example">Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
|
||||||
Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer in the documentation and/or other materials
|
|
||||||
provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
||||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGE.
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="footnotes">
|
|
||||||
<h2 class="footnotes">Footnotes: </h2>
|
|
||||||
<div id="text-footnotes">
|
|
||||||
<p class="footnote"><sup><a class="footnum" name="fn.1" href="#fnr.1">1</a></sup> I even reported a few bugs and suggested some fixes in the original
|
|
||||||
<a href="http://marijn.haverbeke.nl/parse-js/">parse-js</a> library, and Marijn pushed fixes literally in minutes.
|
|
||||||
</p></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="postamble">
|
|
||||||
<p class="date">Date: 2011-12-09 14:59:08 EET</p>
|
|
||||||
<p class="author">Author: Mihai Bazon</p>
|
|
||||||
<p class="creator">Org version 7.7 with Emacs version 23</p>
|
|
||||||
<a href="http://validator.w3.org/check?uri=referer">Validate XHTML 1.0</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
588
node_modules/handlebars/node_modules/uglify-js/README.md
generated
vendored
Normal file
588
node_modules/handlebars/node_modules/uglify-js/README.md
generated
vendored
Normal file
@@ -0,0 +1,588 @@
|
|||||||
|
UglifyJS 2
|
||||||
|
==========
|
||||||
|
[](https://travis-ci.org/mishoo/UglifyJS2)
|
||||||
|
|
||||||
|
UglifyJS is a JavaScript parser, minifier, compressor or beautifier toolkit.
|
||||||
|
|
||||||
|
This page documents the command line utility. For
|
||||||
|
[API and internals documentation see my website](http://lisperator.net/uglifyjs/).
|
||||||
|
There's also an
|
||||||
|
[in-browser online demo](http://lisperator.net/uglifyjs/#demo) (for Firefox,
|
||||||
|
Chrome and probably Safari).
|
||||||
|
|
||||||
|
Install
|
||||||
|
-------
|
||||||
|
|
||||||
|
First make sure you have installed the latest version of [node.js](http://nodejs.org/)
|
||||||
|
(You may need to restart your computer after this step).
|
||||||
|
|
||||||
|
From NPM for use as a command line app:
|
||||||
|
|
||||||
|
npm install uglify-js -g
|
||||||
|
|
||||||
|
From NPM for programmatic use:
|
||||||
|
|
||||||
|
npm install uglify-js
|
||||||
|
|
||||||
|
From Git:
|
||||||
|
|
||||||
|
git clone git://github.com/mishoo/UglifyJS2.git
|
||||||
|
cd UglifyJS2
|
||||||
|
npm link .
|
||||||
|
|
||||||
|
Usage
|
||||||
|
-----
|
||||||
|
|
||||||
|
uglifyjs [input files] [options]
|
||||||
|
|
||||||
|
UglifyJS2 can take multiple input files. It's recommended that you pass the
|
||||||
|
input files first, then pass the options. UglifyJS will parse input files
|
||||||
|
in sequence and apply any compression options. The files are parsed in the
|
||||||
|
same global scope, that is, a reference from a file to some
|
||||||
|
variable/function declared in another file will be matched properly.
|
||||||
|
|
||||||
|
If you want to read from STDIN instead, pass a single dash instead of input
|
||||||
|
files.
|
||||||
|
|
||||||
|
The available options are:
|
||||||
|
|
||||||
|
--source-map Specify an output file where to generate source map.
|
||||||
|
[string]
|
||||||
|
--source-map-root The path to the original source to be included in the
|
||||||
|
source map. [string]
|
||||||
|
--source-map-url The path to the source map to be added in //@
|
||||||
|
sourceMappingURL. Defaults to the value passed with
|
||||||
|
--source-map. [string]
|
||||||
|
--in-source-map Input source map, useful if you're compressing JS that was
|
||||||
|
generated from some other original code.
|
||||||
|
--screw-ie8 Pass this flag if you don't care about full compliance with
|
||||||
|
Internet Explorer 6-8 quirks (by default UglifyJS will try
|
||||||
|
to be IE-proof).
|
||||||
|
-p, --prefix Skip prefix for original filenames that appear in source
|
||||||
|
maps. For example -p 3 will drop 3 directories from file
|
||||||
|
names and ensure they are relative paths.
|
||||||
|
-o, --output Output file (default STDOUT).
|
||||||
|
-b, --beautify Beautify output/specify output options. [string]
|
||||||
|
-m, --mangle Mangle names/pass mangler options. [string]
|
||||||
|
-r, --reserved Reserved names to exclude from mangling.
|
||||||
|
-c, --compress Enable compressor/pass compressor options. Pass options
|
||||||
|
like -c hoist_vars=false,if_return=false. Use -c with no
|
||||||
|
argument to use the default compression options. [string]
|
||||||
|
-d, --define Global definitions [string]
|
||||||
|
--comments Preserve copyright comments in the output. By default this
|
||||||
|
works like Google Closure, keeping JSDoc-style comments
|
||||||
|
that contain "@license" or "@preserve". You can optionally
|
||||||
|
pass one of the following arguments to this flag:
|
||||||
|
- "all" to keep all comments
|
||||||
|
- a valid JS regexp (needs to start with a slash) to keep
|
||||||
|
only comments that match.
|
||||||
|
Note that currently not *all* comments can be kept when
|
||||||
|
compression is on, because of dead code removal or
|
||||||
|
cascading statements into sequences. [string]
|
||||||
|
--stats Display operations run time on STDERR. [boolean]
|
||||||
|
--acorn Use Acorn for parsing. [boolean]
|
||||||
|
--spidermonkey Assume input files are SpiderMonkey AST format (as JSON).
|
||||||
|
[boolean]
|
||||||
|
--self Build itself (UglifyJS2) as a library (implies
|
||||||
|
--wrap=UglifyJS --export-all) [boolean]
|
||||||
|
--wrap Embed everything in a big function, making the “exports”
|
||||||
|
and “global” variables available. You need to pass an
|
||||||
|
argument to this option to specify the name that your
|
||||||
|
module will take when included in, say, a browser.
|
||||||
|
[string]
|
||||||
|
--export-all Only used when --wrap, this tells UglifyJS to add code to
|
||||||
|
automatically export all globals. [boolean]
|
||||||
|
--lint Display some scope warnings [boolean]
|
||||||
|
-v, --verbose Verbose [boolean]
|
||||||
|
-V, --version Print version number and exit. [boolean]
|
||||||
|
|
||||||
|
Specify `--output` (`-o`) to declare the output file. Otherwise the output
|
||||||
|
goes to STDOUT.
|
||||||
|
|
||||||
|
## Source map options
|
||||||
|
|
||||||
|
UglifyJS2 can generate a source map file, which is highly useful for
|
||||||
|
debugging your compressed JavaScript. To get a source map, pass
|
||||||
|
`--source-map output.js.map` (full path to the file where you want the
|
||||||
|
source map dumped).
|
||||||
|
|
||||||
|
Additionally you might need `--source-map-root` to pass the URL where the
|
||||||
|
original files can be found. In case you are passing full paths to input
|
||||||
|
files to UglifyJS, you can use `--prefix` (`-p`) to specify the number of
|
||||||
|
directories to drop from the path prefix when declaring files in the source
|
||||||
|
map.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
uglifyjs /home/doe/work/foo/src/js/file1.js \
|
||||||
|
/home/doe/work/foo/src/js/file2.js \
|
||||||
|
-o foo.min.js \
|
||||||
|
--source-map foo.min.js.map \
|
||||||
|
--source-map-root http://foo.com/src \
|
||||||
|
-p 5 -c -m
|
||||||
|
|
||||||
|
The above will compress and mangle `file1.js` and `file2.js`, will drop the
|
||||||
|
output in `foo.min.js` and the source map in `foo.min.js.map`. The source
|
||||||
|
mapping will refer to `http://foo.com/src/js/file1.js` and
|
||||||
|
`http://foo.com/src/js/file2.js` (in fact it will list `http://foo.com/src`
|
||||||
|
as the source map root, and the original files as `js/file1.js` and
|
||||||
|
`js/file2.js`).
|
||||||
|
|
||||||
|
### Composed source map
|
||||||
|
|
||||||
|
When you're compressing JS code that was output by a compiler such as
|
||||||
|
CoffeeScript, mapping to the JS code won't be too helpful. Instead, you'd
|
||||||
|
like to map back to the original code (i.e. CoffeeScript). UglifyJS has an
|
||||||
|
option to take an input source map. Assuming you have a mapping from
|
||||||
|
CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript →
|
||||||
|
compressed JS by mapping every token in the compiled JS to its original
|
||||||
|
location.
|
||||||
|
|
||||||
|
To use this feature you need to pass `--in-source-map
|
||||||
|
/path/to/input/source.map`. Normally the input source map should also point
|
||||||
|
to the file containing the generated JS, so if that's correct you can omit
|
||||||
|
input files from the command line.
|
||||||
|
|
||||||
|
## Mangler options
|
||||||
|
|
||||||
|
To enable the mangler you need to pass `--mangle` (`-m`). The following
|
||||||
|
(comma-separated) options are supported:
|
||||||
|
|
||||||
|
- `sort` — to assign shorter names to most frequently used variables. This
|
||||||
|
saves a few hundred bytes on jQuery before gzip, but the output is
|
||||||
|
_bigger_ after gzip (and seems to happen for other libraries I tried it
|
||||||
|
on) therefore it's not enabled by default.
|
||||||
|
|
||||||
|
- `toplevel` — mangle names declared in the toplevel scope (disabled by
|
||||||
|
default).
|
||||||
|
|
||||||
|
- `eval` — mangle names visible in scopes where `eval` or `when` are used
|
||||||
|
(disabled by default).
|
||||||
|
|
||||||
|
When mangling is enabled but you want to prevent certain names from being
|
||||||
|
mangled, you can declare those names with `--reserved` (`-r`) — pass a
|
||||||
|
comma-separated list of names. For example:
|
||||||
|
|
||||||
|
uglifyjs ... -m -r '$,require,exports'
|
||||||
|
|
||||||
|
to prevent the `require`, `exports` and `$` names from being changed.
|
||||||
|
|
||||||
|
## Compressor options
|
||||||
|
|
||||||
|
You need to pass `--compress` (`-c`) to enable the compressor. Optionally
|
||||||
|
you can pass a comma-separated list of options. Options are in the form
|
||||||
|
`foo=bar`, or just `foo` (the latter implies a boolean option that you want
|
||||||
|
to set `true`; it's effectively a shortcut for `foo=true`).
|
||||||
|
|
||||||
|
- `sequences` -- join consecutive simple statements using the comma operator
|
||||||
|
- `properties` -- rewrite property access using the dot notation, for
|
||||||
|
example `foo["bar"] → foo.bar`
|
||||||
|
- `dead_code` -- remove unreachable code
|
||||||
|
- `drop_debugger` -- remove `debugger;` statements
|
||||||
|
- `unsafe` (default: false) -- apply "unsafe" transformations (discussion below)
|
||||||
|
- `conditionals` -- apply optimizations for `if`-s and conditional
|
||||||
|
expressions
|
||||||
|
- `comparisons` -- apply certain optimizations to binary nodes, for example:
|
||||||
|
`!(a <= b) → a > b` (only when `unsafe`), attempts to negate binary nodes,
|
||||||
|
e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
||||||
|
- `evaluate` -- attempt to evaluate constant expressions
|
||||||
|
- `booleans` -- various optimizations for boolean context, for example `!!a
|
||||||
|
? b : c → a ? b : c`
|
||||||
|
- `loops` -- optimizations for `do`, `while` and `for` loops when we can
|
||||||
|
statically determine the condition
|
||||||
|
- `unused` -- drop unreferenced functions and variables
|
||||||
|
- `hoist_funs` -- hoist function declarations
|
||||||
|
- `hoist_vars` (default: false) -- hoist `var` declarations (this is `false`
|
||||||
|
by default because it seems to increase the size of the output in general)
|
||||||
|
- `if_return` -- optimizations for if/return and if/continue
|
||||||
|
- `join_vars` -- join consecutive `var` statements
|
||||||
|
- `cascade` -- small optimization for sequences, transform `x, x` into `x`
|
||||||
|
and `x = something(), x` into `x = something()`
|
||||||
|
- `warnings` -- display warnings when dropping unreachable code or unused
|
||||||
|
declarations etc.
|
||||||
|
|
||||||
|
### The `unsafe` option
|
||||||
|
|
||||||
|
It enables some transformations that *might* break code logic in certain
|
||||||
|
contrived cases, but should be fine for most code. You might want to try it
|
||||||
|
on your own code, it should reduce the minified size. Here's what happens
|
||||||
|
when this flag is on:
|
||||||
|
|
||||||
|
- `new Array(1, 2, 3)` or `Array(1, 2, 3)` → `[1, 2, 3 ]`
|
||||||
|
- `new Object()` → `{}`
|
||||||
|
- `String(exp)` or `exp.toString()` → `"" + exp`
|
||||||
|
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
||||||
|
- `typeof foo == "undefined"` → `foo === void 0`
|
||||||
|
- `void 0` → `"undefined"` (if there is a variable named "undefined" in
|
||||||
|
scope; we do it because the variable name will be mangled, typically
|
||||||
|
reduced to a single character).
|
||||||
|
|
||||||
|
### Conditional compilation
|
||||||
|
|
||||||
|
You can use the `--define` (`-d`) switch in order to declare global
|
||||||
|
variables that UglifyJS will assume to be constants (unless defined in
|
||||||
|
scope). For example if you pass `--define DEBUG=false` then, coupled with
|
||||||
|
dead code removal UglifyJS will discard the following from the output:
|
||||||
|
```javascript
|
||||||
|
if (DEBUG) {
|
||||||
|
console.log("debug stuff");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
UglifyJS will warn about the condition being always false and about dropping
|
||||||
|
unreachable code; for now there is no option to turn off only this specific
|
||||||
|
warning, you can pass `warnings=false` to turn off *all* warnings.
|
||||||
|
|
||||||
|
Another way of doing that is to declare your globals as constants in a
|
||||||
|
separate file and include it into the build. For example you can have a
|
||||||
|
`build/defines.js` file with the following:
|
||||||
|
```javascript
|
||||||
|
const DEBUG = false;
|
||||||
|
const PRODUCTION = true;
|
||||||
|
// etc.
|
||||||
|
```
|
||||||
|
|
||||||
|
and build your code like this:
|
||||||
|
|
||||||
|
uglifyjs build/defines.js js/foo.js js/bar.js... -c
|
||||||
|
|
||||||
|
UglifyJS will notice the constants and, since they cannot be altered, it
|
||||||
|
will evaluate references to them to the value itself and drop unreachable
|
||||||
|
code as usual. The possible downside of this approach is that the build
|
||||||
|
will contain the `const` declarations.
|
||||||
|
|
||||||
|
<a name="codegen-options"></a>
|
||||||
|
## Beautifier options
|
||||||
|
|
||||||
|
The code generator tries to output shortest code possible by default. In
|
||||||
|
case you want beautified output, pass `--beautify` (`-b`). Optionally you
|
||||||
|
can pass additional arguments that control the code output:
|
||||||
|
|
||||||
|
- `beautify` (default `true`) -- whether to actually beautify the output.
|
||||||
|
Passing `-b` will set this to true, but you might need to pass `-b` even
|
||||||
|
when you want to generate minified code, in order to specify additional
|
||||||
|
arguments, so you can use `-b beautify=false` to override it.
|
||||||
|
- `indent-level` (default 4)
|
||||||
|
- `indent-start` (default 0) -- prefix all lines by that many spaces
|
||||||
|
- `quote-keys` (default `false`) -- pass `true` to quote all keys in literal
|
||||||
|
objects
|
||||||
|
- `space-colon` (default `true`) -- insert a space after the colon signs
|
||||||
|
- `ascii-only` (default `false`) -- escape Unicode characters in strings and
|
||||||
|
regexps
|
||||||
|
- `inline-script` (default `false`) -- escape the slash in occurrences of
|
||||||
|
`</script` in strings
|
||||||
|
- `width` (default 80) -- only takes effect when beautification is on, this
|
||||||
|
specifies an (orientative) line width that the beautifier will try to
|
||||||
|
obey. It refers to the width of the line text (excluding indentation).
|
||||||
|
It doesn't work very well currently, but it does make the code generated
|
||||||
|
by UglifyJS more readable.
|
||||||
|
- `max-line-len` (default 32000) -- maximum line length (for uglified code)
|
||||||
|
- `ie-proof` (default `true`) -- generate “IE-proof” code (for now this
|
||||||
|
means add brackets around the do/while in code like this: `if (foo) do
|
||||||
|
something(); while (bar); else ...`.
|
||||||
|
- `bracketize` (default `false`) -- always insert brackets in `if`, `for`,
|
||||||
|
`do`, `while` or `with` statements, even if their body is a single
|
||||||
|
statement.
|
||||||
|
- `semicolons` (default `true`) -- separate statements with semicolons. If
|
||||||
|
you pass `false` then whenever possible we will use a newline instead of a
|
||||||
|
semicolon, leading to more readable output of uglified code (size before
|
||||||
|
gzip could be smaller; size after gzip insignificantly larger).
|
||||||
|
- `negate-iife` (default `!beautify`) -- prefer negation, rather than
|
||||||
|
parens, for "Immediately-Called Function Expressions". This defaults to
|
||||||
|
`true` when beautification is off, and `false` if beautification is on;
|
||||||
|
pass it manually to force a value.
|
||||||
|
|
||||||
|
### Keeping copyright notices or other comments
|
||||||
|
|
||||||
|
You can pass `--comments` to retain certain comments in the output. By
|
||||||
|
default it will keep JSDoc-style comments that contain "@preserve",
|
||||||
|
"@license" or "@cc_on" (conditional compilation for IE). You can pass
|
||||||
|
`--comments all` to keep all the comments, or a valid JavaScript regexp to
|
||||||
|
keep only comments that match this regexp. For example `--comments
|
||||||
|
'/foo|bar/'` will keep only comments that contain "foo" or "bar".
|
||||||
|
|
||||||
|
Note, however, that there might be situations where comments are lost. For
|
||||||
|
example:
|
||||||
|
```javascript
|
||||||
|
function f() {
|
||||||
|
/** @preserve Foo Bar */
|
||||||
|
function g() {
|
||||||
|
// this function is never called
|
||||||
|
}
|
||||||
|
return something();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Even though it has "@preserve", the comment will be lost because the inner
|
||||||
|
function `g` (which is the AST node to which the comment is attached to) is
|
||||||
|
discarded by the compressor as not referenced.
|
||||||
|
|
||||||
|
The safest comments where to place copyright information (or other info that
|
||||||
|
needs to be kept in the output) are comments attached to toplevel nodes.
|
||||||
|
|
||||||
|
## Support for the SpiderMonkey AST
|
||||||
|
|
||||||
|
UglifyJS2 has its own abstract syntax tree format; for
|
||||||
|
[practical reasons](http://lisperator.net/blog/uglifyjs-why-not-switching-to-spidermonkey-ast/)
|
||||||
|
we can't easily change to using the SpiderMonkey AST internally. However,
|
||||||
|
UglifyJS now has a converter which can import a SpiderMonkey AST.
|
||||||
|
|
||||||
|
For example [Acorn][acorn] is a super-fast parser that produces a
|
||||||
|
SpiderMonkey AST. It has a small CLI utility that parses one file and dumps
|
||||||
|
the AST in JSON on the standard output. To use UglifyJS to mangle and
|
||||||
|
compress that:
|
||||||
|
|
||||||
|
acorn file.js | uglifyjs --spidermonkey -m -c
|
||||||
|
|
||||||
|
The `--spidermonkey` option tells UglifyJS that all input files are not
|
||||||
|
JavaScript, but JS code described in SpiderMonkey AST in JSON. Therefore we
|
||||||
|
don't use our own parser in this case, but just transform that AST into our
|
||||||
|
internal AST.
|
||||||
|
|
||||||
|
### Use Acorn for parsing
|
||||||
|
|
||||||
|
More for fun, I added the `--acorn` option which will use Acorn to do all
|
||||||
|
the parsing. If you pass this option, UglifyJS will `require("acorn")`.
|
||||||
|
|
||||||
|
Acorn is really fast (e.g. 250ms instead of 380ms on some 650K code), but
|
||||||
|
converting the SpiderMonkey tree that Acorn produces takes another 150ms so
|
||||||
|
in total it's a bit more than just using UglifyJS's own parser.
|
||||||
|
|
||||||
|
API Reference
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Assuming installation via NPM, you can load UglifyJS in your application
|
||||||
|
like this:
|
||||||
|
```javascript
|
||||||
|
var UglifyJS = require("uglify-js");
|
||||||
|
```
|
||||||
|
|
||||||
|
It exports a lot of names, but I'll discuss here the basics that are needed
|
||||||
|
for parsing, mangling and compressing a piece of code. The sequence is (1)
|
||||||
|
parse, (2) compress, (3) mangle, (4) generate output code.
|
||||||
|
|
||||||
|
### The simple way
|
||||||
|
|
||||||
|
There's a single toplevel function which combines all the steps. If you
|
||||||
|
don't need additional customization, you might want to go with `minify`.
|
||||||
|
Example:
|
||||||
|
```javascript
|
||||||
|
var result = UglifyJS.minify("/path/to/file.js");
|
||||||
|
console.log(result.code); // minified output
|
||||||
|
// if you need to pass code instead of file name
|
||||||
|
var result = UglifyJS.minify("var b = function () {};", {fromString: true});
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also compress multiple files:
|
||||||
|
```javascript
|
||||||
|
var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ]);
|
||||||
|
console.log(result.code);
|
||||||
|
```
|
||||||
|
|
||||||
|
To generate a source map:
|
||||||
|
```javascript
|
||||||
|
var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], {
|
||||||
|
outSourceMap: "out.js.map"
|
||||||
|
});
|
||||||
|
console.log(result.code); // minified output
|
||||||
|
console.log(result.map);
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that the source map is not saved in a file, it's just returned in
|
||||||
|
`result.map`. The value passed for `outSourceMap` is only used to set the
|
||||||
|
`file` attribute in the source map (see [the spec][sm-spec]).
|
||||||
|
|
||||||
|
You can also specify sourceRoot property to be included in source map:
|
||||||
|
```javascript
|
||||||
|
var result = UglifyJS.minify([ "file1.js", "file2.js", "file3.js" ], {
|
||||||
|
outSourceMap: "out.js.map",
|
||||||
|
sourceRoot: "http://example.com/src"
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
If you're compressing compiled JavaScript and have a source map for it, you
|
||||||
|
can use the `inSourceMap` argument:
|
||||||
|
```javascript
|
||||||
|
var result = UglifyJS.minify("compiled.js", {
|
||||||
|
inSourceMap: "compiled.js.map",
|
||||||
|
outSourceMap: "minified.js.map"
|
||||||
|
});
|
||||||
|
// same as before, it returns `code` and `map`
|
||||||
|
```
|
||||||
|
|
||||||
|
The `inSourceMap` is only used if you also request `outSourceMap` (it makes
|
||||||
|
no sense otherwise).
|
||||||
|
|
||||||
|
Other options:
|
||||||
|
|
||||||
|
- `warnings` (default `false`) — pass `true` to display compressor warnings.
|
||||||
|
|
||||||
|
- `fromString` (default `false`) — if you pass `true` then you can pass
|
||||||
|
JavaScript source code, rather than file names.
|
||||||
|
|
||||||
|
- `mangle` — pass `false` to skip mangling names.
|
||||||
|
|
||||||
|
- `output` (default `null`) — pass an object if you wish to specify
|
||||||
|
additional [output options][codegen]. The defaults are optimized
|
||||||
|
for best compression.
|
||||||
|
|
||||||
|
- `compress` (default `{}`) — pass `false` to skip compressing entirely.
|
||||||
|
Pass an object to specify custom [compressor options][compressor].
|
||||||
|
|
||||||
|
We could add more options to `UglifyJS.minify` — if you need additional
|
||||||
|
functionality please suggest!
|
||||||
|
|
||||||
|
### The hard way
|
||||||
|
|
||||||
|
Following there's more detailed API info, in case the `minify` function is
|
||||||
|
too simple for your needs.
|
||||||
|
|
||||||
|
#### The parser
|
||||||
|
```javascript
|
||||||
|
var toplevel_ast = UglifyJS.parse(code, options);
|
||||||
|
```
|
||||||
|
|
||||||
|
`options` is optional and if present it must be an object. The following
|
||||||
|
properties are available:
|
||||||
|
|
||||||
|
- `strict` — disable automatic semicolon insertion and support for trailing
|
||||||
|
comma in arrays and objects
|
||||||
|
- `filename` — the name of the file where this code is coming from
|
||||||
|
- `toplevel` — a `toplevel` node (as returned by a previous invocation of
|
||||||
|
`parse`)
|
||||||
|
|
||||||
|
The last two options are useful when you'd like to minify multiple files and
|
||||||
|
get a single file as the output and a proper source map. Our CLI tool does
|
||||||
|
something like this:
|
||||||
|
```javascript
|
||||||
|
var toplevel = null;
|
||||||
|
files.forEach(function(file){
|
||||||
|
var code = fs.readFileSync(file);
|
||||||
|
toplevel = UglifyJS.parse(code, {
|
||||||
|
filename: file,
|
||||||
|
toplevel: toplevel
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
After this, we have in `toplevel` a big AST containing all our files, with
|
||||||
|
each token having proper information about where it came from.
|
||||||
|
|
||||||
|
#### Scope information
|
||||||
|
|
||||||
|
UglifyJS contains a scope analyzer that you need to call manually before
|
||||||
|
compressing or mangling. Basically it augments various nodes in the AST
|
||||||
|
with information about where is a name defined, how many times is a name
|
||||||
|
referenced, if it is a global or not, if a function is using `eval` or the
|
||||||
|
`with` statement etc. I will discuss this some place else, for now what's
|
||||||
|
important to know is that you need to call the following before doing
|
||||||
|
anything with the tree:
|
||||||
|
```javascript
|
||||||
|
toplevel.figure_out_scope()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Compression
|
||||||
|
|
||||||
|
Like this:
|
||||||
|
```javascript
|
||||||
|
var compressor = UglifyJS.Compressor(options);
|
||||||
|
var compressed_ast = toplevel.transform(compressor);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `options` can be missing. Available options are discussed above in
|
||||||
|
“Compressor options”. Defaults should lead to best compression in most
|
||||||
|
scripts.
|
||||||
|
|
||||||
|
The compressor is destructive, so don't rely that `toplevel` remains the
|
||||||
|
original tree.
|
||||||
|
|
||||||
|
#### Mangling
|
||||||
|
|
||||||
|
After compression it is a good idea to call again `figure_out_scope` (since
|
||||||
|
the compressor might drop unused variables / unreachable code and this might
|
||||||
|
change the number of identifiers or their position). Optionally, you can
|
||||||
|
call a trick that helps after Gzip (counting character frequency in
|
||||||
|
non-mangleable words). Example:
|
||||||
|
```javascript
|
||||||
|
compressed_ast.figure_out_scope();
|
||||||
|
compressed_ast.compute_char_frequency();
|
||||||
|
compressed_ast.mangle_names();
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Generating output
|
||||||
|
|
||||||
|
AST nodes have a `print` method that takes an output stream. Essentially,
|
||||||
|
to generate code you do this:
|
||||||
|
```javascript
|
||||||
|
var stream = UglifyJS.OutputStream(options);
|
||||||
|
compressed_ast.print(stream);
|
||||||
|
var code = stream.toString(); // this is your minified code
|
||||||
|
```
|
||||||
|
|
||||||
|
or, for a shortcut you can do:
|
||||||
|
```javascript
|
||||||
|
var code = compressed_ast.print_to_string(options);
|
||||||
|
```
|
||||||
|
|
||||||
|
As usual, `options` is optional. The output stream accepts a lot of otions,
|
||||||
|
most of them documented above in section “Beautifier options”. The two
|
||||||
|
which we care about here are `source_map` and `comments`.
|
||||||
|
|
||||||
|
#### Keeping comments in the output
|
||||||
|
|
||||||
|
In order to keep certain comments in the output you need to pass the
|
||||||
|
`comments` option. Pass a RegExp or a function. If you pass a RegExp, only
|
||||||
|
those comments whose body matches the regexp will be kept. Note that body
|
||||||
|
means without the initial `//` or `/*`. If you pass a function, it will be
|
||||||
|
called for every comment in the tree and will receive two arguments: the
|
||||||
|
node that the comment is attached to, and the comment token itself.
|
||||||
|
|
||||||
|
The comment token has these properties:
|
||||||
|
|
||||||
|
- `type`: "comment1" for single-line comments or "comment2" for multi-line
|
||||||
|
comments
|
||||||
|
- `value`: the comment body
|
||||||
|
- `pos` and `endpos`: the start/end positions (zero-based indexes) in the
|
||||||
|
original code where this comment appears
|
||||||
|
- `line` and `col`: the line and column where this comment appears in the
|
||||||
|
original code
|
||||||
|
- `file` — the file name of the original file
|
||||||
|
- `nlb` — true if there was a newline before this comment in the original
|
||||||
|
code, or if this comment contains a newline.
|
||||||
|
|
||||||
|
Your function should return `true` to keep the comment, or a falsy value
|
||||||
|
otherwise.
|
||||||
|
|
||||||
|
#### Generating a source mapping
|
||||||
|
|
||||||
|
You need to pass the `source_map` argument when calling `print`. It needs
|
||||||
|
to be a `SourceMap` object (which is a thin wrapper on top of the
|
||||||
|
[source-map][source-map] library).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```javascript
|
||||||
|
var source_map = UglifyJS.SourceMap(source_map_options);
|
||||||
|
var stream = UglifyJS.OutputStream({
|
||||||
|
...
|
||||||
|
source_map: source_map
|
||||||
|
});
|
||||||
|
compressed_ast.print(stream);
|
||||||
|
|
||||||
|
var code = stream.toString();
|
||||||
|
var map = source_map.toString(); // json output for your source map
|
||||||
|
```
|
||||||
|
|
||||||
|
The `source_map_options` (optional) can contain the following properties:
|
||||||
|
|
||||||
|
- `file`: the name of the JavaScript output file that this mapping refers to
|
||||||
|
- `root`: the `sourceRoot` property (see the [spec][sm-spec])
|
||||||
|
- `orig`: the "original source map", handy when you compress generated JS
|
||||||
|
and want to map the minified output back to the original code where it
|
||||||
|
came from. It can be simply a string in JSON, or a JSON object containing
|
||||||
|
the original source map.
|
||||||
|
|
||||||
|
[acorn]: https://github.com/marijnh/acorn
|
||||||
|
[source-map]: https://github.com/mozilla/source-map
|
||||||
|
[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
|
||||||
|
[codegen]: http://lisperator.net/uglifyjs/codegen
|
||||||
|
[compressor]: http://lisperator.net/uglifyjs/compress
|
||||||
578
node_modules/handlebars/node_modules/uglify-js/README.org
generated
vendored
578
node_modules/handlebars/node_modules/uglify-js/README.org
generated
vendored
@@ -1,578 +0,0 @@
|
|||||||
#+TITLE: UglifyJS -- a JavaScript parser/compressor/beautifier
|
|
||||||
#+KEYWORDS: javascript, js, parser, compiler, compressor, mangle, minify, minifier
|
|
||||||
#+DESCRIPTION: a JavaScript parser/compressor/beautifier in JavaScript
|
|
||||||
#+STYLE: <link rel="stylesheet" type="text/css" href="docstyle.css" />
|
|
||||||
#+AUTHOR: Mihai Bazon
|
|
||||||
#+EMAIL: mihai.bazon@gmail.com
|
|
||||||
|
|
||||||
* UglifyJS --- a JavaScript parser/compressor/beautifier
|
|
||||||
|
|
||||||
This package implements a general-purpose JavaScript
|
|
||||||
parser/compressor/beautifier toolkit. It is developed on [[http://nodejs.org/][NodeJS]], but it
|
|
||||||
should work on any JavaScript platform supporting the CommonJS module system
|
|
||||||
(and if your platform of choice doesn't support CommonJS, you can easily
|
|
||||||
implement it, or discard the =exports.*= lines from UglifyJS sources).
|
|
||||||
|
|
||||||
The tokenizer/parser generates an abstract syntax tree from JS code. You
|
|
||||||
can then traverse the AST to learn more about the code, or do various
|
|
||||||
manipulations on it. This part is implemented in [[../lib/parse-js.js][parse-js.js]] and it's a
|
|
||||||
port to JavaScript of the excellent [[http://marijn.haverbeke.nl/parse-js/][parse-js]] Common Lisp library from [[http://marijn.haverbeke.nl/][Marijn
|
|
||||||
Haverbeke]].
|
|
||||||
|
|
||||||
( See [[http://github.com/mishoo/cl-uglify-js][cl-uglify-js]] if you're looking for the Common Lisp version of
|
|
||||||
UglifyJS. )
|
|
||||||
|
|
||||||
The second part of this package, implemented in [[../lib/process.js][process.js]], inspects and
|
|
||||||
manipulates the AST generated by the parser to provide the following:
|
|
||||||
|
|
||||||
- ability to re-generate JavaScript code from the AST. Optionally
|
|
||||||
indented---you can use this if you want to “beautify” a program that has
|
|
||||||
been compressed, so that you can inspect the source. But you can also run
|
|
||||||
our code generator to print out an AST without any whitespace, so you
|
|
||||||
achieve compression as well.
|
|
||||||
|
|
||||||
- shorten variable names (usually to single characters). Our mangler will
|
|
||||||
analyze the code and generate proper variable names, depending on scope
|
|
||||||
and usage, and is smart enough to deal with globals defined elsewhere, or
|
|
||||||
with =eval()= calls or =with{}= statements. In short, if =eval()= or
|
|
||||||
=with{}= are used in some scope, then all variables in that scope and any
|
|
||||||
variables in the parent scopes will remain unmangled, and any references
|
|
||||||
to such variables remain unmangled as well.
|
|
||||||
|
|
||||||
- various small optimizations that may lead to faster code but certainly
|
|
||||||
lead to smaller code. Where possible, we do the following:
|
|
||||||
|
|
||||||
- foo["bar"] ==> foo.bar
|
|
||||||
|
|
||||||
- remove block brackets ={}=
|
|
||||||
|
|
||||||
- join consecutive var declarations:
|
|
||||||
var a = 10; var b = 20; ==> var a=10,b=20;
|
|
||||||
|
|
||||||
- resolve simple constant expressions: 1 +2 * 3 ==> 7. We only do the
|
|
||||||
replacement if the result occupies less bytes; for example 1/3 would
|
|
||||||
translate to 0.333333333333, so in this case we don't replace it.
|
|
||||||
|
|
||||||
- consecutive statements in blocks are merged into a sequence; in many
|
|
||||||
cases, this leaves blocks with a single statement, so then we can remove
|
|
||||||
the block brackets.
|
|
||||||
|
|
||||||
- various optimizations for IF statements:
|
|
||||||
|
|
||||||
- if (foo) bar(); else baz(); ==> foo?bar():baz();
|
|
||||||
- if (!foo) bar(); else baz(); ==> foo?baz():bar();
|
|
||||||
- if (foo) bar(); ==> foo&&bar();
|
|
||||||
- if (!foo) bar(); ==> foo||bar();
|
|
||||||
- if (foo) return bar(); else return baz(); ==> return foo?bar():baz();
|
|
||||||
- if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
|
|
||||||
|
|
||||||
- remove some unreachable code and warn about it (code that follows a
|
|
||||||
=return=, =throw=, =break= or =continue= statement, except
|
|
||||||
function/variable declarations).
|
|
||||||
|
|
||||||
- act a limited version of a pre-processor (c.f. the pre-processor of
|
|
||||||
C/C++) to allow you to safely replace selected global symbols with
|
|
||||||
specified values. When combined with the optimisations above this can
|
|
||||||
make UglifyJS operate slightly more like a compilation process, in
|
|
||||||
that when certain symbols are replaced by constant values, entire code
|
|
||||||
blocks may be optimised away as unreachable.
|
|
||||||
|
|
||||||
** <<Unsafe transformations>>
|
|
||||||
|
|
||||||
The following transformations can in theory break code, although they're
|
|
||||||
probably safe in most practical cases. To enable them you need to pass the
|
|
||||||
=--unsafe= flag.
|
|
||||||
|
|
||||||
*** Calls involving the global Array constructor
|
|
||||||
|
|
||||||
The following transformations occur:
|
|
||||||
|
|
||||||
#+BEGIN_SRC js
|
|
||||||
new Array(1, 2, 3, 4) => [1,2,3,4]
|
|
||||||
Array(a, b, c) => [a,b,c]
|
|
||||||
new Array(5) => Array(5)
|
|
||||||
new Array(a) => Array(a)
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
These are all safe if the Array name isn't redefined. JavaScript does allow
|
|
||||||
one to globally redefine Array (and pretty much everything, in fact) but I
|
|
||||||
personally don't see why would anyone do that.
|
|
||||||
|
|
||||||
UglifyJS does handle the case where Array is redefined locally, or even
|
|
||||||
globally but with a =function= or =var= declaration. Therefore, in the
|
|
||||||
following cases UglifyJS *doesn't touch* calls or instantiations of Array:
|
|
||||||
|
|
||||||
#+BEGIN_SRC js
|
|
||||||
// case 1. globally declared variable
|
|
||||||
var Array;
|
|
||||||
new Array(1, 2, 3);
|
|
||||||
Array(a, b);
|
|
||||||
|
|
||||||
// or (can be declared later)
|
|
||||||
new Array(1, 2, 3);
|
|
||||||
var Array;
|
|
||||||
|
|
||||||
// or (can be a function)
|
|
||||||
new Array(1, 2, 3);
|
|
||||||
function Array() { ... }
|
|
||||||
|
|
||||||
// case 2. declared in a function
|
|
||||||
(function(){
|
|
||||||
a = new Array(1, 2, 3);
|
|
||||||
b = Array(5, 6);
|
|
||||||
var Array;
|
|
||||||
})();
|
|
||||||
|
|
||||||
// or
|
|
||||||
(function(Array){
|
|
||||||
return Array(5, 6, 7);
|
|
||||||
})();
|
|
||||||
|
|
||||||
// or
|
|
||||||
(function(){
|
|
||||||
return new Array(1, 2, 3, 4);
|
|
||||||
function Array() { ... }
|
|
||||||
})();
|
|
||||||
|
|
||||||
// etc.
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
*** =obj.toString()= ==> =obj+“”=
|
|
||||||
|
|
||||||
** Install (NPM)
|
|
||||||
|
|
||||||
UglifyJS is now available through NPM --- =npm install uglify-js= should do
|
|
||||||
the job.
|
|
||||||
|
|
||||||
** Install latest code from GitHub
|
|
||||||
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
## clone the repository
|
|
||||||
mkdir -p /where/you/wanna/put/it
|
|
||||||
cd /where/you/wanna/put/it
|
|
||||||
git clone git://github.com/mishoo/UglifyJS.git
|
|
||||||
|
|
||||||
## make the module available to Node
|
|
||||||
mkdir -p ~/.node_libraries/
|
|
||||||
cd ~/.node_libraries/
|
|
||||||
ln -s /where/you/wanna/put/it/UglifyJS/uglify-js.js
|
|
||||||
|
|
||||||
## and if you want the CLI script too:
|
|
||||||
mkdir -p ~/bin
|
|
||||||
cd ~/bin
|
|
||||||
ln -s /where/you/wanna/put/it/UglifyJS/bin/uglifyjs
|
|
||||||
# (then add ~/bin to your $PATH if it's not there already)
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
** Usage
|
|
||||||
|
|
||||||
There is a command-line tool that exposes the functionality of this library
|
|
||||||
for your shell-scripting needs:
|
|
||||||
|
|
||||||
#+BEGIN_SRC sh
|
|
||||||
uglifyjs [ options... ] [ filename ]
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
=filename= should be the last argument and should name the file from which
|
|
||||||
to read the JavaScript code. If you don't specify it, it will read code
|
|
||||||
from STDIN.
|
|
||||||
|
|
||||||
Supported options:
|
|
||||||
|
|
||||||
- =-b= or =--beautify= --- output indented code; when passed, additional
|
|
||||||
options control the beautifier:
|
|
||||||
|
|
||||||
- =-i N= or =--indent N= --- indentation level (number of spaces)
|
|
||||||
|
|
||||||
- =-q= or =--quote-keys= --- quote keys in literal objects (by default,
|
|
||||||
only keys that cannot be identifier names will be quotes).
|
|
||||||
|
|
||||||
- =-c= or =----consolidate-primitive-values= --- consolidates null, Boolean,
|
|
||||||
and String values. Known as aliasing in the Closure Compiler. Worsens the
|
|
||||||
data compression ratio of gzip.
|
|
||||||
|
|
||||||
- =--ascii= --- pass this argument to encode non-ASCII characters as
|
|
||||||
=\uXXXX= sequences. By default UglifyJS won't bother to do it and will
|
|
||||||
output Unicode characters instead. (the output is always encoded in UTF8,
|
|
||||||
but if you pass this option you'll only get ASCII).
|
|
||||||
|
|
||||||
- =-nm= or =--no-mangle= --- don't mangle names.
|
|
||||||
|
|
||||||
- =-nmf= or =--no-mangle-functions= -- in case you want to mangle variable
|
|
||||||
names, but not touch function names.
|
|
||||||
|
|
||||||
- =-ns= or =--no-squeeze= --- don't call =ast_squeeze()= (which does various
|
|
||||||
optimizations that result in smaller, less readable code).
|
|
||||||
|
|
||||||
- =-mt= or =--mangle-toplevel= --- mangle names in the toplevel scope too
|
|
||||||
(by default we don't do this).
|
|
||||||
|
|
||||||
- =--no-seqs= --- when =ast_squeeze()= is called (thus, unless you pass
|
|
||||||
=--no-squeeze=) it will reduce consecutive statements in blocks into a
|
|
||||||
sequence. For example, "a = 10; b = 20; foo();" will be written as
|
|
||||||
"a=10,b=20,foo();". In various occasions, this allows us to discard the
|
|
||||||
block brackets (since the block becomes a single statement). This is ON
|
|
||||||
by default because it seems safe and saves a few hundred bytes on some
|
|
||||||
libs that I tested it on, but pass =--no-seqs= to disable it.
|
|
||||||
|
|
||||||
- =--no-dead-code= --- by default, UglifyJS will remove code that is
|
|
||||||
obviously unreachable (code that follows a =return=, =throw=, =break= or
|
|
||||||
=continue= statement and is not a function/variable declaration). Pass
|
|
||||||
this option to disable this optimization.
|
|
||||||
|
|
||||||
- =-nc= or =--no-copyright= --- by default, =uglifyjs= will keep the initial
|
|
||||||
comment tokens in the generated code (assumed to be copyright information
|
|
||||||
etc.). If you pass this it will discard it.
|
|
||||||
|
|
||||||
- =-o filename= or =--output filename= --- put the result in =filename=. If
|
|
||||||
this isn't given, the result goes to standard output (or see next one).
|
|
||||||
|
|
||||||
- =--overwrite= --- if the code is read from a file (not from STDIN) and you
|
|
||||||
pass =--overwrite= then the output will be written in the same file.
|
|
||||||
|
|
||||||
- =--ast= --- pass this if you want to get the Abstract Syntax Tree instead
|
|
||||||
of JavaScript as output. Useful for debugging or learning more about the
|
|
||||||
internals.
|
|
||||||
|
|
||||||
- =-v= or =--verbose= --- output some notes on STDERR (for now just how long
|
|
||||||
each operation takes).
|
|
||||||
|
|
||||||
- =-d SYMBOL[=VALUE]= or =--define SYMBOL[=VALUE]= --- will replace
|
|
||||||
all instances of the specified symbol where used as an identifier
|
|
||||||
(except where symbol has properly declared by a var declaration or
|
|
||||||
use as function parameter or similar) with the specified value. This
|
|
||||||
argument may be specified multiple times to define multiple
|
|
||||||
symbols - if no value is specified the symbol will be replaced with
|
|
||||||
the value =true=, or you can specify a numeric value (such as
|
|
||||||
=1024=), a quoted string value (such as ="object"= or
|
|
||||||
='https://github.com'=), or the name of another symbol or keyword
|
|
||||||
(such as =null= or =document=).
|
|
||||||
This allows you, for example, to assign meaningful names to key
|
|
||||||
constant values but discard the symbolic names in the uglified
|
|
||||||
version for brevity/efficiency, or when used wth care, allows
|
|
||||||
UglifyJS to operate as a form of *conditional compilation*
|
|
||||||
whereby defining appropriate values may, by dint of the constant
|
|
||||||
folding and dead code removal features above, remove entire
|
|
||||||
superfluous code blocks (e.g. completely remove instrumentation or
|
|
||||||
trace code for production use).
|
|
||||||
Where string values are being defined, the handling of quotes are
|
|
||||||
likely to be subject to the specifics of your command shell
|
|
||||||
environment, so you may need to experiment with quoting styles
|
|
||||||
depending on your platform, or you may find the option
|
|
||||||
=--define-from-module= more suitable for use.
|
|
||||||
|
|
||||||
- =-define-from-module SOMEMODULE= --- will load the named module (as
|
|
||||||
per the NodeJS =require()= function) and iterate all the exported
|
|
||||||
properties of the module defining them as symbol names to be defined
|
|
||||||
(as if by the =--define= option) per the name of each property
|
|
||||||
(i.e. without the module name prefix) and given the value of the
|
|
||||||
property. This is a much easier way to handle and document groups of
|
|
||||||
symbols to be defined rather than a large number of =--define=
|
|
||||||
options.
|
|
||||||
|
|
||||||
- =--unsafe= --- enable other additional optimizations that are known to be
|
|
||||||
unsafe in some contrived situations, but could still be generally useful.
|
|
||||||
For now only these:
|
|
||||||
|
|
||||||
- foo.toString() ==> foo+""
|
|
||||||
- new Array(x,...) ==> [x,...]
|
|
||||||
- new Array(x) ==> Array(x)
|
|
||||||
|
|
||||||
- =--max-line-len= (default 32K characters) --- add a newline after around
|
|
||||||
32K characters. I've seen both FF and Chrome croak when all the code was
|
|
||||||
on a single line of around 670K. Pass --max-line-len 0 to disable this
|
|
||||||
safety feature.
|
|
||||||
|
|
||||||
- =--reserved-names= --- some libraries rely on certain names to be used, as
|
|
||||||
pointed out in issue #92 and #81, so this option allow you to exclude such
|
|
||||||
names from the mangler. For example, to keep names =require= and =$super=
|
|
||||||
intact you'd specify --reserved-names "require,$super".
|
|
||||||
|
|
||||||
- =--inline-script= -- when you want to include the output literally in an
|
|
||||||
HTML =<script>= tag you can use this option to prevent =</script= from
|
|
||||||
showing up in the output.
|
|
||||||
|
|
||||||
- =--lift-vars= -- when you pass this, UglifyJS will apply the following
|
|
||||||
transformations (see the notes in API, =ast_lift_variables=):
|
|
||||||
|
|
||||||
- put all =var= declarations at the start of the scope
|
|
||||||
- make sure a variable is declared only once
|
|
||||||
- discard unused function arguments
|
|
||||||
- discard unused inner (named) functions
|
|
||||||
- finally, try to merge assignments into that one =var= declaration, if
|
|
||||||
possible.
|
|
||||||
|
|
||||||
*** API
|
|
||||||
|
|
||||||
To use the library from JavaScript, you'd do the following (example for
|
|
||||||
NodeJS):
|
|
||||||
|
|
||||||
#+BEGIN_SRC js
|
|
||||||
var jsp = require("uglify-js").parser;
|
|
||||||
var pro = require("uglify-js").uglify;
|
|
||||||
|
|
||||||
var orig_code = "... JS code here";
|
|
||||||
var ast = jsp.parse(orig_code); // parse code and get the initial AST
|
|
||||||
ast = pro.ast_mangle(ast); // get a new AST with mangled names
|
|
||||||
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
|
|
||||||
var final_code = pro.gen_code(ast); // compressed code here
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
The above performs the full compression that is possible right now. As you
|
|
||||||
can see, there are a sequence of steps which you can apply. For example if
|
|
||||||
you want compressed output but for some reason you don't want to mangle
|
|
||||||
variable names, you would simply skip the line that calls
|
|
||||||
=pro.ast_mangle(ast)=.
|
|
||||||
|
|
||||||
Some of these functions take optional arguments. Here's a description:
|
|
||||||
|
|
||||||
- =jsp.parse(code, strict_semicolons)= -- parses JS code and returns an AST.
|
|
||||||
=strict_semicolons= is optional and defaults to =false=. If you pass
|
|
||||||
=true= then the parser will throw an error when it expects a semicolon and
|
|
||||||
it doesn't find it. For most JS code you don't want that, but it's useful
|
|
||||||
if you want to strictly sanitize your code.
|
|
||||||
|
|
||||||
- =pro.ast_lift_variables(ast)= -- merge and move =var= declarations to the
|
|
||||||
scop of the scope; discard unused function arguments or variables; discard
|
|
||||||
unused (named) inner functions. It also tries to merge assignments
|
|
||||||
following the =var= declaration into it.
|
|
||||||
|
|
||||||
If your code is very hand-optimized concerning =var= declarations, this
|
|
||||||
lifting variable declarations might actually increase size. For me it
|
|
||||||
helps out. On jQuery it adds 865 bytes (243 after gzip). YMMV. Also
|
|
||||||
note that (since it's not enabled by default) this operation isn't yet
|
|
||||||
heavily tested (please report if you find issues!).
|
|
||||||
|
|
||||||
Note that although it might increase the image size (on jQuery it gains
|
|
||||||
865 bytes, 243 after gzip) it's technically more correct: in certain
|
|
||||||
situations, dead code removal might drop variable declarations, which
|
|
||||||
would not happen if the variables are lifted in advance.
|
|
||||||
|
|
||||||
Here's an example of what it does:
|
|
||||||
|
|
||||||
#+BEGIN_SRC js
|
|
||||||
function f(a, b, c, d, e) {
|
|
||||||
var q;
|
|
||||||
var w;
|
|
||||||
w = 10;
|
|
||||||
q = 20;
|
|
||||||
for (var i = 1; i < 10; ++i) {
|
|
||||||
var boo = foo(a);
|
|
||||||
}
|
|
||||||
for (var i = 0; i < 1; ++i) {
|
|
||||||
var boo = bar(c);
|
|
||||||
}
|
|
||||||
function foo(){ ... }
|
|
||||||
function bar(){ ... }
|
|
||||||
function baz(){ ... }
|
|
||||||
}
|
|
||||||
|
|
||||||
// transforms into ==>
|
|
||||||
|
|
||||||
function f(a, b, c) {
|
|
||||||
var i, boo, w = 10, q = 20;
|
|
||||||
for (i = 1; i < 10; ++i) {
|
|
||||||
boo = foo(a);
|
|
||||||
}
|
|
||||||
for (i = 0; i < 1; ++i) {
|
|
||||||
boo = bar(c);
|
|
||||||
}
|
|
||||||
function foo() { ... }
|
|
||||||
function bar() { ... }
|
|
||||||
}
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
- =pro.ast_mangle(ast, options)= -- generates a new AST containing mangled
|
|
||||||
(compressed) variable and function names. It supports the following
|
|
||||||
options:
|
|
||||||
|
|
||||||
- =toplevel= -- mangle toplevel names (by default we don't touch them).
|
|
||||||
- =except= -- an array of names to exclude from compression.
|
|
||||||
- =defines= -- an object with properties named after symbols to
|
|
||||||
replace (see the =--define= option for the script) and the values
|
|
||||||
representing the AST replacement value.
|
|
||||||
|
|
||||||
- =pro.ast_squeeze(ast, options)= -- employs further optimizations designed
|
|
||||||
to reduce the size of the code that =gen_code= would generate from the
|
|
||||||
AST. Returns a new AST. =options= can be a hash; the supported options
|
|
||||||
are:
|
|
||||||
|
|
||||||
- =make_seqs= (default true) which will cause consecutive statements in a
|
|
||||||
block to be merged using the "sequence" (comma) operator
|
|
||||||
|
|
||||||
- =dead_code= (default true) which will remove unreachable code.
|
|
||||||
|
|
||||||
- =pro.gen_code(ast, options)= -- generates JS code from the AST. By
|
|
||||||
default it's minified, but using the =options= argument you can get nicely
|
|
||||||
formatted output. =options= is, well, optional :-) and if you pass it it
|
|
||||||
must be an object and supports the following properties (below you can see
|
|
||||||
the default values):
|
|
||||||
|
|
||||||
- =beautify: false= -- pass =true= if you want indented output
|
|
||||||
- =indent_start: 0= (only applies when =beautify= is =true=) -- initial
|
|
||||||
indentation in spaces
|
|
||||||
- =indent_level: 4= (only applies when =beautify= is =true=) --
|
|
||||||
indentation level, in spaces (pass an even number)
|
|
||||||
- =quote_keys: false= -- if you pass =true= it will quote all keys in
|
|
||||||
literal objects
|
|
||||||
- =space_colon: false= (only applies when =beautify= is =true=) -- wether
|
|
||||||
to put a space before the colon in object literals
|
|
||||||
- =ascii_only: false= -- pass =true= if you want to encode non-ASCII
|
|
||||||
characters as =\uXXXX=.
|
|
||||||
- =inline_script: false= -- pass =true= to escape occurrences of
|
|
||||||
=</script= in strings
|
|
||||||
|
|
||||||
*** Beautifier shortcoming -- no more comments
|
|
||||||
|
|
||||||
The beautifier can be used as a general purpose indentation tool. It's
|
|
||||||
useful when you want to make a minified file readable. One limitation,
|
|
||||||
though, is that it discards all comments, so you don't really want to use it
|
|
||||||
to reformat your code, unless you don't have, or don't care about, comments.
|
|
||||||
|
|
||||||
In fact it's not the beautifier who discards comments --- they are dumped at
|
|
||||||
the parsing stage, when we build the initial AST. Comments don't really
|
|
||||||
make sense in the AST, and while we could add nodes for them, it would be
|
|
||||||
inconvenient because we'd have to add special rules to ignore them at all
|
|
||||||
the processing stages.
|
|
||||||
|
|
||||||
*** Use as a code pre-processor
|
|
||||||
|
|
||||||
The =--define= option can be used, particularly when combined with the
|
|
||||||
constant folding logic, as a form of pre-processor to enable or remove
|
|
||||||
particular constructions, such as might be used for instrumenting
|
|
||||||
development code, or to produce variations aimed at a specific
|
|
||||||
platform.
|
|
||||||
|
|
||||||
The code below illustrates the way this can be done, and how the
|
|
||||||
symbol replacement is performed.
|
|
||||||
|
|
||||||
#+BEGIN_SRC js
|
|
||||||
CLAUSE1: if (typeof DEVMODE === 'undefined') {
|
|
||||||
DEVMODE = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLAUSE2: function init() {
|
|
||||||
if (DEVMODE) {
|
|
||||||
console.log("init() called");
|
|
||||||
}
|
|
||||||
....
|
|
||||||
DEVMODE && console.log("init() complete");
|
|
||||||
}
|
|
||||||
|
|
||||||
CLAUSE3: function reportDeviceStatus(device) {
|
|
||||||
var DEVMODE = device.mode, DEVNAME = device.name;
|
|
||||||
if (DEVMODE === 'open') {
|
|
||||||
....
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#+END_SRC
|
|
||||||
|
|
||||||
When the above code is normally executed, the undeclared global
|
|
||||||
variable =DEVMODE= will be assigned the value *true* (see =CLAUSE1=)
|
|
||||||
and so the =init()= function (=CLAUSE2=) will write messages to the
|
|
||||||
console log when executed, but in =CLAUSE3= a locally declared
|
|
||||||
variable will mask access to the =DEVMODE= global symbol.
|
|
||||||
|
|
||||||
If the above code is processed by UglifyJS with an argument of
|
|
||||||
=--define DEVMODE=false= then UglifyJS will replace =DEVMODE= with the
|
|
||||||
boolean constant value *false* within =CLAUSE1= and =CLAUSE2=, but it
|
|
||||||
will leave =CLAUSE3= as it stands because there =DEVMODE= resolves to
|
|
||||||
a validly declared variable.
|
|
||||||
|
|
||||||
And more so, the constant-folding features of UglifyJS will recognise
|
|
||||||
that the =if= condition of =CLAUSE1= is thus always false, and so will
|
|
||||||
remove the test and body of =CLAUSE1= altogether (including the
|
|
||||||
otherwise slightly problematical statement =false = true;= which it
|
|
||||||
will have formed by replacing =DEVMODE= in the body). Similarly,
|
|
||||||
within =CLAUSE2= both calls to =console.log()= will be removed
|
|
||||||
altogether.
|
|
||||||
|
|
||||||
In this way you can mimic, to a limited degree, the functionality of
|
|
||||||
the C/C++ pre-processor to enable or completely remove blocks
|
|
||||||
depending on how certain symbols are defined - perhaps using UglifyJS
|
|
||||||
to generate different versions of source aimed at different
|
|
||||||
environments
|
|
||||||
|
|
||||||
It is recommmended (but not made mandatory) that symbols designed for
|
|
||||||
this purpose are given names consisting of =UPPER_CASE_LETTERS= to
|
|
||||||
distinguish them from other (normal) symbols and avoid the sort of
|
|
||||||
clash that =CLAUSE3= above illustrates.
|
|
||||||
|
|
||||||
** Compression -- how good is it?
|
|
||||||
|
|
||||||
Here are updated statistics. (I also updated my Google Closure and YUI
|
|
||||||
installations).
|
|
||||||
|
|
||||||
We're still a lot better than YUI in terms of compression, though slightly
|
|
||||||
slower. We're still a lot faster than Closure, and compression after gzip
|
|
||||||
is comparable.
|
|
||||||
|
|
||||||
| File | UglifyJS | UglifyJS+gzip | Closure | Closure+gzip | YUI | YUI+gzip |
|
|
||||||
|-----------------------------+------------------+---------------+------------------+--------------+------------------+----------|
|
|
||||||
| jquery-1.6.2.js | 91001 (0:01.59) | 31896 | 90678 (0:07.40) | 31979 | 101527 (0:01.82) | 34646 |
|
|
||||||
| paper.js | 142023 (0:01.65) | 43334 | 134301 (0:07.42) | 42495 | 173383 (0:01.58) | 48785 |
|
|
||||||
| prototype.js | 88544 (0:01.09) | 26680 | 86955 (0:06.97) | 26326 | 92130 (0:00.79) | 28624 |
|
|
||||||
| thelib-full.js (DynarchLIB) | 251939 (0:02.55) | 72535 | 249911 (0:09.05) | 72696 | 258869 (0:01.94) | 76584 |
|
|
||||||
|
|
||||||
** Bugs?
|
|
||||||
|
|
||||||
Unfortunately, for the time being there is no automated test suite. But I
|
|
||||||
ran the compressor manually on non-trivial code, and then I tested that the
|
|
||||||
generated code works as expected. A few hundred times.
|
|
||||||
|
|
||||||
DynarchLIB was started in times when there was no good JS minifier.
|
|
||||||
Therefore I was quite religious about trying to write short code manually,
|
|
||||||
and as such DL contains a lot of syntactic hacks[1] such as “foo == bar ? a
|
|
||||||
= 10 : b = 20”, though the more readable version would clearly be to use
|
|
||||||
“if/else”.
|
|
||||||
|
|
||||||
Since the parser/compressor runs fine on DL and jQuery, I'm quite confident
|
|
||||||
that it's solid enough for production use. If you can identify any bugs,
|
|
||||||
I'd love to hear about them ([[http://groups.google.com/group/uglifyjs][use the Google Group]] or email me directly).
|
|
||||||
|
|
||||||
[1] I even reported a few bugs and suggested some fixes in the original
|
|
||||||
[[http://marijn.haverbeke.nl/parse-js/][parse-js]] library, and Marijn pushed fixes literally in minutes.
|
|
||||||
|
|
||||||
** Links
|
|
||||||
|
|
||||||
- Twitter: [[http://twitter.com/UglifyJS][@UglifyJS]]
|
|
||||||
- Project at GitHub: [[http://github.com/mishoo/UglifyJS][http://github.com/mishoo/UglifyJS]]
|
|
||||||
- Google Group: [[http://groups.google.com/group/uglifyjs][http://groups.google.com/group/uglifyjs]]
|
|
||||||
- Common Lisp JS parser: [[http://marijn.haverbeke.nl/parse-js/][http://marijn.haverbeke.nl/parse-js/]]
|
|
||||||
- JS-to-Lisp compiler: [[http://github.com/marijnh/js][http://github.com/marijnh/js]]
|
|
||||||
- Common Lisp JS uglifier: [[http://github.com/mishoo/cl-uglify-js][http://github.com/mishoo/cl-uglify-js]]
|
|
||||||
|
|
||||||
** License
|
|
||||||
|
|
||||||
UglifyJS is released under the BSD license:
|
|
||||||
|
|
||||||
#+BEGIN_EXAMPLE
|
|
||||||
Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
|
||||||
Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer in the documentation and/or other materials
|
|
||||||
provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
|
||||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
|
||||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
||||||
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
||||||
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGE.
|
|
||||||
#+END_EXAMPLE
|
|
||||||
678
node_modules/handlebars/node_modules/uglify-js/bin/uglifyjs
generated
vendored
678
node_modules/handlebars/node_modules/uglify-js/bin/uglifyjs
generated
vendored
@@ -1,332 +1,402 @@
|
|||||||
#!/usr/bin/env node
|
#! /usr/bin/env node
|
||||||
// -*- js -*-
|
// -*- js -*-
|
||||||
|
|
||||||
global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util");
|
"use strict";
|
||||||
var fs = require("fs");
|
|
||||||
var uglify = require("uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js
|
|
||||||
consolidator = uglify.consolidator,
|
|
||||||
jsp = uglify.parser,
|
|
||||||
pro = uglify.uglify;
|
|
||||||
|
|
||||||
var options = {
|
var UglifyJS = require("../tools/node");
|
||||||
ast: false,
|
var sys = require("util");
|
||||||
consolidate: false,
|
var optimist = require("optimist");
|
||||||
mangle: true,
|
var fs = require("fs");
|
||||||
mangle_toplevel: false,
|
var async = require("async");
|
||||||
no_mangle_functions: false,
|
var acorn;
|
||||||
squeeze: true,
|
var ARGS = optimist
|
||||||
make_seqs: true,
|
.usage("$0 input1.js [input2.js ...] [options]\n\
|
||||||
dead_code: true,
|
Use a single dash to read input from the standard input.\
|
||||||
verbose: false,
|
\n\n\
|
||||||
show_copyright: true,
|
NOTE: by default there is no mangling/compression.\n\
|
||||||
out_same_file: false,
|
Without [options] it will simply parse input files and dump the AST\n\
|
||||||
max_line_length: 32 * 1024,
|
with whitespace and comments discarded. To achieve compression and\n\
|
||||||
unsafe: false,
|
mangling you need to use `-c` and `-m`.\
|
||||||
reserved_names: null,
|
")
|
||||||
defines: { },
|
.describe("source-map", "Specify an output file where to generate source map.")
|
||||||
lift_vars: false,
|
.describe("source-map-root", "The path to the original source to be included in the source map.")
|
||||||
codegen_options: {
|
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
|
||||||
ascii_only: false,
|
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
||||||
beautify: false,
|
.describe("screw-ie8", "Pass this flag if you don't care about full compliance with Internet Explorer 6-8 quirks (by default UglifyJS will try to be IE-proof).")
|
||||||
indent_level: 4,
|
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
||||||
indent_start: 0,
|
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
||||||
quote_keys: false,
|
For example -p 3 will drop 3 directories from file names and ensure they are relative paths.")
|
||||||
space_colon: false,
|
.describe("o", "Output file (default STDOUT).")
|
||||||
inline_script: false
|
.describe("b", "Beautify output/specify output options.")
|
||||||
},
|
.describe("m", "Mangle names/pass mangler options.")
|
||||||
make: false,
|
.describe("r", "Reserved names to exclude from mangling.")
|
||||||
output: true // stdout
|
.describe("c", "Enable compressor/pass compressor options. \
|
||||||
|
Pass options like -c hoist_vars=false,if_return=false. \
|
||||||
|
Use -c with no argument to use the default compression options.")
|
||||||
|
.describe("d", "Global definitions")
|
||||||
|
.describe("e", "Embed everything in a big function, with a configurable parameter/argument list.")
|
||||||
|
|
||||||
|
.describe("comments", "Preserve copyright comments in the output. \
|
||||||
|
By default this works like Google Closure, keeping JSDoc-style comments that contain \"@license\" or \"@preserve\". \
|
||||||
|
You can optionally pass one of the following arguments to this flag:\n\
|
||||||
|
- \"all\" to keep all comments\n\
|
||||||
|
- a valid JS regexp (needs to start with a slash) to keep only comments that match.\n\
|
||||||
|
\
|
||||||
|
Note that currently not *all* comments can be kept when compression is on, \
|
||||||
|
because of dead code removal or cascading statements into sequences.")
|
||||||
|
|
||||||
|
.describe("stats", "Display operations run time on STDERR.")
|
||||||
|
.describe("acorn", "Use Acorn for parsing.")
|
||||||
|
.describe("spidermonkey", "Assume input files are SpiderMonkey AST format (as JSON).")
|
||||||
|
.describe("self", "Build itself (UglifyJS2) as a library (implies --wrap=UglifyJS --export-all)")
|
||||||
|
.describe("wrap", "Embed everything in a big function, making the “exports” and “global” variables available. \
|
||||||
|
You need to pass an argument to this option to specify the name that your module will take when included in, say, a browser.")
|
||||||
|
.describe("export-all", "Only used when --wrap, this tells UglifyJS to add code to automatically export all globals.")
|
||||||
|
.describe("lint", "Display some scope warnings")
|
||||||
|
.describe("v", "Verbose")
|
||||||
|
.describe("V", "Print version number and exit.")
|
||||||
|
|
||||||
|
.alias("p", "prefix")
|
||||||
|
.alias("o", "output")
|
||||||
|
.alias("v", "verbose")
|
||||||
|
.alias("b", "beautify")
|
||||||
|
.alias("m", "mangle")
|
||||||
|
.alias("c", "compress")
|
||||||
|
.alias("d", "define")
|
||||||
|
.alias("r", "reserved")
|
||||||
|
.alias("V", "version")
|
||||||
|
.alias("e", "enclose")
|
||||||
|
|
||||||
|
.string("source-map")
|
||||||
|
.string("source-map-root")
|
||||||
|
.string("source-map-url")
|
||||||
|
.string("b")
|
||||||
|
.string("m")
|
||||||
|
.string("c")
|
||||||
|
.string("d")
|
||||||
|
.string("e")
|
||||||
|
.string("comments")
|
||||||
|
.string("wrap")
|
||||||
|
|
||||||
|
.boolean("expr")
|
||||||
|
.boolean("screw-ie8")
|
||||||
|
.boolean("export-all")
|
||||||
|
.boolean("self")
|
||||||
|
.boolean("v")
|
||||||
|
.boolean("stats")
|
||||||
|
.boolean("acorn")
|
||||||
|
.boolean("spidermonkey")
|
||||||
|
.boolean("lint")
|
||||||
|
.boolean("V")
|
||||||
|
|
||||||
|
.wrap(80)
|
||||||
|
|
||||||
|
.argv
|
||||||
|
;
|
||||||
|
|
||||||
|
normalize(ARGS);
|
||||||
|
|
||||||
|
if (ARGS.version || ARGS.V) {
|
||||||
|
var json = require("../package.json");
|
||||||
|
sys.puts(json.name + ' ' + json.version);
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ARGS.ast_help) {
|
||||||
|
var desc = UglifyJS.describe_ast();
|
||||||
|
sys.puts(typeof desc == "string" ? desc : JSON.stringify(desc, null, 2));
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ARGS.h || ARGS.help) {
|
||||||
|
sys.puts(optimist.help());
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ARGS.acorn) {
|
||||||
|
acorn = require("acorn");
|
||||||
|
}
|
||||||
|
|
||||||
|
var COMPRESS = getOptions("c", true);
|
||||||
|
var MANGLE = getOptions("m", true);
|
||||||
|
var BEAUTIFY = getOptions("b", true);
|
||||||
|
|
||||||
|
if (ARGS.d) {
|
||||||
|
if (COMPRESS) COMPRESS.global_defs = getOptions("d");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ARGS.screw_ie8) {
|
||||||
|
if (COMPRESS) COMPRESS.screw_ie8 = true;
|
||||||
|
if (MANGLE) MANGLE.screw_ie8 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ARGS.r) {
|
||||||
|
if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
var OUTPUT_OPTIONS = {
|
||||||
|
beautify: BEAUTIFY ? true : false
|
||||||
};
|
};
|
||||||
|
|
||||||
var args = jsp.slice(process.argv, 2);
|
if (BEAUTIFY)
|
||||||
var filename;
|
UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY);
|
||||||
|
|
||||||
out: while (args.length > 0) {
|
if (ARGS.comments) {
|
||||||
var v = args.shift();
|
if (/^\//.test(ARGS.comments)) {
|
||||||
switch (v) {
|
OUTPUT_OPTIONS.comments = new Function("return(" + ARGS.comments + ")")();
|
||||||
case "-b":
|
} else if (ARGS.comments == "all") {
|
||||||
case "--beautify":
|
OUTPUT_OPTIONS.comments = true;
|
||||||
options.codegen_options.beautify = true;
|
} else {
|
||||||
break;
|
OUTPUT_OPTIONS.comments = function(node, comment) {
|
||||||
case "-c":
|
var text = comment.value;
|
||||||
case "--consolidate-primitive-values":
|
var type = comment.type;
|
||||||
options.consolidate = true;
|
if (type == "comment2") {
|
||||||
break;
|
// multiline comment
|
||||||
case "-i":
|
return /@preserve|@license|@cc_on/i.test(text);
|
||||||
case "--indent":
|
|
||||||
options.codegen_options.indent_level = args.shift();
|
|
||||||
break;
|
|
||||||
case "-q":
|
|
||||||
case "--quote-keys":
|
|
||||||
options.codegen_options.quote_keys = true;
|
|
||||||
break;
|
|
||||||
case "-mt":
|
|
||||||
case "--mangle-toplevel":
|
|
||||||
options.mangle_toplevel = true;
|
|
||||||
break;
|
|
||||||
case "-nmf":
|
|
||||||
case "--no-mangle-functions":
|
|
||||||
options.no_mangle_functions = true;
|
|
||||||
break;
|
|
||||||
case "--no-mangle":
|
|
||||||
case "-nm":
|
|
||||||
options.mangle = false;
|
|
||||||
break;
|
|
||||||
case "--no-squeeze":
|
|
||||||
case "-ns":
|
|
||||||
options.squeeze = false;
|
|
||||||
break;
|
|
||||||
case "--no-seqs":
|
|
||||||
options.make_seqs = false;
|
|
||||||
break;
|
|
||||||
case "--no-dead-code":
|
|
||||||
options.dead_code = false;
|
|
||||||
break;
|
|
||||||
case "--no-copyright":
|
|
||||||
case "-nc":
|
|
||||||
options.show_copyright = false;
|
|
||||||
break;
|
|
||||||
case "-o":
|
|
||||||
case "--output":
|
|
||||||
options.output = args.shift();
|
|
||||||
break;
|
|
||||||
case "--overwrite":
|
|
||||||
options.out_same_file = true;
|
|
||||||
break;
|
|
||||||
case "-v":
|
|
||||||
case "--verbose":
|
|
||||||
options.verbose = true;
|
|
||||||
break;
|
|
||||||
case "--ast":
|
|
||||||
options.ast = true;
|
|
||||||
break;
|
|
||||||
case "--unsafe":
|
|
||||||
options.unsafe = true;
|
|
||||||
break;
|
|
||||||
case "--max-line-len":
|
|
||||||
options.max_line_length = parseInt(args.shift(), 10);
|
|
||||||
break;
|
|
||||||
case "--reserved-names":
|
|
||||||
options.reserved_names = args.shift().split(",");
|
|
||||||
break;
|
|
||||||
case "--lift-vars":
|
|
||||||
options.lift_vars = true;
|
|
||||||
break;
|
|
||||||
case "-d":
|
|
||||||
case "--define":
|
|
||||||
var defarg = args.shift();
|
|
||||||
try {
|
|
||||||
var defsym = function(sym) {
|
|
||||||
// KEYWORDS_ATOM doesn't include NaN or Infinity - should we check
|
|
||||||
// for them too ?? We don't check reserved words and the like as the
|
|
||||||
// define values are only substituted AFTER parsing
|
|
||||||
if (jsp.KEYWORDS_ATOM.hasOwnProperty(sym)) {
|
|
||||||
throw "Don't define values for inbuilt constant '"+sym+"'";
|
|
||||||
}
|
}
|
||||||
return sym;
|
|
||||||
},
|
|
||||||
defval = function(v) {
|
|
||||||
if (v.match(/^"(.*)"$/) || v.match(/^'(.*)'$/)) {
|
|
||||||
return [ "string", RegExp.$1 ];
|
|
||||||
}
|
}
|
||||||
else if (!isNaN(parseFloat(v))) {
|
|
||||||
return [ "num", parseFloat(v) ];
|
|
||||||
}
|
}
|
||||||
else if (v.match(/^[a-z\$_][a-z\$_0-9]*$/i)) {
|
}
|
||||||
return [ "name", v ];
|
|
||||||
|
var files = ARGS._.slice();
|
||||||
|
|
||||||
|
if (ARGS.self) {
|
||||||
|
if (files.length > 0) {
|
||||||
|
sys.error("WARN: Ignoring input files since --self was passed");
|
||||||
}
|
}
|
||||||
else if (!v.match(/"/)) {
|
files = UglifyJS.FILES;
|
||||||
return [ "string", v ];
|
if (!ARGS.wrap) ARGS.wrap = "UglifyJS";
|
||||||
|
ARGS.export_all = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ORIG_MAP = ARGS.in_source_map;
|
||||||
|
|
||||||
|
if (ORIG_MAP) {
|
||||||
|
ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP));
|
||||||
|
if (files.length == 0) {
|
||||||
|
sys.error("INFO: Using file from the input source map: " + ORIG_MAP.file);
|
||||||
|
files = [ ORIG_MAP.file ];
|
||||||
}
|
}
|
||||||
else if (!v.match(/'/)) {
|
if (ARGS.source_map_root == null) {
|
||||||
return [ "string", v ];
|
ARGS.source_map_root = ORIG_MAP.sourceRoot;
|
||||||
}
|
}
|
||||||
throw "Can't understand the specified value: "+v;
|
}
|
||||||
};
|
|
||||||
if (defarg.match(/^([a-z_\$][a-z_\$0-9]*)(=(.*))?$/i)) {
|
if (files.length == 0) {
|
||||||
var sym = defsym(RegExp.$1),
|
files = [ "-" ];
|
||||||
val = RegExp.$2 ? defval(RegExp.$2.substr(1)) : [ 'name', 'true' ];
|
}
|
||||||
options.defines[sym] = val;
|
|
||||||
|
if (files.indexOf("-") >= 0 && ARGS.source_map) {
|
||||||
|
sys.error("ERROR: Source map doesn't work with input from STDIN");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files.filter(function(el){ return el == "-" }).length > 1) {
|
||||||
|
sys.error("ERROR: Can read a single file from STDIN (two or more dashes specified)");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var STATS = {};
|
||||||
|
var OUTPUT_FILE = ARGS.o;
|
||||||
|
var TOPLEVEL = null;
|
||||||
|
|
||||||
|
var SOURCE_MAP = ARGS.source_map ? UglifyJS.SourceMap({
|
||||||
|
file: OUTPUT_FILE,
|
||||||
|
root: ARGS.source_map_root,
|
||||||
|
orig: ORIG_MAP,
|
||||||
|
}) : null;
|
||||||
|
|
||||||
|
OUTPUT_OPTIONS.source_map = SOURCE_MAP;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var output = UglifyJS.OutputStream(OUTPUT_OPTIONS);
|
||||||
|
var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS);
|
||||||
|
} catch(ex) {
|
||||||
|
if (ex instanceof UglifyJS.DefaultsError) {
|
||||||
|
sys.error(ex.msg);
|
||||||
|
sys.error("Supported options:");
|
||||||
|
sys.error(sys.inspect(ex.defs));
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async.eachLimit(files, 1, function (file, cb) {
|
||||||
|
read_whole_file(file, function (err, code) {
|
||||||
|
if (err) {
|
||||||
|
sys.error("ERROR: can't read file: " + filename);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
if (ARGS.p != null) {
|
||||||
|
file = file.replace(/^\/+/, "").split(/\/+/).slice(ARGS.p).join("/");
|
||||||
|
}
|
||||||
|
time_it("parse", function(){
|
||||||
|
if (ARGS.spidermonkey) {
|
||||||
|
var program = JSON.parse(code);
|
||||||
|
if (!TOPLEVEL) TOPLEVEL = program;
|
||||||
|
else TOPLEVEL.body = TOPLEVEL.body.concat(program.body);
|
||||||
|
}
|
||||||
|
else if (ARGS.acorn) {
|
||||||
|
TOPLEVEL = acorn.parse(code, {
|
||||||
|
locations : true,
|
||||||
|
trackComments : true,
|
||||||
|
sourceFile : file,
|
||||||
|
program : TOPLEVEL
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "The --define option expects SYMBOL[=value]";
|
TOPLEVEL = UglifyJS.parse(code, {
|
||||||
}
|
filename : file,
|
||||||
} catch(ex) {
|
toplevel : TOPLEVEL,
|
||||||
sys.print("ERROR: In option --define "+defarg+"\n"+ex+"\n");
|
expression : ARGS.expr,
|
||||||
process.exit(1);
|
});
|
||||||
}
|
};
|
||||||
break;
|
});
|
||||||
case "--define-from-module":
|
cb();
|
||||||
var defmodarg = args.shift(),
|
});
|
||||||
defmodule = require(defmodarg),
|
}, function () {
|
||||||
sym,
|
if (ARGS.acorn || ARGS.spidermonkey) time_it("convert_ast", function(){
|
||||||
val;
|
TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL);
|
||||||
for (sym in defmodule) {
|
|
||||||
if (defmodule.hasOwnProperty(sym)) {
|
|
||||||
options.defines[sym] = function(val) {
|
|
||||||
if (typeof val == "string")
|
|
||||||
return [ "string", val ];
|
|
||||||
if (typeof val == "number")
|
|
||||||
return [ "num", val ];
|
|
||||||
if (val === true)
|
|
||||||
return [ 'name', 'true' ];
|
|
||||||
if (val === false)
|
|
||||||
return [ 'name', 'false' ];
|
|
||||||
if (val === null)
|
|
||||||
return [ 'name', 'null' ];
|
|
||||||
if (val === undefined)
|
|
||||||
return [ 'name', 'undefined' ];
|
|
||||||
sys.print("ERROR: In option --define-from-module "+defmodarg+"\n");
|
|
||||||
sys.print("ERROR: Unknown object type for: "+sym+"="+val+"\n");
|
|
||||||
process.exit(1);
|
|
||||||
return null;
|
|
||||||
}(defmodule[sym]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "--ascii":
|
|
||||||
options.codegen_options.ascii_only = true;
|
|
||||||
break;
|
|
||||||
case "--make":
|
|
||||||
options.make = true;
|
|
||||||
break;
|
|
||||||
case "--inline-script":
|
|
||||||
options.codegen_options.inline_script = true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
filename = v;
|
|
||||||
break out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.verbose) {
|
|
||||||
pro.set_logger(function(msg){
|
|
||||||
sys.debug(msg);
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
jsp.set_logger(function(msg){
|
if (ARGS.wrap) {
|
||||||
sys.debug(msg);
|
TOPLEVEL = TOPLEVEL.wrap_commonjs(ARGS.wrap, ARGS.export_all);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ARGS.enclose) {
|
||||||
|
var arg_parameter_list = ARGS.enclose;
|
||||||
|
|
||||||
|
if (!(arg_parameter_list instanceof Array)) {
|
||||||
|
arg_parameter_list = [arg_parameter_list];
|
||||||
|
}
|
||||||
|
|
||||||
|
TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint;
|
||||||
|
|
||||||
|
if (SCOPE_IS_NEEDED) {
|
||||||
|
time_it("scope", function(){
|
||||||
|
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8 });
|
||||||
|
if (ARGS.lint) {
|
||||||
|
TOPLEVEL.scope_warnings();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (COMPRESS) {
|
||||||
|
time_it("squeeze", function(){
|
||||||
|
TOPLEVEL = TOPLEVEL.transform(compressor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SCOPE_IS_NEEDED) {
|
||||||
|
time_it("scope", function(){
|
||||||
|
TOPLEVEL.figure_out_scope({ screw_ie8: ARGS.screw_ie8 });
|
||||||
|
if (MANGLE) {
|
||||||
|
TOPLEVEL.compute_char_frequency(MANGLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MANGLE) time_it("mangle", function(){
|
||||||
|
TOPLEVEL.mangle_names(MANGLE);
|
||||||
|
});
|
||||||
|
time_it("generate", function(){
|
||||||
|
TOPLEVEL.print(output);
|
||||||
|
});
|
||||||
|
|
||||||
|
output = output.get();
|
||||||
|
|
||||||
|
if (SOURCE_MAP) {
|
||||||
|
fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
|
||||||
|
output += "\n//# sourceMappingURL=" + (ARGS.source_map_url || ARGS.source_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OUTPUT_FILE) {
|
||||||
|
fs.writeFileSync(OUTPUT_FILE, output, "utf8");
|
||||||
|
} else {
|
||||||
|
sys.print(output);
|
||||||
|
sys.error("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ARGS.stats) {
|
||||||
|
sys.error(UglifyJS.string_template("Timing information (compressed {count} files):", {
|
||||||
|
count: files.length
|
||||||
|
}));
|
||||||
|
for (var i in STATS) if (STATS.hasOwnProperty(i)) {
|
||||||
|
sys.error(UglifyJS.string_template("- {name}: {time}s", {
|
||||||
|
name: i,
|
||||||
|
time: (STATS[i] / 1000).toFixed(3)
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (options.make) {
|
/* -----[ functions ]----- */
|
||||||
options.out_same_file = false; // doesn't make sense in this case
|
|
||||||
var makefile = JSON.parse(fs.readFileSync(filename || "Makefile.uglify.js").toString());
|
function normalize(o) {
|
||||||
output(makefile.files.map(function(file){
|
for (var i in o) if (o.hasOwnProperty(i) && /-/.test(i)) {
|
||||||
var code = fs.readFileSync(file.name);
|
o[i.replace(/-/g, "_")] = o[i];
|
||||||
if (file.module) {
|
delete o[i];
|
||||||
code = "!function(exports, global){global = this;\n" + code + "\n;this." + file.module + " = exports;}({})";
|
|
||||||
}
|
}
|
||||||
else if (file.hide) {
|
|
||||||
code = "(function(){" + code + "}());";
|
|
||||||
}
|
|
||||||
return squeeze_it(code);
|
|
||||||
}).join("\n"));
|
|
||||||
}
|
|
||||||
else if (filename) {
|
|
||||||
fs.readFile(filename, "utf8", function(err, text){
|
|
||||||
if (err) throw err;
|
|
||||||
output(squeeze_it(text));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var stdin = process.openStdin();
|
|
||||||
stdin.setEncoding("utf8");
|
|
||||||
var text = "";
|
|
||||||
stdin.on("data", function(chunk){
|
|
||||||
text += chunk;
|
|
||||||
});
|
|
||||||
stdin.on("end", function() {
|
|
||||||
output(squeeze_it(text));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function output(text) {
|
function getOptions(x, constants) {
|
||||||
var out;
|
x = ARGS[x];
|
||||||
if (options.out_same_file && filename)
|
if (!x) return null;
|
||||||
options.output = filename;
|
var ret = {};
|
||||||
if (options.output === true) {
|
if (x !== true) {
|
||||||
out = process.stdout;
|
var ast;
|
||||||
} else {
|
|
||||||
out = fs.createWriteStream(options.output, {
|
|
||||||
flags: "w",
|
|
||||||
encoding: "utf8",
|
|
||||||
mode: 0644
|
|
||||||
});
|
|
||||||
}
|
|
||||||
out.write(text.replace(/;*$/, ";"));
|
|
||||||
if (options.output !== true) {
|
|
||||||
out.end();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------- main ends here.
|
|
||||||
|
|
||||||
function show_copyright(comments) {
|
|
||||||
var ret = "";
|
|
||||||
for (var i = 0; i < comments.length; ++i) {
|
|
||||||
var c = comments[i];
|
|
||||||
if (c.type == "comment1") {
|
|
||||||
ret += "//" + c.value + "\n";
|
|
||||||
} else {
|
|
||||||
ret += "/*" + c.value + "*/";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
function squeeze_it(code) {
|
|
||||||
var result = "";
|
|
||||||
if (options.show_copyright) {
|
|
||||||
var tok = jsp.tokenizer(code), c;
|
|
||||||
c = tok();
|
|
||||||
result += show_copyright(c.comments_before);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
var ast = time_it("parse", function(){ return jsp.parse(code); });
|
ast = UglifyJS.parse(x);
|
||||||
if (options.consolidate) ast = time_it("consolidate", function(){
|
|
||||||
return consolidator.ast_consolidate(ast);
|
|
||||||
});
|
|
||||||
if (options.lift_vars) {
|
|
||||||
ast = time_it("lift", function(){ return pro.ast_lift_variables(ast); });
|
|
||||||
}
|
|
||||||
if (options.mangle) ast = time_it("mangle", function(){
|
|
||||||
return pro.ast_mangle(ast, {
|
|
||||||
toplevel : options.mangle_toplevel,
|
|
||||||
defines : options.defines,
|
|
||||||
except : options.reserved_names,
|
|
||||||
no_functions : options.no_mangle_functions
|
|
||||||
});
|
|
||||||
});
|
|
||||||
if (options.squeeze) ast = time_it("squeeze", function(){
|
|
||||||
ast = pro.ast_squeeze(ast, {
|
|
||||||
make_seqs : options.make_seqs,
|
|
||||||
dead_code : options.dead_code,
|
|
||||||
keep_comps : !options.unsafe
|
|
||||||
});
|
|
||||||
if (options.unsafe)
|
|
||||||
ast = pro.ast_squeeze_more(ast);
|
|
||||||
return ast;
|
|
||||||
});
|
|
||||||
if (options.ast)
|
|
||||||
return sys.inspect(ast, null, null);
|
|
||||||
result += time_it("generate", function(){ return pro.gen_code(ast, options.codegen_options) });
|
|
||||||
if (!options.codegen_options.beautify && options.max_line_length) {
|
|
||||||
result = time_it("split", function(){ return pro.split_lines(result, options.max_line_length) });
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
sys.debug(ex.stack);
|
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
||||||
sys.debug(sys.inspect(ex));
|
sys.error("Error parsing arguments in: " + x);
|
||||||
sys.debug(JSON.stringify(ex));
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
ast.walk(new UglifyJS.TreeWalker(function(node){
|
||||||
|
if (node instanceof UglifyJS.AST_Toplevel) return; // descend
|
||||||
|
if (node instanceof UglifyJS.AST_SimpleStatement) return; // descend
|
||||||
|
if (node instanceof UglifyJS.AST_Seq) return; // descend
|
||||||
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
|
var name = node.left.print_to_string({ beautify: false }).replace(/-/g, "_");
|
||||||
|
var value = node.right;
|
||||||
|
if (constants)
|
||||||
|
value = new Function("return (" + value.print_to_string() + ")")();
|
||||||
|
ret[name] = value;
|
||||||
|
return true; // no descend
|
||||||
|
}
|
||||||
|
sys.error(node.TYPE)
|
||||||
|
sys.error("Error parsing arguments in: " + x);
|
||||||
|
process.exit(1);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_whole_file(filename, cb) {
|
||||||
|
if (filename == "-") {
|
||||||
|
var chunks = [];
|
||||||
|
process.stdin.setEncoding('utf-8');
|
||||||
|
process.stdin.on('data', function (chunk) {
|
||||||
|
chunks.push(chunk);
|
||||||
|
}).on('end', function () {
|
||||||
|
cb(null, chunks.join(""));
|
||||||
|
});
|
||||||
|
process.openStdin();
|
||||||
|
} else {
|
||||||
|
fs.readFile(filename, "utf-8", cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function time_it(name, cont) {
|
function time_it(name, cont) {
|
||||||
if (!options.verbose)
|
|
||||||
return cont();
|
|
||||||
var t1 = new Date().getTime();
|
var t1 = new Date().getTime();
|
||||||
try { return cont(); }
|
var ret = cont();
|
||||||
finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); }
|
if (ARGS.stats) {
|
||||||
};
|
var spent = new Date().getTime() - t1;
|
||||||
|
if (STATS[name]) STATS[name] += spent;
|
||||||
|
else STATS[name] = spent;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
75
node_modules/handlebars/node_modules/uglify-js/docstyle.css
generated
vendored
75
node_modules/handlebars/node_modules/uglify-js/docstyle.css
generated
vendored
@@ -1,75 +0,0 @@
|
|||||||
html { font-family: "Lucida Grande","Trebuchet MS",sans-serif; font-size: 12pt; }
|
|
||||||
body { max-width: 60em; }
|
|
||||||
.title { text-align: center; }
|
|
||||||
.todo { color: red; }
|
|
||||||
.done { color: green; }
|
|
||||||
.tag { background-color:lightblue; font-weight:normal }
|
|
||||||
.target { }
|
|
||||||
.timestamp { color: grey }
|
|
||||||
.timestamp-kwd { color: CadetBlue }
|
|
||||||
p.verse { margin-left: 3% }
|
|
||||||
pre {
|
|
||||||
border: 1pt solid #AEBDCC;
|
|
||||||
background-color: #F3F5F7;
|
|
||||||
padding: 5pt;
|
|
||||||
font-family: monospace;
|
|
||||||
font-size: 90%;
|
|
||||||
overflow:auto;
|
|
||||||
}
|
|
||||||
pre.src {
|
|
||||||
background-color: #eee; color: #112; border: 1px solid #000;
|
|
||||||
}
|
|
||||||
table { border-collapse: collapse; }
|
|
||||||
td, th { vertical-align: top; }
|
|
||||||
dt { font-weight: bold; }
|
|
||||||
div.figure { padding: 0.5em; }
|
|
||||||
div.figure p { text-align: center; }
|
|
||||||
.linenr { font-size:smaller }
|
|
||||||
.code-highlighted {background-color:#ffff00;}
|
|
||||||
.org-info-js_info-navigation { border-style:none; }
|
|
||||||
#org-info-js_console-label { font-size:10px; font-weight:bold;
|
|
||||||
white-space:nowrap; }
|
|
||||||
.org-info-js_search-highlight {background-color:#ffff00; color:#000000;
|
|
||||||
font-weight:bold; }
|
|
||||||
|
|
||||||
sup {
|
|
||||||
vertical-align: baseline;
|
|
||||||
position: relative;
|
|
||||||
top: -0.5em;
|
|
||||||
font-size: 80%;
|
|
||||||
}
|
|
||||||
|
|
||||||
sup a:link, sup a:visited {
|
|
||||||
text-decoration: none;
|
|
||||||
color: #c00;
|
|
||||||
}
|
|
||||||
|
|
||||||
sup a:before { content: "["; color: #999; }
|
|
||||||
sup a:after { content: "]"; color: #999; }
|
|
||||||
|
|
||||||
h1.title { border-bottom: 4px solid #000; padding-bottom: 5px; margin-bottom: 2em; }
|
|
||||||
|
|
||||||
#postamble {
|
|
||||||
color: #777;
|
|
||||||
font-size: 90%;
|
|
||||||
padding-top: 1em; padding-bottom: 1em; border-top: 1px solid #999;
|
|
||||||
margin-top: 2em;
|
|
||||||
padding-left: 2em;
|
|
||||||
padding-right: 2em;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
#postamble p { margin: 0; }
|
|
||||||
|
|
||||||
#footnotes { border-top: 1px solid #000; }
|
|
||||||
|
|
||||||
h1 { font-size: 200% }
|
|
||||||
h2 { font-size: 175% }
|
|
||||||
h3 { font-size: 150% }
|
|
||||||
h4 { font-size: 125% }
|
|
||||||
|
|
||||||
h1, h2, h3, h4 { font-family: "Bookman",Georgia,"Times New Roman",serif; font-weight: normal; }
|
|
||||||
|
|
||||||
@media print {
|
|
||||||
html { font-size: 11pt; }
|
|
||||||
}
|
|
||||||
985
node_modules/handlebars/node_modules/uglify-js/lib/ast.js
generated
vendored
Normal file
985
node_modules/handlebars/node_modules/uglify-js/lib/ast.js
generated
vendored
Normal file
@@ -0,0 +1,985 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
|
||||||
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
|
https://github.com/mishoo/UglifyJS2
|
||||||
|
|
||||||
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
|
Author: Mihai Bazon
|
||||||
|
<mihai.bazon@gmail.com>
|
||||||
|
http://mihai.bazon.net/blog
|
||||||
|
|
||||||
|
Distributed under the BSD license:
|
||||||
|
|
||||||
|
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials
|
||||||
|
provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||||
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function DEFNODE(type, props, methods, base) {
|
||||||
|
if (arguments.length < 4) base = AST_Node;
|
||||||
|
if (!props) props = [];
|
||||||
|
else props = props.split(/\s+/);
|
||||||
|
var self_props = props;
|
||||||
|
if (base && base.PROPS)
|
||||||
|
props = props.concat(base.PROPS);
|
||||||
|
var code = "return function AST_" + type + "(props){ if (props) { ";
|
||||||
|
for (var i = props.length; --i >= 0;) {
|
||||||
|
code += "this." + props[i] + " = props." + props[i] + ";";
|
||||||
|
}
|
||||||
|
var proto = base && new base;
|
||||||
|
if (proto && proto.initialize || (methods && methods.initialize))
|
||||||
|
code += "this.initialize();";
|
||||||
|
code += "}}";
|
||||||
|
var ctor = new Function(code)();
|
||||||
|
if (proto) {
|
||||||
|
ctor.prototype = proto;
|
||||||
|
ctor.BASE = base;
|
||||||
|
}
|
||||||
|
if (base) base.SUBCLASSES.push(ctor);
|
||||||
|
ctor.prototype.CTOR = ctor;
|
||||||
|
ctor.PROPS = props || null;
|
||||||
|
ctor.SELF_PROPS = self_props;
|
||||||
|
ctor.SUBCLASSES = [];
|
||||||
|
if (type) {
|
||||||
|
ctor.prototype.TYPE = ctor.TYPE = type;
|
||||||
|
}
|
||||||
|
if (methods) for (i in methods) if (methods.hasOwnProperty(i)) {
|
||||||
|
if (/^\$/.test(i)) {
|
||||||
|
ctor[i.substr(1)] = methods[i];
|
||||||
|
} else {
|
||||||
|
ctor.prototype[i] = methods[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctor.DEFMETHOD = function(name, method) {
|
||||||
|
this.prototype[name] = method;
|
||||||
|
};
|
||||||
|
return ctor;
|
||||||
|
};
|
||||||
|
|
||||||
|
var AST_Token = DEFNODE("Token", "type value line col pos endpos nlb comments_before file", {
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
var AST_Node = DEFNODE("Node", "start end", {
|
||||||
|
clone: function() {
|
||||||
|
return new this.CTOR(this);
|
||||||
|
},
|
||||||
|
$documentation: "Base class of all AST nodes",
|
||||||
|
$propdoc: {
|
||||||
|
start: "[AST_Token] The first token of this node",
|
||||||
|
end: "[AST_Token] The last token of this node"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this);
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
return this._walk(visitor); // not sure the indirection will be any help
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
AST_Node.warn_function = null;
|
||||||
|
AST_Node.warn = function(txt, props) {
|
||||||
|
if (AST_Node.warn_function)
|
||||||
|
AST_Node.warn_function(string_template(txt, props));
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -----[ statements ]----- */
|
||||||
|
|
||||||
|
var AST_Statement = DEFNODE("Statement", null, {
|
||||||
|
$documentation: "Base class of all statements",
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_Debugger = DEFNODE("Debugger", null, {
|
||||||
|
$documentation: "Represents a debugger statement",
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_Directive = DEFNODE("Directive", "value scope", {
|
||||||
|
$documentation: "Represents a directive, like \"use strict\";",
|
||||||
|
$propdoc: {
|
||||||
|
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||||
|
scope: "[AST_Scope/S] The scope that this directive affects"
|
||||||
|
},
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||||
|
$documentation: "A statement consisting of an expression, i.e. a = 1 + 2",
|
||||||
|
$propdoc: {
|
||||||
|
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.body._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
function walk_body(node, visitor) {
|
||||||
|
if (node.body instanceof AST_Statement) {
|
||||||
|
node.body._walk(visitor);
|
||||||
|
}
|
||||||
|
else node.body.forEach(function(stat){
|
||||||
|
stat._walk(visitor);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var AST_Block = DEFNODE("Block", "body", {
|
||||||
|
$documentation: "A body of statements (usually bracketed)",
|
||||||
|
$propdoc: {
|
||||||
|
body: "[AST_Statement*] an array of statements"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
walk_body(this, visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_BlockStatement = DEFNODE("BlockStatement", null, {
|
||||||
|
$documentation: "A block statement",
|
||||||
|
}, AST_Block);
|
||||||
|
|
||||||
|
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||||
|
$documentation: "The empty statement (empty block or simply a semicolon)",
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this);
|
||||||
|
}
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
|
||||||
|
$documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
|
||||||
|
$propdoc: {
|
||||||
|
body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.body._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||||
|
$documentation: "Statement with a label",
|
||||||
|
$propdoc: {
|
||||||
|
label: "[AST_Label] a label definition"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.label._walk(visitor);
|
||||||
|
this.body._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
|
var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
||||||
|
$documentation: "Base class for do/while statements",
|
||||||
|
$propdoc: {
|
||||||
|
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.condition._walk(visitor);
|
||||||
|
this.body._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
|
var AST_Do = DEFNODE("Do", null, {
|
||||||
|
$documentation: "A `do` statement",
|
||||||
|
}, AST_DWLoop);
|
||||||
|
|
||||||
|
var AST_While = DEFNODE("While", null, {
|
||||||
|
$documentation: "A `while` statement",
|
||||||
|
}, AST_DWLoop);
|
||||||
|
|
||||||
|
var AST_For = DEFNODE("For", "init condition step", {
|
||||||
|
$documentation: "A `for` statement",
|
||||||
|
$propdoc: {
|
||||||
|
init: "[AST_Node?] the `for` initialization code, or null if empty",
|
||||||
|
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
||||||
|
step: "[AST_Node?] the `for` update clause, or null if empty"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
if (this.init) this.init._walk(visitor);
|
||||||
|
if (this.condition) this.condition._walk(visitor);
|
||||||
|
if (this.step) this.step._walk(visitor);
|
||||||
|
this.body._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
|
var AST_ForIn = DEFNODE("ForIn", "init name object", {
|
||||||
|
$documentation: "A `for ... in` statement",
|
||||||
|
$propdoc: {
|
||||||
|
init: "[AST_Node] the `for/in` initialization code",
|
||||||
|
name: "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var",
|
||||||
|
object: "[AST_Node] the object that we're looping through"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.init._walk(visitor);
|
||||||
|
this.object._walk(visitor);
|
||||||
|
this.body._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
|
var AST_With = DEFNODE("With", "expression", {
|
||||||
|
$documentation: "A `with` statement",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "[AST_Node] the `with` expression"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.expression._walk(visitor);
|
||||||
|
this.body._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
|
/* -----[ scope and functions ]----- */
|
||||||
|
|
||||||
|
var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {
|
||||||
|
$documentation: "Base class for all statements introducing a lexical scope",
|
||||||
|
$propdoc: {
|
||||||
|
directives: "[string*/S] an array of directives declared in this scope",
|
||||||
|
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
||||||
|
functions: "[Object/S] like `variables`, but only lists function declarations",
|
||||||
|
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||||
|
uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
|
||||||
|
parent_scope: "[AST_Scope?/S] link to the parent scope",
|
||||||
|
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
||||||
|
cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
|
||||||
|
},
|
||||||
|
}, AST_Block);
|
||||||
|
|
||||||
|
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||||
|
$documentation: "The toplevel scope",
|
||||||
|
$propdoc: {
|
||||||
|
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
||||||
|
},
|
||||||
|
wrap_enclose: function(arg_parameter_pairs) {
|
||||||
|
var self = this;
|
||||||
|
var args = [];
|
||||||
|
var parameters = [];
|
||||||
|
|
||||||
|
arg_parameter_pairs.forEach(function(pair) {
|
||||||
|
var split = pair.split(":");
|
||||||
|
|
||||||
|
args.push(split[0]);
|
||||||
|
parameters.push(split[1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")";
|
||||||
|
wrapped_tl = parse(wrapped_tl);
|
||||||
|
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||||
|
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||||
|
return MAP.splice(self.body);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return wrapped_tl;
|
||||||
|
},
|
||||||
|
wrap_commonjs: function(name, export_all) {
|
||||||
|
var self = this;
|
||||||
|
var to_export = [];
|
||||||
|
if (export_all) {
|
||||||
|
self.figure_out_scope();
|
||||||
|
self.walk(new TreeWalker(function(node){
|
||||||
|
if (node instanceof AST_SymbolDeclaration && node.definition().global) {
|
||||||
|
if (!find_if(function(n){ return n.name == node.name }, to_export))
|
||||||
|
to_export.push(node);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
var wrapped_tl = "(function(exports, global){ global['" + name + "'] = exports; '$ORIG'; '$EXPORTS'; }({}, (function(){return this}())))";
|
||||||
|
wrapped_tl = parse(wrapped_tl);
|
||||||
|
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||||
|
if (node instanceof AST_SimpleStatement) {
|
||||||
|
node = node.body;
|
||||||
|
if (node instanceof AST_String) switch (node.getValue()) {
|
||||||
|
case "$ORIG":
|
||||||
|
return MAP.splice(self.body);
|
||||||
|
case "$EXPORTS":
|
||||||
|
var body = [];
|
||||||
|
to_export.forEach(function(sym){
|
||||||
|
body.push(new AST_SimpleStatement({
|
||||||
|
body: new AST_Assign({
|
||||||
|
left: new AST_Sub({
|
||||||
|
expression: new AST_SymbolRef({ name: "exports" }),
|
||||||
|
property: new AST_String({ value: sym.name }),
|
||||||
|
}),
|
||||||
|
operator: "=",
|
||||||
|
right: new AST_SymbolRef(sym),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
return MAP.splice(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return wrapped_tl;
|
||||||
|
}
|
||||||
|
}, AST_Scope);
|
||||||
|
|
||||||
|
var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||||
|
$documentation: "Base class for functions",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolDeclaration?] the name of this function",
|
||||||
|
argnames: "[AST_SymbolFunarg*] array of function arguments",
|
||||||
|
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
if (this.name) this.name._walk(visitor);
|
||||||
|
this.argnames.forEach(function(arg){
|
||||||
|
arg._walk(visitor);
|
||||||
|
});
|
||||||
|
walk_body(this, visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Scope);
|
||||||
|
|
||||||
|
var AST_Accessor = DEFNODE("Accessor", null, {
|
||||||
|
$documentation: "A setter/getter function"
|
||||||
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
var AST_Function = DEFNODE("Function", null, {
|
||||||
|
$documentation: "A function expression"
|
||||||
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
var AST_Defun = DEFNODE("Defun", null, {
|
||||||
|
$documentation: "A function definition"
|
||||||
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
/* -----[ JUMPS ]----- */
|
||||||
|
|
||||||
|
var AST_Jump = DEFNODE("Jump", null, {
|
||||||
|
$documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_Exit = DEFNODE("Exit", "value", {
|
||||||
|
$documentation: "Base class for “exits” (`return` and `throw`)",
|
||||||
|
$propdoc: {
|
||||||
|
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, this.value && function(){
|
||||||
|
this.value._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Jump);
|
||||||
|
|
||||||
|
var AST_Return = DEFNODE("Return", null, {
|
||||||
|
$documentation: "A `return` statement"
|
||||||
|
}, AST_Exit);
|
||||||
|
|
||||||
|
var AST_Throw = DEFNODE("Throw", null, {
|
||||||
|
$documentation: "A `throw` statement"
|
||||||
|
}, AST_Exit);
|
||||||
|
|
||||||
|
var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
||||||
|
$documentation: "Base class for loop control statements (`break` and `continue`)",
|
||||||
|
$propdoc: {
|
||||||
|
label: "[AST_LabelRef?] the label, or null if none",
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, this.label && function(){
|
||||||
|
this.label._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Jump);
|
||||||
|
|
||||||
|
var AST_Break = DEFNODE("Break", null, {
|
||||||
|
$documentation: "A `break` statement"
|
||||||
|
}, AST_LoopControl);
|
||||||
|
|
||||||
|
var AST_Continue = DEFNODE("Continue", null, {
|
||||||
|
$documentation: "A `continue` statement"
|
||||||
|
}, AST_LoopControl);
|
||||||
|
|
||||||
|
/* -----[ IF ]----- */
|
||||||
|
|
||||||
|
var AST_If = DEFNODE("If", "condition alternative", {
|
||||||
|
$documentation: "A `if` statement",
|
||||||
|
$propdoc: {
|
||||||
|
condition: "[AST_Node] the `if` condition",
|
||||||
|
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.condition._walk(visitor);
|
||||||
|
this.body._walk(visitor);
|
||||||
|
if (this.alternative) this.alternative._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
|
/* -----[ SWITCH ]----- */
|
||||||
|
|
||||||
|
var AST_Switch = DEFNODE("Switch", "expression", {
|
||||||
|
$documentation: "A `switch` statement",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "[AST_Node] the `switch` “discriminant”"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.expression._walk(visitor);
|
||||||
|
walk_body(this, visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Block);
|
||||||
|
|
||||||
|
var AST_SwitchBranch = DEFNODE("SwitchBranch", null, {
|
||||||
|
$documentation: "Base class for `switch` branches",
|
||||||
|
}, AST_Block);
|
||||||
|
|
||||||
|
var AST_Default = DEFNODE("Default", null, {
|
||||||
|
$documentation: "A `default` switch branch",
|
||||||
|
}, AST_SwitchBranch);
|
||||||
|
|
||||||
|
var AST_Case = DEFNODE("Case", "expression", {
|
||||||
|
$documentation: "A `case` switch branch",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "[AST_Node] the `case` expression"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.expression._walk(visitor);
|
||||||
|
walk_body(this, visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_SwitchBranch);
|
||||||
|
|
||||||
|
/* -----[ EXCEPTIONS ]----- */
|
||||||
|
|
||||||
|
var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
||||||
|
$documentation: "A `try` statement",
|
||||||
|
$propdoc: {
|
||||||
|
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
||||||
|
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
walk_body(this, visitor);
|
||||||
|
if (this.bcatch) this.bcatch._walk(visitor);
|
||||||
|
if (this.bfinally) this.bfinally._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Block);
|
||||||
|
|
||||||
|
// XXX: this is wrong according to ECMA-262 (12.4). the catch block
|
||||||
|
// should introduce another scope, as the argname should be visible
|
||||||
|
// only inside the catch block. However, doing it this way because of
|
||||||
|
// IE which simply introduces the name in the surrounding scope. If
|
||||||
|
// we ever want to fix this then AST_Catch should inherit from
|
||||||
|
// AST_Scope.
|
||||||
|
var AST_Catch = DEFNODE("Catch", "argname", {
|
||||||
|
$documentation: "A `catch` node; only makes sense as part of a `try` statement",
|
||||||
|
$propdoc: {
|
||||||
|
argname: "[AST_SymbolCatch] symbol for the exception"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.argname._walk(visitor);
|
||||||
|
walk_body(this, visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Block);
|
||||||
|
|
||||||
|
var AST_Finally = DEFNODE("Finally", null, {
|
||||||
|
$documentation: "A `finally` node; only makes sense as part of a `try` statement"
|
||||||
|
}, AST_Block);
|
||||||
|
|
||||||
|
/* -----[ VAR/CONST ]----- */
|
||||||
|
|
||||||
|
var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||||
|
$documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
|
||||||
|
$propdoc: {
|
||||||
|
definitions: "[AST_VarDef*] array of variable definitions"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.definitions.forEach(function(def){
|
||||||
|
def._walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_Var = DEFNODE("Var", null, {
|
||||||
|
$documentation: "A `var` statement"
|
||||||
|
}, AST_Definitions);
|
||||||
|
|
||||||
|
var AST_Const = DEFNODE("Const", null, {
|
||||||
|
$documentation: "A `const` statement"
|
||||||
|
}, AST_Definitions);
|
||||||
|
|
||||||
|
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||||
|
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolVar|AST_SymbolConst] name of the variable",
|
||||||
|
value: "[AST_Node?] initializer, or null of there's no initializer"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.name._walk(visitor);
|
||||||
|
if (this.value) this.value._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/* -----[ OTHER ]----- */
|
||||||
|
|
||||||
|
var AST_Call = DEFNODE("Call", "expression args", {
|
||||||
|
$documentation: "A function call expression",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "[AST_Node] expression to invoke as function",
|
||||||
|
args: "[AST_Node*] array of arguments"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.expression._walk(visitor);
|
||||||
|
this.args.forEach(function(arg){
|
||||||
|
arg._walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_New = DEFNODE("New", null, {
|
||||||
|
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
|
||||||
|
}, AST_Call);
|
||||||
|
|
||||||
|
var AST_Seq = DEFNODE("Seq", "car cdr", {
|
||||||
|
$documentation: "A sequence expression (two comma-separated expressions)",
|
||||||
|
$propdoc: {
|
||||||
|
car: "[AST_Node] first element in sequence",
|
||||||
|
cdr: "[AST_Node] second element in sequence"
|
||||||
|
},
|
||||||
|
$cons: function(x, y) {
|
||||||
|
var seq = new AST_Seq(x);
|
||||||
|
seq.car = x;
|
||||||
|
seq.cdr = y;
|
||||||
|
return seq;
|
||||||
|
},
|
||||||
|
$from_array: function(array) {
|
||||||
|
if (array.length == 0) return null;
|
||||||
|
if (array.length == 1) return array[0].clone();
|
||||||
|
var list = null;
|
||||||
|
for (var i = array.length; --i >= 0;) {
|
||||||
|
list = AST_Seq.cons(array[i], list);
|
||||||
|
}
|
||||||
|
var p = list;
|
||||||
|
while (p) {
|
||||||
|
if (p.cdr && !p.cdr.cdr) {
|
||||||
|
p.cdr = p.cdr.car;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = p.cdr;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
},
|
||||||
|
to_array: function() {
|
||||||
|
var p = this, a = [];
|
||||||
|
while (p) {
|
||||||
|
a.push(p.car);
|
||||||
|
if (p.cdr && !(p.cdr instanceof AST_Seq)) {
|
||||||
|
a.push(p.cdr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p = p.cdr;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
add: function(node) {
|
||||||
|
var p = this;
|
||||||
|
while (p) {
|
||||||
|
if (!(p.cdr instanceof AST_Seq)) {
|
||||||
|
var cell = AST_Seq.cons(p.cdr, node);
|
||||||
|
return p.cdr = cell;
|
||||||
|
}
|
||||||
|
p = p.cdr;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.car._walk(visitor);
|
||||||
|
if (this.cdr) this.cdr._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
|
||||||
|
$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "[AST_Node] the “container” expression",
|
||||||
|
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_Dot = DEFNODE("Dot", null, {
|
||||||
|
$documentation: "A dotted property access expression",
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.expression._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_PropAccess);
|
||||||
|
|
||||||
|
var AST_Sub = DEFNODE("Sub", null, {
|
||||||
|
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.expression._walk(visitor);
|
||||||
|
this.property._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_PropAccess);
|
||||||
|
|
||||||
|
var AST_Unary = DEFNODE("Unary", "operator expression", {
|
||||||
|
$documentation: "Base class for unary expressions",
|
||||||
|
$propdoc: {
|
||||||
|
operator: "[string] the operator",
|
||||||
|
expression: "[AST_Node] expression that this unary operator applies to"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.expression._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, {
|
||||||
|
$documentation: "Unary prefix expression, i.e. `typeof i` or `++i`"
|
||||||
|
}, AST_Unary);
|
||||||
|
|
||||||
|
var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, {
|
||||||
|
$documentation: "Unary postfix expression, i.e. `i++`"
|
||||||
|
}, AST_Unary);
|
||||||
|
|
||||||
|
var AST_Binary = DEFNODE("Binary", "left operator right", {
|
||||||
|
$documentation: "Binary expression, i.e. `a + b`",
|
||||||
|
$propdoc: {
|
||||||
|
left: "[AST_Node] left-hand side expression",
|
||||||
|
operator: "[string] the operator",
|
||||||
|
right: "[AST_Node] right-hand side expression"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.left._walk(visitor);
|
||||||
|
this.right._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative", {
|
||||||
|
$documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`",
|
||||||
|
$propdoc: {
|
||||||
|
condition: "[AST_Node]",
|
||||||
|
consequent: "[AST_Node]",
|
||||||
|
alternative: "[AST_Node]"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.condition._walk(visitor);
|
||||||
|
this.consequent._walk(visitor);
|
||||||
|
this.alternative._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_Assign = DEFNODE("Assign", null, {
|
||||||
|
$documentation: "An assignment expression — `a = b + 5`",
|
||||||
|
}, AST_Binary);
|
||||||
|
|
||||||
|
/* -----[ LITERALS ]----- */
|
||||||
|
|
||||||
|
var AST_Array = DEFNODE("Array", "elements", {
|
||||||
|
$documentation: "An array literal",
|
||||||
|
$propdoc: {
|
||||||
|
elements: "[AST_Node*] array of elements"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.elements.forEach(function(el){
|
||||||
|
el._walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_Object = DEFNODE("Object", "properties", {
|
||||||
|
$documentation: "An object literal",
|
||||||
|
$propdoc: {
|
||||||
|
properties: "[AST_ObjectProperty*] array of properties"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.properties.forEach(function(prop){
|
||||||
|
prop._walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||||
|
$documentation: "Base class for literal object properties",
|
||||||
|
$propdoc: {
|
||||||
|
key: "[string] the property name; it's always a plain string in our AST, no matter if it was a string, number or identifier in original code",
|
||||||
|
value: "[AST_Node] property value. For setters and getters this is an AST_Function."
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.value._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", null, {
|
||||||
|
$documentation: "A key: value object property",
|
||||||
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
|
var AST_ObjectSetter = DEFNODE("ObjectSetter", null, {
|
||||||
|
$documentation: "An object setter property",
|
||||||
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
|
var AST_ObjectGetter = DEFNODE("ObjectGetter", null, {
|
||||||
|
$documentation: "An object getter property",
|
||||||
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
|
var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
||||||
|
$propdoc: {
|
||||||
|
name: "[string] name of this symbol",
|
||||||
|
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
||||||
|
thedef: "[SymbolDef/S] the definition of this symbol"
|
||||||
|
},
|
||||||
|
$documentation: "Base class for all symbols",
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
||||||
|
$documentation: "The name of a property accessor (setter/getter function)"
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
|
||||||
|
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
|
||||||
|
$propdoc: {
|
||||||
|
init: "[AST_Node*/S] array of initializers for this declaration."
|
||||||
|
}
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
||||||
|
$documentation: "Symbol defining a variable",
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||||
|
$documentation: "A constant declaration"
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
|
||||||
|
$documentation: "Symbol naming a function argument",
|
||||||
|
}, AST_SymbolVar);
|
||||||
|
|
||||||
|
var AST_SymbolDefun = DEFNODE("SymbolDefun", null, {
|
||||||
|
$documentation: "Symbol defining a function",
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolLambda = DEFNODE("SymbolLambda", null, {
|
||||||
|
$documentation: "Symbol naming a function expression",
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
||||||
|
$documentation: "Symbol naming the exception in catch",
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_Label = DEFNODE("Label", "references", {
|
||||||
|
$documentation: "Symbol naming a label (declaration)",
|
||||||
|
$propdoc: {
|
||||||
|
references: "[AST_LabelRef*] a list of nodes referring to this label"
|
||||||
|
}
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_SymbolRef = DEFNODE("SymbolRef", null, {
|
||||||
|
$documentation: "Reference to some symbol (not definition/declaration)",
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_LabelRef = DEFNODE("LabelRef", null, {
|
||||||
|
$documentation: "Reference to a label symbol",
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_This = DEFNODE("This", null, {
|
||||||
|
$documentation: "The `this` symbol",
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_Constant = DEFNODE("Constant", null, {
|
||||||
|
$documentation: "Base class for all constants",
|
||||||
|
getValue: function() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_String = DEFNODE("String", "value", {
|
||||||
|
$documentation: "A string literal",
|
||||||
|
$propdoc: {
|
||||||
|
value: "[string] the contents of this string"
|
||||||
|
}
|
||||||
|
}, AST_Constant);
|
||||||
|
|
||||||
|
var AST_Number = DEFNODE("Number", "value", {
|
||||||
|
$documentation: "A number literal",
|
||||||
|
$propdoc: {
|
||||||
|
value: "[number] the numeric value"
|
||||||
|
}
|
||||||
|
}, AST_Constant);
|
||||||
|
|
||||||
|
var AST_RegExp = DEFNODE("RegExp", "value", {
|
||||||
|
$documentation: "A regexp literal",
|
||||||
|
$propdoc: {
|
||||||
|
value: "[RegExp] the actual regexp"
|
||||||
|
}
|
||||||
|
}, AST_Constant);
|
||||||
|
|
||||||
|
var AST_Atom = DEFNODE("Atom", null, {
|
||||||
|
$documentation: "Base class for atoms",
|
||||||
|
}, AST_Constant);
|
||||||
|
|
||||||
|
var AST_Null = DEFNODE("Null", null, {
|
||||||
|
$documentation: "The `null` atom",
|
||||||
|
value: null
|
||||||
|
}, AST_Atom);
|
||||||
|
|
||||||
|
var AST_NaN = DEFNODE("NaN", null, {
|
||||||
|
$documentation: "The impossible value",
|
||||||
|
value: 0/0
|
||||||
|
}, AST_Atom);
|
||||||
|
|
||||||
|
var AST_Undefined = DEFNODE("Undefined", null, {
|
||||||
|
$documentation: "The `undefined` value",
|
||||||
|
value: (function(){}())
|
||||||
|
}, AST_Atom);
|
||||||
|
|
||||||
|
var AST_Hole = DEFNODE("Hole", null, {
|
||||||
|
$documentation: "A hole in an array",
|
||||||
|
value: (function(){}())
|
||||||
|
}, AST_Atom);
|
||||||
|
|
||||||
|
var AST_Infinity = DEFNODE("Infinity", null, {
|
||||||
|
$documentation: "The `Infinity` value",
|
||||||
|
value: 1/0
|
||||||
|
}, AST_Atom);
|
||||||
|
|
||||||
|
var AST_Boolean = DEFNODE("Boolean", null, {
|
||||||
|
$documentation: "Base class for booleans",
|
||||||
|
}, AST_Atom);
|
||||||
|
|
||||||
|
var AST_False = DEFNODE("False", null, {
|
||||||
|
$documentation: "The `false` atom",
|
||||||
|
value: false
|
||||||
|
}, AST_Boolean);
|
||||||
|
|
||||||
|
var AST_True = DEFNODE("True", null, {
|
||||||
|
$documentation: "The `true` atom",
|
||||||
|
value: true
|
||||||
|
}, AST_Boolean);
|
||||||
|
|
||||||
|
/* -----[ TreeWalker ]----- */
|
||||||
|
|
||||||
|
function TreeWalker(callback) {
|
||||||
|
this.visit = callback;
|
||||||
|
this.stack = [];
|
||||||
|
};
|
||||||
|
TreeWalker.prototype = {
|
||||||
|
_visit: function(node, descend) {
|
||||||
|
this.stack.push(node);
|
||||||
|
var ret = this.visit(node, descend ? function(){
|
||||||
|
descend.call(node);
|
||||||
|
} : noop);
|
||||||
|
if (!ret && descend) {
|
||||||
|
descend.call(node);
|
||||||
|
}
|
||||||
|
this.stack.pop();
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
parent: function(n) {
|
||||||
|
return this.stack[this.stack.length - 2 - (n || 0)];
|
||||||
|
},
|
||||||
|
push: function (node) {
|
||||||
|
this.stack.push(node);
|
||||||
|
},
|
||||||
|
pop: function() {
|
||||||
|
return this.stack.pop();
|
||||||
|
},
|
||||||
|
self: function() {
|
||||||
|
return this.stack[this.stack.length - 1];
|
||||||
|
},
|
||||||
|
find_parent: function(type) {
|
||||||
|
var stack = this.stack;
|
||||||
|
for (var i = stack.length; --i >= 0;) {
|
||||||
|
var x = stack[i];
|
||||||
|
if (x instanceof type) return x;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
in_boolean_context: function() {
|
||||||
|
var stack = this.stack;
|
||||||
|
var i = stack.length, self = stack[--i];
|
||||||
|
while (i > 0) {
|
||||||
|
var p = stack[--i];
|
||||||
|
if ((p instanceof AST_If && p.condition === self) ||
|
||||||
|
(p instanceof AST_Conditional && p.condition === self) ||
|
||||||
|
(p instanceof AST_DWLoop && p.condition === self) ||
|
||||||
|
(p instanceof AST_For && p.condition === self) ||
|
||||||
|
(p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||")))
|
||||||
|
return false;
|
||||||
|
self = p;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loopcontrol_target: function(label) {
|
||||||
|
var stack = this.stack;
|
||||||
|
if (label) {
|
||||||
|
for (var i = stack.length; --i >= 0;) {
|
||||||
|
var x = stack[i];
|
||||||
|
if (x instanceof AST_LabeledStatement && x.label.name == label.name) {
|
||||||
|
return x.body;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (var i = stack.length; --i >= 0;) {
|
||||||
|
var x = stack[i];
|
||||||
|
if (x instanceof AST_Switch
|
||||||
|
|| x instanceof AST_For
|
||||||
|
|| x instanceof AST_ForIn
|
||||||
|
|| x instanceof AST_DWLoop) return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
2028
node_modules/handlebars/node_modules/uglify-js/lib/compress.js
generated
vendored
Normal file
2028
node_modules/handlebars/node_modules/uglify-js/lib/compress.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2599
node_modules/handlebars/node_modules/uglify-js/lib/consolidator.js
generated
vendored
2599
node_modules/handlebars/node_modules/uglify-js/lib/consolidator.js
generated
vendored
File diff suppressed because it is too large
Load Diff
267
node_modules/handlebars/node_modules/uglify-js/lib/mozilla-ast.js
generated
vendored
Normal file
267
node_modules/handlebars/node_modules/uglify-js/lib/mozilla-ast.js
generated
vendored
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
|
||||||
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
|
https://github.com/mishoo/UglifyJS2
|
||||||
|
|
||||||
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
|
Author: Mihai Bazon
|
||||||
|
<mihai.bazon@gmail.com>
|
||||||
|
http://mihai.bazon.net/blog
|
||||||
|
|
||||||
|
Distributed under the BSD license:
|
||||||
|
|
||||||
|
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials
|
||||||
|
provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||||
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var MOZ_TO_ME = {
|
||||||
|
TryStatement : function(M) {
|
||||||
|
return new AST_Try({
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M),
|
||||||
|
body : from_moz(M.block).body,
|
||||||
|
bcatch : from_moz(M.handlers[0]),
|
||||||
|
bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null
|
||||||
|
});
|
||||||
|
},
|
||||||
|
CatchClause : function(M) {
|
||||||
|
return new AST_Catch({
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M),
|
||||||
|
argname : from_moz(M.param),
|
||||||
|
body : from_moz(M.body).body
|
||||||
|
});
|
||||||
|
},
|
||||||
|
ObjectExpression : function(M) {
|
||||||
|
return new AST_Object({
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M),
|
||||||
|
properties : M.properties.map(function(prop){
|
||||||
|
var key = prop.key;
|
||||||
|
var name = key.type == "Identifier" ? key.name : key.value;
|
||||||
|
var args = {
|
||||||
|
start : my_start_token(key),
|
||||||
|
end : my_end_token(prop.value),
|
||||||
|
key : name,
|
||||||
|
value : from_moz(prop.value)
|
||||||
|
};
|
||||||
|
switch (prop.kind) {
|
||||||
|
case "init":
|
||||||
|
return new AST_ObjectKeyVal(args);
|
||||||
|
case "set":
|
||||||
|
args.value.name = from_moz(key);
|
||||||
|
return new AST_ObjectSetter(args);
|
||||||
|
case "get":
|
||||||
|
args.value.name = from_moz(key);
|
||||||
|
return new AST_ObjectGetter(args);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
},
|
||||||
|
SequenceExpression : function(M) {
|
||||||
|
return AST_Seq.from_array(M.expressions.map(from_moz));
|
||||||
|
},
|
||||||
|
MemberExpression : function(M) {
|
||||||
|
return new (M.computed ? AST_Sub : AST_Dot)({
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M),
|
||||||
|
property : M.computed ? from_moz(M.property) : M.property.name,
|
||||||
|
expression : from_moz(M.object)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
SwitchCase : function(M) {
|
||||||
|
return new (M.test ? AST_Case : AST_Default)({
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M),
|
||||||
|
expression : from_moz(M.test),
|
||||||
|
body : M.consequent.map(from_moz)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
Literal : function(M) {
|
||||||
|
var val = M.value, args = {
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M)
|
||||||
|
};
|
||||||
|
if (val === null) return new AST_Null(args);
|
||||||
|
switch (typeof val) {
|
||||||
|
case "string":
|
||||||
|
args.value = val;
|
||||||
|
return new AST_String(args);
|
||||||
|
case "number":
|
||||||
|
args.value = val;
|
||||||
|
return new AST_Number(args);
|
||||||
|
case "boolean":
|
||||||
|
return new (val ? AST_True : AST_False)(args);
|
||||||
|
default:
|
||||||
|
args.value = val;
|
||||||
|
return new AST_RegExp(args);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
UnaryExpression: From_Moz_Unary,
|
||||||
|
UpdateExpression: From_Moz_Unary,
|
||||||
|
Identifier: function(M) {
|
||||||
|
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
||||||
|
return new (M.name == "this" ? AST_This
|
||||||
|
: p.type == "LabeledStatement" ? AST_Label
|
||||||
|
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar)
|
||||||
|
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
|
||||||
|
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
|
||||||
|
: p.type == "CatchClause" ? AST_SymbolCatch
|
||||||
|
: p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef
|
||||||
|
: AST_SymbolRef)({
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M),
|
||||||
|
name : M.name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function From_Moz_Unary(M) {
|
||||||
|
var prefix = "prefix" in M ? M.prefix
|
||||||
|
: M.type == "UnaryExpression" ? true : false;
|
||||||
|
return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M),
|
||||||
|
operator : M.operator,
|
||||||
|
expression : from_moz(M.argument)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var ME_TO_MOZ = {};
|
||||||
|
|
||||||
|
map("Node", AST_Node);
|
||||||
|
map("Program", AST_Toplevel, "body@body");
|
||||||
|
map("Function", AST_Function, "id>name, params@argnames, body%body");
|
||||||
|
map("EmptyStatement", AST_EmptyStatement);
|
||||||
|
map("BlockStatement", AST_BlockStatement, "body@body");
|
||||||
|
map("ExpressionStatement", AST_SimpleStatement, "expression>body");
|
||||||
|
map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative");
|
||||||
|
map("LabeledStatement", AST_LabeledStatement, "label>label, body>body");
|
||||||
|
map("BreakStatement", AST_Break, "label>label");
|
||||||
|
map("ContinueStatement", AST_Continue, "label>label");
|
||||||
|
map("WithStatement", AST_With, "object>expression, body>body");
|
||||||
|
map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body");
|
||||||
|
map("ReturnStatement", AST_Return, "argument>value");
|
||||||
|
map("ThrowStatement", AST_Throw, "argument>value");
|
||||||
|
map("WhileStatement", AST_While, "test>condition, body>body");
|
||||||
|
map("DoWhileStatement", AST_Do, "test>condition, body>body");
|
||||||
|
map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body");
|
||||||
|
map("ForInStatement", AST_ForIn, "left>init, right>object, body>body");
|
||||||
|
map("DebuggerStatement", AST_Debugger);
|
||||||
|
map("FunctionDeclaration", AST_Defun, "id>name, params@argnames, body%body");
|
||||||
|
map("VariableDeclaration", AST_Var, "declarations@definitions");
|
||||||
|
map("VariableDeclarator", AST_VarDef, "id>name, init>value");
|
||||||
|
|
||||||
|
map("ThisExpression", AST_This);
|
||||||
|
map("ArrayExpression", AST_Array, "elements@elements");
|
||||||
|
map("FunctionExpression", AST_Function, "id>name, params@argnames, body%body");
|
||||||
|
map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right");
|
||||||
|
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
|
||||||
|
map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right");
|
||||||
|
map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
|
||||||
|
map("NewExpression", AST_New, "callee>expression, arguments@args");
|
||||||
|
map("CallExpression", AST_Call, "callee>expression, arguments@args");
|
||||||
|
|
||||||
|
/* -----[ tools ]----- */
|
||||||
|
|
||||||
|
function my_start_token(moznode) {
|
||||||
|
return new AST_Token({
|
||||||
|
file : moznode.loc && moznode.loc.source,
|
||||||
|
line : moznode.loc && moznode.loc.start.line,
|
||||||
|
col : moznode.loc && moznode.loc.start.column,
|
||||||
|
pos : moznode.start,
|
||||||
|
endpos : moznode.start
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function my_end_token(moznode) {
|
||||||
|
return new AST_Token({
|
||||||
|
file : moznode.loc && moznode.loc.source,
|
||||||
|
line : moznode.loc && moznode.loc.end.line,
|
||||||
|
col : moznode.loc && moznode.loc.end.column,
|
||||||
|
pos : moznode.end,
|
||||||
|
endpos : moznode.end
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function map(moztype, mytype, propmap) {
|
||||||
|
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
||||||
|
moz_to_me += "return new mytype({\n" +
|
||||||
|
"start: my_start_token(M),\n" +
|
||||||
|
"end: my_end_token(M)";
|
||||||
|
|
||||||
|
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){
|
||||||
|
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
|
||||||
|
if (!m) throw new Error("Can't understand property map: " + prop);
|
||||||
|
var moz = "M." + m[1], how = m[2], my = m[3];
|
||||||
|
moz_to_me += ",\n" + my + ": ";
|
||||||
|
if (how == "@") {
|
||||||
|
moz_to_me += moz + ".map(from_moz)";
|
||||||
|
} else if (how == ">") {
|
||||||
|
moz_to_me += "from_moz(" + moz + ")";
|
||||||
|
} else if (how == "=") {
|
||||||
|
moz_to_me += moz;
|
||||||
|
} else if (how == "%") {
|
||||||
|
moz_to_me += "from_moz(" + moz + ").body";
|
||||||
|
} else throw new Error("Can't understand operator in propmap: " + prop);
|
||||||
|
});
|
||||||
|
moz_to_me += "\n})}";
|
||||||
|
|
||||||
|
// moz_to_me = parse(moz_to_me).print_to_string({ beautify: true });
|
||||||
|
// console.log(moz_to_me);
|
||||||
|
|
||||||
|
moz_to_me = new Function("mytype", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
|
||||||
|
mytype, my_start_token, my_end_token, from_moz
|
||||||
|
);
|
||||||
|
return MOZ_TO_ME[moztype] = moz_to_me;
|
||||||
|
};
|
||||||
|
|
||||||
|
var FROM_MOZ_STACK = null;
|
||||||
|
|
||||||
|
function from_moz(node) {
|
||||||
|
FROM_MOZ_STACK.push(node);
|
||||||
|
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
|
||||||
|
FROM_MOZ_STACK.pop();
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
AST_Node.from_mozilla_ast = function(node){
|
||||||
|
var save_stack = FROM_MOZ_STACK;
|
||||||
|
FROM_MOZ_STACK = [];
|
||||||
|
var ast = from_moz(node);
|
||||||
|
FROM_MOZ_STACK = save_stack;
|
||||||
|
return ast;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
75
node_modules/handlebars/node_modules/uglify-js/lib/object-ast.js
generated
vendored
75
node_modules/handlebars/node_modules/uglify-js/lib/object-ast.js
generated
vendored
@@ -1,75 +0,0 @@
|
|||||||
var jsp = require("./parse-js"),
|
|
||||||
pro = require("./process");
|
|
||||||
|
|
||||||
var BY_TYPE = {};
|
|
||||||
|
|
||||||
function HOP(obj, prop) {
|
|
||||||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
||||||
};
|
|
||||||
|
|
||||||
function AST_Node(parent) {
|
|
||||||
this.parent = parent;
|
|
||||||
};
|
|
||||||
|
|
||||||
AST_Node.prototype.init = function(){};
|
|
||||||
|
|
||||||
function DEFINE_NODE_CLASS(type, props, methods) {
|
|
||||||
var base = methods && methods.BASE || AST_Node;
|
|
||||||
if (!base) base = AST_Node;
|
|
||||||
function D(parent, data) {
|
|
||||||
base.apply(this, arguments);
|
|
||||||
if (props) props.forEach(function(name, i){
|
|
||||||
this["_" + name] = data[i];
|
|
||||||
});
|
|
||||||
this.init();
|
|
||||||
};
|
|
||||||
var P = D.prototype = new AST_Node;
|
|
||||||
P.node_type = function(){ return type };
|
|
||||||
if (props) props.forEach(function(name){
|
|
||||||
var propname = "_" + name;
|
|
||||||
P["set_" + name] = function(val) {
|
|
||||||
this[propname] = val;
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
P["get_" + name] = function() {
|
|
||||||
return this[propname];
|
|
||||||
};
|
|
||||||
});
|
|
||||||
if (type != null) BY_TYPE[type] = D;
|
|
||||||
if (methods) for (var i in methods) if (HOP(methods, i)) {
|
|
||||||
P[i] = methods[i];
|
|
||||||
}
|
|
||||||
return D;
|
|
||||||
};
|
|
||||||
|
|
||||||
var AST_String_Node = DEFINE_NODE_CLASS("string", ["value"]);
|
|
||||||
var AST_Number_Node = DEFINE_NODE_CLASS("num", ["value"]);
|
|
||||||
var AST_Name_Node = DEFINE_NODE_CLASS("name", ["value"]);
|
|
||||||
|
|
||||||
var AST_Statlist_Node = DEFINE_NODE_CLASS(null, ["body"]);
|
|
||||||
var AST_Root_Node = DEFINE_NODE_CLASS("toplevel", null, { BASE: AST_Statlist_Node });
|
|
||||||
var AST_Block_Node = DEFINE_NODE_CLASS("block", null, { BASE: AST_Statlist_Node });
|
|
||||||
var AST_Splice_Node = DEFINE_NODE_CLASS("splice", null, { BASE: AST_Statlist_Node });
|
|
||||||
|
|
||||||
var AST_Var_Node = DEFINE_NODE_CLASS("var", ["definitions"]);
|
|
||||||
var AST_Const_Node = DEFINE_NODE_CLASS("const", ["definitions"]);
|
|
||||||
|
|
||||||
var AST_Try_Node = DEFINE_NODE_CLASS("try", ["body", "catch", "finally"]);
|
|
||||||
var AST_Throw_Node = DEFINE_NODE_CLASS("throw", ["exception"]);
|
|
||||||
|
|
||||||
var AST_New_Node = DEFINE_NODE_CLASS("new", ["constructor", "arguments"]);
|
|
||||||
|
|
||||||
var AST_Switch_Node = DEFINE_NODE_CLASS("switch", ["expression", "branches"]);
|
|
||||||
var AST_Switch_Branch_Node = DEFINE_NODE_CLASS(null, ["expression", "body"]);
|
|
||||||
|
|
||||||
var AST_Break_Node = DEFINE_NODE_CLASS("break", ["label"]);
|
|
||||||
var AST_Continue_Node = DEFINE_NODE_CLASS("continue", ["label"]);
|
|
||||||
var AST_Assign_Node = DEFINE_NODE_CLASS("assign", ["operator", "lvalue", "rvalue"]);
|
|
||||||
var AST_Dot_Node = DEFINE_NODE_CLASS("dot", ["expression", "name"]);
|
|
||||||
var AST_Call_Node = DEFINE_NODE_CLASS("call", ["function", "arguments"]);
|
|
||||||
|
|
||||||
var AST_Lambda_Node = DEFINE_NODE_CLASS(null, ["name", "arguments", "body"])
|
|
||||||
var AST_Function_Node = DEFINE_NODE_CLASS("function", null, AST_Lambda_Node);
|
|
||||||
var AST_Defun_Node = DEFINE_NODE_CLASS("defun", null, AST_Lambda_Node);
|
|
||||||
|
|
||||||
var AST_If_Node = DEFINE_NODE_CLASS("if", ["condition", "then", "else"]);
|
|
||||||
1229
node_modules/handlebars/node_modules/uglify-js/lib/output.js
generated
vendored
Normal file
1229
node_modules/handlebars/node_modules/uglify-js/lib/output.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1346
node_modules/handlebars/node_modules/uglify-js/lib/parse-js.js
generated
vendored
1346
node_modules/handlebars/node_modules/uglify-js/lib/parse-js.js
generated
vendored
File diff suppressed because it is too large
Load Diff
1410
node_modules/handlebars/node_modules/uglify-js/lib/parse.js
generated
vendored
Normal file
1410
node_modules/handlebars/node_modules/uglify-js/lib/parse.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2011
node_modules/handlebars/node_modules/uglify-js/lib/process.js
generated
vendored
2011
node_modules/handlebars/node_modules/uglify-js/lib/process.js
generated
vendored
File diff suppressed because it is too large
Load Diff
581
node_modules/handlebars/node_modules/uglify-js/lib/scope.js
generated
vendored
Normal file
581
node_modules/handlebars/node_modules/uglify-js/lib/scope.js
generated
vendored
Normal file
@@ -0,0 +1,581 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
|
||||||
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
|
https://github.com/mishoo/UglifyJS2
|
||||||
|
|
||||||
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
|
Author: Mihai Bazon
|
||||||
|
<mihai.bazon@gmail.com>
|
||||||
|
http://mihai.bazon.net/blog
|
||||||
|
|
||||||
|
Distributed under the BSD license:
|
||||||
|
|
||||||
|
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials
|
||||||
|
provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||||
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function SymbolDef(scope, index, orig) {
|
||||||
|
this.name = orig.name;
|
||||||
|
this.orig = [ orig ];
|
||||||
|
this.scope = scope;
|
||||||
|
this.references = [];
|
||||||
|
this.global = false;
|
||||||
|
this.mangled_name = null;
|
||||||
|
this.undeclared = false;
|
||||||
|
this.constant = false;
|
||||||
|
this.index = index;
|
||||||
|
};
|
||||||
|
|
||||||
|
SymbolDef.prototype = {
|
||||||
|
unmangleable: function(options) {
|
||||||
|
return (this.global && !(options && options.toplevel))
|
||||||
|
|| this.undeclared
|
||||||
|
|| (!(options && options.eval) && (this.scope.uses_eval || this.scope.uses_with));
|
||||||
|
},
|
||||||
|
mangle: function(options) {
|
||||||
|
if (!this.mangled_name && !this.unmangleable(options)) {
|
||||||
|
var s = this.scope;
|
||||||
|
if (this.orig[0] instanceof AST_SymbolLambda && !options.screw_ie8)
|
||||||
|
s = s.parent_scope;
|
||||||
|
this.mangled_name = s.next_mangled(options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("figure_out_scope", function(){
|
||||||
|
// This does what ast_add_scope did in UglifyJS v1.
|
||||||
|
//
|
||||||
|
// Part of it could be done at parse time, but it would complicate
|
||||||
|
// the parser (and it's already kinda complex). It's also worth
|
||||||
|
// having it separated because we might need to call it multiple
|
||||||
|
// times on the same tree.
|
||||||
|
|
||||||
|
// pass 1: setup scope chaining and handle definitions
|
||||||
|
var self = this;
|
||||||
|
var scope = self.parent_scope = null;
|
||||||
|
var labels = new Dictionary();
|
||||||
|
var nesting = 0;
|
||||||
|
var tw = new TreeWalker(function(node, descend){
|
||||||
|
if (node instanceof AST_Scope) {
|
||||||
|
node.init_scope_vars(nesting);
|
||||||
|
var save_scope = node.parent_scope = scope;
|
||||||
|
var save_labels = labels;
|
||||||
|
++nesting;
|
||||||
|
scope = node;
|
||||||
|
labels = new Dictionary();
|
||||||
|
descend();
|
||||||
|
labels = save_labels;
|
||||||
|
scope = save_scope;
|
||||||
|
--nesting;
|
||||||
|
return true; // don't descend again in TreeWalker
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Directive) {
|
||||||
|
node.scope = scope;
|
||||||
|
push_uniq(scope.directives, node.value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_With) {
|
||||||
|
for (var s = scope; s; s = s.parent_scope)
|
||||||
|
s.uses_with = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_LabeledStatement) {
|
||||||
|
var l = node.label;
|
||||||
|
if (labels.has(l.name))
|
||||||
|
throw new Error(string_template("Label {name} defined twice", l));
|
||||||
|
labels.set(l.name, l);
|
||||||
|
descend();
|
||||||
|
labels.del(l.name);
|
||||||
|
return true; // no descend again
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Symbol) {
|
||||||
|
node.scope = scope;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Label) {
|
||||||
|
node.thedef = node;
|
||||||
|
node.init_scope_vars();
|
||||||
|
}
|
||||||
|
if (node instanceof AST_SymbolLambda) {
|
||||||
|
scope.def_function(node);
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_SymbolDefun) {
|
||||||
|
// Careful here, the scope where this should be defined is
|
||||||
|
// the parent scope. The reason is that we enter a new
|
||||||
|
// scope when we encounter the AST_Defun node (which is
|
||||||
|
// instanceof AST_Scope) but we get to the symbol a bit
|
||||||
|
// later.
|
||||||
|
(node.scope = scope.parent_scope).def_function(node);
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_SymbolVar
|
||||||
|
|| node instanceof AST_SymbolConst) {
|
||||||
|
var def = scope.def_variable(node);
|
||||||
|
def.constant = node instanceof AST_SymbolConst;
|
||||||
|
def.init = tw.parent().value;
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_SymbolCatch) {
|
||||||
|
// XXX: this is wrong according to ECMA-262 (12.4). the
|
||||||
|
// `catch` argument name should be visible only inside the
|
||||||
|
// catch block. For a quick fix AST_Catch should inherit
|
||||||
|
// from AST_Scope. Keeping it this way because of IE,
|
||||||
|
// which doesn't obey the standard. (it introduces the
|
||||||
|
// identifier in the enclosing scope)
|
||||||
|
scope.def_variable(node);
|
||||||
|
}
|
||||||
|
if (node instanceof AST_LabelRef) {
|
||||||
|
var sym = labels.get(node.name);
|
||||||
|
if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
|
||||||
|
name: node.name,
|
||||||
|
line: node.start.line,
|
||||||
|
col: node.start.col
|
||||||
|
}));
|
||||||
|
node.thedef = sym;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.walk(tw);
|
||||||
|
|
||||||
|
// pass 2: find back references and eval
|
||||||
|
var func = null;
|
||||||
|
var globals = self.globals = new Dictionary();
|
||||||
|
var tw = new TreeWalker(function(node, descend){
|
||||||
|
if (node instanceof AST_Lambda) {
|
||||||
|
var prev_func = func;
|
||||||
|
func = node;
|
||||||
|
descend();
|
||||||
|
func = prev_func;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_LabelRef) {
|
||||||
|
node.reference();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_SymbolRef) {
|
||||||
|
var name = node.name;
|
||||||
|
var sym = node.scope.find_variable(name);
|
||||||
|
if (!sym) {
|
||||||
|
var g;
|
||||||
|
if (globals.has(name)) {
|
||||||
|
g = globals.get(name);
|
||||||
|
} else {
|
||||||
|
g = new SymbolDef(self, globals.size(), node);
|
||||||
|
g.undeclared = true;
|
||||||
|
g.global = true;
|
||||||
|
globals.set(name, g);
|
||||||
|
}
|
||||||
|
node.thedef = g;
|
||||||
|
if (name == "eval" && tw.parent() instanceof AST_Call) {
|
||||||
|
for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope)
|
||||||
|
s.uses_eval = true;
|
||||||
|
}
|
||||||
|
if (name == "arguments") {
|
||||||
|
func.uses_arguments = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
node.thedef = sym;
|
||||||
|
}
|
||||||
|
node.reference();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.walk(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
|
||||||
|
this.directives = []; // contains the directives defined in this scope, i.e. "use strict"
|
||||||
|
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||||
|
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
||||||
|
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||||
|
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
|
||||||
|
this.parent_scope = null; // the parent scope
|
||||||
|
this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes
|
||||||
|
this.cname = -1; // the current index for mangling functions/variables
|
||||||
|
this.nesting = nesting; // the nesting level of this scope (0 means toplevel)
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("strict", function(){
|
||||||
|
return this.has_directive("use strict");
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||||
|
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||||
|
this.uses_arguments = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_SymbolRef.DEFMETHOD("reference", function() {
|
||||||
|
var def = this.definition();
|
||||||
|
def.references.push(this);
|
||||||
|
var s = this.scope;
|
||||||
|
while (s) {
|
||||||
|
push_uniq(s.enclosed, def);
|
||||||
|
if (s === def.scope) break;
|
||||||
|
s = s.parent_scope;
|
||||||
|
}
|
||||||
|
this.frame = this.scope.nesting - def.scope.nesting;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Label.DEFMETHOD("init_scope_vars", function(){
|
||||||
|
this.references = [];
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_LabelRef.DEFMETHOD("reference", function(){
|
||||||
|
this.thedef.references.push(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||||
|
if (name instanceof AST_Symbol) name = name.name;
|
||||||
|
return this.variables.get(name)
|
||||||
|
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("has_directive", function(value){
|
||||||
|
return this.parent_scope && this.parent_scope.has_directive(value)
|
||||||
|
|| (this.directives.indexOf(value) >= 0 ? this : null);
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||||
|
this.functions.set(symbol.name, this.def_variable(symbol));
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||||
|
var def;
|
||||||
|
if (!this.variables.has(symbol.name)) {
|
||||||
|
def = new SymbolDef(this, this.variables.size(), symbol);
|
||||||
|
this.variables.set(symbol.name, def);
|
||||||
|
def.global = !this.parent_scope;
|
||||||
|
} else {
|
||||||
|
def = this.variables.get(symbol.name);
|
||||||
|
def.orig.push(symbol);
|
||||||
|
}
|
||||||
|
return symbol.thedef = def;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||||
|
var ext = this.enclosed;
|
||||||
|
out: while (true) {
|
||||||
|
var m = base54(++this.cname);
|
||||||
|
if (!is_identifier(m)) continue; // skip over "do"
|
||||||
|
// we must ensure that the mangled name does not shadow a name
|
||||||
|
// from some parent scope that is referenced in this or in
|
||||||
|
// inner scopes.
|
||||||
|
for (var i = ext.length; --i >= 0;) {
|
||||||
|
var sym = ext[i];
|
||||||
|
var name = sym.mangled_name || (sym.unmangleable(options) && sym.name);
|
||||||
|
if (m == name) continue out;
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("references", function(sym){
|
||||||
|
if (sym instanceof AST_Symbol) sym = sym.definition();
|
||||||
|
return this.enclosed.indexOf(sym) < 0 ? null : sym;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||||
|
return this.definition().unmangleable(options);
|
||||||
|
});
|
||||||
|
|
||||||
|
// property accessors are not mangleable
|
||||||
|
AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
// labels are always mangleable
|
||||||
|
AST_Label.DEFMETHOD("unmangleable", function(){
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
||||||
|
return this.definition().references.length == 0
|
||||||
|
&& !(this.scope.uses_eval || this.scope.uses_with);
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Symbol.DEFMETHOD("undeclared", function(){
|
||||||
|
return this.definition().undeclared;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_LabelRef.DEFMETHOD("undeclared", function(){
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Label.DEFMETHOD("undeclared", function(){
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Symbol.DEFMETHOD("definition", function(){
|
||||||
|
return this.thedef;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Symbol.DEFMETHOD("global", function(){
|
||||||
|
return this.definition().global;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||||
|
return defaults(options, {
|
||||||
|
except : [],
|
||||||
|
eval : false,
|
||||||
|
sort : false,
|
||||||
|
toplevel : false,
|
||||||
|
screw_ie8 : false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||||
|
options = this._default_mangler_options(options);
|
||||||
|
// We only need to mangle declaration nodes. Special logic wired
|
||||||
|
// into the code generator will display the mangled name if it's
|
||||||
|
// present (and for AST_SymbolRef-s it'll use the mangled name of
|
||||||
|
// the AST_SymbolDeclaration that it points to).
|
||||||
|
var lname = -1;
|
||||||
|
var to_mangle = [];
|
||||||
|
var tw = new TreeWalker(function(node, descend){
|
||||||
|
if (node instanceof AST_LabeledStatement) {
|
||||||
|
// lname is incremented when we get to the AST_Label
|
||||||
|
var save_nesting = lname;
|
||||||
|
descend();
|
||||||
|
lname = save_nesting;
|
||||||
|
return true; // don't descend again in TreeWalker
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Scope) {
|
||||||
|
var p = tw.parent(), a = [];
|
||||||
|
node.variables.each(function(symbol){
|
||||||
|
if (options.except.indexOf(symbol.name) < 0) {
|
||||||
|
a.push(symbol);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (options.sort) a.sort(function(a, b){
|
||||||
|
return b.references.length - a.references.length;
|
||||||
|
});
|
||||||
|
to_mangle.push.apply(to_mangle, a);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Label) {
|
||||||
|
var name;
|
||||||
|
do name = base54(++lname); while (!is_identifier(name));
|
||||||
|
node.mangled_name = name;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.walk(tw);
|
||||||
|
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||||
|
options = this._default_mangler_options(options);
|
||||||
|
var tw = new TreeWalker(function(node){
|
||||||
|
if (node instanceof AST_Constant)
|
||||||
|
base54.consider(node.print_to_string());
|
||||||
|
else if (node instanceof AST_Return)
|
||||||
|
base54.consider("return");
|
||||||
|
else if (node instanceof AST_Throw)
|
||||||
|
base54.consider("throw");
|
||||||
|
else if (node instanceof AST_Continue)
|
||||||
|
base54.consider("continue");
|
||||||
|
else if (node instanceof AST_Break)
|
||||||
|
base54.consider("break");
|
||||||
|
else if (node instanceof AST_Debugger)
|
||||||
|
base54.consider("debugger");
|
||||||
|
else if (node instanceof AST_Directive)
|
||||||
|
base54.consider(node.value);
|
||||||
|
else if (node instanceof AST_While)
|
||||||
|
base54.consider("while");
|
||||||
|
else if (node instanceof AST_Do)
|
||||||
|
base54.consider("do while");
|
||||||
|
else if (node instanceof AST_If) {
|
||||||
|
base54.consider("if");
|
||||||
|
if (node.alternative) base54.consider("else");
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_Var)
|
||||||
|
base54.consider("var");
|
||||||
|
else if (node instanceof AST_Const)
|
||||||
|
base54.consider("const");
|
||||||
|
else if (node instanceof AST_Lambda)
|
||||||
|
base54.consider("function");
|
||||||
|
else if (node instanceof AST_For)
|
||||||
|
base54.consider("for");
|
||||||
|
else if (node instanceof AST_ForIn)
|
||||||
|
base54.consider("for in");
|
||||||
|
else if (node instanceof AST_Switch)
|
||||||
|
base54.consider("switch");
|
||||||
|
else if (node instanceof AST_Case)
|
||||||
|
base54.consider("case");
|
||||||
|
else if (node instanceof AST_Default)
|
||||||
|
base54.consider("default");
|
||||||
|
else if (node instanceof AST_With)
|
||||||
|
base54.consider("with");
|
||||||
|
else if (node instanceof AST_ObjectSetter)
|
||||||
|
base54.consider("set" + node.key);
|
||||||
|
else if (node instanceof AST_ObjectGetter)
|
||||||
|
base54.consider("get" + node.key);
|
||||||
|
else if (node instanceof AST_ObjectKeyVal)
|
||||||
|
base54.consider(node.key);
|
||||||
|
else if (node instanceof AST_New)
|
||||||
|
base54.consider("new");
|
||||||
|
else if (node instanceof AST_This)
|
||||||
|
base54.consider("this");
|
||||||
|
else if (node instanceof AST_Try)
|
||||||
|
base54.consider("try");
|
||||||
|
else if (node instanceof AST_Catch)
|
||||||
|
base54.consider("catch");
|
||||||
|
else if (node instanceof AST_Finally)
|
||||||
|
base54.consider("finally");
|
||||||
|
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
||||||
|
base54.consider(node.name);
|
||||||
|
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
||||||
|
base54.consider(node.operator);
|
||||||
|
else if (node instanceof AST_Dot)
|
||||||
|
base54.consider(node.property);
|
||||||
|
});
|
||||||
|
this.walk(tw);
|
||||||
|
base54.sort();
|
||||||
|
});
|
||||||
|
|
||||||
|
var base54 = (function() {
|
||||||
|
var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
||||||
|
var chars, frequency;
|
||||||
|
function reset() {
|
||||||
|
frequency = Object.create(null);
|
||||||
|
chars = string.split("").map(function(ch){ return ch.charCodeAt(0) });
|
||||||
|
chars.forEach(function(ch){ frequency[ch] = 0 });
|
||||||
|
}
|
||||||
|
base54.consider = function(str){
|
||||||
|
for (var i = str.length; --i >= 0;) {
|
||||||
|
var code = str.charCodeAt(i);
|
||||||
|
if (code in frequency) ++frequency[code];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
base54.sort = function() {
|
||||||
|
chars = mergeSort(chars, function(a, b){
|
||||||
|
if (is_digit(a) && !is_digit(b)) return 1;
|
||||||
|
if (is_digit(b) && !is_digit(a)) return -1;
|
||||||
|
return frequency[b] - frequency[a];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
base54.reset = reset;
|
||||||
|
reset();
|
||||||
|
base54.get = function(){ return chars };
|
||||||
|
base54.freq = function(){ return frequency };
|
||||||
|
function base54(num) {
|
||||||
|
var ret = "", base = 54;
|
||||||
|
do {
|
||||||
|
ret += String.fromCharCode(chars[num % base]);
|
||||||
|
num = Math.floor(num / base);
|
||||||
|
base = 64;
|
||||||
|
} while (num > 0);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
return base54;
|
||||||
|
})();
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
||||||
|
options = defaults(options, {
|
||||||
|
undeclared : false, // this makes a lot of noise
|
||||||
|
unreferenced : true,
|
||||||
|
assign_to_global : true,
|
||||||
|
func_arguments : true,
|
||||||
|
nested_defuns : true,
|
||||||
|
eval : true
|
||||||
|
});
|
||||||
|
var tw = new TreeWalker(function(node){
|
||||||
|
if (options.undeclared
|
||||||
|
&& node instanceof AST_SymbolRef
|
||||||
|
&& node.undeclared())
|
||||||
|
{
|
||||||
|
// XXX: this also warns about JS standard names,
|
||||||
|
// i.e. Object, Array, parseInt etc. Should add a list of
|
||||||
|
// exceptions.
|
||||||
|
AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", {
|
||||||
|
name: node.name,
|
||||||
|
file: node.start.file,
|
||||||
|
line: node.start.line,
|
||||||
|
col: node.start.col
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (options.assign_to_global)
|
||||||
|
{
|
||||||
|
var sym = null;
|
||||||
|
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef)
|
||||||
|
sym = node.left;
|
||||||
|
else if (node instanceof AST_ForIn && node.init instanceof AST_SymbolRef)
|
||||||
|
sym = node.init;
|
||||||
|
if (sym
|
||||||
|
&& (sym.undeclared()
|
||||||
|
|| (sym.global() && sym.scope !== sym.definition().scope))) {
|
||||||
|
AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", {
|
||||||
|
msg: sym.undeclared() ? "Accidental global?" : "Assignment to global",
|
||||||
|
name: sym.name,
|
||||||
|
file: sym.start.file,
|
||||||
|
line: sym.start.line,
|
||||||
|
col: sym.start.col
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (options.eval
|
||||||
|
&& node instanceof AST_SymbolRef
|
||||||
|
&& node.undeclared()
|
||||||
|
&& node.name == "eval") {
|
||||||
|
AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start);
|
||||||
|
}
|
||||||
|
if (options.unreferenced
|
||||||
|
&& (node instanceof AST_SymbolDeclaration || node instanceof AST_Label)
|
||||||
|
&& node.unreferenced()) {
|
||||||
|
AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", {
|
||||||
|
type: node instanceof AST_Label ? "Label" : "Symbol",
|
||||||
|
name: node.name,
|
||||||
|
file: node.start.file,
|
||||||
|
line: node.start.line,
|
||||||
|
col: node.start.col
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (options.func_arguments
|
||||||
|
&& node instanceof AST_Lambda
|
||||||
|
&& node.uses_arguments) {
|
||||||
|
AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", {
|
||||||
|
name: node.name ? node.name.name : "anonymous",
|
||||||
|
file: node.start.file,
|
||||||
|
line: node.start.line,
|
||||||
|
col: node.start.col
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (options.nested_defuns
|
||||||
|
&& node instanceof AST_Defun
|
||||||
|
&& !(tw.parent() instanceof AST_Scope)) {
|
||||||
|
AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", {
|
||||||
|
name: node.name.name,
|
||||||
|
type: tw.parent().TYPE,
|
||||||
|
file: node.start.file,
|
||||||
|
line: node.start.line,
|
||||||
|
col: node.start.col
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.walk(tw);
|
||||||
|
});
|
||||||
81
node_modules/handlebars/node_modules/uglify-js/lib/sourcemap.js
generated
vendored
Normal file
81
node_modules/handlebars/node_modules/uglify-js/lib/sourcemap.js
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
|
||||||
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
|
https://github.com/mishoo/UglifyJS2
|
||||||
|
|
||||||
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
|
Author: Mihai Bazon
|
||||||
|
<mihai.bazon@gmail.com>
|
||||||
|
http://mihai.bazon.net/blog
|
||||||
|
|
||||||
|
Distributed under the BSD license:
|
||||||
|
|
||||||
|
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials
|
||||||
|
provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||||
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// a small wrapper around fitzgen's source-map library
|
||||||
|
function SourceMap(options) {
|
||||||
|
options = defaults(options, {
|
||||||
|
file : null,
|
||||||
|
root : null,
|
||||||
|
orig : null,
|
||||||
|
});
|
||||||
|
var generator = new MOZ_SourceMap.SourceMapGenerator({
|
||||||
|
file : options.file,
|
||||||
|
sourceRoot : options.root
|
||||||
|
});
|
||||||
|
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
|
||||||
|
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||||
|
if (orig_map) {
|
||||||
|
var info = orig_map.originalPositionFor({
|
||||||
|
line: orig_line,
|
||||||
|
column: orig_col
|
||||||
|
});
|
||||||
|
source = info.source;
|
||||||
|
orig_line = info.line;
|
||||||
|
orig_col = info.column;
|
||||||
|
name = info.name;
|
||||||
|
}
|
||||||
|
generator.addMapping({
|
||||||
|
generated : { line: gen_line, column: gen_col },
|
||||||
|
original : { line: orig_line, column: orig_col },
|
||||||
|
source : source,
|
||||||
|
name : name
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
add : add,
|
||||||
|
get : function() { return generator },
|
||||||
|
toString : function() { return generator.toString() }
|
||||||
|
};
|
||||||
|
};
|
||||||
73
node_modules/handlebars/node_modules/uglify-js/lib/squeeze-more.js
generated
vendored
73
node_modules/handlebars/node_modules/uglify-js/lib/squeeze-more.js
generated
vendored
@@ -1,73 +0,0 @@
|
|||||||
var jsp = require("./parse-js"),
|
|
||||||
pro = require("./process"),
|
|
||||||
slice = jsp.slice,
|
|
||||||
member = jsp.member,
|
|
||||||
curry = jsp.curry,
|
|
||||||
MAP = pro.MAP,
|
|
||||||
PRECEDENCE = jsp.PRECEDENCE,
|
|
||||||
OPERATORS = jsp.OPERATORS;
|
|
||||||
|
|
||||||
function ast_squeeze_more(ast) {
|
|
||||||
var w = pro.ast_walker(), walk = w.walk, scope;
|
|
||||||
function with_scope(s, cont) {
|
|
||||||
var save = scope, ret;
|
|
||||||
scope = s;
|
|
||||||
ret = cont();
|
|
||||||
scope = save;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
function _lambda(name, args, body) {
|
|
||||||
return [ this[0], name, args, with_scope(body.scope, curry(MAP, body, walk)) ];
|
|
||||||
};
|
|
||||||
return w.with_walkers({
|
|
||||||
"toplevel": function(body) {
|
|
||||||
return [ this[0], with_scope(this.scope, curry(MAP, body, walk)) ];
|
|
||||||
},
|
|
||||||
"function": _lambda,
|
|
||||||
"defun": _lambda,
|
|
||||||
"new": function(ctor, args) {
|
|
||||||
if (ctor[0] == "name") {
|
|
||||||
if (ctor[1] == "Array" && !scope.has("Array")) {
|
|
||||||
if (args.length != 1) {
|
|
||||||
return [ "array", args ];
|
|
||||||
} else {
|
|
||||||
return walk([ "call", [ "name", "Array" ], args ]);
|
|
||||||
}
|
|
||||||
} else if (ctor[1] == "Object" && !scope.has("Object")) {
|
|
||||||
if (!args.length) {
|
|
||||||
return [ "object", [] ];
|
|
||||||
} else {
|
|
||||||
return walk([ "call", [ "name", "Object" ], args ]);
|
|
||||||
}
|
|
||||||
} else if ((ctor[1] == "RegExp" || ctor[1] == "Function" || ctor[1] == "Error") && !scope.has(ctor[1])) {
|
|
||||||
return walk([ "call", [ "name", ctor[1] ], args]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"call": function(expr, args) {
|
|
||||||
if (expr[0] == "dot" && expr[1][0] == "string" && args.length == 1
|
|
||||||
&& (args[0][1] > 0 && expr[2] == "substring" || expr[2] == "substr")) {
|
|
||||||
return [ "call", [ "dot", expr[1], "slice"], args];
|
|
||||||
}
|
|
||||||
if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
|
|
||||||
// foo.toString() ==> foo+""
|
|
||||||
return [ "binary", "+", expr[1], [ "string", "" ]];
|
|
||||||
}
|
|
||||||
if (expr[0] == "name") {
|
|
||||||
if (expr[1] == "Array" && args.length != 1 && !scope.has("Array")) {
|
|
||||||
return [ "array", args ];
|
|
||||||
}
|
|
||||||
if (expr[1] == "Object" && !args.length && !scope.has("Object")) {
|
|
||||||
return [ "object", [] ];
|
|
||||||
}
|
|
||||||
if (expr[1] == "String" && !scope.has("String")) {
|
|
||||||
return [ "binary", "+", args[0], [ "string", "" ]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, function() {
|
|
||||||
return walk(pro.ast_add_scope(ast));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.ast_squeeze_more = ast_squeeze_more;
|
|
||||||
217
node_modules/handlebars/node_modules/uglify-js/lib/transform.js
generated
vendored
Normal file
217
node_modules/handlebars/node_modules/uglify-js/lib/transform.js
generated
vendored
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
|
||||||
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
|
https://github.com/mishoo/UglifyJS2
|
||||||
|
|
||||||
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
|
Author: Mihai Bazon
|
||||||
|
<mihai.bazon@gmail.com>
|
||||||
|
http://mihai.bazon.net/blog
|
||||||
|
|
||||||
|
Distributed under the BSD license:
|
||||||
|
|
||||||
|
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials
|
||||||
|
provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||||
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Tree transformer helpers.
|
||||||
|
|
||||||
|
function TreeTransformer(before, after) {
|
||||||
|
TreeWalker.call(this);
|
||||||
|
this.before = before;
|
||||||
|
this.after = after;
|
||||||
|
}
|
||||||
|
TreeTransformer.prototype = new TreeWalker;
|
||||||
|
|
||||||
|
(function(undefined){
|
||||||
|
|
||||||
|
function _(node, descend) {
|
||||||
|
node.DEFMETHOD("transform", function(tw, in_list){
|
||||||
|
var x, y;
|
||||||
|
tw.push(this);
|
||||||
|
if (tw.before) x = tw.before(this, descend, in_list);
|
||||||
|
if (x === undefined) {
|
||||||
|
if (!tw.after) {
|
||||||
|
x = this;
|
||||||
|
descend(x, tw);
|
||||||
|
} else {
|
||||||
|
tw.stack[tw.stack.length - 1] = x = this.clone();
|
||||||
|
descend(x, tw);
|
||||||
|
y = tw.after(x, in_list);
|
||||||
|
if (y !== undefined) x = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tw.pop();
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function do_list(list, tw) {
|
||||||
|
return MAP(list, function(node){
|
||||||
|
return node.transform(tw, true);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
_(AST_Node, noop);
|
||||||
|
|
||||||
|
_(AST_LabeledStatement, function(self, tw){
|
||||||
|
self.label = self.label.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_SimpleStatement, function(self, tw){
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Block, function(self, tw){
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_DWLoop, function(self, tw){
|
||||||
|
self.condition = self.condition.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_For, function(self, tw){
|
||||||
|
if (self.init) self.init = self.init.transform(tw);
|
||||||
|
if (self.condition) self.condition = self.condition.transform(tw);
|
||||||
|
if (self.step) self.step = self.step.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_ForIn, function(self, tw){
|
||||||
|
self.init = self.init.transform(tw);
|
||||||
|
self.object = self.object.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_With, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Exit, function(self, tw){
|
||||||
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_LoopControl, function(self, tw){
|
||||||
|
if (self.label) self.label = self.label.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_If, function(self, tw){
|
||||||
|
self.condition = self.condition.transform(tw);
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Switch, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Case, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Try, function(self, tw){
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
||||||
|
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Catch, function(self, tw){
|
||||||
|
self.argname = self.argname.transform(tw);
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Definitions, function(self, tw){
|
||||||
|
self.definitions = do_list(self.definitions, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_VarDef, function(self, tw){
|
||||||
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Lambda, function(self, tw){
|
||||||
|
if (self.name) self.name = self.name.transform(tw);
|
||||||
|
self.argnames = do_list(self.argnames, tw);
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Call, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.args = do_list(self.args, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Seq, function(self, tw){
|
||||||
|
self.car = self.car.transform(tw);
|
||||||
|
self.cdr = self.cdr.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Dot, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Sub, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
self.property = self.property.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Unary, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Binary, function(self, tw){
|
||||||
|
self.left = self.left.transform(tw);
|
||||||
|
self.right = self.right.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Conditional, function(self, tw){
|
||||||
|
self.condition = self.condition.transform(tw);
|
||||||
|
self.consequent = self.consequent.transform(tw);
|
||||||
|
self.alternative = self.alternative.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Array, function(self, tw){
|
||||||
|
self.elements = do_list(self.elements, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Object, function(self, tw){
|
||||||
|
self.properties = do_list(self.properties, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_ObjectProperty, function(self, tw){
|
||||||
|
self.value = self.value.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
295
node_modules/handlebars/node_modules/uglify-js/lib/utils.js
generated
vendored
Normal file
295
node_modules/handlebars/node_modules/uglify-js/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
/***********************************************************************
|
||||||
|
|
||||||
|
A JavaScript tokenizer / parser / beautifier / compressor.
|
||||||
|
https://github.com/mishoo/UglifyJS2
|
||||||
|
|
||||||
|
-------------------------------- (C) ---------------------------------
|
||||||
|
|
||||||
|
Author: Mihai Bazon
|
||||||
|
<mihai.bazon@gmail.com>
|
||||||
|
http://mihai.bazon.net/blog
|
||||||
|
|
||||||
|
Distributed under the BSD license:
|
||||||
|
|
||||||
|
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials
|
||||||
|
provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
|
||||||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||||
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
***********************************************************************/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function array_to_hash(a) {
|
||||||
|
var ret = Object.create(null);
|
||||||
|
for (var i = 0; i < a.length; ++i)
|
||||||
|
ret[a[i]] = true;
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
function slice(a, start) {
|
||||||
|
return Array.prototype.slice.call(a, start || 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
function characters(str) {
|
||||||
|
return str.split("");
|
||||||
|
};
|
||||||
|
|
||||||
|
function member(name, array) {
|
||||||
|
for (var i = array.length; --i >= 0;)
|
||||||
|
if (array[i] == name)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
function find_if(func, array) {
|
||||||
|
for (var i = 0, n = array.length; i < n; ++i) {
|
||||||
|
if (func(array[i]))
|
||||||
|
return array[i];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function repeat_string(str, i) {
|
||||||
|
if (i <= 0) return "";
|
||||||
|
if (i == 1) return str;
|
||||||
|
var d = repeat_string(str, i >> 1);
|
||||||
|
d += d;
|
||||||
|
if (i & 1) d += str;
|
||||||
|
return d;
|
||||||
|
};
|
||||||
|
|
||||||
|
function DefaultsError(msg, defs) {
|
||||||
|
this.msg = msg;
|
||||||
|
this.defs = defs;
|
||||||
|
};
|
||||||
|
|
||||||
|
function defaults(args, defs, croak) {
|
||||||
|
if (args === true)
|
||||||
|
args = {};
|
||||||
|
var ret = args || {};
|
||||||
|
if (croak) for (var i in ret) if (ret.hasOwnProperty(i) && !defs.hasOwnProperty(i))
|
||||||
|
throw new DefaultsError("`" + i + "` is not a supported option", defs);
|
||||||
|
for (var i in defs) if (defs.hasOwnProperty(i)) {
|
||||||
|
ret[i] = (args && args.hasOwnProperty(i)) ? args[i] : defs[i];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
function merge(obj, ext) {
|
||||||
|
for (var i in ext) if (ext.hasOwnProperty(i)) {
|
||||||
|
obj[i] = ext[i];
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
function noop() {};
|
||||||
|
|
||||||
|
var MAP = (function(){
|
||||||
|
function MAP(a, f, backwards) {
|
||||||
|
var ret = [], top = [], i;
|
||||||
|
function doit() {
|
||||||
|
var val = f(a[i], i);
|
||||||
|
var is_last = val instanceof Last;
|
||||||
|
if (is_last) val = val.v;
|
||||||
|
if (val instanceof AtTop) {
|
||||||
|
val = val.v;
|
||||||
|
if (val instanceof Splice) {
|
||||||
|
top.push.apply(top, backwards ? val.v.slice().reverse() : val.v);
|
||||||
|
} else {
|
||||||
|
top.push(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (val !== skip) {
|
||||||
|
if (val instanceof Splice) {
|
||||||
|
ret.push.apply(ret, backwards ? val.v.slice().reverse() : val.v);
|
||||||
|
} else {
|
||||||
|
ret.push(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return is_last;
|
||||||
|
};
|
||||||
|
if (a instanceof Array) {
|
||||||
|
if (backwards) {
|
||||||
|
for (i = a.length; --i >= 0;) if (doit()) break;
|
||||||
|
ret.reverse();
|
||||||
|
top.reverse();
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < a.length; ++i) if (doit()) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (i in a) if (a.hasOwnProperty(i)) if (doit()) break;
|
||||||
|
}
|
||||||
|
return top.concat(ret);
|
||||||
|
};
|
||||||
|
MAP.at_top = function(val) { return new AtTop(val) };
|
||||||
|
MAP.splice = function(val) { return new Splice(val) };
|
||||||
|
MAP.last = function(val) { return new Last(val) };
|
||||||
|
var skip = MAP.skip = {};
|
||||||
|
function AtTop(val) { this.v = val };
|
||||||
|
function Splice(val) { this.v = val };
|
||||||
|
function Last(val) { this.v = val };
|
||||||
|
return MAP;
|
||||||
|
})();
|
||||||
|
|
||||||
|
function push_uniq(array, el) {
|
||||||
|
if (array.indexOf(el) < 0)
|
||||||
|
array.push(el);
|
||||||
|
};
|
||||||
|
|
||||||
|
function string_template(text, props) {
|
||||||
|
return text.replace(/\{(.+?)\}/g, function(str, p){
|
||||||
|
return props[p];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function remove(array, el) {
|
||||||
|
for (var i = array.length; --i >= 0;) {
|
||||||
|
if (array[i] === el) array.splice(i, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function mergeSort(array, cmp) {
|
||||||
|
if (array.length < 2) return array.slice();
|
||||||
|
function merge(a, b) {
|
||||||
|
var r = [], ai = 0, bi = 0, i = 0;
|
||||||
|
while (ai < a.length && bi < b.length) {
|
||||||
|
cmp(a[ai], b[bi]) <= 0
|
||||||
|
? r[i++] = a[ai++]
|
||||||
|
: r[i++] = b[bi++];
|
||||||
|
}
|
||||||
|
if (ai < a.length) r.push.apply(r, a.slice(ai));
|
||||||
|
if (bi < b.length) r.push.apply(r, b.slice(bi));
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
function _ms(a) {
|
||||||
|
if (a.length <= 1)
|
||||||
|
return a;
|
||||||
|
var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
|
||||||
|
left = _ms(left);
|
||||||
|
right = _ms(right);
|
||||||
|
return merge(left, right);
|
||||||
|
};
|
||||||
|
return _ms(array);
|
||||||
|
};
|
||||||
|
|
||||||
|
function set_difference(a, b) {
|
||||||
|
return a.filter(function(el){
|
||||||
|
return b.indexOf(el) < 0;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function set_intersection(a, b) {
|
||||||
|
return a.filter(function(el){
|
||||||
|
return b.indexOf(el) >= 0;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// this function is taken from Acorn [1], written by Marijn Haverbeke
|
||||||
|
// [1] https://github.com/marijnh/acorn
|
||||||
|
function makePredicate(words) {
|
||||||
|
if (!(words instanceof Array)) words = words.split(" ");
|
||||||
|
var f = "", cats = [];
|
||||||
|
out: for (var i = 0; i < words.length; ++i) {
|
||||||
|
for (var j = 0; j < cats.length; ++j)
|
||||||
|
if (cats[j][0].length == words[i].length) {
|
||||||
|
cats[j].push(words[i]);
|
||||||
|
continue out;
|
||||||
|
}
|
||||||
|
cats.push([words[i]]);
|
||||||
|
}
|
||||||
|
function compareTo(arr) {
|
||||||
|
if (arr.length == 1) return f += "return str === " + JSON.stringify(arr[0]) + ";";
|
||||||
|
f += "switch(str){";
|
||||||
|
for (var i = 0; i < arr.length; ++i) f += "case " + JSON.stringify(arr[i]) + ":";
|
||||||
|
f += "return true}return false;";
|
||||||
|
}
|
||||||
|
// When there are more than three length categories, an outer
|
||||||
|
// switch first dispatches on the lengths, to save on comparisons.
|
||||||
|
if (cats.length > 3) {
|
||||||
|
cats.sort(function(a, b) {return b.length - a.length;});
|
||||||
|
f += "switch(str.length){";
|
||||||
|
for (var i = 0; i < cats.length; ++i) {
|
||||||
|
var cat = cats[i];
|
||||||
|
f += "case " + cat[0].length + ":";
|
||||||
|
compareTo(cat);
|
||||||
|
}
|
||||||
|
f += "}";
|
||||||
|
// Otherwise, simply generate a flat `switch` statement.
|
||||||
|
} else {
|
||||||
|
compareTo(words);
|
||||||
|
}
|
||||||
|
return new Function("str", f);
|
||||||
|
};
|
||||||
|
|
||||||
|
function all(array, predicate) {
|
||||||
|
for (var i = array.length; --i >= 0;)
|
||||||
|
if (!predicate(array[i]))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
function Dictionary() {
|
||||||
|
this._values = Object.create(null);
|
||||||
|
this._size = 0;
|
||||||
|
};
|
||||||
|
Dictionary.prototype = {
|
||||||
|
set: function(key, val) {
|
||||||
|
if (!this.has(key)) ++this._size;
|
||||||
|
this._values["$" + key] = val;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
add: function(key, val) {
|
||||||
|
if (this.has(key)) {
|
||||||
|
this.get(key).push(val);
|
||||||
|
} else {
|
||||||
|
this.set(key, [ val ]);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
get: function(key) { return this._values["$" + key] },
|
||||||
|
del: function(key) {
|
||||||
|
if (this.has(key)) {
|
||||||
|
--this._size;
|
||||||
|
delete this._values["$" + key];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
has: function(key) { return ("$" + key) in this._values },
|
||||||
|
each: function(f) {
|
||||||
|
for (var i in this._values)
|
||||||
|
f(this._values[i], i.substr(1));
|
||||||
|
},
|
||||||
|
size: function() {
|
||||||
|
return this._size;
|
||||||
|
},
|
||||||
|
map: function(f) {
|
||||||
|
var ret = [];
|
||||||
|
for (var i in this._values)
|
||||||
|
ret.push(f(this._values[i], i.substr(1)));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
19
node_modules/handlebars/node_modules/uglify-js/node_modules/async/LICENSE
generated
vendored
Normal file
19
node_modules/handlebars/node_modules/uglify-js/node_modules/async/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2010 Caolan McMahon
|
||||||
|
|
||||||
|
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.
|
||||||
1414
node_modules/handlebars/node_modules/uglify-js/node_modules/async/README.md
generated
vendored
Normal file
1414
node_modules/handlebars/node_modules/uglify-js/node_modules/async/README.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11
node_modules/handlebars/node_modules/uglify-js/node_modules/async/component.json
generated
vendored
Normal file
11
node_modules/handlebars/node_modules/uglify-js/node_modules/async/component.json
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "async",
|
||||||
|
"repo": "caolan/async",
|
||||||
|
"description": "Higher-order functions and common patterns for asynchronous code",
|
||||||
|
"version": "0.1.23",
|
||||||
|
"keywords": [],
|
||||||
|
"dependencies": {},
|
||||||
|
"development": {},
|
||||||
|
"main": "lib/async.js",
|
||||||
|
"scripts": [ "lib/async.js" ]
|
||||||
|
}
|
||||||
955
node_modules/handlebars/node_modules/uglify-js/node_modules/async/lib/async.js
generated
vendored
Executable file
955
node_modules/handlebars/node_modules/uglify-js/node_modules/async/lib/async.js
generated
vendored
Executable file
@@ -0,0 +1,955 @@
|
|||||||
|
/*global setImmediate: false, setTimeout: false, console: false */
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
var async = {};
|
||||||
|
|
||||||
|
// global on the server, window in the browser
|
||||||
|
var root, previous_async;
|
||||||
|
|
||||||
|
root = this;
|
||||||
|
if (root != null) {
|
||||||
|
previous_async = root.async;
|
||||||
|
}
|
||||||
|
|
||||||
|
async.noConflict = function () {
|
||||||
|
root.async = previous_async;
|
||||||
|
return async;
|
||||||
|
};
|
||||||
|
|
||||||
|
function only_once(fn) {
|
||||||
|
var called = false;
|
||||||
|
return function() {
|
||||||
|
if (called) throw new Error("Callback was already called.");
|
||||||
|
called = true;
|
||||||
|
fn.apply(root, arguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//// cross-browser compatiblity functions ////
|
||||||
|
|
||||||
|
var _each = function (arr, iterator) {
|
||||||
|
if (arr.forEach) {
|
||||||
|
return arr.forEach(iterator);
|
||||||
|
}
|
||||||
|
for (var i = 0; i < arr.length; i += 1) {
|
||||||
|
iterator(arr[i], i, arr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var _map = function (arr, iterator) {
|
||||||
|
if (arr.map) {
|
||||||
|
return arr.map(iterator);
|
||||||
|
}
|
||||||
|
var results = [];
|
||||||
|
_each(arr, function (x, i, a) {
|
||||||
|
results.push(iterator(x, i, a));
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
var _reduce = function (arr, iterator, memo) {
|
||||||
|
if (arr.reduce) {
|
||||||
|
return arr.reduce(iterator, memo);
|
||||||
|
}
|
||||||
|
_each(arr, function (x, i, a) {
|
||||||
|
memo = iterator(memo, x, i, a);
|
||||||
|
});
|
||||||
|
return memo;
|
||||||
|
};
|
||||||
|
|
||||||
|
var _keys = function (obj) {
|
||||||
|
if (Object.keys) {
|
||||||
|
return Object.keys(obj);
|
||||||
|
}
|
||||||
|
var keys = [];
|
||||||
|
for (var k in obj) {
|
||||||
|
if (obj.hasOwnProperty(k)) {
|
||||||
|
keys.push(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
//// exported async module functions ////
|
||||||
|
|
||||||
|
//// nextTick implementation with browser-compatible fallback ////
|
||||||
|
if (typeof process === 'undefined' || !(process.nextTick)) {
|
||||||
|
if (typeof setImmediate === 'function') {
|
||||||
|
async.nextTick = function (fn) {
|
||||||
|
// not a direct alias for IE10 compatibility
|
||||||
|
setImmediate(fn);
|
||||||
|
};
|
||||||
|
async.setImmediate = async.nextTick;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
async.nextTick = function (fn) {
|
||||||
|
setTimeout(fn, 0);
|
||||||
|
};
|
||||||
|
async.setImmediate = async.nextTick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
async.nextTick = process.nextTick;
|
||||||
|
if (typeof setImmediate !== 'undefined') {
|
||||||
|
async.setImmediate = setImmediate;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
async.setImmediate = async.nextTick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async.each = function (arr, iterator, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (!arr.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var completed = 0;
|
||||||
|
_each(arr, function (x) {
|
||||||
|
iterator(x, only_once(function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
completed += 1;
|
||||||
|
if (completed >= arr.length) {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.forEach = async.each;
|
||||||
|
|
||||||
|
async.eachSeries = function (arr, iterator, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (!arr.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var completed = 0;
|
||||||
|
var iterate = function () {
|
||||||
|
iterator(arr[completed], function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
completed += 1;
|
||||||
|
if (completed >= arr.length) {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
iterate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
iterate();
|
||||||
|
};
|
||||||
|
async.forEachSeries = async.eachSeries;
|
||||||
|
|
||||||
|
async.eachLimit = function (arr, limit, iterator, callback) {
|
||||||
|
var fn = _eachLimit(limit);
|
||||||
|
fn.apply(null, [arr, iterator, callback]);
|
||||||
|
};
|
||||||
|
async.forEachLimit = async.eachLimit;
|
||||||
|
|
||||||
|
var _eachLimit = function (limit) {
|
||||||
|
|
||||||
|
return function (arr, iterator, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (!arr.length || limit <= 0) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var completed = 0;
|
||||||
|
var started = 0;
|
||||||
|
var running = 0;
|
||||||
|
|
||||||
|
(function replenish () {
|
||||||
|
if (completed >= arr.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (running < limit && started < arr.length) {
|
||||||
|
started += 1;
|
||||||
|
running += 1;
|
||||||
|
iterator(arr[started - 1], function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
completed += 1;
|
||||||
|
running -= 1;
|
||||||
|
if (completed >= arr.length) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
replenish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var doParallel = function (fn) {
|
||||||
|
return function () {
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
return fn.apply(null, [async.each].concat(args));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
var doParallelLimit = function(limit, fn) {
|
||||||
|
return function () {
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
return fn.apply(null, [_eachLimit(limit)].concat(args));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
var doSeries = function (fn) {
|
||||||
|
return function () {
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
return fn.apply(null, [async.eachSeries].concat(args));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var _asyncMap = function (eachfn, arr, iterator, callback) {
|
||||||
|
var results = [];
|
||||||
|
arr = _map(arr, function (x, i) {
|
||||||
|
return {index: i, value: x};
|
||||||
|
});
|
||||||
|
eachfn(arr, function (x, callback) {
|
||||||
|
iterator(x.value, function (err, v) {
|
||||||
|
results[x.index] = v;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, results);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.map = doParallel(_asyncMap);
|
||||||
|
async.mapSeries = doSeries(_asyncMap);
|
||||||
|
async.mapLimit = function (arr, limit, iterator, callback) {
|
||||||
|
return _mapLimit(limit)(arr, iterator, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
var _mapLimit = function(limit) {
|
||||||
|
return doParallelLimit(limit, _asyncMap);
|
||||||
|
};
|
||||||
|
|
||||||
|
// reduce only has a series version, as doing reduce in parallel won't
|
||||||
|
// work in many situations.
|
||||||
|
async.reduce = function (arr, memo, iterator, callback) {
|
||||||
|
async.eachSeries(arr, function (x, callback) {
|
||||||
|
iterator(memo, x, function (err, v) {
|
||||||
|
memo = v;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, memo);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// inject alias
|
||||||
|
async.inject = async.reduce;
|
||||||
|
// foldl alias
|
||||||
|
async.foldl = async.reduce;
|
||||||
|
|
||||||
|
async.reduceRight = function (arr, memo, iterator, callback) {
|
||||||
|
var reversed = _map(arr, function (x) {
|
||||||
|
return x;
|
||||||
|
}).reverse();
|
||||||
|
async.reduce(reversed, memo, iterator, callback);
|
||||||
|
};
|
||||||
|
// foldr alias
|
||||||
|
async.foldr = async.reduceRight;
|
||||||
|
|
||||||
|
var _filter = function (eachfn, arr, iterator, callback) {
|
||||||
|
var results = [];
|
||||||
|
arr = _map(arr, function (x, i) {
|
||||||
|
return {index: i, value: x};
|
||||||
|
});
|
||||||
|
eachfn(arr, function (x, callback) {
|
||||||
|
iterator(x.value, function (v) {
|
||||||
|
if (v) {
|
||||||
|
results.push(x);
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(_map(results.sort(function (a, b) {
|
||||||
|
return a.index - b.index;
|
||||||
|
}), function (x) {
|
||||||
|
return x.value;
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.filter = doParallel(_filter);
|
||||||
|
async.filterSeries = doSeries(_filter);
|
||||||
|
// select alias
|
||||||
|
async.select = async.filter;
|
||||||
|
async.selectSeries = async.filterSeries;
|
||||||
|
|
||||||
|
var _reject = function (eachfn, arr, iterator, callback) {
|
||||||
|
var results = [];
|
||||||
|
arr = _map(arr, function (x, i) {
|
||||||
|
return {index: i, value: x};
|
||||||
|
});
|
||||||
|
eachfn(arr, function (x, callback) {
|
||||||
|
iterator(x.value, function (v) {
|
||||||
|
if (!v) {
|
||||||
|
results.push(x);
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(_map(results.sort(function (a, b) {
|
||||||
|
return a.index - b.index;
|
||||||
|
}), function (x) {
|
||||||
|
return x.value;
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.reject = doParallel(_reject);
|
||||||
|
async.rejectSeries = doSeries(_reject);
|
||||||
|
|
||||||
|
var _detect = function (eachfn, arr, iterator, main_callback) {
|
||||||
|
eachfn(arr, function (x, callback) {
|
||||||
|
iterator(x, function (result) {
|
||||||
|
if (result) {
|
||||||
|
main_callback(x);
|
||||||
|
main_callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
main_callback();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.detect = doParallel(_detect);
|
||||||
|
async.detectSeries = doSeries(_detect);
|
||||||
|
|
||||||
|
async.some = function (arr, iterator, main_callback) {
|
||||||
|
async.each(arr, function (x, callback) {
|
||||||
|
iterator(x, function (v) {
|
||||||
|
if (v) {
|
||||||
|
main_callback(true);
|
||||||
|
main_callback = function () {};
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
main_callback(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// any alias
|
||||||
|
async.any = async.some;
|
||||||
|
|
||||||
|
async.every = function (arr, iterator, main_callback) {
|
||||||
|
async.each(arr, function (x, callback) {
|
||||||
|
iterator(x, function (v) {
|
||||||
|
if (!v) {
|
||||||
|
main_callback(false);
|
||||||
|
main_callback = function () {};
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
main_callback(true);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// all alias
|
||||||
|
async.all = async.every;
|
||||||
|
|
||||||
|
async.sortBy = function (arr, iterator, callback) {
|
||||||
|
async.map(arr, function (x, callback) {
|
||||||
|
iterator(x, function (err, criteria) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback(null, {value: x, criteria: criteria});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function (err, results) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var fn = function (left, right) {
|
||||||
|
var a = left.criteria, b = right.criteria;
|
||||||
|
return a < b ? -1 : a > b ? 1 : 0;
|
||||||
|
};
|
||||||
|
callback(null, _map(results.sort(fn), function (x) {
|
||||||
|
return x.value;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async.auto = function (tasks, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
var keys = _keys(tasks);
|
||||||
|
if (!keys.length) {
|
||||||
|
return callback(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var results = {};
|
||||||
|
|
||||||
|
var listeners = [];
|
||||||
|
var addListener = function (fn) {
|
||||||
|
listeners.unshift(fn);
|
||||||
|
};
|
||||||
|
var removeListener = function (fn) {
|
||||||
|
for (var i = 0; i < listeners.length; i += 1) {
|
||||||
|
if (listeners[i] === fn) {
|
||||||
|
listeners.splice(i, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var taskComplete = function () {
|
||||||
|
_each(listeners.slice(0), function (fn) {
|
||||||
|
fn();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
addListener(function () {
|
||||||
|
if (_keys(results).length === keys.length) {
|
||||||
|
callback(null, results);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_each(keys, function (k) {
|
||||||
|
var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
|
||||||
|
var taskCallback = function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
var safeResults = {};
|
||||||
|
_each(_keys(results), function(rkey) {
|
||||||
|
safeResults[rkey] = results[rkey];
|
||||||
|
});
|
||||||
|
safeResults[k] = args;
|
||||||
|
callback(err, safeResults);
|
||||||
|
// stop subsequent errors hitting callback multiple times
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
results[k] = args;
|
||||||
|
async.setImmediate(taskComplete);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
|
||||||
|
var ready = function () {
|
||||||
|
return _reduce(requires, function (a, x) {
|
||||||
|
return (a && results.hasOwnProperty(x));
|
||||||
|
}, true) && !results.hasOwnProperty(k);
|
||||||
|
};
|
||||||
|
if (ready()) {
|
||||||
|
task[task.length - 1](taskCallback, results);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var listener = function () {
|
||||||
|
if (ready()) {
|
||||||
|
removeListener(listener);
|
||||||
|
task[task.length - 1](taskCallback, results);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addListener(listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async.waterfall = function (tasks, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (tasks.constructor !== Array) {
|
||||||
|
var err = new Error('First argument to waterfall must be an array of functions');
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (!tasks.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var wrapIterator = function (iterator) {
|
||||||
|
return function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback.apply(null, arguments);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
var next = iterator.next();
|
||||||
|
if (next) {
|
||||||
|
args.push(wrapIterator(next));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
args.push(callback);
|
||||||
|
}
|
||||||
|
async.setImmediate(function () {
|
||||||
|
iterator.apply(null, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
wrapIterator(async.iterator(tasks))();
|
||||||
|
};
|
||||||
|
|
||||||
|
var _parallel = function(eachfn, tasks, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (tasks.constructor === Array) {
|
||||||
|
eachfn.map(tasks, function (fn, callback) {
|
||||||
|
if (fn) {
|
||||||
|
fn(function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
callback.call(null, err, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var results = {};
|
||||||
|
eachfn.each(_keys(tasks), function (k, callback) {
|
||||||
|
tasks[k](function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
results[k] = args;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async.parallel = function (tasks, callback) {
|
||||||
|
_parallel({ map: async.map, each: async.each }, tasks, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
async.parallelLimit = function(tasks, limit, callback) {
|
||||||
|
_parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
async.series = function (tasks, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (tasks.constructor === Array) {
|
||||||
|
async.mapSeries(tasks, function (fn, callback) {
|
||||||
|
if (fn) {
|
||||||
|
fn(function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
callback.call(null, err, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var results = {};
|
||||||
|
async.eachSeries(_keys(tasks), function (k, callback) {
|
||||||
|
tasks[k](function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
results[k] = args;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async.iterator = function (tasks) {
|
||||||
|
var makeCallback = function (index) {
|
||||||
|
var fn = function () {
|
||||||
|
if (tasks.length) {
|
||||||
|
tasks[index].apply(null, arguments);
|
||||||
|
}
|
||||||
|
return fn.next();
|
||||||
|
};
|
||||||
|
fn.next = function () {
|
||||||
|
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
|
||||||
|
};
|
||||||
|
return fn;
|
||||||
|
};
|
||||||
|
return makeCallback(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
async.apply = function (fn) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
return function () {
|
||||||
|
return fn.apply(
|
||||||
|
null, args.concat(Array.prototype.slice.call(arguments))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var _concat = function (eachfn, arr, fn, callback) {
|
||||||
|
var r = [];
|
||||||
|
eachfn(arr, function (x, cb) {
|
||||||
|
fn(x, function (err, y) {
|
||||||
|
r = r.concat(y || []);
|
||||||
|
cb(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, r);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.concat = doParallel(_concat);
|
||||||
|
async.concatSeries = doSeries(_concat);
|
||||||
|
|
||||||
|
async.whilst = function (test, iterator, callback) {
|
||||||
|
if (test()) {
|
||||||
|
iterator(function (err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
async.whilst(test, iterator, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async.doWhilst = function (iterator, test, callback) {
|
||||||
|
iterator(function (err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (test()) {
|
||||||
|
async.doWhilst(iterator, test, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async.until = function (test, iterator, callback) {
|
||||||
|
if (!test()) {
|
||||||
|
iterator(function (err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
async.until(test, iterator, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async.doUntil = function (iterator, test, callback) {
|
||||||
|
iterator(function (err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (!test()) {
|
||||||
|
async.doUntil(iterator, test, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async.queue = function (worker, concurrency) {
|
||||||
|
if (concurrency === undefined) {
|
||||||
|
concurrency = 1;
|
||||||
|
}
|
||||||
|
function _insert(q, data, pos, callback) {
|
||||||
|
if(data.constructor !== Array) {
|
||||||
|
data = [data];
|
||||||
|
}
|
||||||
|
_each(data, function(task) {
|
||||||
|
var item = {
|
||||||
|
data: task,
|
||||||
|
callback: typeof callback === 'function' ? callback : null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (pos) {
|
||||||
|
q.tasks.unshift(item);
|
||||||
|
} else {
|
||||||
|
q.tasks.push(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (q.saturated && q.tasks.length === concurrency) {
|
||||||
|
q.saturated();
|
||||||
|
}
|
||||||
|
async.setImmediate(q.process);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var workers = 0;
|
||||||
|
var q = {
|
||||||
|
tasks: [],
|
||||||
|
concurrency: concurrency,
|
||||||
|
saturated: null,
|
||||||
|
empty: null,
|
||||||
|
drain: null,
|
||||||
|
push: function (data, callback) {
|
||||||
|
_insert(q, data, false, callback);
|
||||||
|
},
|
||||||
|
unshift: function (data, callback) {
|
||||||
|
_insert(q, data, true, callback);
|
||||||
|
},
|
||||||
|
process: function () {
|
||||||
|
if (workers < q.concurrency && q.tasks.length) {
|
||||||
|
var task = q.tasks.shift();
|
||||||
|
if (q.empty && q.tasks.length === 0) {
|
||||||
|
q.empty();
|
||||||
|
}
|
||||||
|
workers += 1;
|
||||||
|
var next = function () {
|
||||||
|
workers -= 1;
|
||||||
|
if (task.callback) {
|
||||||
|
task.callback.apply(task, arguments);
|
||||||
|
}
|
||||||
|
if (q.drain && q.tasks.length + workers === 0) {
|
||||||
|
q.drain();
|
||||||
|
}
|
||||||
|
q.process();
|
||||||
|
};
|
||||||
|
var cb = only_once(next);
|
||||||
|
worker(task.data, cb);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
length: function () {
|
||||||
|
return q.tasks.length;
|
||||||
|
},
|
||||||
|
running: function () {
|
||||||
|
return workers;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return q;
|
||||||
|
};
|
||||||
|
|
||||||
|
async.cargo = function (worker, payload) {
|
||||||
|
var working = false,
|
||||||
|
tasks = [];
|
||||||
|
|
||||||
|
var cargo = {
|
||||||
|
tasks: tasks,
|
||||||
|
payload: payload,
|
||||||
|
saturated: null,
|
||||||
|
empty: null,
|
||||||
|
drain: null,
|
||||||
|
push: function (data, callback) {
|
||||||
|
if(data.constructor !== Array) {
|
||||||
|
data = [data];
|
||||||
|
}
|
||||||
|
_each(data, function(task) {
|
||||||
|
tasks.push({
|
||||||
|
data: task,
|
||||||
|
callback: typeof callback === 'function' ? callback : null
|
||||||
|
});
|
||||||
|
if (cargo.saturated && tasks.length === payload) {
|
||||||
|
cargo.saturated();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
async.setImmediate(cargo.process);
|
||||||
|
},
|
||||||
|
process: function process() {
|
||||||
|
if (working) return;
|
||||||
|
if (tasks.length === 0) {
|
||||||
|
if(cargo.drain) cargo.drain();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ts = typeof payload === 'number'
|
||||||
|
? tasks.splice(0, payload)
|
||||||
|
: tasks.splice(0);
|
||||||
|
|
||||||
|
var ds = _map(ts, function (task) {
|
||||||
|
return task.data;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(cargo.empty) cargo.empty();
|
||||||
|
working = true;
|
||||||
|
worker(ds, function () {
|
||||||
|
working = false;
|
||||||
|
|
||||||
|
var args = arguments;
|
||||||
|
_each(ts, function (data) {
|
||||||
|
if (data.callback) {
|
||||||
|
data.callback.apply(null, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
process();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
length: function () {
|
||||||
|
return tasks.length;
|
||||||
|
},
|
||||||
|
running: function () {
|
||||||
|
return working;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return cargo;
|
||||||
|
};
|
||||||
|
|
||||||
|
var _console_fn = function (name) {
|
||||||
|
return function (fn) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
fn.apply(null, args.concat([function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (typeof console !== 'undefined') {
|
||||||
|
if (err) {
|
||||||
|
if (console.error) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (console[name]) {
|
||||||
|
_each(args, function (x) {
|
||||||
|
console[name](x);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
async.log = _console_fn('log');
|
||||||
|
async.dir = _console_fn('dir');
|
||||||
|
/*async.info = _console_fn('info');
|
||||||
|
async.warn = _console_fn('warn');
|
||||||
|
async.error = _console_fn('error');*/
|
||||||
|
|
||||||
|
async.memoize = function (fn, hasher) {
|
||||||
|
var memo = {};
|
||||||
|
var queues = {};
|
||||||
|
hasher = hasher || function (x) {
|
||||||
|
return x;
|
||||||
|
};
|
||||||
|
var memoized = function () {
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
var callback = args.pop();
|
||||||
|
var key = hasher.apply(null, args);
|
||||||
|
if (key in memo) {
|
||||||
|
callback.apply(null, memo[key]);
|
||||||
|
}
|
||||||
|
else if (key in queues) {
|
||||||
|
queues[key].push(callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
queues[key] = [callback];
|
||||||
|
fn.apply(null, args.concat([function () {
|
||||||
|
memo[key] = arguments;
|
||||||
|
var q = queues[key];
|
||||||
|
delete queues[key];
|
||||||
|
for (var i = 0, l = q.length; i < l; i++) {
|
||||||
|
q[i].apply(null, arguments);
|
||||||
|
}
|
||||||
|
}]));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
memoized.memo = memo;
|
||||||
|
memoized.unmemoized = fn;
|
||||||
|
return memoized;
|
||||||
|
};
|
||||||
|
|
||||||
|
async.unmemoize = function (fn) {
|
||||||
|
return function () {
|
||||||
|
return (fn.unmemoized || fn).apply(null, arguments);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
async.times = function (count, iterator, callback) {
|
||||||
|
var counter = [];
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
counter.push(i);
|
||||||
|
}
|
||||||
|
return async.map(counter, iterator, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
async.timesSeries = function (count, iterator, callback) {
|
||||||
|
var counter = [];
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
counter.push(i);
|
||||||
|
}
|
||||||
|
return async.mapSeries(counter, iterator, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
async.compose = function (/* functions... */) {
|
||||||
|
var fns = Array.prototype.reverse.call(arguments);
|
||||||
|
return function () {
|
||||||
|
var that = this;
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
var callback = args.pop();
|
||||||
|
async.reduce(fns, args, function (newargs, fn, cb) {
|
||||||
|
fn.apply(that, newargs.concat([function () {
|
||||||
|
var err = arguments[0];
|
||||||
|
var nextargs = Array.prototype.slice.call(arguments, 1);
|
||||||
|
cb(err, nextargs);
|
||||||
|
}]))
|
||||||
|
},
|
||||||
|
function (err, results) {
|
||||||
|
callback.apply(that, [err].concat(results));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var _applyEach = function (eachfn, fns /*args...*/) {
|
||||||
|
var go = function () {
|
||||||
|
var that = this;
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
var callback = args.pop();
|
||||||
|
return eachfn(fns, function (fn, cb) {
|
||||||
|
fn.apply(that, args.concat([cb]));
|
||||||
|
},
|
||||||
|
callback);
|
||||||
|
};
|
||||||
|
if (arguments.length > 2) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 2);
|
||||||
|
return go.apply(this, args);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return go;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
async.applyEach = doParallel(_applyEach);
|
||||||
|
async.applyEachSeries = doSeries(_applyEach);
|
||||||
|
|
||||||
|
async.forever = function (fn, callback) {
|
||||||
|
function next(err) {
|
||||||
|
if (err) {
|
||||||
|
if (callback) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
fn(next);
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
// AMD / RequireJS
|
||||||
|
if (typeof define !== 'undefined' && define.amd) {
|
||||||
|
define([], function () {
|
||||||
|
return async;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Node.js
|
||||||
|
else if (typeof module !== 'undefined' && module.exports) {
|
||||||
|
module.exports = async;
|
||||||
|
}
|
||||||
|
// included directly via <script> tag
|
||||||
|
else {
|
||||||
|
root.async = async;
|
||||||
|
}
|
||||||
|
|
||||||
|
}());
|
||||||
42
node_modules/handlebars/node_modules/uglify-js/node_modules/async/package.json
generated
vendored
Normal file
42
node_modules/handlebars/node_modules/uglify-js/node_modules/async/package.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/.npmignore
generated
vendored
Normal file
2
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
dist/*
|
||||||
|
node_modules/*
|
||||||
4
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/.travis.yml
generated
vendored
Normal file
4
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- 0.8
|
||||||
|
- "0.10"
|
||||||
112
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/CHANGELOG.md
generated
vendored
Normal file
112
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
# Change Log
|
||||||
|
|
||||||
|
## 0.1.31
|
||||||
|
|
||||||
|
* Delay parsing the mappings in SourceMapConsumer until queried for a source
|
||||||
|
location.
|
||||||
|
|
||||||
|
* Support Sass source maps (which at the time of writing deviate from the spec
|
||||||
|
in small ways) in SourceMapConsumer.
|
||||||
|
|
||||||
|
## 0.1.30
|
||||||
|
|
||||||
|
* Do not join source root with a source, when the source is a data URI.
|
||||||
|
|
||||||
|
* Extend the test runner to allow running single specific test files at a time.
|
||||||
|
|
||||||
|
* Performance improvements in `SourceNode.prototype.walk` and
|
||||||
|
`SourceMapConsumer.prototype.eachMapping`.
|
||||||
|
|
||||||
|
* Source map browser builds will now work inside Workers.
|
||||||
|
|
||||||
|
* Better error messages when attempting to add an invalid mapping to a
|
||||||
|
`SourceMapGenerator`.
|
||||||
|
|
||||||
|
## 0.1.29
|
||||||
|
|
||||||
|
* Allow duplicate entries in the `names` and `sources` arrays of source maps
|
||||||
|
(usually from TypeScript) we are parsing. Fixes github isse 72.
|
||||||
|
|
||||||
|
## 0.1.28
|
||||||
|
|
||||||
|
* Skip duplicate mappings when creating source maps from SourceNode; github
|
||||||
|
issue 75.
|
||||||
|
|
||||||
|
## 0.1.27
|
||||||
|
|
||||||
|
* Don't throw an error when the `file` property is missing in SourceMapConsumer,
|
||||||
|
we don't use it anyway.
|
||||||
|
|
||||||
|
## 0.1.26
|
||||||
|
|
||||||
|
* Fix SourceNode.fromStringWithSourceMap for empty maps. Fixes github issue 70.
|
||||||
|
|
||||||
|
## 0.1.25
|
||||||
|
|
||||||
|
* Make compatible with browserify
|
||||||
|
|
||||||
|
## 0.1.24
|
||||||
|
|
||||||
|
* Fix issue with absolute paths and `file://` URIs. See
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=885597
|
||||||
|
|
||||||
|
## 0.1.23
|
||||||
|
|
||||||
|
* Fix issue with absolute paths and sourcesContent, github issue 64.
|
||||||
|
|
||||||
|
## 0.1.22
|
||||||
|
|
||||||
|
* Ignore duplicate mappings in SourceMapGenerator. Fixes github issue 21.
|
||||||
|
|
||||||
|
## 0.1.21
|
||||||
|
|
||||||
|
* Fixed handling of sources that start with a slash so that they are relative to
|
||||||
|
the source root's host.
|
||||||
|
|
||||||
|
## 0.1.20
|
||||||
|
|
||||||
|
* Fixed github issue #43: absolute URLs aren't joined with the source root
|
||||||
|
anymore.
|
||||||
|
|
||||||
|
## 0.1.19
|
||||||
|
|
||||||
|
* Using Travis CI to run tests.
|
||||||
|
|
||||||
|
## 0.1.18
|
||||||
|
|
||||||
|
* Fixed a bug in the handling of sourceRoot.
|
||||||
|
|
||||||
|
## 0.1.17
|
||||||
|
|
||||||
|
* Added SourceNode.fromStringWithSourceMap.
|
||||||
|
|
||||||
|
## 0.1.16
|
||||||
|
|
||||||
|
* Added missing documentation.
|
||||||
|
|
||||||
|
* Fixed the generating of empty mappings in SourceNode.
|
||||||
|
|
||||||
|
## 0.1.15
|
||||||
|
|
||||||
|
* Added SourceMapGenerator.applySourceMap.
|
||||||
|
|
||||||
|
## 0.1.14
|
||||||
|
|
||||||
|
* The sourceRoot is now handled consistently.
|
||||||
|
|
||||||
|
## 0.1.13
|
||||||
|
|
||||||
|
* Added SourceMapGenerator.fromSourceMap.
|
||||||
|
|
||||||
|
## 0.1.12
|
||||||
|
|
||||||
|
* SourceNode now generates empty mappings too.
|
||||||
|
|
||||||
|
## 0.1.11
|
||||||
|
|
||||||
|
* Added name support to SourceNode.
|
||||||
|
|
||||||
|
## 0.1.10
|
||||||
|
|
||||||
|
* Added sourcesContent support to the customer and generator.
|
||||||
|
|
||||||
28
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/LICENSE
generated
vendored
Normal file
28
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
Copyright (c) 2009-2011, Mozilla Foundation and contributors
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the names of the Mozilla Foundation nor the names of project
|
||||||
|
contributors may be used to endorse or promote products derived from this
|
||||||
|
software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
166
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/Makefile.dryice.js
generated
vendored
Normal file
166
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/Makefile.dryice.js
generated
vendored
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||||||
|
* Licensed under the New BSD license. See LICENSE or:
|
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/
|
||||||
|
var path = require('path');
|
||||||
|
var fs = require('fs');
|
||||||
|
var copy = require('dryice').copy;
|
||||||
|
|
||||||
|
function removeAmdefine(src) {
|
||||||
|
src = String(src).replace(
|
||||||
|
/if\s*\(typeof\s*define\s*!==\s*'function'\)\s*{\s*var\s*define\s*=\s*require\('amdefine'\)\(module,\s*require\);\s*}\s*/g,
|
||||||
|
'');
|
||||||
|
src = src.replace(
|
||||||
|
/\b(define\(.*)('amdefine',?)/gm,
|
||||||
|
'$1');
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
removeAmdefine.onRead = true;
|
||||||
|
|
||||||
|
function makeNonRelative(src) {
|
||||||
|
return src
|
||||||
|
.replace(/require\('.\//g, 'require(\'source-map/')
|
||||||
|
.replace(/\.\.\/\.\.\/lib\//g, '');
|
||||||
|
}
|
||||||
|
makeNonRelative.onRead = true;
|
||||||
|
|
||||||
|
function buildBrowser() {
|
||||||
|
console.log('\nCreating dist/source-map.js');
|
||||||
|
|
||||||
|
var project = copy.createCommonJsProject({
|
||||||
|
roots: [ path.join(__dirname, 'lib') ]
|
||||||
|
});
|
||||||
|
|
||||||
|
copy({
|
||||||
|
source: [
|
||||||
|
'build/mini-require.js',
|
||||||
|
{
|
||||||
|
project: project,
|
||||||
|
require: [ 'source-map/source-map-generator',
|
||||||
|
'source-map/source-map-consumer',
|
||||||
|
'source-map/source-node']
|
||||||
|
},
|
||||||
|
'build/suffix-browser.js'
|
||||||
|
],
|
||||||
|
filter: [
|
||||||
|
copy.filter.moduleDefines,
|
||||||
|
removeAmdefine
|
||||||
|
],
|
||||||
|
dest: 'dist/source-map.js'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildBrowserMin() {
|
||||||
|
console.log('\nCreating dist/source-map.min.js');
|
||||||
|
|
||||||
|
copy({
|
||||||
|
source: 'dist/source-map.js',
|
||||||
|
filter: copy.filter.uglifyjs,
|
||||||
|
dest: 'dist/source-map.min.js'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildFirefox() {
|
||||||
|
console.log('\nCreating dist/SourceMap.jsm');
|
||||||
|
|
||||||
|
var project = copy.createCommonJsProject({
|
||||||
|
roots: [ path.join(__dirname, 'lib') ]
|
||||||
|
});
|
||||||
|
|
||||||
|
copy({
|
||||||
|
source: [
|
||||||
|
'build/prefix-source-map.jsm',
|
||||||
|
{
|
||||||
|
project: project,
|
||||||
|
require: [ 'source-map/source-map-consumer',
|
||||||
|
'source-map/source-map-generator',
|
||||||
|
'source-map/source-node' ]
|
||||||
|
},
|
||||||
|
'build/suffix-source-map.jsm'
|
||||||
|
],
|
||||||
|
filter: [
|
||||||
|
copy.filter.moduleDefines,
|
||||||
|
removeAmdefine,
|
||||||
|
makeNonRelative
|
||||||
|
],
|
||||||
|
dest: 'dist/SourceMap.jsm'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create dist/test/Utils.jsm
|
||||||
|
console.log('\nCreating dist/test/Utils.jsm');
|
||||||
|
|
||||||
|
project = copy.createCommonJsProject({
|
||||||
|
roots: [ __dirname, path.join(__dirname, 'lib') ]
|
||||||
|
});
|
||||||
|
|
||||||
|
copy({
|
||||||
|
source: [
|
||||||
|
'build/prefix-utils.jsm',
|
||||||
|
'build/assert-shim.js',
|
||||||
|
{
|
||||||
|
project: project,
|
||||||
|
require: [ 'test/source-map/util' ]
|
||||||
|
},
|
||||||
|
'build/suffix-utils.jsm'
|
||||||
|
],
|
||||||
|
filter: [
|
||||||
|
copy.filter.moduleDefines,
|
||||||
|
removeAmdefine,
|
||||||
|
makeNonRelative
|
||||||
|
],
|
||||||
|
dest: 'dist/test/Utils.jsm'
|
||||||
|
});
|
||||||
|
|
||||||
|
function isTestFile(f) {
|
||||||
|
return /^test\-.*?\.js/.test(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
var testFiles = fs.readdirSync(path.join(__dirname, 'test', 'source-map')).filter(isTestFile);
|
||||||
|
|
||||||
|
testFiles.forEach(function (testFile) {
|
||||||
|
console.log('\nCreating', path.join('dist', 'test', testFile.replace(/\-/g, '_')));
|
||||||
|
|
||||||
|
copy({
|
||||||
|
source: [
|
||||||
|
'build/test-prefix.js',
|
||||||
|
path.join('test', 'source-map', testFile),
|
||||||
|
'build/test-suffix.js'
|
||||||
|
],
|
||||||
|
filter: [
|
||||||
|
removeAmdefine,
|
||||||
|
makeNonRelative,
|
||||||
|
function (input, source) {
|
||||||
|
return input.replace('define(',
|
||||||
|
'define("'
|
||||||
|
+ path.join('test', 'source-map', testFile.replace(/\.js$/, ''))
|
||||||
|
+ '", ["require", "exports", "module"], ');
|
||||||
|
},
|
||||||
|
function (input, source) {
|
||||||
|
return input.replace('{THIS_MODULE}', function () {
|
||||||
|
return "test/source-map/" + testFile.replace(/\.js$/, '');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
],
|
||||||
|
dest: path.join('dist', 'test', testFile.replace(/\-/g, '_'))
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureDir(name) {
|
||||||
|
var dirExists = false;
|
||||||
|
try {
|
||||||
|
dirExists = fs.statSync(name).isDirectory();
|
||||||
|
} catch (err) {}
|
||||||
|
|
||||||
|
if (!dirExists) {
|
||||||
|
fs.mkdirSync(name, 0777);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureDir("dist");
|
||||||
|
ensureDir("dist/test");
|
||||||
|
buildFirefox();
|
||||||
|
buildBrowser();
|
||||||
|
buildBrowserMin();
|
||||||
434
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/README.md
generated
vendored
Normal file
434
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/README.md
generated
vendored
Normal file
@@ -0,0 +1,434 @@
|
|||||||
|
# Source Map
|
||||||
|
|
||||||
|
This is a library to generate and consume the source map format
|
||||||
|
[described here][format].
|
||||||
|
|
||||||
|
This library is written in the Asynchronous Module Definition format, and works
|
||||||
|
in the following environments:
|
||||||
|
|
||||||
|
* Modern Browsers supporting ECMAScript 5 (either after the build, or with an
|
||||||
|
AMD loader such as RequireJS)
|
||||||
|
|
||||||
|
* Inside Firefox (as a JSM file, after the build)
|
||||||
|
|
||||||
|
* With NodeJS versions 0.8.X and higher
|
||||||
|
|
||||||
|
## Node
|
||||||
|
|
||||||
|
$ npm install source-map
|
||||||
|
|
||||||
|
## Building from Source (for everywhere else)
|
||||||
|
|
||||||
|
Install Node and then run
|
||||||
|
|
||||||
|
$ git clone https://fitzgen@github.com/mozilla/source-map.git
|
||||||
|
$ cd source-map
|
||||||
|
$ npm link .
|
||||||
|
|
||||||
|
Next, run
|
||||||
|
|
||||||
|
$ node Makefile.dryice.js
|
||||||
|
|
||||||
|
This should spew a bunch of stuff to stdout, and create the following files:
|
||||||
|
|
||||||
|
* `dist/source-map.js` - The unminified browser version.
|
||||||
|
|
||||||
|
* `dist/source-map.min.js` - The minified browser version.
|
||||||
|
|
||||||
|
* `dist/SourceMap.jsm` - The JavaScript Module for inclusion in Firefox source.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Consuming a source map
|
||||||
|
|
||||||
|
var rawSourceMap = {
|
||||||
|
version: 3,
|
||||||
|
file: 'min.js',
|
||||||
|
names: ['bar', 'baz', 'n'],
|
||||||
|
sources: ['one.js', 'two.js'],
|
||||||
|
sourceRoot: 'http://example.com/www/js/',
|
||||||
|
mappings: 'CAAC,IAAI,IAAM,SAAUA,GAClB,OAAOC,IAAID;CCDb,IAAI,IAAM,SAAUE,GAClB,OAAOA'
|
||||||
|
};
|
||||||
|
|
||||||
|
var smc = new SourceMapConsumer(rawSourceMap);
|
||||||
|
|
||||||
|
console.log(smc.sources);
|
||||||
|
// [ 'http://example.com/www/js/one.js',
|
||||||
|
// 'http://example.com/www/js/two.js' ]
|
||||||
|
|
||||||
|
console.log(smc.originalPositionFor({
|
||||||
|
line: 2,
|
||||||
|
column: 28
|
||||||
|
}));
|
||||||
|
// { source: 'http://example.com/www/js/two.js',
|
||||||
|
// line: 2,
|
||||||
|
// column: 10,
|
||||||
|
// name: 'n' }
|
||||||
|
|
||||||
|
console.log(smc.generatedPositionFor({
|
||||||
|
source: 'http://example.com/www/js/two.js',
|
||||||
|
line: 2,
|
||||||
|
column: 10
|
||||||
|
}));
|
||||||
|
// { line: 2, column: 28 }
|
||||||
|
|
||||||
|
smc.eachMapping(function (m) {
|
||||||
|
// ...
|
||||||
|
});
|
||||||
|
|
||||||
|
### Generating a source map
|
||||||
|
|
||||||
|
In depth guide:
|
||||||
|
[**Compiling to JavaScript, and Debugging with Source Maps**](https://hacks.mozilla.org/2013/05/compiling-to-javascript-and-debugging-with-source-maps/)
|
||||||
|
|
||||||
|
#### With SourceNode (high level API)
|
||||||
|
|
||||||
|
function compile(ast) {
|
||||||
|
switch (ast.type) {
|
||||||
|
case 'BinaryExpression':
|
||||||
|
return new SourceNode(
|
||||||
|
ast.location.line,
|
||||||
|
ast.location.column,
|
||||||
|
ast.location.source,
|
||||||
|
[compile(ast.left), " + ", compile(ast.right)]
|
||||||
|
);
|
||||||
|
case 'Literal':
|
||||||
|
return new SourceNode(
|
||||||
|
ast.location.line,
|
||||||
|
ast.location.column,
|
||||||
|
ast.location.source,
|
||||||
|
String(ast.value)
|
||||||
|
);
|
||||||
|
// ...
|
||||||
|
default:
|
||||||
|
throw new Error("Bad AST");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ast = parse("40 + 2", "add.js");
|
||||||
|
console.log(compile(ast).toStringWithSourceMap({
|
||||||
|
file: 'add.js'
|
||||||
|
}));
|
||||||
|
// { code: '40 + 2',
|
||||||
|
// map: [object SourceMapGenerator] }
|
||||||
|
|
||||||
|
#### With SourceMapGenerator (low level API)
|
||||||
|
|
||||||
|
var map = new SourceMapGenerator({
|
||||||
|
file: "source-mapped.js"
|
||||||
|
});
|
||||||
|
|
||||||
|
map.addMapping({
|
||||||
|
generated: {
|
||||||
|
line: 10,
|
||||||
|
column: 35
|
||||||
|
},
|
||||||
|
source: "foo.js",
|
||||||
|
original: {
|
||||||
|
line: 33,
|
||||||
|
column: 2
|
||||||
|
},
|
||||||
|
name: "christopher"
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(map.toString());
|
||||||
|
// '{"version":3,"file":"source-mapped.js","sources":["foo.js"],"names":["christopher"],"mappings":";;;;;;;;;mCAgCEA"}'
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
Get a reference to the module:
|
||||||
|
|
||||||
|
// NodeJS
|
||||||
|
var sourceMap = require('source-map');
|
||||||
|
|
||||||
|
// Browser builds
|
||||||
|
var sourceMap = window.sourceMap;
|
||||||
|
|
||||||
|
// Inside Firefox
|
||||||
|
let sourceMap = {};
|
||||||
|
Components.utils.import('resource:///modules/devtools/SourceMap.jsm', sourceMap);
|
||||||
|
|
||||||
|
### SourceMapConsumer
|
||||||
|
|
||||||
|
A SourceMapConsumer instance represents a parsed source map which we can query
|
||||||
|
for information about the original file positions by giving it a file position
|
||||||
|
in the generated source.
|
||||||
|
|
||||||
|
#### new SourceMapConsumer(rawSourceMap)
|
||||||
|
|
||||||
|
The only parameter is the raw source map (either as a string which can be
|
||||||
|
`JSON.parse`'d, or an object). According to the spec, source maps have the
|
||||||
|
following attributes:
|
||||||
|
|
||||||
|
* `version`: Which version of the source map spec this map is following.
|
||||||
|
|
||||||
|
* `sources`: An array of URLs to the original source files.
|
||||||
|
|
||||||
|
* `names`: An array of identifiers which can be referrenced by individual
|
||||||
|
mappings.
|
||||||
|
|
||||||
|
* `sourceRoot`: Optional. The URL root from which all sources are relative.
|
||||||
|
|
||||||
|
* `sourcesContent`: Optional. An array of contents of the original source files.
|
||||||
|
|
||||||
|
* `mappings`: A string of base64 VLQs which contain the actual mappings.
|
||||||
|
|
||||||
|
* `file`: The generated filename this source map is associated with.
|
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.originalPositionFor(generatedPosition)
|
||||||
|
|
||||||
|
Returns the original source, line, and column information for the generated
|
||||||
|
source's line and column positions provided. The only argument is an object with
|
||||||
|
the following properties:
|
||||||
|
|
||||||
|
* `line`: The line number in the generated source.
|
||||||
|
|
||||||
|
* `column`: The column number in the generated source.
|
||||||
|
|
||||||
|
and an object is returned with the following properties:
|
||||||
|
|
||||||
|
* `source`: The original source file, or null if this information is not
|
||||||
|
available.
|
||||||
|
|
||||||
|
* `line`: The line number in the original source, or null if this information is
|
||||||
|
not available.
|
||||||
|
|
||||||
|
* `column`: The column number in the original source, or null or null if this
|
||||||
|
information is not available.
|
||||||
|
|
||||||
|
* `name`: The original identifier, or null if this information is not available.
|
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.generatedPositionFor(originalPosition)
|
||||||
|
|
||||||
|
Returns the generated line and column information for the original source,
|
||||||
|
line, and column positions provided. The only argument is an object with
|
||||||
|
the following properties:
|
||||||
|
|
||||||
|
* `source`: The filename of the original source.
|
||||||
|
|
||||||
|
* `line`: The line number in the original source.
|
||||||
|
|
||||||
|
* `column`: The column number in the original source.
|
||||||
|
|
||||||
|
and an object is returned with the following properties:
|
||||||
|
|
||||||
|
* `line`: The line number in the generated source, or null.
|
||||||
|
|
||||||
|
* `column`: The column number in the generated source, or null.
|
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.sourceContentFor(source)
|
||||||
|
|
||||||
|
Returns the original source content for the source provided. The only
|
||||||
|
argument is the URL of the original source file.
|
||||||
|
|
||||||
|
#### SourceMapConsumer.prototype.eachMapping(callback, context, order)
|
||||||
|
|
||||||
|
Iterate over each mapping between an original source/line/column and a
|
||||||
|
generated line/column in this source map.
|
||||||
|
|
||||||
|
* `callback`: The function that is called with each mapping. Mappings have the
|
||||||
|
form `{ source, generatedLine, generatedColumn, originalLine, originalColumn,
|
||||||
|
name }`
|
||||||
|
|
||||||
|
* `context`: Optional. If specified, this object will be the value of `this`
|
||||||
|
every time that `callback` is called.
|
||||||
|
|
||||||
|
* `order`: Either `SourceMapConsumer.GENERATED_ORDER` or
|
||||||
|
`SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to iterate over
|
||||||
|
the mappings sorted by the generated file's line/column order or the
|
||||||
|
original's source/line/column order, respectively. Defaults to
|
||||||
|
`SourceMapConsumer.GENERATED_ORDER`.
|
||||||
|
|
||||||
|
### SourceMapGenerator
|
||||||
|
|
||||||
|
An instance of the SourceMapGenerator represents a source map which is being
|
||||||
|
built incrementally.
|
||||||
|
|
||||||
|
#### new SourceMapGenerator(startOfSourceMap)
|
||||||
|
|
||||||
|
To create a new one, you must pass an object with the following properties:
|
||||||
|
|
||||||
|
* `file`: The filename of the generated source that this source map is
|
||||||
|
associated with.
|
||||||
|
|
||||||
|
* `sourceRoot`: An optional root for all relative URLs in this source map.
|
||||||
|
|
||||||
|
#### SourceMapGenerator.fromSourceMap(sourceMapConsumer)
|
||||||
|
|
||||||
|
Creates a new SourceMapGenerator based on a SourceMapConsumer
|
||||||
|
|
||||||
|
* `sourceMapConsumer` The SourceMap.
|
||||||
|
|
||||||
|
#### SourceMapGenerator.prototype.addMapping(mapping)
|
||||||
|
|
||||||
|
Add a single mapping from original source line and column to the generated
|
||||||
|
source's line and column for this source map being created. The mapping object
|
||||||
|
should have the following properties:
|
||||||
|
|
||||||
|
* `generated`: An object with the generated line and column positions.
|
||||||
|
|
||||||
|
* `original`: An object with the original line and column positions.
|
||||||
|
|
||||||
|
* `source`: The original source file (relative to the sourceRoot).
|
||||||
|
|
||||||
|
* `name`: An optional original token name for this mapping.
|
||||||
|
|
||||||
|
#### SourceMapGenerator.prototype.setSourceContent(sourceFile, sourceContent)
|
||||||
|
|
||||||
|
Set the source content for an original source file.
|
||||||
|
|
||||||
|
* `sourceFile` the URL of the original source file.
|
||||||
|
|
||||||
|
* `sourceContent` the content of the source file.
|
||||||
|
|
||||||
|
#### SourceMapGenerator.prototype.applySourceMap(sourceMapConsumer[, sourceFile])
|
||||||
|
|
||||||
|
Applies a SourceMap for a source file to the SourceMap.
|
||||||
|
Each mapping to the supplied source file is rewritten using the
|
||||||
|
supplied SourceMap. Note: The resolution for the resulting mappings
|
||||||
|
is the minimium of this map and the supplied map.
|
||||||
|
|
||||||
|
* `sourceMapConsumer`: The SourceMap to be applied.
|
||||||
|
|
||||||
|
* `sourceFile`: Optional. The filename of the source file.
|
||||||
|
If omitted, sourceMapConsumer.file will be used.
|
||||||
|
|
||||||
|
#### SourceMapGenerator.prototype.toString()
|
||||||
|
|
||||||
|
Renders the source map being generated to a string.
|
||||||
|
|
||||||
|
### SourceNode
|
||||||
|
|
||||||
|
SourceNodes provide a way to abstract over interpolating and/or concatenating
|
||||||
|
snippets of generated JavaScript source code, while maintaining the line and
|
||||||
|
column information associated between those snippets and the original source
|
||||||
|
code. This is useful as the final intermediate representation a compiler might
|
||||||
|
use before outputting the generated JS and source map.
|
||||||
|
|
||||||
|
#### new SourceNode(line, column, source[, chunk[, name]])
|
||||||
|
|
||||||
|
* `line`: The original line number associated with this source node, or null if
|
||||||
|
it isn't associated with an original line.
|
||||||
|
|
||||||
|
* `column`: The original column number associated with this source node, or null
|
||||||
|
if it isn't associated with an original column.
|
||||||
|
|
||||||
|
* `source`: The original source's filename.
|
||||||
|
|
||||||
|
* `chunk`: Optional. Is immediately passed to `SourceNode.prototype.add`, see
|
||||||
|
below.
|
||||||
|
|
||||||
|
* `name`: Optional. The original identifier.
|
||||||
|
|
||||||
|
#### SourceNode.fromStringWithSourceMap(code, sourceMapConsumer)
|
||||||
|
|
||||||
|
Creates a SourceNode from generated code and a SourceMapConsumer.
|
||||||
|
|
||||||
|
* `code`: The generated code
|
||||||
|
|
||||||
|
* `sourceMapConsumer` The SourceMap for the generated code
|
||||||
|
|
||||||
|
#### SourceNode.prototype.add(chunk)
|
||||||
|
|
||||||
|
Add a chunk of generated JS to this source node.
|
||||||
|
|
||||||
|
* `chunk`: A string snippet of generated JS code, another instance of
|
||||||
|
`SourceNode`, or an array where each member is one of those things.
|
||||||
|
|
||||||
|
#### SourceNode.prototype.prepend(chunk)
|
||||||
|
|
||||||
|
Prepend a chunk of generated JS to this source node.
|
||||||
|
|
||||||
|
* `chunk`: A string snippet of generated JS code, another instance of
|
||||||
|
`SourceNode`, or an array where each member is one of those things.
|
||||||
|
|
||||||
|
#### SourceNode.prototype.setSourceContent(sourceFile, sourceContent)
|
||||||
|
|
||||||
|
Set the source content for a source file. This will be added to the
|
||||||
|
`SourceMap` in the `sourcesContent` field.
|
||||||
|
|
||||||
|
* `sourceFile`: The filename of the source file
|
||||||
|
|
||||||
|
* `sourceContent`: The content of the source file
|
||||||
|
|
||||||
|
#### SourceNode.prototype.walk(fn)
|
||||||
|
|
||||||
|
Walk over the tree of JS snippets in this node and its children. The walking
|
||||||
|
function is called once for each snippet of JS and is passed that snippet and
|
||||||
|
the its original associated source's line/column location.
|
||||||
|
|
||||||
|
* `fn`: The traversal function.
|
||||||
|
|
||||||
|
#### SourceNode.prototype.walkSourceContents(fn)
|
||||||
|
|
||||||
|
Walk over the tree of SourceNodes. The walking function is called for each
|
||||||
|
source file content and is passed the filename and source content.
|
||||||
|
|
||||||
|
* `fn`: The traversal function.
|
||||||
|
|
||||||
|
#### SourceNode.prototype.join(sep)
|
||||||
|
|
||||||
|
Like `Array.prototype.join` except for SourceNodes. Inserts the separator
|
||||||
|
between each of this source node's children.
|
||||||
|
|
||||||
|
* `sep`: The separator.
|
||||||
|
|
||||||
|
#### SourceNode.prototype.replaceRight(pattern, replacement)
|
||||||
|
|
||||||
|
Call `String.prototype.replace` on the very right-most source snippet. Useful
|
||||||
|
for trimming whitespace from the end of a source node, etc.
|
||||||
|
|
||||||
|
* `pattern`: The pattern to replace.
|
||||||
|
|
||||||
|
* `replacement`: The thing to replace the pattern with.
|
||||||
|
|
||||||
|
#### SourceNode.prototype.toString()
|
||||||
|
|
||||||
|
Return the string representation of this source node. Walks over the tree and
|
||||||
|
concatenates all the various snippets together to one string.
|
||||||
|
|
||||||
|
### SourceNode.prototype.toStringWithSourceMap(startOfSourceMap)
|
||||||
|
|
||||||
|
Returns the string representation of this tree of source nodes, plus a
|
||||||
|
SourceMapGenerator which contains all the mappings between the generated and
|
||||||
|
original sources.
|
||||||
|
|
||||||
|
The arguments are the same as those to `new SourceMapGenerator`.
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
[](https://travis-ci.org/mozilla/source-map)
|
||||||
|
|
||||||
|
Install NodeJS version 0.8.0 or greater, then run `node test/run-tests.js`.
|
||||||
|
|
||||||
|
To add new tests, create a new file named `test/test-<your new test name>.js`
|
||||||
|
and export your test functions with names that start with "test", for example
|
||||||
|
|
||||||
|
exports["test doing the foo bar"] = function (assert, util) {
|
||||||
|
...
|
||||||
|
};
|
||||||
|
|
||||||
|
The new test will be located automatically when you run the suite.
|
||||||
|
|
||||||
|
The `util` argument is the test utility module located at `test/source-map/util`.
|
||||||
|
|
||||||
|
The `assert` argument is a cut down version of node's assert module. You have
|
||||||
|
access to the following assertion functions:
|
||||||
|
|
||||||
|
* `doesNotThrow`
|
||||||
|
|
||||||
|
* `equal`
|
||||||
|
|
||||||
|
* `ok`
|
||||||
|
|
||||||
|
* `strictEqual`
|
||||||
|
|
||||||
|
* `throws`
|
||||||
|
|
||||||
|
(The reason for the restricted set of test functions is because we need the
|
||||||
|
tests to run inside Firefox's test suite as well and so the assert module is
|
||||||
|
shimmed in that environment. See `build/assert-shim.js`.)
|
||||||
|
|
||||||
|
[format]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit
|
||||||
|
[feature]: https://wiki.mozilla.org/DevTools/Features/SourceMap
|
||||||
|
[Dryice]: https://github.com/mozilla/dryice
|
||||||
56
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/build/assert-shim.js
generated
vendored
Normal file
56
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/build/assert-shim.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||||||
|
* Licensed under the New BSD license. See LICENSE or:
|
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/
|
||||||
|
define('test/source-map/assert', ['exports'], function (exports) {
|
||||||
|
|
||||||
|
let do_throw = function (msg) {
|
||||||
|
throw new Error(msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.init = function (throw_fn) {
|
||||||
|
do_throw = throw_fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.doesNotThrow = function (fn) {
|
||||||
|
try {
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
do_throw(e.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.equal = function (actual, expected, msg) {
|
||||||
|
msg = msg || String(actual) + ' != ' + String(expected);
|
||||||
|
if (actual != expected) {
|
||||||
|
do_throw(msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.ok = function (val, msg) {
|
||||||
|
msg = msg || String(val) + ' is falsey';
|
||||||
|
if (!Boolean(val)) {
|
||||||
|
do_throw(msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.strictEqual = function (actual, expected, msg) {
|
||||||
|
msg = msg || String(actual) + ' !== ' + String(expected);
|
||||||
|
if (actual !== expected) {
|
||||||
|
do_throw(msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.throws = function (fn) {
|
||||||
|
try {
|
||||||
|
fn();
|
||||||
|
do_throw('Expected an error to be thrown, but it wasn\'t.');
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
152
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/build/mini-require.js
generated
vendored
Normal file
152
node_modules/handlebars/node_modules/uglify-js/node_modules/source-map/build/mini-require.js
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/* -*- Mode: js; js-indent-level: 2; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Mozilla Foundation and contributors
|
||||||
|
* Licensed under the New BSD license. See LICENSE or:
|
||||||
|
* http://opensource.org/licenses/BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a module along with a payload.
|
||||||
|
* @param {string} moduleName Name for the payload
|
||||||
|
* @param {ignored} deps Ignored. For compatibility with CommonJS AMD Spec
|
||||||
|
* @param {function} payload Function with (require, exports, module) params
|
||||||
|
*/
|
||||||
|
function define(moduleName, deps, payload) {
|
||||||
|
if (typeof moduleName != "string") {
|
||||||
|
throw new TypeError('Expected string, got: ' + moduleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arguments.length == 2) {
|
||||||
|
payload = deps;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moduleName in define.modules) {
|
||||||
|
throw new Error("Module already defined: " + moduleName);
|
||||||
|
}
|
||||||
|
define.modules[moduleName] = payload;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The global store of un-instantiated modules
|
||||||
|
*/
|
||||||
|
define.modules = {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We invoke require() in the context of a Domain so we can have multiple
|
||||||
|
* sets of modules running separate from each other.
|
||||||
|
* This contrasts with JSMs which are singletons, Domains allows us to
|
||||||
|
* optionally load a CommonJS module twice with separate data each time.
|
||||||
|
* Perhaps you want 2 command lines with a different set of commands in each,
|
||||||
|
* for example.
|
||||||
|
*/
|
||||||
|
function Domain() {
|
||||||
|
this.modules = {};
|
||||||
|
this._currentModule = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup module names and resolve them by calling the definition function if
|
||||||
|
* needed.
|
||||||
|
* There are 2 ways to call this, either with an array of dependencies and a
|
||||||
|
* callback to call when the dependencies are found (which can happen
|
||||||
|
* asynchronously in an in-page context) or with a single string an no callback
|
||||||
|
* where the dependency is resolved synchronously and returned.
|
||||||
|
* The API is designed to be compatible with the CommonJS AMD spec and
|
||||||
|
* RequireJS.
|
||||||
|
* @param {string[]|string} deps A name, or names for the payload
|
||||||
|
* @param {function|undefined} callback Function to call when the dependencies
|
||||||
|
* are resolved
|
||||||
|
* @return {undefined|object} The module required or undefined for
|
||||||
|
* array/callback method
|
||||||
|
*/
|
||||||
|
Domain.prototype.require = function(deps, callback) {
|
||||||
|
if (Array.isArray(deps)) {
|
||||||
|
var params = deps.map(function(dep) {
|
||||||
|
return this.lookup(dep);
|
||||||
|
}, this);
|
||||||
|
if (callback) {
|
||||||
|
callback.apply(null, params);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return this.lookup(deps);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function normalize(path) {
|
||||||
|
var bits = path.split('/');
|
||||||
|
var i = 1;
|
||||||
|
while (i < bits.length) {
|
||||||
|
if (bits[i] === '..') {
|
||||||
|
bits.splice(i-1, 1);
|
||||||
|
} else if (bits[i] === '.') {
|
||||||
|
bits.splice(i, 1);
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bits.join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
function join(a, b) {
|
||||||
|
a = a.trim();
|
||||||
|
b = b.trim();
|
||||||
|
if (/^\//.test(b)) {
|
||||||
|
return b;
|
||||||
|
} else {
|
||||||
|
return a.replace(/\/*$/, '/') + b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function dirname(path) {
|
||||||
|
var bits = path.split('/');
|
||||||
|
bits.pop();
|
||||||
|
return bits.join('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup module names and resolve them by calling the definition function if
|
||||||
|
* needed.
|
||||||
|
* @param {string} moduleName A name for the payload to lookup
|
||||||
|
* @return {object} The module specified by aModuleName or null if not found.
|
||||||
|
*/
|
||||||
|
Domain.prototype.lookup = function(moduleName) {
|
||||||
|
if (/^\./.test(moduleName)) {
|
||||||
|
moduleName = normalize(join(dirname(this._currentModule), moduleName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moduleName in this.modules) {
|
||||||
|
var module = this.modules[moduleName];
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(moduleName in define.modules)) {
|
||||||
|
throw new Error("Module not defined: " + moduleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
var module = define.modules[moduleName];
|
||||||
|
|
||||||
|
if (typeof module == "function") {
|
||||||
|
var exports = {};
|
||||||
|
var previousModule = this._currentModule;
|
||||||
|
this._currentModule = moduleName;
|
||||||
|
module(this.require.bind(this), exports, { id: moduleName, uri: "" });
|
||||||
|
this._currentModule = previousModule;
|
||||||
|
module = exports;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cache the resulting module object for next time
|
||||||
|
this.modules[moduleName] = module;
|
||||||
|
|
||||||
|
return module;
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
define.Domain = Domain;
|
||||||
|
define.globalDomain = new Domain();
|
||||||
|
var require = define.globalDomain.require.bind(define.globalDomain);
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user