├── .gitignore
├── MIT-LICENSE
├── Makefile
├── README.markdown
├── component.json
├── node_modules
├── .bin
│ └── uglifyjs
├── node-static
│ ├── LICENSE
│ ├── README.md
│ ├── benchmark
│ │ └── node-static-0.3.0.txt
│ ├── examples
│ │ └── file-server.js
│ ├── lib
│ │ ├── node-static.js
│ │ └── node-static
│ │ │ ├── mime.js
│ │ │ └── util.js
│ └── package.json
└── uglify-js
│ ├── .gitignore
│ ├── README.html
│ ├── README.org
│ ├── bin
│ └── uglifyjs
│ ├── docstyle.css
│ ├── lib
│ ├── object-ast.js
│ ├── parse-js.js
│ ├── process.js
│ └── squeeze-more.js
│ ├── package.json
│ ├── package.json~
│ ├── test
│ ├── beautify.js
│ ├── testparser.js
│ └── unit
│ │ ├── compress
│ │ ├── expected
│ │ │ ├── array1.js
│ │ │ ├── array2.js
│ │ │ ├── array3.js
│ │ │ ├── array4.js
│ │ │ ├── assignment.js
│ │ │ ├── concatstring.js
│ │ │ ├── const.js
│ │ │ ├── empty-blocks.js
│ │ │ ├── forstatement.js
│ │ │ ├── if.js
│ │ │ ├── ifreturn.js
│ │ │ ├── ifreturn2.js
│ │ │ ├── issue10.js
│ │ │ ├── issue11.js
│ │ │ ├── issue13.js
│ │ │ ├── issue14.js
│ │ │ ├── issue16.js
│ │ │ ├── issue17.js
│ │ │ ├── issue20.js
│ │ │ ├── issue21.js
│ │ │ ├── issue25.js
│ │ │ ├── issue27.js
│ │ │ ├── issue28.js
│ │ │ ├── issue29.js
│ │ │ ├── issue30.js
│ │ │ ├── issue34.js
│ │ │ ├── issue4.js
│ │ │ ├── issue48.js
│ │ │ ├── issue50.js
│ │ │ ├── issue53.js
│ │ │ ├── issue54.1.js
│ │ │ ├── issue68.js
│ │ │ ├── issue69.js
│ │ │ ├── issue9.js
│ │ │ ├── mangle.js
│ │ │ ├── null_string.js
│ │ │ ├── strict-equals.js
│ │ │ ├── var.js
│ │ │ ├── whitespace.js
│ │ │ └── with.js
│ │ └── test
│ │ │ ├── array1.js
│ │ │ ├── array2.js
│ │ │ ├── array3.js
│ │ │ ├── array4.js
│ │ │ ├── assignment.js
│ │ │ ├── concatstring.js
│ │ │ ├── const.js
│ │ │ ├── empty-blocks.js
│ │ │ ├── forstatement.js
│ │ │ ├── if.js
│ │ │ ├── ifreturn.js
│ │ │ ├── ifreturn2.js
│ │ │ ├── issue10.js
│ │ │ ├── issue11.js
│ │ │ ├── issue13.js
│ │ │ ├── issue14.js
│ │ │ ├── issue16.js
│ │ │ ├── issue17.js
│ │ │ ├── issue20.js
│ │ │ ├── issue21.js
│ │ │ ├── issue25.js
│ │ │ ├── issue27.js
│ │ │ ├── issue28.js
│ │ │ ├── issue29.js
│ │ │ ├── issue30.js
│ │ │ ├── issue34.js
│ │ │ ├── issue4.js
│ │ │ ├── issue48.js
│ │ │ ├── issue50.js
│ │ │ ├── issue53.js
│ │ │ ├── issue54.1.js
│ │ │ ├── issue68.js
│ │ │ ├── issue69.js
│ │ │ ├── issue9.js
│ │ │ ├── mangle.js
│ │ │ ├── null_string.js
│ │ │ ├── strict-equals.js
│ │ │ ├── var.js
│ │ │ ├── whitespace.js
│ │ │ └── with.js
│ │ └── scripts.js
│ ├── tmp
│ ├── hoist.js
│ ├── instrument.js
│ ├── instrument2.js
│ └── test.js
│ └── uglify-js.js
├── plugins
├── amd.js
├── commonjs.js
├── defer.js
└── json.js
├── src
└── loadrunner.js
├── test
├── amd_test.html
├── commonjs_test.html
├── data.json
├── deferred_test.html
├── index.html
├── javascripts
│ ├── a.js
│ ├── b.js
│ ├── c.js
│ ├── compiled.js
│ ├── d.js
│ ├── deferred_bundle.js
│ ├── deferred_scripts.js
│ ├── e.js
│ ├── main.js
│ ├── modcompiled.js
│ ├── s1.js
│ ├── s2.js
│ └── s3.js
├── json_test.html
├── modules
│ ├── amd
│ │ ├── dotdotslash.js
│ │ ├── moda.js
│ │ ├── modb.js
│ │ ├── modlit.js
│ │ ├── modnodep.js
│ │ └── modrel.js
│ ├── app.js
│ ├── ded-a.js
│ ├── ded-b1.js
│ ├── ded-b2.js
│ ├── deep.js
│ ├── defered.js
│ ├── defered2.js
│ ├── many.js
│ ├── moda.js
│ ├── modb.js
│ ├── modc.js
│ ├── modcompiled.js
│ ├── modd.js
│ ├── mode.js
│ ├── modj.js
│ ├── requirejs
│ │ ├── moddep.js
│ │ └── modtrivial.js
│ └── sub
│ │ ├── modsubfolder.js
│ │ ├── script.js
│ │ ├── submoda.js
│ │ └── submodb.js
├── server
└── test.html
└── vendor
└── qunit
├── qunit.css
└── qunit.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010 Dan Webb
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | all: clean main
2 |
3 | dist/plugins/%.js: plugins/%.js
4 | `npm bin`/uglifyjs -o $@ $<
5 |
6 | dist/%.js: src/%.js
7 | `npm bin`/uglifyjs -o $@ $<
8 |
9 | dist:
10 | mkdir -p dist/plugins
11 |
12 | main: dist js plugins
13 |
14 | plugins: dist/plugins/amd.js dist/plugins/defer.js dist/plugins/json.js
15 |
16 | js: dist/loadrunner.js
17 |
18 | clean:
19 | rm -rf dist
20 |
21 | testserver: .
22 | ./test/server
23 |
24 | test: .
25 | open 'http://localhost:8080/test/index.html'
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | Loadrunner is a JavaScript dependency manager.
2 |
3 | Loadrunner started off as my science project script loader and module system but its turned into a generic dependency manager that you can build on to manage any type of asynchronous dependency from CSS templates to DOM events to cache loading. It does however include build in support for loading regular JavaScript files, AMD modules and its own, more elegant (IMHO) flavour of modules.
4 |
5 | Run the tests
6 | -------------
7 |
8 | Open test/test.html. To run against the minified version open test/test.html?dist=true. Also, try reading the tests. They illustrate how it works possibly better than the examples below.
9 |
10 | Build a minified version
11 | ------------------------
12 |
13 | Just run:
14 |
15 | make
16 |
17 |
18 | The Basics
19 | ----------
20 |
21 | In its basic form, loadrunner exposes two top level functions: `using` and `provide`.
22 |
23 | __using(dependency[, dependency1, dependency2, ...][, collectResults:boolean][, callback])__ => Combination
24 |
25 | Takes any number of dependencies, which can be any type of dependency object or a string representing a dependency (a path to a javascript file or module identifier works by default), and returns a dependency called a *Combination* which waits for all of the given dependencies to complete in any order. If you specify a callback then it's attached to this dependency as a convenience.
26 |
27 | Dependencies are not loaded until a callback is attached.
28 |
29 | ```javascript
30 | // use some javascript files
31 | using('javascripts/jquery.js', 'javascripts/underscore.js', function() {
32 | $(function() {
33 | _(['foo', 'bar', 'baz']).each(function(i) {
34 | $(document.body).append('
' + i + '
');
35 | });
36 | })
37 | });
38 | ```
39 |
40 | Depending on the type of dependencies specified in the `using` block some arguments may be passed to the callback function. For instance, in the case of using a module, the module's exports are passed as a function argument.
41 |
42 | ```javascript
43 | // use some modules
44 | using('dom', 'events', function(dom, events) {
45 | var el = dom.get('#thing');
46 |
47 | events.on(el, function() {
48 | alert('kersplang');
49 | });
50 | });
51 |
52 | // get reference to a dependency
53 | var mods = using('dom', 'events');
54 |
55 | // use that dependency with others
56 | using(mods, 'javascripts/jquery.js', function(dom, events) {
57 |
58 | });
59 | ```
60 |
61 | Using can provide all exports in a single object if required. Just use the 'as' method.
62 |
63 | ```javascript
64 | // use some modules in one object
65 | using('dom', 'events').as(function(imports) {
66 | var el = imports.dom.get('#thing');
67 | imports.events.on(el, function() {
68 | alert('kersplang');
69 | });
70 | });
71 | ```
72 |
73 | In this case, the exports are still available individually.
74 |
75 | ```javascript
76 | // use some modules in one object, and also have them immediately available
77 | using('dom', 'events').as(function(imports, dom, events) {
78 | var el = dom.get('#thing');
79 | imports.events.on(el, function() {
80 | alert('kersplang');
81 | });
82 | });
83 | ```
84 |
85 | Using can load scripts synchronously (in order) by being provided arguments in an array.
86 |
87 | ```javascript
88 | // load 'dom' first, then load 'events', then execute the callback
89 | using(['dom', 'events'], true, function(imports) {
90 |
91 | });
92 | ```
93 |
94 |
95 | __provide([id,] factory)__ => Module
96 |
97 | `provide` defines a module with the given id. If you don't provide an id then the module's id will be inferred from the location of the javascript file that contains it (dom/events.js => dom/events). Provide returns a type of definition, *Module*. The second argument can be either a function that is run to define the module, or any kind of other type. In the case of this being a function, then when the module is evaluated the function is called with a single argument, normally called *exports*, which is a function that you call to specify which public values the module exports. Note that you can call this at any point after the module has been evaluated. _Exporting module values is asynchronous._ Among other things, this allows seamless operation with the `using` function to allow your modules to depend on other items.
98 |
99 | ```javascript
100 | // define a module, "config", that exports some static values
101 | provide('config', {
102 | env: 'staging',
103 | admin: true
104 | });
105 |
106 | // define then use a module, test
107 | provide('test', function(exports) {
108 | var thing = 47;
109 |
110 | exports(thing);
111 | });
112 |
113 | using('test', function(thing) {
114 | alert(thing); // => 47
115 | });
116 |
117 | // define and use a module that depends on other modules (app/main.js)
118 | provide(function(exports) {
119 | using('test', function(thing) {
120 | exports(thing + 10);
121 | });
122 | });
123 |
124 | using('app/main', function(main) {
125 | alert(main); //=> 57
126 | });
127 | ```
128 |
129 | Debugging
130 | --------
131 |
132 | Loadrunner provides a debug command to run in the console. Enter `loadrunner.debug()`, and you'll see a set of met, inProgress and paused dependencies.
133 |
134 | Another great debugging method is to inspect `loadrunner.Module.exports`.
135 |
136 |
137 | Bundling
138 | --------
139 |
140 | Modules can be joined together in single files, provided they have names explicitly defined. Tools such as [Loadbuilder](https://github.com/danwrong/loadbuilder) can help with automatically inserting the module names.
141 |
142 | If a module is requested in a `using` before it has been provided, loadrunner will make a call to load the module individually. To prevent this, loadrunner provides some options:
143 |
144 | * `loadrunner.autoFetch = false` Assumes modules will be provided in later-loading bundles, so loadrunner will not fetch scripts. To explicitly fetch scripts, you must run `forceStart` on the dependency, eg: `using('bundle').forceStart();`
145 | * `using.bundles.push({'bundle': ['moda', 'modb'])` Declare the location of modules in bundles. When a module is requested, loadrunner will wait first on the evaluation of the bundle, fetching it if required.
146 |
147 | If your wish to bundle scripts, then they must first be wrapped with `deferred` syntax, like so:
148 |
149 | ```javascript
150 | deferred('jquery.js', function() { /* jquery source */ });
151 | ```
152 |
153 | Loadrunner supports the `deferred` syntax through the `defer` plugin.
154 |
155 | AMD Modules
156 | -----------
157 |
158 | Loadrunner will have support for [AMD Modules](http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) with the use of a plugin. However, this support is not be complete at this time.
159 |
160 |
161 | More documentation forthcoming...
162 |
163 |
--------------------------------------------------------------------------------
/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "loadrunner",
3 | "version": "0.1.2",
4 | "description": "Simple, flexible and sane JavaScript loader and build tool for browsers.",
5 | "contributors": [{ "name": "Dan Webb", "email": "dan@danwebb.net" }],
6 | "homepage": "https://github.com/danwrong/loadrunner",
7 | "main" : "./src/loadrunner.js"
8 | }
--------------------------------------------------------------------------------
/node_modules/.bin/uglifyjs:
--------------------------------------------------------------------------------
1 | ../uglify-js/bin/uglifyjs
--------------------------------------------------------------------------------
/node_modules/node-static/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010 Alexis Sellier
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/node_modules/node-static/README.md:
--------------------------------------------------------------------------------
1 | node-static
2 | ===========
3 |
4 | > a simple, *rfc 2616 compliant* file streaming module for [node](http://nodejs.org)
5 |
6 | node-static has an in-memory file cache, making it highly efficient.
7 | node-static understands and supports *conditional GET* and *HEAD* requests.
8 | node-static was inspired by some of the other static-file serving modules out there,
9 | such as node-paperboy and antinode.
10 |
11 | synopsis
12 | --------
13 |
14 | var static = require('node-static');
15 |
16 | //
17 | // Create a node-static server instance to serve the './public' folder
18 | //
19 | var file = new(static.Server)('./public');
20 |
21 | require('http').createServer(function (request, response) {
22 | request.addListener('end', function () {
23 | //
24 | // Serve files!
25 | //
26 | file.serve(request, response);
27 | });
28 | }).listen(8080);
29 |
30 | API
31 | ---
32 |
33 | ### Creating a node-static Server #
34 |
35 | Creating a file server instance is as simple as:
36 |
37 | new static.Server();
38 |
39 | This will serve files in the current directory. If you want to serve files in a specific
40 | directory, pass it as the first argument:
41 |
42 | new static.Server('./public');
43 |
44 | You can also specify how long the client is supposed to cache the files node-static serves:
45 |
46 | new static.Server('./public', { cache: 3600 });
47 |
48 | This will set the `Cache-Control` header, telling clients to cache the file for an hour.
49 | This is the default setting.
50 |
51 | ### Serving files under a directory #
52 |
53 | To serve files under a directory, simply call the `serve` method on a `Server` instance, passing it
54 | the HTTP request and response object:
55 |
56 | var fileServer = new static.Server('./public');
57 |
58 | require('http').createServer(function (request, response) {
59 | request.addListener('end', function () {
60 | fileServer.serve(request, response);
61 | });
62 | }).listen(8080);
63 |
64 | ### Serving specific files #
65 |
66 | If you want to serve a specific file, like an error page for example, use the `serveFile` method:
67 |
68 | fileServer.serveFile('/error.html', 500, {}, request, response);
69 |
70 | This will serve the `error.html` file, from under the file root directory, with a `500` status code.
71 | For example, you could serve an error page, when the initial request wasn't found:
72 |
73 | require('http').createServer(function (request, response) {
74 | request.addListener('end', function () {
75 | fileServer.serve(request, response, function (e, res) {
76 | if (e && (e.status === 404)) { // If the file wasn't found
77 | fileServer.serveFile('/not-found.html', request, response);
78 | }
79 | });
80 | });
81 | }).listen(8080);
82 |
83 | More on intercepting errors bellow.
84 |
85 | ### Intercepting errors & Listening #
86 |
87 | An optional callback can be passed as last argument, it will be called every time a file
88 | has been served successfully, or if there was an error serving the file:
89 |
90 | var fileServer = new static.Server('./public');
91 |
92 | require('http').createServer(function (request, response) {
93 | request.addListener('end', function () {
94 | fileServer.serve(request, response, function (err, result) {
95 | if (err) { // There was an error serving the file
96 | sys.error("Error serving " + request.url + " - " + err.message);
97 |
98 | // Respond to the client
99 | response.writeHead(err.status, err.headers);
100 | response.end();
101 | }
102 | });
103 | });
104 | }).listen(8080);
105 |
106 | Note that if you pass a callback, and there is an error serving the file, node-static
107 | *will not* respond to the client. This gives you the opportunity to re-route the request,
108 | or handle it differently.
109 |
110 | For example, you may want to interpret a request as a static request, but if the file isn't found,
111 | send it to an application.
112 |
113 | If you only want to *listen* for errors, you can use *event listeners*:
114 |
115 | fileServer.serve(request, response).addListener('error', function (err) {
116 | sys.error("Error serving " + request.url + " - " + err.message);
117 | });
118 |
119 | With this method, you don't have to explicitly send the response back, in case of an error.
120 |
121 | ### Options when creating an instance of `Server` #
122 |
123 | #### `cache` #
124 |
125 | Sets the `Cache-Control` header.
126 |
127 | example: `{ cache: 7200 }`
128 |
129 | Passing a number will set the cache duration to that number of seconds.
130 | Passing `false` will disable the `Cache-Control` header.
131 |
132 | > Defaults to `3600`
133 |
134 | #### `headers` #
135 |
136 | Sets response headers.
137 |
138 | example: `{ 'X-Hello': 'World!' }`
139 |
140 | > defaults to `{}`
141 |
142 |
--------------------------------------------------------------------------------
/node_modules/node-static/benchmark/node-static-0.3.0.txt:
--------------------------------------------------------------------------------
1 | This is ApacheBench, Version 2.3 <$Revision: 655654 $>
2 | Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
3 | Licensed to The Apache Software Foundation, http://www.apache.org/
4 |
5 | Benchmarking 127.0.0.1 (be patient)
6 |
7 |
8 | Server Software: node-static/0.3.0
9 | Server Hostname: 127.0.0.1
10 | Server Port: 8080
11 |
12 | Document Path: /lib/node-static.js
13 | Document Length: 6038 bytes
14 |
15 | Concurrency Level: 20
16 | Time taken for tests: 2.323 seconds
17 | Complete requests: 10000
18 | Failed requests: 0
19 | Write errors: 0
20 | Total transferred: 63190000 bytes
21 | HTML transferred: 60380000 bytes
22 | Requests per second: 4304.67 [#/sec] (mean)
23 | Time per request: 4.646 [ms] (mean)
24 | Time per request: 0.232 [ms] (mean, across all concurrent requests)
25 | Transfer rate: 26563.66 [Kbytes/sec] received
26 |
27 | Connection Times (ms)
28 | min mean[+/-sd] median max
29 | Connect: 0 0 0.2 0 3
30 | Processing: 1 4 1.4 4 28
31 | Waiting: 1 4 1.3 4 18
32 | Total: 2 5 1.5 4 28
33 |
34 | Percentage of the requests served within a certain time (ms)
35 | 50% 4
36 | 66% 5
37 | 75% 5
38 | 80% 5
39 | 90% 5
40 | 95% 6
41 | 98% 8
42 | 99% 9
43 | 100% 28 (longest request)
44 |
--------------------------------------------------------------------------------
/node_modules/node-static/examples/file-server.js:
--------------------------------------------------------------------------------
1 | var sys = require('sys');
2 | var static = require('../lib/node-static');
3 |
4 | //
5 | // Create a node-static server to serve the current directory
6 | //
7 | var file = new(static.Server)('.', { cache: 7200, headers: {'X-Hello':'World!'} });
8 |
9 | require('http').createServer(function (request, response) {
10 | request.addListener('end', function () {
11 | //
12 | // Serve files!
13 | //
14 | file.serve(request, response, function (err, res) {
15 | if (err) { // An error as occured
16 | sys.error("> Error serving " + request.url + " - " + err.message);
17 | response.writeHead(err.status, err.headers);
18 | response.end();
19 | } else { // The file was served successfully
20 | sys.puts("> " + request.url + " - " + res.message);
21 | }
22 | });
23 | });
24 | }).listen(8080);
25 |
26 | sys.puts("> node-static is listening on http://127.0.0.1:8080");
27 |
--------------------------------------------------------------------------------
/node_modules/node-static/lib/node-static.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs'),
2 | sys = require('sys'),
3 | events = require('events'),
4 | buffer = require('buffer'),
5 | http = require('http'),
6 | url = require('url'),
7 | path = require('path');
8 |
9 | this.version = [0, 5, 9];
10 |
11 | var mime = require('./node-static/mime');
12 | var util = require('./node-static/util');
13 |
14 | var serverInfo = 'node-static/' + this.version.join('.');
15 |
16 | // In-memory file store
17 | this.store = {};
18 | this.indexStore = {};
19 |
20 | this.Server = function (root, options) {
21 | if (root && (typeof(root) === 'object')) { options = root, root = null }
22 |
23 | this.root = path.resolve(root || '.');
24 | this.options = options || {};
25 | this.cache = 3600;
26 |
27 | this.defaultHeaders = {};
28 | this.options.headers = this.options.headers || {};
29 |
30 | if ('cache' in this.options) {
31 | if (typeof(this.options.cache) === 'number') {
32 | this.cache = this.options.cache;
33 | } else if (! this.options.cache) {
34 | this.cache = false;
35 | }
36 | }
37 |
38 | if (this.cache !== false) {
39 | this.defaultHeaders['Cache-Control'] = 'max-age=' + this.cache;
40 | }
41 | this.defaultHeaders['Server'] = serverInfo;
42 |
43 | for (var k in this.defaultHeaders) {
44 | this.options.headers[k] = this.options.headers[k] ||
45 | this.defaultHeaders[k];
46 | }
47 | };
48 |
49 | this.Server.prototype.serveDir = function (pathname, req, res, finish) {
50 | var htmlIndex = path.join(pathname, 'index.html'),
51 | that = this;
52 |
53 | fs.stat(htmlIndex, function (e, stat) {
54 | if (!e) {
55 | that.respond(null, 200, {}, [htmlIndex], stat, req, res, finish);
56 | } else {
57 | if (pathname in exports.store) {
58 | streamFiles(exports.indexStore[pathname].files);
59 | } else {
60 | // Stream a directory of files as a single file.
61 | fs.readFile(path.join(pathname, 'index.json'), function (e, contents) {
62 | if (e) { return finish(404, {}) }
63 | var index = JSON.parse(contents);
64 | exports.indexStore[pathname] = index;
65 | streamFiles(index.files);
66 | });
67 | }
68 | }
69 | });
70 | function streamFiles(files) {
71 | util.mstat(pathname, files, function (e, stat) {
72 | that.respond(pathname, 200, {}, files, stat, req, res, finish);
73 | });
74 | }
75 | };
76 | this.Server.prototype.serveFile = function (pathname, status, headers, req, res) {
77 | var that = this;
78 | var promise = new(events.EventEmitter);
79 |
80 | pathname = this.resolve(pathname);
81 |
82 | fs.stat(pathname, function (e, stat) {
83 | if (e) {
84 | return promise.emit('error', e);
85 | }
86 | that.respond(null, status, headers, [pathname], stat, req, res, function (status, headers) {
87 | that.finish(status, headers, req, res, promise);
88 | });
89 | });
90 | return promise;
91 | };
92 | this.Server.prototype.finish = function (status, headers, req, res, promise, callback) {
93 | var result = {
94 | status: status,
95 | headers: headers,
96 | message: http.STATUS_CODES[status]
97 | };
98 |
99 | headers['Server'] = serverInfo;
100 |
101 | if (!status || status >= 400) {
102 | if (callback) {
103 | callback(result);
104 | } else {
105 | if (promise.listeners('error').length > 0) {
106 | promise.emit('error', result);
107 | }
108 | res.writeHead(status, headers);
109 | res.end();
110 | }
111 | } else {
112 | // Don't end the request here, if we're streaming;
113 | // it's taken care of in `prototype.stream`.
114 | if (status !== 200 || req.method !== 'GET') {
115 | res.writeHead(status, headers);
116 | res.end();
117 | }
118 | callback && callback(null, result);
119 | promise.emit('success', result);
120 | }
121 | };
122 |
123 | this.Server.prototype.servePath = function (pathname, status, headers, req, res, finish) {
124 | var that = this,
125 | promise = new(events.EventEmitter);
126 |
127 | pathname = this.resolve(pathname);
128 |
129 | // Only allow GET and HEAD requests
130 | if (req.method !== 'GET' && req.method !== 'HEAD') {
131 | finish(405, { 'Allow': 'GET, HEAD' });
132 | return promise;
133 | }
134 |
135 | // Make sure we're not trying to access a
136 | // file outside of the root.
137 | if (pathname.indexOf(that.root) === 0) {
138 | fs.stat(pathname, function (e, stat) {
139 | if (e) {
140 | finish(404, {});
141 | } else if (stat.isFile()) { // Stream a single file.
142 | that.respond(null, status, headers, [pathname], stat, req, res, finish);
143 | } else if (stat.isDirectory()) { // Stream a directory of files.
144 | that.serveDir(pathname, req, res, finish);
145 | } else {
146 | finish(400, {});
147 | }
148 | });
149 | } else {
150 | // Forbidden
151 | finish(403, {});
152 | }
153 | return promise;
154 | };
155 | this.Server.prototype.resolve = function (pathname) {
156 | return path.resolve(path.join(this.root, pathname));
157 | };
158 | this.Server.prototype.serve = function (req, res, callback) {
159 | var that = this,
160 | promise = new(events.EventEmitter);
161 |
162 | var pathname = decodeURI(url.parse(req.url).pathname);
163 |
164 | var finish = function (status, headers) {
165 | that.finish(status, headers, req, res, promise, callback);
166 | };
167 |
168 | process.nextTick(function () {
169 | that.servePath(pathname, 200, {}, req, res, finish).on('success', function (result) {
170 | promise.emit('success', result);
171 | }).on('error', function (err) {
172 | promise.emit('error');
173 | });
174 | });
175 | if (! callback) { return promise }
176 | };
177 |
178 | this.Server.prototype.respond = function (pathname, status, _headers, files, stat, req, res, finish) {
179 | var mtime = Date.parse(stat.mtime),
180 | key = pathname || files[0],
181 | headers = {};
182 |
183 | // Copy default headers
184 | for (var k in this.options.headers) { headers[k] = this.options.headers[k] }
185 |
186 | headers['Etag'] = JSON.stringify([stat.ino, stat.size, mtime].join('-'));
187 | headers['Date'] = new(Date)().toUTCString();
188 | headers['Last-Modified'] = new(Date)(stat.mtime).toUTCString();
189 |
190 | // Conditional GET
191 | // If the "If-Modified-Since" or "If-None-Match" headers
192 | // match the conditions, send a 304 Not Modified.
193 | if (req.headers['if-none-match'] === headers['Etag'] ||
194 | Date.parse(req.headers['if-modified-since']) >= mtime) {
195 | finish(304, headers);
196 | } else if (req.method === 'HEAD') {
197 | finish(200, headers);
198 | } else {
199 | headers['Content-Length'] = stat.size;
200 | headers['Content-Type'] = mime.contentTypes[path.extname(files[0]).slice(1)] ||
201 | 'application/octet-stream';
202 |
203 | for (var k in _headers) { headers[k] = _headers[k] }
204 |
205 | res.writeHead(status, headers);
206 |
207 | // If the file was cached and it's not older
208 | // than what's on disk, serve the cached version.
209 | if (this.cache && (key in exports.store) &&
210 | exports.store[key].stat.mtime >= stat.mtime) {
211 | res.end(exports.store[key].buffer);
212 | finish(status, headers);
213 | } else {
214 | this.stream(pathname, files, new(buffer.Buffer)(stat.size), res, function (e, buffer) {
215 | if (e) { return finish(500, {}) }
216 | exports.store[key] = {
217 | stat: stat,
218 | buffer: buffer,
219 | timestamp: Date.now()
220 | };
221 | finish(status, headers);
222 | });
223 | }
224 | }
225 | };
226 |
227 | this.Server.prototype.stream = function (pathname, files, buffer, res, callback) {
228 | (function streamFile(files, offset) {
229 | var file = files.shift();
230 |
231 | if (file) {
232 | file = file[0] === '/' ? file : path.join(pathname || '.', file);
233 |
234 | // Stream the file to the client
235 | fs.createReadStream(file, {
236 | flags: 'r',
237 | mode: 0666
238 | }).on('data', function (chunk) {
239 | chunk.copy(buffer, offset);
240 | offset += chunk.length;
241 | }).on('close', function () {
242 | streamFile(files, offset);
243 | }).on('error', function (err) {
244 | callback(err);
245 | console.error(err);
246 | }).pipe(res, { end: false });
247 | } else {
248 | res.end();
249 | callback(null, buffer, offset);
250 | }
251 | })(files.slice(0), 0);
252 | };
253 |
--------------------------------------------------------------------------------
/node_modules/node-static/lib/node-static/mime.js:
--------------------------------------------------------------------------------
1 | this.contentTypes = {
2 | "aiff": "audio/x-aiff",
3 | "arj": "application/x-arj-compressed",
4 | "asf": "video/x-ms-asf",
5 | "asx": "video/x-ms-asx",
6 | "au": "audio/ulaw",
7 | "avi": "video/x-msvideo",
8 | "bcpio": "application/x-bcpio",
9 | "ccad": "application/clariscad",
10 | "cod": "application/vnd.rim.cod",
11 | "com": "application/x-msdos-program",
12 | "cpio": "application/x-cpio",
13 | "cpt": "application/mac-compactpro",
14 | "csh": "application/x-csh",
15 | "css": "text/css",
16 | "deb": "application/x-debian-package",
17 | "dl": "video/dl",
18 | "doc": "application/msword",
19 | "drw": "application/drafting",
20 | "dvi": "application/x-dvi",
21 | "dwg": "application/acad",
22 | "dxf": "application/dxf",
23 | "dxr": "application/x-director",
24 | "etx": "text/x-setext",
25 | "ez": "application/andrew-inset",
26 | "fli": "video/x-fli",
27 | "flv": "video/x-flv",
28 | "gif": "image/gif",
29 | "gl": "video/gl",
30 | "gtar": "application/x-gtar",
31 | "gz": "application/x-gzip",
32 | "hdf": "application/x-hdf",
33 | "hqx": "application/mac-binhex40",
34 | "html": "text/html",
35 | "ice": "x-conference/x-cooltalk",
36 | "ico": "image/x-icon",
37 | "ief": "image/ief",
38 | "igs": "model/iges",
39 | "ips": "application/x-ipscript",
40 | "ipx": "application/x-ipix",
41 | "jad": "text/vnd.sun.j2me.app-descriptor",
42 | "jar": "application/java-archive",
43 | "jpeg": "image/jpeg",
44 | "jpg": "image/jpeg",
45 | "js": "text/javascript",
46 | "json": "application/json",
47 | "latex": "application/x-latex",
48 | "less": "text/css",
49 | "lsp": "application/x-lisp",
50 | "lzh": "application/octet-stream",
51 | "m": "text/plain",
52 | "m3u": "audio/x-mpegurl",
53 | "man": "application/x-troff-man",
54 | "manifest": "text/cache-manifest",
55 | "me": "application/x-troff-me",
56 | "midi": "audio/midi",
57 | "mif": "application/x-mif",
58 | "mime": "www/mime",
59 | "movie": "video/x-sgi-movie",
60 | "mp4": "video/mp4",
61 | "mpg": "video/mpeg",
62 | "mpga": "audio/mpeg",
63 | "ms": "application/x-troff-ms",
64 | "nc": "application/x-netcdf",
65 | "oda": "application/oda",
66 | "ogm": "application/ogg",
67 | "pbm": "image/x-portable-bitmap",
68 | "pdf": "application/pdf",
69 | "pgm": "image/x-portable-graymap",
70 | "pgn": "application/x-chess-pgn",
71 | "pgp": "application/pgp",
72 | "pm": "application/x-perl",
73 | "png": "image/png",
74 | "pnm": "image/x-portable-anymap",
75 | "ppm": "image/x-portable-pixmap",
76 | "ppz": "application/vnd.ms-powerpoint",
77 | "pre": "application/x-freelance",
78 | "prt": "application/pro_eng",
79 | "ps": "application/postscript",
80 | "qt": "video/quicktime",
81 | "ra": "audio/x-realaudio",
82 | "rar": "application/x-rar-compressed",
83 | "ras": "image/x-cmu-raster",
84 | "rgb": "image/x-rgb",
85 | "rm": "audio/x-pn-realaudio",
86 | "rpm": "audio/x-pn-realaudio-plugin",
87 | "rtf": "text/rtf",
88 | "rtx": "text/richtext",
89 | "scm": "application/x-lotusscreencam",
90 | "set": "application/set",
91 | "sgml": "text/sgml",
92 | "sh": "application/x-sh",
93 | "shar": "application/x-shar",
94 | "silo": "model/mesh",
95 | "sit": "application/x-stuffit",
96 | "skt": "application/x-koan",
97 | "smil": "application/smil",
98 | "snd": "audio/basic",
99 | "sol": "application/solids",
100 | "spl": "application/x-futuresplash",
101 | "src": "application/x-wais-source",
102 | "stl": "application/SLA",
103 | "stp": "application/STEP",
104 | "sv4cpio": "application/x-sv4cpio",
105 | "sv4crc": "application/x-sv4crc",
106 | "svg": "image/svg+xml",
107 | "swf": "application/x-shockwave-flash",
108 | "tar": "application/x-tar",
109 | "tcl": "application/x-tcl",
110 | "tex": "application/x-tex",
111 | "texinfo": "application/x-texinfo",
112 | "tgz": "application/x-tar-gz",
113 | "tiff": "image/tiff",
114 | "tr": "application/x-troff",
115 | "tsi": "audio/TSP-audio",
116 | "tsp": "application/dsptype",
117 | "tsv": "text/tab-separated-values",
118 | "txt": "text/plain",
119 | "unv": "application/i-deas",
120 | "ustar": "application/x-ustar",
121 | "vcd": "application/x-cdlink",
122 | "vda": "application/vda",
123 | "vivo": "video/vnd.vivo",
124 | "vrm": "x-world/x-vrml",
125 | "wav": "audio/x-wav",
126 | "wax": "audio/x-ms-wax",
127 | "wma": "audio/x-ms-wma",
128 | "wmv": "video/x-ms-wmv",
129 | "wmx": "video/x-ms-wmx",
130 | "wrl": "model/vrml",
131 | "wvx": "video/x-ms-wvx",
132 | "xbm": "image/x-xbitmap",
133 | "xlw": "application/vnd.ms-excel",
134 | "xml": "text/xml",
135 | "xpm": "image/x-xpixmap",
136 | "xwd": "image/x-xwindowdump",
137 | "xyz": "chemical/x-pdb",
138 | "zip": "application/zip"
139 | };
140 |
--------------------------------------------------------------------------------
/node_modules/node-static/lib/node-static/util.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs'),
2 | path = require('path');
3 |
4 | this.mstat = function (dir, files, callback) {
5 | (function mstat(files, stats) {
6 | var file = files.shift();
7 |
8 | if (file) {
9 | fs.stat(path.join(dir, file), function (e, stat) {
10 | if (e) {
11 | callback(e);
12 | } else {
13 | mstat(files, stats.concat([stat]));
14 | }
15 | });
16 | } else {
17 | callback(null, {
18 | size: stats.reduce(function (total, stat) {
19 | return total + stat.size;
20 | }, 0),
21 | mtime: stats.reduce(function (latest, stat) {
22 | return latest > stat.mtime ? latest : stat.mtime;
23 | }, 0),
24 | ino: stats.reduce(function (total, stat) {
25 | return total + stat.ino;
26 | }, 0)
27 | });
28 | }
29 | })(files.slice(0), []);
30 | };
31 |
--------------------------------------------------------------------------------
/node_modules/node-static/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "node-static",
3 | "description" : "simple, compliant file streaming module for node",
4 | "url" : "http://github.com/cloudhead/node-static",
5 | "keywords" : ["http", "static", "file", "server"],
6 | "author" : "Alexis Sellier ",
7 | "contributors" : [],
8 | "licenses" : ["MIT"],
9 | "dependencies" : [],
10 | "lib" : "lib",
11 | "main" : "./lib/node-static",
12 | "version" : "0.5.9",
13 | "directories" : { "test": "./test" },
14 | "engines" : { "node": ">= 0.4.1" }
15 | }
16 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .tmp*~
3 | *.local.*
4 | .pinf-*
--------------------------------------------------------------------------------
/node_modules/uglify-js/README.org:
--------------------------------------------------------------------------------
1 | #+TITLE: UglifyJS -- a JavaScript parser/compressor/beautifier
2 | #+KEYWORDS: javascript, js, parser, compiler, compressor, mangle, minify, minifier
3 | #+DESCRIPTION: a JavaScript parser/compressor/beautifier in JavaScript
4 | #+STYLE:
5 | #+AUTHOR: Mihai Bazon
6 | #+EMAIL: mihai.bazon@gmail.com
7 |
8 | * UglifyJS --- a JavaScript parser/compressor/beautifier
9 |
10 | This package implements a general-purpose JavaScript
11 | parser/compressor/beautifier toolkit. It is developed on [[http://nodejs.org/][NodeJS]], but it
12 | should work on any JavaScript platform supporting the CommonJS module system
13 | (and if your platform of choice doesn't support CommonJS, you can easily
14 | implement it, or discard the =exports.*= lines from UglifyJS sources).
15 |
16 | The tokenizer/parser generates an abstract syntax tree from JS code. You
17 | can then traverse the AST to learn more about the code, or do various
18 | manipulations on it. This part is implemented in [[../lib/parse-js.js][parse-js.js]] and it's a
19 | port to JavaScript of the excellent [[http://marijn.haverbeke.nl/parse-js/][parse-js]] Common Lisp library from [[http://marijn.haverbeke.nl/][Marijn
20 | Haverbeke]].
21 |
22 | ( See [[http://github.com/mishoo/cl-uglify-js][cl-uglify-js]] if you're looking for the Common Lisp version of
23 | UglifyJS. )
24 |
25 | The second part of this package, implemented in [[../lib/process.js][process.js]], inspects and
26 | manipulates the AST generated by the parser to provide the following:
27 |
28 | - ability to re-generate JavaScript code from the AST. Optionally
29 | indented---you can use this if you want to “beautify” a program that has
30 | been compressed, so that you can inspect the source. But you can also run
31 | our code generator to print out an AST without any whitespace, so you
32 | achieve compression as well.
33 |
34 | - shorten variable names (usually to single characters). Our mangler will
35 | analyze the code and generate proper variable names, depending on scope
36 | and usage, and is smart enough to deal with globals defined elsewhere, or
37 | with =eval()= calls or =with{}= statements. In short, if =eval()= or
38 | =with{}= are used in some scope, then all variables in that scope and any
39 | variables in the parent scopes will remain unmangled, and any references
40 | to such variables remain unmangled as well.
41 |
42 | - various small optimizations that may lead to faster code but certainly
43 | lead to smaller code. Where possible, we do the following:
44 |
45 | - foo["bar"] ==> foo.bar
46 |
47 | - remove block brackets ={}=
48 |
49 | - join consecutive var declarations:
50 | var a = 10; var b = 20; ==> var a=10,b=20;
51 |
52 | - resolve simple constant expressions: 1 +2 * 3 ==> 7. We only do the
53 | replacement if the result occupies less bytes; for example 1/3 would
54 | translate to 0.333333333333, so in this case we don't replace it.
55 |
56 | - consecutive statements in blocks are merged into a sequence; in many
57 | cases, this leaves blocks with a single statement, so then we can remove
58 | the block brackets.
59 |
60 | - various optimizations for IF statements:
61 |
62 | - if (foo) bar(); else baz(); ==> foo?bar():baz();
63 | - if (!foo) bar(); else baz(); ==> foo?baz():bar();
64 | - if (foo) bar(); ==> foo&&bar();
65 | - if (!foo) bar(); ==> foo||bar();
66 | - if (foo) return bar(); else return baz(); ==> return foo?bar():baz();
67 | - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()}
68 |
69 | - remove some unreachable code and warn about it (code that follows a
70 | =return=, =throw=, =break= or =continue= statement, except
71 | function/variable declarations).
72 |
73 | - act a limited version of a pre-processor (c.f. the pre-processor of
74 | C/C++) to allow you to safely replace selected global symbols with
75 | specified values. When combined with the optimisations above this can
76 | make UglifyJS operate slightly more like a compilation process, in
77 | that when certain symbols are replaced by constant values, entire code
78 | blocks may be optimised away as unreachable.
79 |
80 | ** <>
81 |
82 | The following transformations can in theory break code, although they're
83 | probably safe in most practical cases. To enable them you need to pass the
84 | =--unsafe= flag.
85 |
86 | *** Calls involving the global Array constructor
87 |
88 | The following transformations occur:
89 |
90 | #+BEGIN_SRC js
91 | new Array(1, 2, 3, 4) => [1,2,3,4]
92 | Array(a, b, c) => [a,b,c]
93 | new Array(5) => Array(5)
94 | new Array(a) => Array(a)
95 | #+END_SRC
96 |
97 | These are all safe if the Array name isn't redefined. JavaScript does allow
98 | one to globally redefine Array (and pretty much everything, in fact) but I
99 | personally don't see why would anyone do that.
100 |
101 | UglifyJS does handle the case where Array is redefined locally, or even
102 | globally but with a =function= or =var= declaration. Therefore, in the
103 | following cases UglifyJS *doesn't touch* calls or instantiations of Array:
104 |
105 | #+BEGIN_SRC js
106 | // case 1. globally declared variable
107 | var Array;
108 | new Array(1, 2, 3);
109 | Array(a, b);
110 |
111 | // or (can be declared later)
112 | new Array(1, 2, 3);
113 | var Array;
114 |
115 | // or (can be a function)
116 | new Array(1, 2, 3);
117 | function Array() { ... }
118 |
119 | // case 2. declared in a function
120 | (function(){
121 | a = new Array(1, 2, 3);
122 | b = Array(5, 6);
123 | var Array;
124 | })();
125 |
126 | // or
127 | (function(Array){
128 | return Array(5, 6, 7);
129 | })();
130 |
131 | // or
132 | (function(){
133 | return new Array(1, 2, 3, 4);
134 | function Array() { ... }
135 | })();
136 |
137 | // etc.
138 | #+END_SRC
139 |
140 | *** =obj.toString()= ==> =obj+“”=
141 |
142 | ** Install (NPM)
143 |
144 | UglifyJS is now available through NPM --- =npm install uglify-js= should do
145 | the job.
146 |
147 | ** Install latest code from GitHub
148 |
149 | #+BEGIN_SRC sh
150 | ## clone the repository
151 | mkdir -p /where/you/wanna/put/it
152 | cd /where/you/wanna/put/it
153 | git clone git://github.com/mishoo/UglifyJS.git
154 |
155 | ## make the module available to Node
156 | mkdir -p ~/.node_libraries/
157 | cd ~/.node_libraries/
158 | ln -s /where/you/wanna/put/it/UglifyJS/uglify-js.js
159 |
160 | ## and if you want the CLI script too:
161 | mkdir -p ~/bin
162 | cd ~/bin
163 | ln -s /where/you/wanna/put/it/UglifyJS/bin/uglifyjs
164 | # (then add ~/bin to your $PATH if it's not there already)
165 | #+END_SRC
166 |
167 | ** Usage
168 |
169 | There is a command-line tool that exposes the functionality of this library
170 | for your shell-scripting needs:
171 |
172 | #+BEGIN_SRC sh
173 | uglifyjs [ options... ] [ filename ]
174 | #+END_SRC
175 |
176 | =filename= should be the last argument and should name the file from which
177 | to read the JavaScript code. If you don't specify it, it will read code
178 | from STDIN.
179 |
180 | Supported options:
181 |
182 | - =-b= or =--beautify= --- output indented code; when passed, additional
183 | options control the beautifier:
184 |
185 | - =-i N= or =--indent N= --- indentation level (number of spaces)
186 |
187 | - =-q= or =--quote-keys= --- quote keys in literal objects (by default,
188 | only keys that cannot be identifier names will be quotes).
189 |
190 | - =--ascii= --- pass this argument to encode non-ASCII characters as
191 | =\uXXXX= sequences. By default UglifyJS won't bother to do it and will
192 | output Unicode characters instead. (the output is always encoded in UTF8,
193 | but if you pass this option you'll only get ASCII).
194 |
195 | - =-nm= or =--no-mangle= --- don't mangle variable names
196 |
197 | - =-ns= or =--no-squeeze= --- don't call =ast_squeeze()= (which does various
198 | optimizations that result in smaller, less readable code).
199 |
200 | - =-mt= or =--mangle-toplevel= --- mangle names in the toplevel scope too
201 | (by default we don't do this).
202 |
203 | - =--no-seqs= --- when =ast_squeeze()= is called (thus, unless you pass
204 | =--no-squeeze=) it will reduce consecutive statements in blocks into a
205 | sequence. For example, "a = 10; b = 20; foo();" will be written as
206 | "a=10,b=20,foo();". In various occasions, this allows us to discard the
207 | block brackets (since the block becomes a single statement). This is ON
208 | by default because it seems safe and saves a few hundred bytes on some
209 | libs that I tested it on, but pass =--no-seqs= to disable it.
210 |
211 | - =--no-dead-code= --- by default, UglifyJS will remove code that is
212 | obviously unreachable (code that follows a =return=, =throw=, =break= or
213 | =continue= statement and is not a function/variable declaration). Pass
214 | this option to disable this optimization.
215 |
216 | - =-nc= or =--no-copyright= --- by default, =uglifyjs= will keep the initial
217 | comment tokens in the generated code (assumed to be copyright information
218 | etc.). If you pass this it will discard it.
219 |
220 | - =-o filename= or =--output filename= --- put the result in =filename=. If
221 | this isn't given, the result goes to standard output (or see next one).
222 |
223 | - =--overwrite= --- if the code is read from a file (not from STDIN) and you
224 | pass =--overwrite= then the output will be written in the same file.
225 |
226 | - =--ast= --- pass this if you want to get the Abstract Syntax Tree instead
227 | of JavaScript as output. Useful for debugging or learning more about the
228 | internals.
229 |
230 | - =-v= or =--verbose= --- output some notes on STDERR (for now just how long
231 | each operation takes).
232 |
233 | - =-d SYMBOL[=VALUE]= or =--define SYMBOL[=VALUE]= --- will replace
234 | all instances of the specified symbol where used as an identifier
235 | (except where symbol has properly declared by a var declaration or
236 | use as function parameter or similar) with the specified value. This
237 | argument may be specified multiple times to define multiple
238 | symbols - if no value is specified the symbol will be replaced with
239 | the value =true=, or you can specify a numeric value (such as
240 | =1024=), a quoted string value (such as ="object"= or
241 | ='https://github.com'=), or the name of another symbol or keyword
242 | (such as =null= or =document=).
243 | This allows you, for example, to assign meaningful names to key
244 | constant values but discard the symbolic names in the uglified
245 | version for brevity/efficiency, or when used wth care, allows
246 | UglifyJS to operate as a form of *conditional compilation*
247 | whereby defining appropriate values may, by dint of the constant
248 | folding and dead code removal features above, remove entire
249 | superfluous code blocks (e.g. completely remove instrumentation or
250 | trace code for production use).
251 | Where string values are being defined, the handling of quotes are
252 | likely to be subject to the specifics of your command shell
253 | environment, so you may need to experiment with quoting styles
254 | depending on your platform, or you may find the option
255 | =--define-from-module= more suitable for use.
256 |
257 | - =-define-from-module SOMEMODULE= --- will load the named module (as
258 | per the NodeJS =require()= function) and iterate all the exported
259 | properties of the module defining them as symbol names to be defined
260 | (as if by the =--define= option) per the name of each property
261 | (i.e. without the module name prefix) and given the value of the
262 | property. This is a much easier way to handle and document groups of
263 | symbols to be defined rather than a large number of =--define=
264 | options.
265 |
266 | - =--unsafe= --- enable other additional optimizations that are known to be
267 | unsafe in some contrived situations, but could still be generally useful.
268 | For now only these:
269 |
270 | - foo.toString() ==> foo+""
271 | - new Array(x,...) ==> [x,...]
272 | - new Array(x) ==> Array(x)
273 |
274 | - =--max-line-len= (default 32K characters) --- add a newline after around
275 | 32K characters. I've seen both FF and Chrome croak when all the code was
276 | on a single line of around 670K. Pass --max-line-len 0 to disable this
277 | safety feature.
278 |
279 | - =--reserved-names= --- some libraries rely on certain names to be used, as
280 | pointed out in issue #92 and #81, so this option allow you to exclude such
281 | names from the mangler. For example, to keep names =require= and =$super=
282 | intact you'd specify --reserved-names "require,$super".
283 |
284 | - =--inline-script= -- when you want to include the output literally in an
285 | HTML =
364 |
365 | function f(a, b, c) {
366 | var i, boo, w = 10, q = 20;
367 | for (i = 1; i < 10; ++i) {
368 | boo = foo(a);
369 | }
370 | for (i = 0; i < 1; ++i) {
371 | boo = bar(c);
372 | }
373 | function foo() { ... }
374 | function bar() { ... }
375 | }
376 | #+END_SRC
377 |
378 | - =pro.ast_mangle(ast, options)= -- generates a new AST containing mangled
379 | (compressed) variable and function names. It supports the following
380 | options:
381 |
382 | - =toplevel= -- mangle toplevel names (by default we don't touch them).
383 | - =except= -- an array of names to exclude from compression.
384 | - =defines= -- an object with properties named after symbols to
385 | replace (see the =--define= option for the script) and the values
386 | representing the AST replacement value.
387 |
388 | - =pro.ast_squeeze(ast, options)= -- employs further optimizations designed
389 | to reduce the size of the code that =gen_code= would generate from the
390 | AST. Returns a new AST. =options= can be a hash; the supported options
391 | are:
392 |
393 | - =make_seqs= (default true) which will cause consecutive statements in a
394 | block to be merged using the "sequence" (comma) operator
395 |
396 | - =dead_code= (default true) which will remove unreachable code.
397 |
398 | - =pro.gen_code(ast, options)= -- generates JS code from the AST. By
399 | default it's minified, but using the =options= argument you can get nicely
400 | formatted output. =options= is, well, optional :-) and if you pass it it
401 | must be an object and supports the following properties (below you can see
402 | the default values):
403 |
404 | - =beautify: false= -- pass =true= if you want indented output
405 | - =indent_start: 0= (only applies when =beautify= is =true=) -- initial
406 | indentation in spaces
407 | - =indent_level: 4= (only applies when =beautify= is =true=) --
408 | indentation level, in spaces (pass an even number)
409 | - =quote_keys: false= -- if you pass =true= it will quote all keys in
410 | literal objects
411 | - =space_colon: false= (only applies when =beautify= is =true=) -- wether
412 | to put a space before the colon in object literals
413 | - =ascii_only: false= -- pass =true= if you want to encode non-ASCII
414 | characters as =\uXXXX=.
415 | - =inline_script: false= -- pass =true= to escape occurrences of
416 | =
544 | Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
545 |
546 | Redistribution and use in source and binary forms, with or without
547 | modification, are permitted provided that the following conditions
548 | are met:
549 |
550 | * Redistributions of source code must retain the above
551 | copyright notice, this list of conditions and the following
552 | disclaimer.
553 |
554 | * Redistributions in binary form must reproduce the above
555 | copyright notice, this list of conditions and the following
556 | disclaimer in the documentation and/or other materials
557 | provided with the distribution.
558 |
559 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
560 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
561 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
562 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
563 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
564 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
565 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
566 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
567 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
568 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
569 | THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
570 | SUCH DAMAGE.
571 | #+END_EXAMPLE
572 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/bin/uglifyjs:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 | // -*- js -*-
3 |
4 | global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util");
5 | var fs = require("fs");
6 | var uglify = require("uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js
7 | jsp = uglify.parser,
8 | pro = uglify.uglify;
9 |
10 | var options = {
11 | ast: false,
12 | mangle: true,
13 | mangle_toplevel: false,
14 | squeeze: true,
15 | make_seqs: true,
16 | dead_code: true,
17 | verbose: false,
18 | show_copyright: true,
19 | out_same_file: false,
20 | max_line_length: 32 * 1024,
21 | unsafe: false,
22 | reserved_names: null,
23 | defines: { },
24 | lift_vars: false,
25 | codegen_options: {
26 | ascii_only: false,
27 | beautify: false,
28 | indent_level: 4,
29 | indent_start: 0,
30 | quote_keys: false,
31 | space_colon: false,
32 | inline_script: false
33 | },
34 | make: false,
35 | output: true // stdout
36 | };
37 |
38 | var args = jsp.slice(process.argv, 2);
39 | var filename;
40 |
41 | out: while (args.length > 0) {
42 | var v = args.shift();
43 | switch (v) {
44 | case "-b":
45 | case "--beautify":
46 | options.codegen_options.beautify = true;
47 | break;
48 | case "-i":
49 | case "--indent":
50 | options.codegen_options.indent_level = args.shift();
51 | break;
52 | case "-q":
53 | case "--quote-keys":
54 | options.codegen_options.quote_keys = true;
55 | break;
56 | case "-mt":
57 | case "--mangle-toplevel":
58 | options.mangle_toplevel = true;
59 | break;
60 | case "--no-mangle":
61 | case "-nm":
62 | options.mangle = false;
63 | break;
64 | case "--no-squeeze":
65 | case "-ns":
66 | options.squeeze = false;
67 | break;
68 | case "--no-seqs":
69 | options.make_seqs = false;
70 | break;
71 | case "--no-dead-code":
72 | options.dead_code = false;
73 | break;
74 | case "--no-copyright":
75 | case "-nc":
76 | options.show_copyright = false;
77 | break;
78 | case "-o":
79 | case "--output":
80 | options.output = args.shift();
81 | break;
82 | case "--overwrite":
83 | options.out_same_file = true;
84 | break;
85 | case "-v":
86 | case "--verbose":
87 | options.verbose = true;
88 | break;
89 | case "--ast":
90 | options.ast = true;
91 | break;
92 | case "--unsafe":
93 | options.unsafe = true;
94 | break;
95 | case "--max-line-len":
96 | options.max_line_length = parseInt(args.shift(), 10);
97 | break;
98 | case "--reserved-names":
99 | options.reserved_names = args.shift().split(",");
100 | break;
101 | case "--lift-vars":
102 | options.lift_vars = true;
103 | break;
104 | case "-d":
105 | case "--define":
106 | var defarg = args.shift();
107 | try {
108 | var defsym = function(sym) {
109 | // KEYWORDS_ATOM doesn't include NaN or Infinity - should we check
110 | // for them too ?? We don't check reserved words and the like as the
111 | // define values are only substituted AFTER parsing
112 | if (jsp.KEYWORDS_ATOM.hasOwnProperty(sym)) {
113 | throw "Don't define values for inbuilt constant '"+sym+"'";
114 | }
115 | return sym;
116 | },
117 | defval = function(v) {
118 | if (v.match(/^"(.*)"$/) || v.match(/^'(.*)'$/)) {
119 | return [ "string", RegExp.$1 ];
120 | }
121 | else if (!isNaN(parseFloat(v))) {
122 | return [ "num", parseFloat(v) ];
123 | }
124 | else if (v.match(/^[a-z\$_][a-z\$_0-9]*$/i)) {
125 | return [ "name", v ];
126 | }
127 | else if (!v.match(/"/)) {
128 | return [ "string", v ];
129 | }
130 | else if (!v.match(/'/)) {
131 | return [ "string", v ];
132 | }
133 | throw "Can't understand the specified value: "+v;
134 | };
135 | if (defarg.match(/^([a-z_\$][a-z_\$0-9]*)(=(.*))?$/i)) {
136 | var sym = defsym(RegExp.$1),
137 | val = RegExp.$2 ? defval(RegExp.$2.substr(1)) : [ 'name', 'true' ];
138 | options.defines[sym] = val;
139 | }
140 | else {
141 | throw "The --define option expects SYMBOL[=value]";
142 | }
143 | } catch(ex) {
144 | sys.print("ERROR: In option --define "+defarg+"\n"+ex+"\n");
145 | process.exit(1);
146 | }
147 | break;
148 | case "--define-from-module":
149 | var defmodarg = args.shift(),
150 | defmodule = require(defmodarg),
151 | sym,
152 | val;
153 | for (sym in defmodule) {
154 | if (defmodule.hasOwnProperty(sym)) {
155 | options.defines[sym] = function(val) {
156 | if (typeof val == "string")
157 | return [ "string", val ];
158 | if (typeof val == "number")
159 | return [ "num", val ];
160 | if (val === true)
161 | return [ 'name', 'true' ];
162 | if (val === false)
163 | return [ 'name', 'false' ];
164 | if (val === null)
165 | return [ 'name', 'null' ];
166 | if (val === undefined)
167 | return [ 'name', 'undefined' ];
168 | sys.print("ERROR: In option --define-from-module "+defmodarg+"\n");
169 | sys.print("ERROR: Unknown object type for: "+sym+"="+val+"\n");
170 | process.exit(1);
171 | return null;
172 | }(defmodule[sym]);
173 | }
174 | }
175 | break;
176 | case "--ascii":
177 | options.codegen_options.ascii_only = true;
178 | break;
179 | case "--make":
180 | options.make = true;
181 | break;
182 | case "--inline-script":
183 | options.codegen_options.inline_script = true;
184 | break;
185 | default:
186 | filename = v;
187 | break out;
188 | }
189 | }
190 |
191 | if (options.verbose) {
192 | pro.set_logger(function(msg){
193 | sys.debug(msg);
194 | });
195 | }
196 |
197 | jsp.set_logger(function(msg){
198 | sys.debug(msg);
199 | });
200 |
201 | if (options.make) {
202 | options.out_same_file = false; // doesn't make sense in this case
203 | var makefile = JSON.parse(fs.readFileSync(filename || "Makefile.uglify.js").toString());
204 | output(makefile.files.map(function(file){
205 | var code = fs.readFileSync(file.name);
206 | if (file.module) {
207 | code = "!function(exports, global){global = this;\n" + code + "\n;this." + file.module + " = exports;}({})";
208 | }
209 | else if (file.hide) {
210 | code = "(function(){" + code + "}());";
211 | }
212 | return squeeze_it(code);
213 | }).join("\n"));
214 | }
215 | else if (filename) {
216 | fs.readFile(filename, "utf8", function(err, text){
217 | if (err) throw err;
218 | output(squeeze_it(text));
219 | });
220 | }
221 | else {
222 | var stdin = process.openStdin();
223 | stdin.setEncoding("utf8");
224 | var text = "";
225 | stdin.on("data", function(chunk){
226 | text += chunk;
227 | });
228 | stdin.on("end", function() {
229 | output(squeeze_it(text));
230 | });
231 | }
232 |
233 | function output(text) {
234 | var out;
235 | if (options.out_same_file && filename)
236 | options.output = filename;
237 | if (options.output === true) {
238 | out = process.stdout;
239 | } else {
240 | out = fs.createWriteStream(options.output, {
241 | flags: "w",
242 | encoding: "utf8",
243 | mode: 0644
244 | });
245 | }
246 | out.write(text + ";");
247 | if (options.output !== true) {
248 | out.end();
249 | }
250 | };
251 |
252 | // --------- main ends here.
253 |
254 | function show_copyright(comments) {
255 | var ret = "";
256 | for (var i = 0; i < comments.length; ++i) {
257 | var c = comments[i];
258 | if (c.type == "comment1") {
259 | ret += "//" + c.value + "\n";
260 | } else {
261 | ret += "/*" + c.value + "*/";
262 | }
263 | }
264 | return ret;
265 | };
266 |
267 | function squeeze_it(code) {
268 | var result = "";
269 | if (options.show_copyright) {
270 | var tok = jsp.tokenizer(code), c;
271 | c = tok();
272 | result += show_copyright(c.comments_before);
273 | }
274 | try {
275 | var ast = time_it("parse", function(){ return jsp.parse(code); });
276 | if (options.lift_vars) {
277 | ast = time_it("lift", function(){ return pro.ast_lift_variables(ast); });
278 | }
279 | if (options.mangle) ast = time_it("mangle", function(){
280 | return pro.ast_mangle(ast, {
281 | toplevel: options.mangle_toplevel,
282 | defines: options.defines,
283 | except: options.reserved_names
284 | });
285 | });
286 | if (options.squeeze) ast = time_it("squeeze", function(){
287 | ast = pro.ast_squeeze(ast, {
288 | make_seqs : options.make_seqs,
289 | dead_code : options.dead_code,
290 | keep_comps : !options.unsafe
291 | });
292 | if (options.unsafe)
293 | ast = pro.ast_squeeze_more(ast);
294 | return ast;
295 | });
296 | if (options.ast)
297 | return sys.inspect(ast, null, null);
298 | result += time_it("generate", function(){ return pro.gen_code(ast, options.codegen_options) });
299 | if (!options.codegen_options.beautify && options.max_line_length) {
300 | result = time_it("split", function(){ return pro.split_lines(result, options.max_line_length) });
301 | }
302 | return result;
303 | } catch(ex) {
304 | sys.debug(ex.stack);
305 | sys.debug(sys.inspect(ex));
306 | sys.debug(JSON.stringify(ex));
307 | process.exit(1);
308 | }
309 | };
310 |
311 | function time_it(name, cont) {
312 | if (!options.verbose)
313 | return cont();
314 | var t1 = new Date().getTime();
315 | try { return cont(); }
316 | finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); }
317 | };
318 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/docstyle.css:
--------------------------------------------------------------------------------
1 | html { font-family: "Lucida Grande","Trebuchet MS",sans-serif; font-size: 12pt; }
2 | body { max-width: 60em; }
3 | .title { text-align: center; }
4 | .todo { color: red; }
5 | .done { color: green; }
6 | .tag { background-color:lightblue; font-weight:normal }
7 | .target { }
8 | .timestamp { color: grey }
9 | .timestamp-kwd { color: CadetBlue }
10 | p.verse { margin-left: 3% }
11 | pre {
12 | border: 1pt solid #AEBDCC;
13 | background-color: #F3F5F7;
14 | padding: 5pt;
15 | font-family: monospace;
16 | font-size: 90%;
17 | overflow:auto;
18 | }
19 | pre.src {
20 | background-color: #eee; color: #112; border: 1px solid #000;
21 | }
22 | table { border-collapse: collapse; }
23 | td, th { vertical-align: top; }
24 | dt { font-weight: bold; }
25 | div.figure { padding: 0.5em; }
26 | div.figure p { text-align: center; }
27 | .linenr { font-size:smaller }
28 | .code-highlighted {background-color:#ffff00;}
29 | .org-info-js_info-navigation { border-style:none; }
30 | #org-info-js_console-label { font-size:10px; font-weight:bold;
31 | white-space:nowrap; }
32 | .org-info-js_search-highlight {background-color:#ffff00; color:#000000;
33 | font-weight:bold; }
34 |
35 | sup {
36 | vertical-align: baseline;
37 | position: relative;
38 | top: -0.5em;
39 | font-size: 80%;
40 | }
41 |
42 | sup a:link, sup a:visited {
43 | text-decoration: none;
44 | color: #c00;
45 | }
46 |
47 | sup a:before { content: "["; color: #999; }
48 | sup a:after { content: "]"; color: #999; }
49 |
50 | h1.title { border-bottom: 4px solid #000; padding-bottom: 5px; margin-bottom: 2em; }
51 |
52 | #postamble {
53 | color: #777;
54 | font-size: 90%;
55 | padding-top: 1em; padding-bottom: 1em; border-top: 1px solid #999;
56 | margin-top: 2em;
57 | padding-left: 2em;
58 | padding-right: 2em;
59 | text-align: right;
60 | }
61 |
62 | #postamble p { margin: 0; }
63 |
64 | #footnotes { border-top: 1px solid #000; }
65 |
66 | h1 { font-size: 200% }
67 | h2 { font-size: 175% }
68 | h3 { font-size: 150% }
69 | h4 { font-size: 125% }
70 |
71 | h1, h2, h3, h4 { font-family: "Bookman",Georgia,"Times New Roman",serif; font-weight: normal; }
72 |
73 | @media print {
74 | html { font-size: 11pt; }
75 | }
76 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/lib/object-ast.js:
--------------------------------------------------------------------------------
1 | var jsp = require("./parse-js"),
2 | pro = require("./process");
3 |
4 | var BY_TYPE = {};
5 |
6 | function HOP(obj, prop) {
7 | return Object.prototype.hasOwnProperty.call(obj, prop);
8 | };
9 |
10 | function AST_Node(parent) {
11 | this.parent = parent;
12 | };
13 |
14 | AST_Node.prototype.init = function(){};
15 |
16 | function DEFINE_NODE_CLASS(type, props, methods) {
17 | var base = methods && methods.BASE || AST_Node;
18 | if (!base) base = AST_Node;
19 | function D(parent, data) {
20 | base.apply(this, arguments);
21 | if (props) props.forEach(function(name, i){
22 | this["_" + name] = data[i];
23 | });
24 | this.init();
25 | };
26 | var P = D.prototype = new AST_Node;
27 | P.node_type = function(){ return type };
28 | if (props) props.forEach(function(name){
29 | var propname = "_" + name;
30 | P["set_" + name] = function(val) {
31 | this[propname] = val;
32 | return this;
33 | };
34 | P["get_" + name] = function() {
35 | return this[propname];
36 | };
37 | });
38 | if (type != null) BY_TYPE[type] = D;
39 | if (methods) for (var i in methods) if (HOP(methods, i)) {
40 | P[i] = methods[i];
41 | }
42 | return D;
43 | };
44 |
45 | var AST_String_Node = DEFINE_NODE_CLASS("string", ["value"]);
46 | var AST_Number_Node = DEFINE_NODE_CLASS("num", ["value"]);
47 | var AST_Name_Node = DEFINE_NODE_CLASS("name", ["value"]);
48 |
49 | var AST_Statlist_Node = DEFINE_NODE_CLASS(null, ["body"]);
50 | var AST_Root_Node = DEFINE_NODE_CLASS("toplevel", null, { BASE: AST_Statlist_Node });
51 | var AST_Block_Node = DEFINE_NODE_CLASS("block", null, { BASE: AST_Statlist_Node });
52 | var AST_Splice_Node = DEFINE_NODE_CLASS("splice", null, { BASE: AST_Statlist_Node });
53 |
54 | var AST_Var_Node = DEFINE_NODE_CLASS("var", ["definitions"]);
55 | var AST_Const_Node = DEFINE_NODE_CLASS("const", ["definitions"]);
56 |
57 | var AST_Try_Node = DEFINE_NODE_CLASS("try", ["body", "catch", "finally"]);
58 | var AST_Throw_Node = DEFINE_NODE_CLASS("throw", ["exception"]);
59 |
60 | var AST_New_Node = DEFINE_NODE_CLASS("new", ["constructor", "arguments"]);
61 |
62 | var AST_Switch_Node = DEFINE_NODE_CLASS("switch", ["expression", "branches"]);
63 | var AST_Switch_Branch_Node = DEFINE_NODE_CLASS(null, ["expression", "body"]);
64 |
65 | var AST_Break_Node = DEFINE_NODE_CLASS("break", ["label"]);
66 | var AST_Continue_Node = DEFINE_NODE_CLASS("continue", ["label"]);
67 | var AST_Assign_Node = DEFINE_NODE_CLASS("assign", ["operator", "lvalue", "rvalue"]);
68 | var AST_Dot_Node = DEFINE_NODE_CLASS("dot", ["expression", "name"]);
69 | var AST_Call_Node = DEFINE_NODE_CLASS("call", ["function", "arguments"]);
70 |
71 | var AST_Lambda_Node = DEFINE_NODE_CLASS(null, ["name", "arguments", "body"])
72 | var AST_Function_Node = DEFINE_NODE_CLASS("function", null, AST_Lambda_Node);
73 | var AST_Defun_Node = DEFINE_NODE_CLASS("defun", null, AST_Lambda_Node);
74 |
75 | var AST_If_Node = DEFINE_NODE_CLASS("if", ["condition", "then", "else"]);
76 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/lib/squeeze-more.js:
--------------------------------------------------------------------------------
1 | var jsp = require("./parse-js"),
2 | pro = require("./process"),
3 | slice = jsp.slice,
4 | member = jsp.member,
5 | curry = jsp.curry,
6 | MAP = pro.MAP,
7 | PRECEDENCE = jsp.PRECEDENCE,
8 | OPERATORS = jsp.OPERATORS;
9 |
10 | function ast_squeeze_more(ast) {
11 | var w = pro.ast_walker(), walk = w.walk, scope;
12 | function with_scope(s, cont) {
13 | var save = scope, ret;
14 | scope = s;
15 | ret = cont();
16 | scope = save;
17 | return ret;
18 | };
19 | function _lambda(name, args, body) {
20 | return [ this[0], name, args, with_scope(body.scope, curry(MAP, body, walk)) ];
21 | };
22 | return w.with_walkers({
23 | "toplevel": function(body) {
24 | return [ this[0], with_scope(this.scope, curry(MAP, body, walk)) ];
25 | },
26 | "function": _lambda,
27 | "defun": _lambda,
28 | "new": function(ctor, args) {
29 | if (ctor[0] == "name" && ctor[1] == "Array" && !scope.has("Array")) {
30 | if (args.length != 1) {
31 | return [ "array", args ];
32 | } else {
33 | return walk([ "call", [ "name", "Array" ], args ]);
34 | }
35 | }
36 | },
37 | "call": function(expr, args) {
38 | if (expr[0] == "dot" && expr[2] == "toString" && args.length == 0) {
39 | // foo.toString() ==> foo+""
40 | return [ "binary", "+", expr[1], [ "string", "" ]];
41 | }
42 | if (expr[0] == "name" && expr[1] == "Array" && args.length != 1 && !scope.has("Array")) {
43 | return [ "array", args ];
44 | }
45 | }
46 | }, function() {
47 | return walk(pro.ast_add_scope(ast));
48 | });
49 | };
50 |
51 | exports.ast_squeeze_more = ast_squeeze_more;
52 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "uglify-js",
3 |
4 | "description" : "JavaScript parser and compressor/beautifier toolkit",
5 |
6 | "author" : {
7 | "name" : "Mihai Bazon",
8 | "email" : "mihai.bazon@gmail.com",
9 | "url" : "http://mihai.bazon.net/blog"
10 | },
11 |
12 | "version" : "1.1.1",
13 |
14 | "main" : "./uglify-js.js",
15 |
16 | "bin" : {
17 | "uglifyjs" : "./bin/uglifyjs"
18 | },
19 |
20 | "repository": {
21 | "type": "git",
22 | "url": "git@github.com:mishoo/UglifyJS.git"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/package.json~:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "uglify-js",
3 |
4 | "description" : "JavaScript parser and compressor/beautifier toolkit",
5 |
6 | "author" : {
7 | "name" : "Mihai Bazon",
8 | "email" : "mihai.bazon@gmail.com",
9 | "url" : "http://mihai.bazon.net/blog"
10 | },
11 |
12 | "version" : "1.1.0",
13 |
14 | "main" : "./uglify-js.js",
15 |
16 | "bin" : {
17 | "uglifyjs" : "./bin/uglifyjs"
18 | },
19 |
20 | "repository": {
21 | "type": "git",
22 | "url": "git@github.com:mishoo/UglifyJS.git"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/beautify.js:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 |
3 | global.sys = require("sys");
4 | var fs = require("fs");
5 |
6 | var jsp = require("../lib/parse-js");
7 | var pro = require("../lib/process");
8 |
9 | var filename = process.argv[2];
10 | fs.readFile(filename, "utf8", function(err, text){
11 | try {
12 | var ast = time_it("parse", function(){ return jsp.parse(text); });
13 | ast = time_it("mangle", function(){ return pro.ast_mangle(ast); });
14 | ast = time_it("squeeze", function(){ return pro.ast_squeeze(ast); });
15 | var gen = time_it("generate", function(){ return pro.gen_code(ast, false); });
16 | sys.puts(gen);
17 | } catch(ex) {
18 | sys.debug(ex.stack);
19 | sys.debug(sys.inspect(ex));
20 | sys.debug(JSON.stringify(ex));
21 | }
22 | });
23 |
24 | function time_it(name, cont) {
25 | var t1 = new Date().getTime();
26 | try { return cont(); }
27 | finally { sys.debug("// " + name + ": " + ((new Date().getTime() - t1) / 1000).toFixed(3) + " sec."); }
28 | };
29 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/testparser.js:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 |
3 | var parseJS = require("../lib/parse-js");
4 | var sys = require("sys");
5 |
6 | // write debug in a very straightforward manner
7 | var debug = function(){
8 | sys.log(Array.prototype.slice.call(arguments).join(', '));
9 | };
10 |
11 | ParserTestSuite(function(i, input, desc){
12 | try {
13 | parseJS.parse(input);
14 | debug("ok " + i + ": " + desc);
15 | } catch(e){
16 | debug("FAIL " + i + " " + desc + " (" + e + ")");
17 | }
18 | });
19 |
20 | function ParserTestSuite(callback){
21 | var inps = [
22 | ["var abc;", "Regular variable statement w/o assignment"],
23 | ["var abc = 5;", "Regular variable statement with assignment"],
24 | ["/* */;", "Multiline comment"],
25 | ['/** **/;', 'Double star multiline comment'],
26 | ["var f = function(){;};", "Function expression in var assignment"],
27 | ['hi; // moo\n;', 'single line comment'],
28 | ['var varwithfunction;', 'Dont match keywords as substrings'], // difference between `var withsomevar` and `"str"` (local search and lits)
29 | ['a + b;', 'addition'],
30 | ["'a';", 'single string literal'],
31 | ["'a\\n';", 'single string literal with escaped return'],
32 | ['"a";', 'double string literal'],
33 | ['"a\\n";', 'double string literal with escaped return'],
34 | ['"var";', 'string is a keyword'],
35 | ['"variable";', 'string starts with a keyword'],
36 | ['"somevariable";', 'string contains a keyword'],
37 | ['"somevar";', 'string ends with a keyword'],
38 | ['500;', 'int literal'],
39 | ['500.;', 'float literal w/o decimals'],
40 | ['500.432;', 'float literal with decimals'],
41 | ['.432432;', 'float literal w/o int'],
42 | ['(a,b,c);', 'parens and comma'],
43 | ['[1,2,abc];', 'array literal'],
44 | ['var o = {a:1};', 'object literal unquoted key'],
45 | ['var o = {"b":2};', 'object literal quoted key'], // opening curly may not be at the start of a statement...
46 | ['var o = {c:c};', 'object literal keyname is identifier'],
47 | ['var o = {a:1,"b":2,c:c};', 'object literal combinations'],
48 | ['var x;\nvar y;', 'two lines'],
49 | ['var x;\nfunction n(){; }', 'function def'],
50 | ['var x;\nfunction n(abc){; }', 'function def with arg'],
51 | ['var x;\nfunction n(abc, def){ ;}', 'function def with args'],
52 | ['function n(){ "hello"; }', 'function def with body'],
53 | ['/a/;', 'regex literal'],
54 | ['/a/b;', 'regex literal with flag'],
55 | ['/a/ / /b/;', 'regex div regex'],
56 | ['a/b/c;', 'triple division looks like regex'],
57 | ['+function(){/regex/;};', 'regex at start of function body'],
58 | // http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=86
59 | // http://code.google.com/p/es-lab/source/browse/trunk/tests/parser/parsertests.js?r=430
60 |
61 | // first tests for the lexer, should also parse as program (when you append a semi)
62 |
63 | // comments
64 | ['//foo!@#^&$1234\nbar;', 'single line comment'],
65 | ['/* abcd!@#@$* { } && null*/;', 'single line multi line comment'],
66 | ['/*foo\nbar*/;','multi line comment'],
67 | ['/*x*x*/;','multi line comment with *'],
68 | ['/**/;','empty comment'],
69 | // identifiers
70 | ["x;",'1 identifier'],
71 | ["_x;",'2 identifier'],
72 | ["xyz;",'3 identifier'],
73 | ["$x;",'4 identifier'],
74 | ["x$;",'5 identifier'],
75 | ["_;",'6 identifier'],
76 | ["x5;",'7 identifier'],
77 | ["x_y;",'8 identifier'],
78 | ["x+5;",'9 identifier'],
79 | ["xyz123;",'10 identifier'],
80 | ["x1y1z1;",'11 identifier'],
81 | ["foo\\u00D8bar;",'12 identifier unicode escape'],
82 | //["foo�bar;",'13 identifier unicode embedded (might fail)'],
83 | // numbers
84 | ["5;", '1 number'],
85 | ["5.5;", '2 number'],
86 | ["0;", '3 number'],
87 | ["0.0;", '4 number'],
88 | ["0.001;", '5 number'],
89 | ["1.e2;", '6 number'],
90 | ["1.e-2;", '7 number'],
91 | ["1.E2;", '8 number'],
92 | ["1.E-2;", '9 number'],
93 | [".5;", '10 number'],
94 | [".5e3;", '11 number'],
95 | [".5e-3;", '12 number'],
96 | ["0.5e3;", '13 number'],
97 | ["55;", '14 number'],
98 | ["123;", '15 number'],
99 | ["55.55;", '16 number'],
100 | ["55.55e10;", '17 number'],
101 | ["123.456;", '18 number'],
102 | ["1+e;", '20 number'],
103 | ["0x01;", '22 number'],
104 | ["0XCAFE;", '23 number'],
105 | ["0x12345678;", '24 number'],
106 | ["0x1234ABCD;", '25 number'],
107 | ["0x0001;", '26 number'],
108 | // strings
109 | ["\"foo\";", '1 string'],
110 | ["\'foo\';", '2 string'],
111 | ["\"x\";", '3 string'],
112 | ["\'\';", '4 string'],
113 | ["\"foo\\tbar\";", '5 string'],
114 | ["\"!@#$%^&*()_+{}[]\";", '6 string'],
115 | ["\"/*test*/\";", '7 string'],
116 | ["\"//test\";", '8 string'],
117 | ["\"\\\\\";", '9 string'],
118 | ["\"\\u0001\";", '10 string'],
119 | ["\"\\uFEFF\";", '11 string'],
120 | ["\"\\u10002\";", '12 string'],
121 | ["\"\\x55\";", '13 string'],
122 | ["\"\\x55a\";", '14 string'],
123 | ["\"a\\\\nb\";", '15 string'],
124 | ['";"', '16 string: semi in a string'],
125 | ['"a\\\nb";', '17 string: line terminator escape'],
126 | // literals
127 | ["null;", "null"],
128 | ["true;", "true"],
129 | ["false;", "false"],
130 | // regex
131 | ["/a/;", "1 regex"],
132 | ["/abc/;", "2 regex"],
133 | ["/abc[a-z]*def/g;", "3 regex"],
134 | ["/\\b/;", "4 regex"],
135 | ["/[a-zA-Z]/;", "5 regex"],
136 |
137 | // program tests (for as far as they havent been covered above)
138 |
139 | // regexp
140 | ["/foo(.*)/g;", "another regexp"],
141 | // arrays
142 | ["[];", "1 array"],
143 | ["[ ];", "2 array"],
144 | ["[1];", "3 array"],
145 | ["[1,2];", "4 array"],
146 | ["[1,2,,];", "5 array"],
147 | ["[1,2,3];", "6 array"],
148 | ["[1,2,3,,,];", "7 array"],
149 | // objects
150 | ["{};", "1 object"],
151 | ["({x:5});", "2 object"],
152 | ["({x:5,y:6});", "3 object"],
153 | ["({x:5,});", "4 object"],
154 | ["({if:5});", "5 object"],
155 | ["({ get x() {42;} });", "6 object"],
156 | ["({ set y(a) {1;} });", "7 object"],
157 | // member expression
158 | ["o.m;", "1 member expression"],
159 | ["o['m'];", "2 member expression"],
160 | ["o['n']['m'];", "3 member expression"],
161 | ["o.n.m;", "4 member expression"],
162 | ["o.if;", "5 member expression"],
163 | // call and invoke expressions
164 | ["f();", "1 call/invoke expression"],
165 | ["f(x);", "2 call/invoke expression"],
166 | ["f(x,y);", "3 call/invoke expression"],
167 | ["o.m();", "4 call/invoke expression"],
168 | ["o['m'];", "5 call/invoke expression"],
169 | ["o.m(x);", "6 call/invoke expression"],
170 | ["o['m'](x);", "7 call/invoke expression"],
171 | ["o.m(x,y);", "8 call/invoke expression"],
172 | ["o['m'](x,y);", "9 call/invoke expression"],
173 | ["f(x)(y);", "10 call/invoke expression"],
174 | ["f().x;", "11 call/invoke expression"],
175 |
176 | // eval
177 | ["eval('x');", "1 eval"],
178 | ["(eval)('x');", "2 eval"],
179 | ["(1,eval)('x');", "3 eval"],
180 | ["eval(x,y);", "4 eval"],
181 | // new expression
182 | ["new f();", "1 new expression"],
183 | ["new o;", "2 new expression"],
184 | ["new o.m;", "3 new expression"],
185 | ["new o.m(x);", "4 new expression"],
186 | ["new o.m(x,y);", "5 new expression"],
187 | // prefix/postfix
188 | ["++x;", "1 pre/postfix"],
189 | ["x++;", "2 pre/postfix"],
190 | ["--x;", "3 pre/postfix"],
191 | ["x--;", "4 pre/postfix"],
192 | ["x ++;", "5 pre/postfix"],
193 | ["x /* comment */ ++;", "6 pre/postfix"],
194 | ["++ /* comment */ x;", "7 pre/postfix"],
195 | // unary operators
196 | ["delete x;", "1 unary operator"],
197 | ["void x;", "2 unary operator"],
198 | ["+ x;", "3 unary operator"],
199 | ["-x;", "4 unary operator"],
200 | ["~x;", "5 unary operator"],
201 | ["!x;", "6 unary operator"],
202 | // meh
203 | ["new Date++;", "new date ++"],
204 | ["+x++;", " + x ++"],
205 | // expression expressions
206 | ["1 * 2;", "1 expression expressions"],
207 | ["1 / 2;", "2 expression expressions"],
208 | ["1 % 2;", "3 expression expressions"],
209 | ["1 + 2;", "4 expression expressions"],
210 | ["1 - 2;", "5 expression expressions"],
211 | ["1 << 2;", "6 expression expressions"],
212 | ["1 >>> 2;", "7 expression expressions"],
213 | ["1 >> 2;", "8 expression expressions"],
214 | ["1 * 2 + 3;", "9 expression expressions"],
215 | ["(1+2)*3;", "10 expression expressions"],
216 | ["1*(2+3);", "11 expression expressions"],
217 | ["xy;", "13 expression expressions"],
219 | ["x<=y;", "14 expression expressions"],
220 | ["x>=y;", "15 expression expressions"],
221 | ["x instanceof y;", "16 expression expressions"],
222 | ["x in y;", "17 expression expressions"],
223 | ["x&y;", "18 expression expressions"],
224 | ["x^y;", "19 expression expressions"],
225 | ["x|y;", "20 expression expressions"],
226 | ["x+y>>= y;", "1 assignment"],
239 | ["x <<= y;", "2 assignment"],
240 | ["x = y;", "3 assignment"],
241 | ["x += y;", "4 assignment"],
242 | ["x /= y;", "5 assignment"],
243 | // comma
244 | ["x, y;", "comma"],
245 | // block
246 | ["{};", "1 block"],
247 | ["{x;};", "2 block"],
248 | ["{x;y;};", "3 block"],
249 | // vars
250 | ["var x;", "1 var"],
251 | ["var x,y;", "2 var"],
252 | ["var x=1,y=2;", "3 var"],
253 | ["var x,y=2;", "4 var"],
254 | // empty
255 | [";", "1 empty"],
256 | ["\n;", "2 empty"],
257 | // expression statement
258 | ["x;", "1 expression statement"],
259 | ["5;", "2 expression statement"],
260 | ["1+2;", "3 expression statement"],
261 | // if
262 | ["if (c) x; else y;", "1 if statement"],
263 | ["if (c) x;", "2 if statement"],
264 | ["if (c) {} else {};", "3 if statement"],
265 | ["if (c1) if (c2) s1; else s2;", "4 if statement"],
266 | // while
267 | ["do s; while (e);", "1 while statement"],
268 | ["do { s; } while (e);", "2 while statement"],
269 | ["while (e) s;", "3 while statement"],
270 | ["while (e) { s; };", "4 while statement"],
271 | // for
272 | ["for (;;) ;", "1 for statement"],
273 | ["for (;c;x++) x;", "2 for statement"],
274 | ["for (i;i> 1;
3 | var c = 8 >>> 1;
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/issue34.js:
--------------------------------------------------------------------------------
1 | var a = {};
2 | a["this"] = 1;
3 | a["that"] = 2;
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/issue4.js:
--------------------------------------------------------------------------------
1 | var a = 2e3;
2 | var b = 2e-3;
3 | var c = 2e-5;
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/issue48.js:
--------------------------------------------------------------------------------
1 | var s, i; s = ''; i = 0;
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/issue50.js:
--------------------------------------------------------------------------------
1 | function bar(a) {
2 | try {
3 | foo();
4 | } catch(e) {
5 | alert("Exception caught (foo not defined)");
6 | }
7 | alert(a); // 10 in FF, "[object Error]" in IE
8 | }
9 | bar(10);
10 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/issue53.js:
--------------------------------------------------------------------------------
1 | x = (y, z)
2 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/issue54.1.js:
--------------------------------------------------------------------------------
1 | foo.toString();
2 | a.toString(16);
3 | b.toString.call(c);
4 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/issue68.js:
--------------------------------------------------------------------------------
1 | function f() {
2 | if (a) return;
3 | g();
4 | function g(){}
5 | };
6 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/issue69.js:
--------------------------------------------------------------------------------
1 | [(a,b)]
2 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/issue9.js:
--------------------------------------------------------------------------------
1 | var a = {
2 | a: 1,
3 | b: 2, // <-- trailing comma
4 | };
5 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/mangle.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | var x = function fun(a, fun, b) {
3 | return fun;
4 | };
5 | }());
6 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/null_string.js:
--------------------------------------------------------------------------------
1 | var nullString = "\0"
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/strict-equals.js:
--------------------------------------------------------------------------------
1 | typeof a === 'string'
2 | b + "" !== c + ""
3 | d < e === f < g
4 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/var.js:
--------------------------------------------------------------------------------
1 | // var declarations after each other should be combined
2 | var a = 1;
3 | var b = 2;
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/whitespace.js:
--------------------------------------------------------------------------------
1 | function id(a) {
2 | // Form-Feed
3 | // Vertical Tab
4 | // No-Break Space
5 | // Mongolian Vowel Separator
6 | // En quad
7 | // Em quad
8 | // En space
9 | // Em space
10 | // Three-Per-Em Space
11 | // Four-Per-Em Space
12 | // Six-Per-Em Space
13 | // Figure Space
14 | // Punctuation Space
15 | // Thin Space
16 | // Hair Space
17 | // Narrow No-Break Space
18 | // Medium Mathematical Space
19 | // Ideographic Space
20 | return a;
21 | }
22 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/compress/test/with.js:
--------------------------------------------------------------------------------
1 | with({}) {
2 | };
3 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/test/unit/scripts.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs'),
2 | uglify = require('uglify-js'),
3 | jsp = uglify.parser,
4 | nodeunit = require('nodeunit'),
5 | path = require('path'),
6 | pro = uglify.uglify;
7 |
8 | var Script = process.binding('evals').Script;
9 |
10 | var scriptsPath = __dirname;
11 |
12 | function compress(code) {
13 | var ast = jsp.parse(code);
14 | ast = pro.ast_mangle(ast);
15 | ast = pro.ast_squeeze(ast, { no_warnings: true });
16 | ast = pro.ast_squeeze_more(ast);
17 | return pro.gen_code(ast);
18 | };
19 |
20 | var testDir = path.join(scriptsPath, "compress", "test");
21 | var expectedDir = path.join(scriptsPath, "compress", "expected");
22 |
23 | function getTester(script) {
24 | return function(test) {
25 | var testPath = path.join(testDir, script);
26 | var expectedPath = path.join(expectedDir, script);
27 | var content = fs.readFileSync(testPath, 'utf-8');
28 | var outputCompress = compress(content);
29 |
30 | // Check if the noncompressdata is larger or same size as the compressed data
31 | test.ok(content.length >= outputCompress.length);
32 |
33 | // Check that a recompress gives the same result
34 | var outputReCompress = compress(content);
35 | test.equal(outputCompress, outputReCompress);
36 |
37 | // Check if the compressed output is what is expected
38 | var expected = fs.readFileSync(expectedPath, 'utf-8');
39 | test.equal(outputCompress, expected.replace(/(\r?\n)+$/, ""));
40 |
41 | test.done();
42 | };
43 | };
44 |
45 | var tests = {};
46 |
47 | var scripts = fs.readdirSync(testDir);
48 | for (var i in scripts) {
49 | var script = scripts[i];
50 | if (/\.js$/.test(script)) {
51 | tests[script] = getTester(script);
52 | }
53 | }
54 |
55 | module.exports = nodeunit.testCase(tests);
56 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/tmp/hoist.js:
--------------------------------------------------------------------------------
1 | function foo(arg1, arg2, arg3, arg4, arg5, arg6) {
2 | var a = 5;
3 | {
4 | var d = 10, mak = 20, buz = 30;
5 | var q = buz * 2;
6 | }
7 | if (moo) {
8 | var a, b, c;
9 | }
10 | for (var arg1 = 0, d = 20; arg1 < 10; ++arg1)
11 | console.log(arg3);
12 | for (var i in mak) {}
13 | for (j in d) {}
14 | var d;
15 |
16 | function test() {
17 |
18 | };
19 |
20 | //test();
21 |
22 | (function moo(first, second){
23 | console.log(first);
24 | })(1);
25 |
26 | (function moo(first, second){
27 | console.log(moo());
28 | })(1);
29 | }
30 |
31 |
32 | var foo;
33 | var bar;
34 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/tmp/instrument.js:
--------------------------------------------------------------------------------
1 | // sample on how to use the parser and walker API to instrument some code
2 |
3 | var jsp = require("uglify-js").parser;
4 | var pro = require("uglify-js").uglify;
5 |
6 | function instrument(code) {
7 | var ast = jsp.parse(code, false, true); // true for the third arg specifies that we want
8 | // to have start/end tokens embedded in the
9 | // statements
10 | var w = pro.ast_walker();
11 |
12 | // we're gonna need this to push elements that we're currently looking at, to avoid
13 | // endless recursion.
14 | var analyzing = [];
15 | function do_stat() {
16 | var ret;
17 | if (this[0].start && analyzing.indexOf(this) < 0) {
18 | // without the `analyzing' hack, w.walk(this) would re-enter here leading
19 | // to infinite recursion
20 | analyzing.push(this);
21 | ret = [ "splice", // XXX: "block" is safer
22 | [ [ "stat",
23 | [ "call", [ "name", "trace" ],
24 | [ [ "string", this[0].toString() ],
25 | [ "num", this[0].start.line ],
26 | [ "num", this[0].start.col ],
27 | [ "num", this[0].end.line ],
28 | [ "num", this[0].end.col ]]]],
29 | w.walk(this) ]];
30 | analyzing.pop(this);
31 | }
32 | return ret;
33 | };
34 | var new_ast = w.with_walkers({
35 | "stat" : do_stat,
36 | "label" : do_stat,
37 | "break" : do_stat,
38 | "continue" : do_stat,
39 | "debugger" : do_stat,
40 | "var" : do_stat,
41 | "const" : do_stat,
42 | "return" : do_stat,
43 | "throw" : do_stat,
44 | "try" : do_stat,
45 | "defun" : do_stat,
46 | "if" : do_stat,
47 | "while" : do_stat,
48 | "do" : do_stat,
49 | "for" : do_stat,
50 | "for-in" : do_stat,
51 | "switch" : do_stat,
52 | "with" : do_stat
53 | }, function(){
54 | return w.walk(ast);
55 | });
56 | return pro.gen_code(new_ast, { beautify: true });
57 | }
58 |
59 |
60 |
61 |
62 | ////// test code follows.
63 |
64 | var code = instrument(test.toString());
65 | console.log(code);
66 |
67 | function test() {
68 | // simple stats
69 | a = 5;
70 | c += a + b;
71 | "foo";
72 |
73 | // var
74 | var foo = 5;
75 | const bar = 6, baz = 7;
76 |
77 | // switch block. note we can't track case lines the same way.
78 | switch ("foo") {
79 | case "foo":
80 | return 1;
81 | case "bar":
82 | return 2;
83 | }
84 |
85 | // for/for in
86 | for (var i = 0; i < 5; ++i) {
87 | console.log("Hello " + i);
88 | }
89 | for (var i in [ 1, 2, 3]) {
90 | console.log(i);
91 | }
92 |
93 | // note however that the following is broken. I guess we
94 | // should add the block brackets in this case...
95 | for (var i = 0; i < 5; ++i)
96 | console.log("foo");
97 | }
98 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/tmp/instrument2.js:
--------------------------------------------------------------------------------
1 | // sample on how to use the parser and walker API to instrument some code
2 |
3 | var jsp = require("uglify-js").parser;
4 | var pro = require("uglify-js").uglify;
5 |
6 | function instrument(code) {
7 | var ast = jsp.parse(code, false, true); // true for the third arg specifies that we want
8 | // to have start/end tokens embedded in the
9 | // statements
10 | var w = pro.ast_walker();
11 |
12 | function trace (line, comment) {
13 | var code = pro.gen_code(line, { beautify: true });
14 | var data = line[0]
15 |
16 | var args = []
17 | if (!comment) comment = ""
18 | if (typeof data === "object") {
19 | code = code.split(/\n/).shift()
20 | args = [ [ "string", data.toString() ],
21 | [ "string", code ],
22 | [ "num", data.start.line ],
23 | [ "num", data.start.col ],
24 | [ "num", data.end.line ],
25 | [ "num", data.end.col ]]
26 | } else {
27 | args = [ [ "string", data ],
28 | [ "string", code ]]
29 |
30 | }
31 | return [ "call", [ "name", "trace" ], args ];
32 | }
33 |
34 | // we're gonna need this to push elements that we're currently looking at, to avoid
35 | // endless recursion.
36 | var analyzing = [];
37 | function do_stat() {
38 | var ret;
39 | if (this[0].start && analyzing.indexOf(this) < 0) {
40 | // without the `analyzing' hack, w.walk(this) would re-enter here leading
41 | // to infinite recursion
42 | analyzing.push(this);
43 | ret = [ "splice",
44 | [ [ "stat", trace(this) ],
45 | w.walk(this) ]];
46 | analyzing.pop(this);
47 | }
48 | return ret;
49 | }
50 |
51 | function do_cond(c, t, f) {
52 | return [ this[0], w.walk(c),
53 | ["seq", trace(t), w.walk(t) ],
54 | ["seq", trace(f), w.walk(f) ]];
55 | }
56 |
57 | function do_binary(c, l, r) {
58 | if (c !== "&&" && c !== "||") {
59 | return [this[0], c, w.walk(l), w.walk(r)];
60 | }
61 | return [ this[0], c,
62 | ["seq", trace(l), w.walk(l) ],
63 | ["seq", trace(r), w.walk(r) ]];
64 | }
65 |
66 | var new_ast = w.with_walkers({
67 | "stat" : do_stat,
68 | "label" : do_stat,
69 | "break" : do_stat,
70 | "continue" : do_stat,
71 | "debugger" : do_stat,
72 | "var" : do_stat,
73 | "const" : do_stat,
74 | "return" : do_stat,
75 | "throw" : do_stat,
76 | "try" : do_stat,
77 | "defun" : do_stat,
78 | "if" : do_stat,
79 | "while" : do_stat,
80 | "do" : do_stat,
81 | "for" : do_stat,
82 | "for-in" : do_stat,
83 | "switch" : do_stat,
84 | "with" : do_stat,
85 | "conditional" : do_cond,
86 | "binary" : do_binary
87 | }, function(){
88 | return w.walk(ast);
89 | });
90 | return pro.gen_code(new_ast, { beautify: true });
91 | }
92 |
93 |
94 | ////// test code follows.
95 |
96 | var code = instrument(test.toString());
97 | console.log(code);
98 |
99 | function test() {
100 | // simple stats
101 | a = 5;
102 | c += a + b;
103 | "foo";
104 |
105 | // var
106 | var foo = 5;
107 | const bar = 6, baz = 7;
108 |
109 | // switch block. note we can't track case lines the same way.
110 | switch ("foo") {
111 | case "foo":
112 | return 1;
113 | case "bar":
114 | return 2;
115 | }
116 |
117 | // for/for in
118 | for (var i = 0; i < 5; ++i) {
119 | console.log("Hello " + i);
120 | }
121 | for (var i in [ 1, 2, 3]) {
122 | console.log(i);
123 | }
124 |
125 | for (var i = 0; i < 5; ++i)
126 | console.log("foo");
127 |
128 | for (var i = 0; i < 5; ++i) {
129 | console.log("foo");
130 | }
131 |
132 | var k = plurp() ? 1 : 0;
133 | var x = a ? doX(y) && goZoo("zoo")
134 | : b ? blerg({ x: y })
135 | : null;
136 |
137 | var x = X || Y;
138 | }
139 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/tmp/test.js:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 |
3 | global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util");
4 | var fs = require("fs");
5 | var uglify = require("uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js
6 | jsp = uglify.parser,
7 | pro = uglify.uglify;
8 |
9 | var code = fs.readFileSync("hoist.js", "utf8");
10 | var ast = jsp.parse(code);
11 |
12 | ast = pro.ast_lift_variables(ast);
13 |
14 | var w = pro.ast_walker();
15 | ast = w.with_walkers({
16 | "function": function() {
17 | var node = w.dive(this); // walk depth first
18 | console.log(pro.gen_code(node, { beautify: true }));
19 | return node;
20 | },
21 | "name": function(name) {
22 | return [ this[0], "X" ];
23 | }
24 | }, function(){
25 | return w.walk(ast);
26 | });
27 |
28 | console.log(pro.gen_code(ast, {
29 | beautify: true
30 | }));
31 |
--------------------------------------------------------------------------------
/node_modules/uglify-js/uglify-js.js:
--------------------------------------------------------------------------------
1 | //convienence function(src, [options]);
2 | function uglify(orig_code, options){
3 | options || (options = {});
4 | var jsp = uglify.parser;
5 | var pro = uglify.uglify;
6 |
7 | var ast = jsp.parse(orig_code, options.strict_semicolons); // parse code and get the initial AST
8 | ast = pro.ast_mangle(ast, options.mangle_options); // get a new AST with mangled names
9 | ast = pro.ast_squeeze(ast, options.squeeze_options); // get an AST with compression optimizations
10 | var final_code = pro.gen_code(ast, options.gen_options); // compressed code here
11 | return final_code;
12 | };
13 |
14 | uglify.parser = require("./lib/parse-js");
15 | uglify.uglify = require("./lib/process");
16 |
17 | module.exports = uglify
--------------------------------------------------------------------------------
/plugins/amd.js:
--------------------------------------------------------------------------------
1 | (function(context) {
2 | loadrunner(function(using, provide) {
3 | function makeArray(o) {
4 | return Array.prototype.slice.call(o);
5 | }
6 |
7 | var isArray = Array.isArray || function(obj) {
8 | return obj.constructor == Array;
9 | }
10 |
11 | function indexOf(arr, thing) {
12 | for (var i=0, item; item = arr[i]; i++) {
13 | if (thing == item) {
14 | return i;
15 | }
16 | }
17 |
18 | return -1;
19 | }
20 |
21 | function resolve(id, mod) {
22 | // replace the './' on the id with the dir taken from the mod id.
23 | var from = mod.id || '';
24 | var modParts = from.split('/'); modParts.pop();
25 | var idParts = id.split('/');
26 | var relative = false;
27 | while (idParts[0] == '..' && modParts.length) {
28 | modParts.pop();
29 | idParts.shift();
30 | relative = true;
31 | }
32 | if (idParts[0] == '.') {
33 | idParts.shift();
34 | relative = true;
35 | }
36 | if (relative) {
37 | idParts = modParts.concat(idParts);
38 | }
39 | return idParts.join('/');
40 | }
41 |
42 | function mapArgs(args, mod) {
43 | var mapped = [];
44 |
45 | function require(id) {
46 | return loadrunner.Module.exports[resolve(id.replace(/^.+!/, ''), mod)];
47 | }
48 |
49 | for (var i=0, len = args.length; i < len; i++) {
50 | if (args[i] == 'require') {
51 | mapped.push(require);
52 | continue;
53 | }
54 |
55 | if (args[i] == 'exports') {
56 | mod.exports = mod.exports || {};
57 | mapped.push(mod.exports);
58 | continue;
59 | }
60 |
61 | if (args[i] == 'module') {
62 | mapped.push(mod);
63 | continue;
64 | }
65 |
66 | mapped.push(require(args[i]));
67 | }
68 | return mapped;
69 | }
70 |
71 | function define() {
72 | var args = makeArray(arguments), dependencies = [], id, factory;
73 |
74 | if (typeof args[0] == 'string') {
75 | id = args.shift();
76 | }
77 |
78 | if (isArray(args[0])) {
79 | dependencies = args.shift();
80 | }
81 |
82 | factory = args.shift();
83 |
84 | var def = new loadrunner.Definition(id, function(exports) {
85 | var mods = [], thisDef = this;
86 |
87 | function executeAMD() {
88 | var args = mapArgs(makeArray(dependencies), thisDef), exported;
89 |
90 | if (typeof factory == 'function') {
91 | exported = factory.apply(thisDef, args);
92 | } else {
93 | exported = factory;
94 | }
95 |
96 | if (typeof exported == 'undefined') {
97 | exported = thisDef.exports;
98 | }
99 |
100 | exports(exported);
101 | }
102 |
103 | for (var i=0, len=dependencies.length; i < len; i++) {
104 | var d = dependencies[i];
105 | if (indexOf(['require', 'exports', 'module'], d) == -1) {
106 | mods.push(resolve(d, thisDef));
107 | }
108 | }
109 |
110 | if (mods.length > 0) {
111 | using.apply(this, mods.concat(executeAMD));
112 | } else {
113 | executeAMD();
114 | }
115 | });
116 |
117 | return def;
118 | }
119 |
120 | context.define = define;
121 | });
122 | }(this));
123 |
--------------------------------------------------------------------------------
/plugins/commonjs.js:
--------------------------------------------------------------------------------
1 | /*
2 | Loadrunner CommonJS
3 |
4 | This plugin extends loadrunner to load bare JavaScript files without requiring
5 | boilerplate code surrounding it.
6 |
7 | To require on a bare JavaScript file, foo.js:
8 | using('CommonJS!foo.js', function() { ... });
9 | This will trigger the load of foo.js if it has not already been loaded.
10 | The exports of the JavaScript will be passed to you.
11 |
12 | If a new 'using' block depends on a JS file that has already been loaded,
13 | it not load the file again, and the function block will fire immediately.
14 | This behaviour is similar to the loadrunner scripts and modules.
15 |
16 | TODO: THERE IS CURRENTLY NO HANDLING FOR LOAD ERRORS.
17 | */
18 | loadrunner(function(using, provide, loadrunner) {
19 | function CommonJS(id) {
20 | if(typeof define !== 'function') {
21 | throw new Error('CommonJS requires the amd plugin');
22 | }
23 |
24 | this.path = loadrunner.Module.prototype.resolvePath(id);
25 | this.id = id;
26 | };
27 | CommonJS.prototype = new loadrunner.Script;
28 | CommonJS.prototype.key = function() {
29 | return 'CommonJS_' + this.id;
30 | };
31 |
32 | CommonJS.prototype.arrayToString = function(array) {
33 | /**
34 | * Returns an array as a snippet of JavaScript code. Pretty much the same as
35 | * JSON.stringify(array), but without the dependency on JSON.
36 | */
37 | return '["' + array.join('","') + '"]';
38 | }
39 |
40 | CommonJS.prototype.fetch = loadrunner.Script.xhrTransport;
41 |
42 | CommonJS.prototype.loaded = function(code) {
43 | var me = this;
44 | var definition = this.generateDefinition(code);
45 | eval(definition).then(function(exports) {
46 | me.complete(exports);
47 | });
48 | };
49 |
50 | CommonJS.prototype.findDependencies = function(code) {
51 | /**
52 | * Returns a list of all of the dependencies that are require()'d in the given
53 | * code. Expects require statements to be of the form require('foo') or
54 | * require("bar"). Requiring variables -- e.g. require(module) -- is not supported.
55 | */
56 | var depNames = [];
57 | var requireRegexp = /require\(['"]([^'"]+)['"]\)/g, match;
58 |
59 | code.replace(requireRegexp, function(original, moduleName) {
60 | depNames.push(moduleName);
61 | return original;
62 | });
63 |
64 | return depNames;
65 | }
66 |
67 | CommonJS.prototype.generateDefinition = function(code) {
68 | /**
69 | * Generates an AMD definition from the given code. Assumes that the code has
70 | * no boilerplate, accesses all dependencies via require() statements, and returns
71 | * its exports by modifying the exports variable.
72 | */
73 | var deps = ['module', 'require', 'exports'].concat(this.findDependencies(code)),
74 | depsJsList = this.arrayToString(deps);
75 |
76 | var def = ('define("%id%", %deps%, function(module, require, exports) {\n%code%\n});').
77 | replace('%code%', code).
78 | replace('%id%', this.id).
79 | replace('%deps%', depsJsList);
80 |
81 | return def;
82 | }
83 |
84 | // Makes CommonJS the default module format
85 | using.matchers.add(/^(commonjs!)?[a-zA-Z0-9_\-\/]+$/, function(id) {
86 | return new CommonJS(id.replace(/^commonjs!/, ''));
87 | });
88 | });
--------------------------------------------------------------------------------
/plugins/defer.js:
--------------------------------------------------------------------------------
1 | (function(context) {
2 | loadrunner(function(using, provide) {
3 | var def;
4 |
5 | function deferred(id, body) {
6 | return new loadrunner.Definition(id, function(exports) {
7 | exports(body());
8 | });
9 | }
10 |
11 | context.deferred = deferred;
12 |
13 | using.matchers.add(/(^script!|\.js(!?)$)/, function(path) {
14 | var force = !!path.match(/!$/);
15 |
16 | path = path.replace(/^script!/,'').replace(/!$/, '');
17 |
18 |
19 | if (def = loadrunner.Definition.provided[path]) {
20 | return def;
21 | } else {
22 | var script = new loadrunner.Script(path, force);
23 |
24 | if (force) script.start();
25 | return script;
26 | }
27 | });
28 |
29 | });
30 | }(this));
--------------------------------------------------------------------------------
/plugins/json.js:
--------------------------------------------------------------------------------
1 | /*
2 | Loadrunner JSON
3 |
4 | This plugin extends loadrunner to load JSON.
5 |
6 | To depend on a JSON file, foo.json:
7 | using('json!foo.json', function(jsonObj) { ... });
8 | This will trigger the load of foo.json if it has not already been loaded.
9 | The returned JSON will be parsed and passed to the jsonObj.
10 |
11 | If a new 'using' block depends on a JSON file that has already been loaded,
12 | it not load the file again, and the function block will fire immediately.
13 | This behaviour is similar to the loadrunner scripts and modules.
14 |
15 | TODO: THERE IS CURRENTLY NO HANDLING FOR LOAD ERRORS.
16 |
17 | */
18 | loadrunner(function(using, provide, loadrunner) {
19 |
20 | function JSONRequest(id, force) {
21 | this.path = this.id = id;
22 | this.force = !!force;
23 | };
24 | JSONRequest.prototype = new loadrunner.Script;
25 | JSONRequest.prototype.key = function() {
26 | return 'json_' + this.id;
27 | };
28 | JSONRequest.prototype.fetch = loadrunner.Script.xhrTransport;
29 | JSONRequest.prototype.loaded = function(data) {
30 | // TODO we should parse the JSON here otherwise this isn't a JSON plugin
31 | // its just an XHR plugin
32 | this.complete(data);
33 | };
34 |
35 | using.matchers.add(/^json!/, function(path) {
36 | return new JSONRequest(path.substring(5));
37 | });
38 |
39 | });
--------------------------------------------------------------------------------
/src/loadrunner.js:
--------------------------------------------------------------------------------
1 | (function(context, document) {
2 | var useInteractive = context.attachEvent && !context.opera,
3 | scripts = document.getElementsByTagName('script'),
4 | scriptTag, scriptTemplate = document.createElement('script'),
5 | currentProvide, currentScript, activeScripts = {}, oldUsing = context.using,
6 | oldProvide = context.provide, oldLoadrunner = context.loadrunner;
7 |
8 | var pausedDependencies = {}, metDependencies = {}, inProgressDependencies = {};
9 |
10 | for (var i=0, s; s = scripts[i]; i++) {
11 | if (s.src.match(/loadrunner\.js(\?|#|$)/)) {
12 | scriptTag = s;
13 | break;
14 | }
15 | }
16 |
17 | var uuid = (function () {
18 | var _uuid = 0;
19 |
20 | return function () {
21 | return _uuid++;
22 | };
23 | })();
24 |
25 | function aug(target) {
26 | for (var i = 1, o; o = arguments[i]; i++) {
27 | for (var key in o) {
28 | target[key] = o[key];
29 | }
30 | }
31 | return target;
32 | }
33 | function makeArray(o) {
34 | return Array.prototype.slice.call(o);
35 | }
36 |
37 | var isArray = Array.isArray || function(obj) {
38 | return obj.constructor == Array;
39 | }
40 |
41 | function indexOf(arr, thing) {
42 | for (var i=0, item; item = arr[i]; i++) {
43 | if (thing == item) {
44 | return i;
45 | }
46 | }
47 |
48 | return -1;
49 | }
50 |
51 | function path() {
52 | var parts = makeArray(arguments), normalized = [];
53 | for (var i=0, len = parts.length; i < len; i++) {
54 | if (parts[i].length > 0) {
55 | normalized.push(parts[i].replace(/\/$/, ''));
56 | }
57 | }
58 | return normalized.join('/');
59 | }
60 |
61 | function pushObjPath(obj, path, newobj) {
62 | var names = path.split('/'), cursor = obj;
63 | while (names.length > 1) {
64 | var name = names.shift();
65 | cursor = cursor[name] = cursor[name] || {};
66 | }
67 | cursor[names[0]] = newobj;
68 | }
69 |
70 | function Dependency() {}
71 |
72 | Dependency.prototype.then = function(cb) {
73 | this.callbacks = this.callbacks || [];
74 | this.callbacks.push(cb);
75 |
76 | if (this.completed) {
77 | cb.apply(context, this.results);
78 | } else {
79 | if (this.callbacks.length == 1) {
80 | this.start();
81 | }
82 | }
83 |
84 | return this;
85 | };
86 | Dependency.prototype.key = function() {
87 | if (!this.id) {
88 | this.id = uuid();
89 | }
90 |
91 | return 'dependency_' + this.id;
92 | };
93 | Dependency.prototype.start = function() {
94 | var dep = this, met, inProgress;
95 |
96 | this.startTime = (new Date).getTime();
97 |
98 | if (met = metDependencies[this.key()]) {
99 | this.complete.apply(this, met.results);
100 | } else if (inProgress = inProgressDependencies[this.key()]) {
101 | inProgress.then(function() {
102 | dep.complete.apply(dep, arguments);
103 | });
104 | } else {
105 | if (this.shouldFetch()) {
106 | inProgressDependencies[this.key()] = this;
107 | this.fetch();
108 | } else {
109 | pausedDependencies[this.key()] = pausedDependencies[this.key()] || [];
110 | pausedDependencies[this.key()].push(this);
111 | }
112 | }
113 | };
114 | Dependency.prototype.shouldFetch = function() {
115 | return true;
116 | }
117 | Dependency.prototype.complete = function() {
118 | var paused;
119 |
120 | this.endTime = (new Date).getTime();
121 |
122 | delete inProgressDependencies[this.key()];
123 |
124 | if (!metDependencies[this.key()]) {
125 | metDependencies[this.key()] = this;
126 | }
127 |
128 | if (!this.completed) {
129 | this.results = makeArray(arguments);
130 | this.completed = true;
131 |
132 | if (this.callbacks) {
133 | for (var i=0, cb; cb = this.callbacks[i]; i++) {
134 | cb.apply(context, this.results);
135 | }
136 | }
137 |
138 | if (paused = pausedDependencies[this.key()]) {
139 | for (var i=0, p; p = paused[i]; i++) {
140 | p.complete.apply(p, arguments);
141 | }
142 |
143 | delete pausedDependencies[this.key()];
144 | }
145 | }
146 | };
147 |
148 | function Script(path, force) {
149 | if (path) {
150 | this.id = this.path = this.resolvePath(path);
151 | }
152 |
153 | this.originalPath = path;
154 |
155 | this.force = !!force;
156 | }
157 | Script.autoFetch = true;
158 |
159 | Script.xhrTransport = function() {
160 | var xhr;
161 |
162 | var me = this;
163 |
164 | if(window.XMLHttpRequest) {
165 | xhr = new window.XMLHttpRequest();
166 | } else {
167 | try {
168 | xhr = new window.ActiveXObject("Microsoft.XMLHTTP");
169 | } catch(e) {
170 | // Eep
171 | return new Error('XHR not found.');
172 | }
173 | }
174 |
175 | xhr.onreadystatechange = function() {
176 | var result;
177 |
178 | if(xhr.readyState == 4) {
179 | me.loaded(xhr.responseText);
180 | }
181 | };
182 |
183 | xhr.open('GET', this.path, true);
184 | xhr.send(null);
185 | };
186 |
187 | Script.scriptTagTransport = function() {
188 | var script = scriptTemplate.cloneNode(false), me = this;
189 |
190 | this.scriptId = 'LR' + uuid();
191 | script.id = this.scriptId;
192 | script.type = 'text/javascript';
193 | script.async = true;
194 |
195 | script.onerror = function() {
196 | throw new Error(me.path + ' not loaded');
197 | }
198 |
199 | script.onreadystatechange = script.onload = function (e) {
200 | e = context.event || e;
201 |
202 | if (e.type == 'load' || indexOf(['loaded', 'complete'], this.readyState) > -1) {
203 | this.onreadystatechange = null;
204 | me.loaded();
205 | }
206 | };
207 |
208 | script.src = this.path;
209 |
210 | currentScript = this;
211 | scripts[0].parentNode.insertBefore(script, scripts[0]);
212 | currentScript = null;
213 |
214 | activeScripts[this.scriptId] = this;
215 | }
216 |
217 | Script.prototype = new Dependency;
218 |
219 | Script.prototype.start = function() {
220 | var me = this, bundle;
221 | if (def = Definition.provided[this.originalPath]) {
222 | def.then(function() {
223 | me.complete();
224 | });
225 | } else if (bundle = findBundle(this.originalPath)) {
226 | bundle.then(function() {
227 | me.start();
228 | });
229 | } else {
230 | Dependency.prototype.start.call(this);
231 | }
232 | };
233 |
234 | Script.prototype.resolvePath = function(filePath) {
235 | filePath = filePath.replace(/^\$/, using.path.replace(/\/$/, '') + '/');
236 | return filePath;
237 | }
238 | Script.prototype.key = function() {
239 | return "script_" + this.id;
240 | };
241 | Script.prototype.shouldFetch = function() {
242 | return Script.autoFetch || this.force;
243 | };
244 | Script.prototype.fetch = Script.scriptTagTransport;
245 | Script.prototype.loaded = function() {
246 | this.complete();
247 | };
248 |
249 | function Module(id, force) {
250 | this.id = id;
251 | this.path = this.resolvePath(id);
252 | this.force = force;
253 | }
254 | Module.exports = {};
255 | Module.prototype = new Script;
256 | Module.prototype.start = function() {
257 | var me = this, def, bundle;
258 |
259 | if (def = Definition.provided[this.id]) {
260 | def.then(function(exports) {
261 | me.complete.call(me, exports);
262 | });
263 | } else if (bundle = findBundle(this.id)) {
264 | bundle.then(function() {
265 | me.start();
266 | });
267 | } else {
268 | Script.prototype.start.call(this);
269 | }
270 | };
271 | Module.prototype.key = function() {
272 | return 'module_' + this.id;
273 | };
274 | Module.prototype.resolvePath = function(id) {
275 | return path(using.path, id + '.js');
276 | };
277 | Module.prototype.loaded = function() {
278 | var p, exports, me = this;
279 | if (!useInteractive) {
280 | p = currentProvide;
281 | currentProvide = null;
282 |
283 | if (p) {
284 | p.setId(this.id);
285 | p.then(function(exports) {
286 | me.complete.call(me, exports);
287 | });
288 | } else if (!Definition.provided[this.id]) {
289 | throw new Error("Tried to load '" + this.id +"' as a module, but it didn't have a 'provide()' in it.");
290 | }
291 | }
292 | };
293 | function Bundle(id, contents) {
294 | this.id = id;
295 | this.contents = contents;
296 | this.dep = createDependency(id);
297 | this.deps = [];
298 | this.path = this.dep.path;
299 | }
300 | Bundle.prototype = new Script;
301 | Bundle.prototype.start = function() {
302 | var me = this, def, dep, key;
303 | for (var i=0, l=this.contents.length; i 0) {
431 | results = results.concat(d.results);
432 | }
433 | }
434 |
435 | me.complete.apply(me, results);
436 | }
437 |
438 | for (var i=0, d; d = this.deps[i]; i++) {
439 | d.then(depComplete);
440 | }
441 |
442 | return this;
443 | };
444 | Collection.prototype.forceFetch = forceFetch;
445 | Collection.prototype.as = function(cb) {
446 | var me = this;
447 |
448 | return this.then(function() {
449 | var flatDeps = flattenDeps(me.deps), obj = {};
450 |
451 | for (var i=0, d; d = flatDeps[i]; i++) {
452 | pushObjPath(obj, d.id, arguments[i]);
453 | }
454 |
455 | cb.apply(this, [obj].concat(makeArray(arguments)));
456 | });
457 | };
458 |
459 | function Sequence(deps) {
460 | this.deps = deps;
461 | }
462 | Sequence.prototype = new Dependency;
463 | Sequence.prototype.fetch = function() {
464 | var me = this, nextDep = 0, allResults = [];
465 |
466 | (function next() {
467 | var dep = me.deps[nextDep++];
468 | if (dep) {
469 | dep.then(function(results) {
470 | if (dep.results.length > 0) {
471 | allResults = allResults.concat(dep.results);
472 | }
473 | next();
474 | });
475 | } else {
476 | me.complete.apply(me, allResults);
477 | }
478 | }());
479 |
480 | return this;
481 | }
482 | Sequence.prototype.forceFetch = forceFetch;
483 |
484 | function Manifest() {
485 | this.entries = {};
486 | }
487 | Manifest.prototype.push = function(bundle) {
488 | var b;
489 |
490 | for (var file in bundle) {
491 | b = new Bundle(file, bundle[file]);
492 |
493 | for (var i=0, alias; alias = bundle[file][i]; i++) {
494 | this.entries[alias] = this.entries[alias] || [];
495 | this.entries[alias].push(b);
496 | }
497 | }
498 | };
499 |
500 | Manifest.prototype.get = function(key) {
501 | if (typeof this.entries[key] == 'undefined') {
502 | return null;
503 | }
504 |
505 | for (var i=0, candidate; candidate = this.entries[key][i]; i++) {
506 | if (typeof candidate.startTime != 'undefined') {
507 | return candidate;
508 | }
509 | }
510 |
511 | return this.entries[key][0];
512 | };
513 |
514 | function interactiveScript() {
515 | for (var i in scripts) {
516 | if (scripts[i].readyState == 'interactive') {
517 | return activeScripts[scripts[i].id];
518 | }
519 | }
520 | }
521 |
522 | function provide() {
523 | var args = makeArray(arguments), name, body;
524 |
525 | if (typeof args[0] == 'string') {
526 | name = args.shift();
527 | }
528 |
529 | body = args.shift();
530 |
531 | return new Definition(name, body);
532 | }
533 |
534 | function using() {
535 | var deps = makeArray(arguments), callback;
536 |
537 | if (typeof deps[deps.length-1] == 'function') {
538 | callback = deps.pop();
539 | }
540 |
541 | var combi = new Collection(mapDependencies(deps));
542 |
543 | if (callback) {
544 | combi.then(callback);
545 | }
546 |
547 | return combi;
548 | }
549 |
550 | function mapDependencies(deps) {
551 | var mapped = [];
552 |
553 | for (var i=0, dep; dep = deps[i]; i++) {
554 | if (typeof dep == 'string') {
555 | dep = createDependency(dep);
556 | }
557 |
558 | if (isArray(dep)) {
559 | dep = new Sequence(mapDependencies(dep));
560 | }
561 |
562 | mapped.push(dep);
563 | }
564 |
565 | return mapped;
566 | }
567 |
568 | function createDependency(id) {
569 | var m, dep;
570 |
571 | for (var i=0, matcher; matcher = using.matchers[i]; i++) {
572 | var regex = matcher[0], factory = matcher[1];
573 | if (m = id.match(regex)) {
574 | return factory(id);
575 | }
576 | }
577 | throw new Error(id + ' was not recognised by loader');
578 | }
579 |
580 | var loadrunner = function(f) {
581 | return f(using, provide, loadrunner);
582 | }
583 |
584 | function noConflict() {
585 | context.using = oldUsing;
586 | context.provide = oldProvide;
587 | context.loadrunner = oldLoadrunner;
588 | return loadrunner;
589 | }
590 |
591 | function debug(key) {
592 | var dep, log = {};
593 |
594 | function pushLog(dep, status) {
595 | log[status] = log[status] || {};
596 | log[status][key] = {
597 | key: key,
598 | start: dep.startTime,
599 | end: dep.endTime,
600 | duration: dep.endTime - (dep.startTime || (new Date).getTime()),
601 | status: status,
602 | origin: dep
603 | };
604 | }
605 |
606 | if (key && ((dep = metDependencies[key]) || (dep = inProgressDependencies[key]) ||
607 | (dep = pausedDependencies[key]))) {
608 | return {
609 | start: dep.startTime,
610 | end: dep.endTime,
611 | duration: dep.endTime - (dep.startTime || (new Date).getTime()),
612 | origin: dep
613 | };
614 | } else {
615 | for (var key in metDependencies) {
616 | pushLog(metDependencies[key], 'met');
617 | }
618 |
619 | for (var key in inProgressDependencies) {
620 | pushLog(inProgressDependencies[key], 'inProgress');
621 | }
622 |
623 | for (var key in pausedDependencies) {
624 | pushLog(pausedDependencies[key], 'paused');
625 | }
626 |
627 | return log;
628 | }
629 | }
630 |
631 | function reset() {
632 | pausedDependencies = {};
633 | metDependencies = {};
634 | inProgressDependencies = {};
635 | using.bundles = new Manifest;
636 | Module.exports = {};
637 | Definition.provided = {};
638 | }
639 |
640 | loadrunner.Script = Script;
641 | loadrunner.Module = Module;
642 | loadrunner.Collection = Collection;
643 | loadrunner.Sequence = Sequence;
644 | loadrunner.Definition = Definition;
645 | loadrunner.Dependency = Dependency;
646 | loadrunner.noConflict = noConflict;
647 | loadrunner.debug = debug;
648 | loadrunner.reset = reset;
649 |
650 | context.loadrunner = loadrunner;
651 | context.using = using;
652 | context.provide = provide;
653 |
654 | using.path = '';
655 |
656 | using.bundles = new Manifest();
657 |
658 | // Append your bundle manifests to this array
659 | // using.bundles.push( { "bundlename" : ["modulename", "modulename2", "script"], "bundle2": ["script2"] });
660 | // Loadbuilder can generate your bundles and manifests
661 | function findBundle(id) {
662 | return using.bundles.get(id) || undefined;
663 | }
664 |
665 | using.matchers = [];
666 | using.matchers.add = function(regex, factory) {
667 | this.unshift([regex, factory]);
668 | }
669 |
670 | using.matchers.add(/^(lr!)?[a-zA-Z0-9_\/.-]+$/, function(id) {
671 | var mod = new Module(id.replace(/^lr!/, ''));
672 | return mod;
673 | });
674 |
675 | using.matchers.add(/(^script!|\.js$)/, function(path) {
676 | var script = new Script(path.replace(/^script!/, ''));
677 | return script;
678 | });
679 |
680 | if (scriptTag) {
681 | using.path = scriptTag.getAttribute('data-path') || scriptTag.src.split(/loadrunner\.js/)[0] || '';
682 |
683 | if (main = scriptTag.getAttribute('data-main')) {
684 | using.apply(context, main.split(/\s*,\s*/)).then(function() {});
685 | }
686 | }
687 | }(this, document));
688 |
--------------------------------------------------------------------------------
/test/amd_test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | AMD plugin test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
101 |
102 |
--------------------------------------------------------------------------------
/test/commonjs_test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | requirejs plugin test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
60 |
61 |
--------------------------------------------------------------------------------
/test/data.json:
--------------------------------------------------------------------------------
1 | { "success": true }
--------------------------------------------------------------------------------
/test/deferred_test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | deferred plugin test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
75 |
76 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Loadrunner and plugin tests
6 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/test/javascripts/a.js:
--------------------------------------------------------------------------------
1 | loadedA = true;
--------------------------------------------------------------------------------
/test/javascripts/b.js:
--------------------------------------------------------------------------------
1 | bLoadCount++;
--------------------------------------------------------------------------------
/test/javascripts/c.js:
--------------------------------------------------------------------------------
1 | loadedC = true;
--------------------------------------------------------------------------------
/test/javascripts/compiled.js:
--------------------------------------------------------------------------------
1 | provide("moda",{test:"success"});using.loaded.push("moda");provide("modc",function(a){using("moda",function(b){a({test:function(){return b.test+" from mod a"}})})});using.loaded.push("modc");provide("modcompiled",function(a){using("modc",function(b){a({test:function(){return b.test()+" via modcompiled"}})})});using.loaded.push("modcompiled");provide("modcompiled",function(a){using("modc",function(b){a({test:function(){return b.test()+" via modcompiled"}})})});using.loaded.push("modules/modcompiled.js");
--------------------------------------------------------------------------------
/test/javascripts/d.js:
--------------------------------------------------------------------------------
1 | loadedD = true;
--------------------------------------------------------------------------------
/test/javascripts/deferred_bundle.js:
--------------------------------------------------------------------------------
1 | deferred('bundled_thing.js', function() {
2 | window.bundleLoadedThing = true;
3 | });
4 |
5 | deferred('bundled_another.js', function() {
6 | window.bundleLoadedAnother = true;
7 | });
8 |
9 | deferred('$bundled_with_modpath.js', function() {
10 | window.bundleLoadedModpath = true;
11 | });
--------------------------------------------------------------------------------
/test/javascripts/deferred_scripts.js:
--------------------------------------------------------------------------------
1 | deferred('thing.js', function() {
2 | window.loadedThing = true;
3 | });
4 |
5 | deferred('another.js', function() {
6 | window.loadedAnother = true;
7 | })
--------------------------------------------------------------------------------
/test/javascripts/e.js:
--------------------------------------------------------------------------------
1 | loadedE = true;
--------------------------------------------------------------------------------
/test/javascripts/main.js:
--------------------------------------------------------------------------------
1 | mainLoaded = true;
--------------------------------------------------------------------------------
/test/javascripts/modcompiled.js:
--------------------------------------------------------------------------------
1 | provide('modcompiled', function(exports) {
2 | using('modc', function(modc) {
3 | exports({
4 | test: function() {
5 | return modc.test() + ' via modcompiled';
6 | }
7 | });
8 | });
9 | });
--------------------------------------------------------------------------------
/test/javascripts/s1.js:
--------------------------------------------------------------------------------
1 | window.testSeq.push(1);
--------------------------------------------------------------------------------
/test/javascripts/s2.js:
--------------------------------------------------------------------------------
1 | window.testSeq.push(2);
--------------------------------------------------------------------------------
/test/javascripts/s3.js:
--------------------------------------------------------------------------------
1 | window.testSeq.push(3);
--------------------------------------------------------------------------------
/test/json_test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | json plugin test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
33 |
34 |
--------------------------------------------------------------------------------
/test/modules/amd/dotdotslash.js:
--------------------------------------------------------------------------------
1 | define(['../sub/submodb'], function(modb) {
2 | return {
3 | modb: modb.test()
4 | };
5 | });
--------------------------------------------------------------------------------
/test/modules/amd/moda.js:
--------------------------------------------------------------------------------
1 | define(['moda'], function(moda) {
2 | return {
3 | moda: moda.test
4 | };
5 | });
--------------------------------------------------------------------------------
/test/modules/amd/modb.js:
--------------------------------------------------------------------------------
1 | define(function() {
2 | return {
3 | test: function() {
4 | return 'AMD success';
5 | }
6 | };
7 | });
--------------------------------------------------------------------------------
/test/modules/amd/modlit.js:
--------------------------------------------------------------------------------
1 | define({
2 | test: 'success'
3 | });
--------------------------------------------------------------------------------
/test/modules/amd/modnodep.js:
--------------------------------------------------------------------------------
1 | define(function() {
2 | return {
3 | test: 'success'
4 | };
5 | });
--------------------------------------------------------------------------------
/test/modules/amd/modrel.js:
--------------------------------------------------------------------------------
1 | define(['./modb'], function(modb) {
2 | return {
3 | modb: modb.test()
4 | };
5 | });
--------------------------------------------------------------------------------
/test/modules/app.js:
--------------------------------------------------------------------------------
1 | provide('app', function(exports) {
2 | using('modd', function(d) {
3 | console.log(d.test());
4 | });
5 |
6 | exports();
7 | })
--------------------------------------------------------------------------------
/test/modules/ded-a.js:
--------------------------------------------------------------------------------
1 | provide('ded-a', function (exports) {
2 | using('ded-b1', 'ded-b2',
3 | function (b1, b2) {
4 | exports(b1 == b2);
5 | });
6 |
7 | });
8 |
--------------------------------------------------------------------------------
/test/modules/ded-b1.js:
--------------------------------------------------------------------------------
1 | provide('ded-b1', function (exports) {
2 | using('javascripts/a.js', function () {
3 | exports(loadedA);
4 | });
5 | });
--------------------------------------------------------------------------------
/test/modules/ded-b2.js:
--------------------------------------------------------------------------------
1 | provide('ded-b2', function (exports) {
2 | using('ded-b1', function (b1) {
3 | exports(b1);
4 | });
5 | });
--------------------------------------------------------------------------------
/test/modules/deep.js:
--------------------------------------------------------------------------------
1 | provide(function(exports) {
2 | var limit = 2000;
3 | var dep = 'moda';
4 | for (var i=0;i
2 |
3 |
4 |
5 | loadrunner test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
437 |
438 |
473 |
474 |
--------------------------------------------------------------------------------
/vendor/qunit/qunit.css:
--------------------------------------------------------------------------------
1 | /** Font Family and Sizes */
2 |
3 | #qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
4 | font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
5 | }
6 |
7 | #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
8 | #qunit-tests { font-size: smaller; }
9 |
10 |
11 | /** Resets */
12 |
13 | #qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
14 | margin: 0;
15 | padding: 0;
16 | }
17 |
18 |
19 | /** Header */
20 |
21 | #qunit-header {
22 | padding: 0.5em 0 0.5em 1em;
23 |
24 | color: #8699a4;
25 | background-color: #0d3349;
26 |
27 | font-size: 1.5em;
28 | line-height: 1em;
29 | font-weight: normal;
30 |
31 | border-radius: 15px 15px 0 0;
32 | -moz-border-radius: 15px 15px 0 0;
33 | -webkit-border-top-right-radius: 15px;
34 | -webkit-border-top-left-radius: 15px;
35 | }
36 |
37 | #qunit-header a {
38 | text-decoration: none;
39 | color: #c2ccd1;
40 | }
41 |
42 | #qunit-header a:hover,
43 | #qunit-header a:focus {
44 | color: #fff;
45 | }
46 |
47 | #qunit-banner {
48 | height: 5px;
49 | }
50 |
51 | #qunit-testrunner-toolbar {
52 | padding: 0.5em 0 0.5em 2em;
53 | color: #5E740B;
54 | background-color: #eee;
55 | }
56 |
57 | #qunit-userAgent {
58 | padding: 0.5em 0 0.5em 2.5em;
59 | background-color: #2b81af;
60 | color: #fff;
61 | text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
62 | }
63 |
64 |
65 | /** Tests: Pass/Fail */
66 |
67 | #qunit-tests {
68 | list-style-position: inside;
69 | }
70 |
71 | #qunit-tests li {
72 | padding: 0.4em 0.5em 0.4em 2.5em;
73 | border-bottom: 1px solid #fff;
74 | list-style-position: inside;
75 | }
76 |
77 | #qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
78 | display: none;
79 | }
80 |
81 | #qunit-tests li strong {
82 | cursor: pointer;
83 | }
84 |
85 | #qunit-tests li a {
86 | padding: 0.5em;
87 | color: #c2ccd1;
88 | text-decoration: none;
89 | }
90 | #qunit-tests li a:hover,
91 | #qunit-tests li a:focus {
92 | color: #000;
93 | }
94 |
95 | #qunit-tests ol {
96 | margin-top: 0.5em;
97 | padding: 0.5em;
98 |
99 | background-color: #fff;
100 |
101 | border-radius: 15px;
102 | -moz-border-radius: 15px;
103 | -webkit-border-radius: 15px;
104 |
105 | box-shadow: inset 0px 2px 13px #999;
106 | -moz-box-shadow: inset 0px 2px 13px #999;
107 | -webkit-box-shadow: inset 0px 2px 13px #999;
108 | }
109 |
110 | #qunit-tests table {
111 | border-collapse: collapse;
112 | margin-top: .2em;
113 | }
114 |
115 | #qunit-tests th {
116 | text-align: right;
117 | vertical-align: top;
118 | padding: 0 .5em 0 0;
119 | }
120 |
121 | #qunit-tests td {
122 | vertical-align: top;
123 | }
124 |
125 | #qunit-tests pre {
126 | margin: 0;
127 | white-space: pre-wrap;
128 | word-wrap: break-word;
129 | }
130 |
131 | #qunit-tests del {
132 | background-color: #e0f2be;
133 | color: #374e0c;
134 | text-decoration: none;
135 | }
136 |
137 | #qunit-tests ins {
138 | background-color: #ffcaca;
139 | color: #500;
140 | text-decoration: none;
141 | }
142 |
143 | /*** Test Counts */
144 |
145 | #qunit-tests b.counts { color: black; }
146 | #qunit-tests b.passed { color: #5E740B; }
147 | #qunit-tests b.failed { color: #710909; }
148 |
149 | #qunit-tests li li {
150 | margin: 0.5em;
151 | padding: 0.4em 0.5em 0.4em 0.5em;
152 | background-color: #fff;
153 | border-bottom: none;
154 | list-style-position: inside;
155 | }
156 |
157 | /*** Passing Styles */
158 |
159 | #qunit-tests li li.pass {
160 | color: #5E740B;
161 | background-color: #fff;
162 | border-left: 26px solid #C6E746;
163 | }
164 |
165 | #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
166 | #qunit-tests .pass .test-name { color: #366097; }
167 |
168 | #qunit-tests .pass .test-actual,
169 | #qunit-tests .pass .test-expected { color: #999999; }
170 |
171 | #qunit-banner.qunit-pass { background-color: #C6E746; }
172 |
173 | /*** Failing Styles */
174 |
175 | #qunit-tests li li.fail {
176 | color: #710909;
177 | background-color: #fff;
178 | border-left: 26px solid #EE5757;
179 | }
180 |
181 | #qunit-tests > li:last-child {
182 | border-radius: 0 0 15px 15px;
183 | -moz-border-radius: 0 0 15px 15px;
184 | -webkit-border-bottom-right-radius: 15px;
185 | -webkit-border-bottom-left-radius: 15px;
186 | }
187 |
188 | #qunit-tests .fail { color: #000000; background-color: #EE5757; }
189 | #qunit-tests .fail .test-name,
190 | #qunit-tests .fail .module-name { color: #000000; }
191 |
192 | #qunit-tests .fail .test-actual { color: #EE5757; }
193 | #qunit-tests .fail .test-expected { color: green; }
194 |
195 | #qunit-banner.qunit-fail { background-color: #EE5757; }
196 |
197 |
198 | /** Result */
199 |
200 | #qunit-testresult {
201 | padding: 0.5em 0.5em 0.5em 2.5em;
202 |
203 | color: #2b81af;
204 | background-color: #D2E0E6;
205 |
206 | border-bottom: 1px solid white;
207 | }
208 |
209 | /** Fixture */
210 |
211 | #qunit-fixture {
212 | position: absolute;
213 | top: -10000px;
214 | left: -10000px;
215 | }
216 |
--------------------------------------------------------------------------------