├── .gitignore
├── demo
├── lib
│ ├── regular.js
│ ├── main.js
│ ├── view.coffee
│ ├── csmain.coffee
│ ├── controller.coffee
│ ├── util.coffee
│ ├── domReady.js
│ └── require.js
├── build.sh
├── index.html
└── build.js
├── bower.json
├── demoserver.js
├── package.json
├── LICENSE
├── README.md
└── cs.js
/.gitignore:
--------------------------------------------------------------------------------
1 | demo-build
2 | node_modules
3 | bower_components
4 |
--------------------------------------------------------------------------------
/demo/lib/regular.js:
--------------------------------------------------------------------------------
1 | //Just a regular JavaScript module.
2 | define({
3 | name: 'regular'
4 | });
5 |
--------------------------------------------------------------------------------
/demo/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | rm -rf ../demo-build
4 | node ../node_modules/requirejs/bin/r.js -o build.js
5 |
--------------------------------------------------------------------------------
/demo/lib/main.js:
--------------------------------------------------------------------------------
1 | require({
2 | paths: {
3 | cs: '../../cs',
4 | 'coffee-script': '../../coffee-script'
5 | }
6 | }, ['cs!csmain']);
7 |
--------------------------------------------------------------------------------
/demo/lib/view.coffee:
--------------------------------------------------------------------------------
1 | define ['cs!util'], (util) ->
2 | render: (body) ->
3 | body.appendChild util.toDom('This is a rendered view')
4 |
--------------------------------------------------------------------------------
/demo/lib/csmain.coffee:
--------------------------------------------------------------------------------
1 | define [
2 | 'cs!controller'
3 | 'cs!view'
4 | 'regular'
5 | ], (controller, view, regular) ->
6 | controller.attach view
7 | console.log 'regular name is: ' + regular.name
8 |
--------------------------------------------------------------------------------
/demo/lib/controller.coffee:
--------------------------------------------------------------------------------
1 | define ['domReady'], (domReady) ->
2 | attach: (view) ->
3 | # Just a simple demonstration of some modules cooperating.
4 | domReady ->
5 | view.render document.getElementsByTagName('body')[0]
6 |
--------------------------------------------------------------------------------
/demo/lib/util.coffee:
--------------------------------------------------------------------------------
1 | define
2 | toDom: (text) ->
3 | # This is a contrived example, this approach is not realistic,
4 | # just used as a demonstration.
5 | node = document.createElement('div')
6 | node.innerHTML = text
7 | return node.firstChild
8 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | CoffeeScript Loader Plugin Demo
5 |
6 |
7 |
8 | CoffeeScript Loader Plugin Demo
9 |
10 |
11 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "require-cs",
3 | "description": "An AMD loader plugin for CoffeeScript",
4 | "version": "0.5.0",
5 | "main": "cs.js",
6 | "dependencies": {
7 | "coffeescript": "^1.7.1"
8 | },
9 | "ignore": [
10 | "demo",
11 | "tools",
12 | ".*",
13 | "coffee-script.js",
14 | "demoserver.js",
15 | "package.json"
16 | ]
17 | }
18 |
--------------------------------------------------------------------------------
/demoserver.js:
--------------------------------------------------------------------------------
1 | var http = require('http');
2 | var send = require('send');
3 | var url = require('url');
4 |
5 | var app = http.createServer(function(req, res){
6 | send(req, url.parse(req.url).pathname, { root: __dirname })
7 | .pipe(res);
8 | });
9 | app.listen(8337, '127.0.0.1');
10 | console.log('Listening on http://127.0.0.1:8337/');
11 | console.log('Load http://127.0.0.1:8337/demo/ for the demo.');
12 | console.log('If you ran demo/build.sh, load http://127.0.0.1:8337/demo-build/ to run the built code');
13 |
14 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cs",
3 | "description": "An AMD loader plugin for CoffeeScript",
4 | "categories": [
5 | "Loader plugins",
6 | "Parsers & Compilers"
7 | ],
8 | "version": "0.5.0",
9 | "dependencies": {
10 | "coffee-script": ">=1.2.0"
11 | },
12 | "main": "cs.js",
13 | "volo": {
14 | "url": "https://raw.github.com/jrburke/require-cs/{version}/cs.js",
15 | "dependencies": {
16 | "coffee-script": "jashkenas/coffee-script"
17 | }
18 | },
19 | "devDependencies": {
20 | "requirejs": "^2.1.4",
21 | "send": "^0.16.2"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/demo/build.js:
--------------------------------------------------------------------------------
1 | ({
2 | appDir: '.',
3 | baseUrl: 'lib',
4 |
5 | //Uncomment to turn off uglify minification.
6 | //optimize: 'none',
7 | dir: '../demo-build',
8 |
9 | //Stub out the cs module after a build since
10 | //it will not be needed.
11 | stubModules: ['cs'],
12 |
13 | paths: {
14 | 'cs' :'../../cs',
15 | 'coffee-script': '../../bower_components/coffeescript/extras/coffee-script'
16 | },
17 |
18 | modules: [
19 | {
20 | name: 'main',
21 | //The optimization will load CoffeeScript to convert
22 | //the CoffeeScript files to plain JS. Use the exclude
23 | //directive so that the coffee-script module is not included
24 | //in the built file.
25 | exclude: ['coffee-script']
26 | }
27 | ]
28 | })
29 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright jQuery Foundation and other contributors, https://jquery.org/
2 |
3 | This software consists of voluntary contributions made by many
4 | individuals. For exact contribution history, see the revision history
5 | available at https://github.com/requirejs/require-cs
6 |
7 | The following license applies to all parts of this software except as
8 | documented below:
9 |
10 | ====
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining
13 | a copy of this software and associated documentation files (the
14 | "Software"), to deal in the Software without restriction, including
15 | without limitation the rights to use, copy, modify, merge, publish,
16 | distribute, sublicense, and/or sell copies of the Software, and to
17 | permit persons to whom the Software is furnished to do so, subject to
18 | the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be
21 | included in all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 |
31 | ====
32 |
33 | Copyright and related rights for sample code are waived via CC0. Sample
34 | code is defined as all source code displayed within the prose of the
35 | documentation and in the demo directories.
36 |
37 | CC0: http://creativecommons.org/publicdomain/zero/1.0/
38 |
39 | ====
40 |
41 | Files located in the node_modules directory, and certain utilities used
42 | to build or test the software in the test and dist directories, are
43 | externally maintained libraries used by this software which have their own
44 | licenses; we recommend you read them, as their terms may differ from the
45 | terms above.
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # require-cs
2 |
3 | A [CoffeeScript](http://jashkenas.github.com/coffee-script/) loader plugin
4 | that may work with module loaders like [RequireJS](http://requirejs.org),
5 | [curl](https://github.com/unscriptable/curl) and
6 | [backdraft](http://bdframework.org/bdLoad/docs/bdLoad-tutorial/bdLoad-tutorial.html).
7 |
8 | It is known to work with RequireJS 1.0+.
9 |
10 | This loader plugin makes it easy to write your JS functionality in CoffeeScript,
11 | and easily use it in the browser, Node or Rhino. Plus, if you use the RequireJS
12 | optimizer, your CoffeeScript files can be translated to JavaScript, and inlined
13 | into optimized layers for fast performance.
14 |
15 | In development, it uses XMLHttpRequest to fetch the .coffee files, so you can only
16 | fetch files that are on the same domain as the HTML page, and most browsers place
17 | restrictions on using XMLHttpRequest from local file URLs, so use a web server to
18 | serve your .coffee files.
19 |
20 | ## Install
21 |
22 | ### Volo
23 |
24 | To install with [Volo](http://volojs.org):
25 |
26 | ```
27 | volo add require-cs
28 | ```
29 |
30 | This will install `cs.js` and `coffee-script.js` into the baseUrl folder, and no further configuration is necessary.
31 |
32 | ### Bower
33 |
34 | To install with [Bower](http://bower.io/):
35 |
36 | ```
37 | bower install require-cs
38 | ```
39 |
40 | Since bower installs `require-cs` and `coffee-script` into separate folders, add the following RequireJS [package configuration](http://requirejs.org/docs/api.html#packages):
41 |
42 | ```javascript
43 | {
44 | baseUrl: '..path_to_packages..'
45 | packages: [
46 | {
47 | name: 'cs',
48 | location: 'require-cs',
49 | main: 'cs'
50 | },
51 | {
52 | name: 'coffee-script',
53 | location: 'coffeescript',
54 | main: 'extras/coffee-script'
55 | }
56 | ]
57 | }
58 | ```
59 |
60 | ### Manual Download
61 |
62 | 1) Download CoffeeScript for the browser that registers as an AMD module. You
63 | can do that by using a "raw" GitHub URL. It takes the form of:
64 |
65 | https://raw.github.com/jashkenas/coffee-script/[BRANCH-OR-VERSION]/extras/coffee-script.js
66 |
67 | Example links:
68 |
69 | * [master](https://raw.github.com/jashkenas/coffee-script/master/extras/coffee-script.js)
70 | * [1.8.0](https://raw.github.com/jashkenas/coffee-script/1.8.0/extras/coffee-script.js)
71 |
72 | Place this in the directory that is your
73 | [baseUrl](http://requirejs.org/docs/api.html#config-baseUrl) for your project,
74 | or set up a [paths config](http://requirejs.org/docs/api.html#config-paths)
75 | for it for the module ID `coffee-script`. The cs.js file specifies `coffee-script`
76 | as a dependency.
77 |
78 | 2) Download the [latest version of cs.js](https://raw.github.com/jrburke/require-cs/latest/cs.js).
79 |
80 | ## Usage
81 |
82 | Reference CoffeeScript files via the cs! plugin name. For example, to load
83 | the `app.coffee` file that is in your baseUrl directory:
84 |
85 | require(['cs!app'], function (app) {
86 |
87 | });
88 |
89 | Or, if creating a module that depends on `util.coffee`:
90 |
91 | define(['cs!util'], function (util) {
92 | util.doSomething();
93 | });
94 |
95 | If you are using define() in a module written with CoffeeScript:
96 |
97 | define ['cs!util'], (util) ->
98 | util.doSomething
99 |
100 | [Literate CoffeeScript](http://coffeescript.org/#literate) was introduced in CoffeeScript 1.5.0.
101 | To utilize this feature with this plugin you will need to have downloaded >= 1.5.0
102 | of CoffeeScript and qualify the file (with extension) of the literate module you wish to use.
103 |
104 | A dependency on the literate module `app.litcoffee`:
105 |
106 | require ['cs!app.litcoffee'], (litapp) ->
107 | litapp.foo()
108 | # ...
109 |
110 | Or a dependency on the literate module `util.coffee.md`:
111 |
112 | define ['cs!util.coffee.md'], (litutil) ->
113 | litutil.doSomething()
114 | # ...
115 |
116 | Note: This plugin supports a mixture of literate and regular CoffeeScript files in the
117 | same project.
118 |
119 | **VERY IMPORTANT**: Only define anonymous modules using CoffeeScript. Otherwise,
120 | the optimization work will not happen correctly — the name of the module is changed
121 | to allow inlining of the translated JS content.
122 |
123 | ## Complete web project
124 |
125 | The **demo** directory shows a complete web example. See the demo/index.html file
126 | as the entry point into the demo. It is not a fancy demo, just shows basic use.
127 |
128 | If you have node installed and need to run a web server to try out the demo,
129 | in this directory run `npm install send`, then start up the demo web server
130 | by running:
131 |
132 | node demoserver.js
133 |
134 | # Optimizing
135 |
136 | See **demo/build.sh** for an example build script that drives the optimizer with
137 | the **demo/build.js** build config.
138 |
139 | The build will generate a **demo-build** directory with the optimized files. Where
140 | the unoptimized demo directory will load 7 files, the optimized one only loads 2,
141 | and the CoffeeScript files have been converted to JavaScript. Since all the CoffeeScript
142 | modules have been converted to JS after the build, the CoffeeScript module and
143 | the source cs.js module are not included/needed in the built file.
144 |
145 | If you want to do dynamic loading of CoffeeScript files after a build, then
146 | comment out `stubModules: ['cs']` and `exclude: ['coffee-script']` from the build
147 | file so that they will be included in the build.
148 |
149 | ## License
150 |
151 | MIT
152 |
153 | ## Code of Conduct
154 |
155 | [jQuery Foundation Code of Conduct](https://jquery.org/conduct/).
156 |
--------------------------------------------------------------------------------
/demo/lib/domReady.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license RequireJS domReady 0.1.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
3 | * Available via the MIT or new BSD license.
4 | * see: http://github.com/jrburke/requirejs for details
5 | */
6 | /*jslint strict: false, plusplus: false */
7 | /*global require: false, define: false, requirejs: false,
8 | window: false, clearInterval: false, document: false,
9 | self: false, setInterval: false */
10 |
11 |
12 | define(function () {
13 | var isBrowser = typeof window !== "undefined" && window.document,
14 | isPageLoaded = !isBrowser,
15 | doc = isBrowser ? document : null,
16 | readyCalls = [],
17 | readyLoaderCalls = [],
18 | //Bind to a specific implementation, but if not there, try a
19 | //a generic one under the "require" name.
20 | req = requirejs || require || {},
21 | oldResourcesReady = req.resourcesReady,
22 | scrollIntervalId;
23 |
24 | function runCallbacks(callbacks) {
25 | for (var i = 0, callback; (callback = callbacks[i]); i++) {
26 | callback(doc);
27 | }
28 | }
29 |
30 | function callReady() {
31 | var callbacks = readyCalls,
32 | loaderCallbacks = readyLoaderCalls;
33 |
34 | if (isPageLoaded) {
35 | //Call the DOM ready callbacks
36 | if (callbacks.length) {
37 | readyCalls = [];
38 | runCallbacks(callbacks);
39 | }
40 |
41 | //Now handle DOM ready + loader ready callbacks.
42 | if (req.resourcesDone && loaderCallbacks.length) {
43 | readyLoaderCalls = [];
44 | runCallbacks(loaderCallbacks);
45 | }
46 | }
47 | }
48 |
49 | /**
50 | * Add a method to require to get callbacks if there are loader resources still
51 | * being loaded. If so, then hold off calling "withResources" callbacks.
52 | *
53 | * @param {Boolean} isReady: pass true if all resources have been loaded.
54 | */
55 | if ('resourcesReady' in req) {
56 | req.resourcesReady = function (isReady) {
57 | //Call the old function if it is around.
58 | if (oldResourcesReady) {
59 | oldResourcesReady(isReady);
60 | }
61 |
62 | if (isReady) {
63 | callReady();
64 | }
65 | };
66 | }
67 |
68 | /**
69 | * Sets the page as loaded.
70 | */
71 | function pageLoaded() {
72 | if (!isPageLoaded) {
73 | isPageLoaded = true;
74 | if (scrollIntervalId) {
75 | clearInterval(scrollIntervalId);
76 | }
77 |
78 | callReady();
79 | }
80 | }
81 |
82 | if (isBrowser) {
83 | if (document.addEventListener) {
84 | //Standards. Hooray! Assumption here that if standards based,
85 | //it knows about DOMContentLoaded.
86 | document.addEventListener("DOMContentLoaded", pageLoaded, false);
87 | window.addEventListener("load", pageLoaded, false);
88 | } else if (window.attachEvent) {
89 | window.attachEvent("onload", pageLoaded);
90 |
91 | //DOMContentLoaded approximation, as found by Diego Perini:
92 | //http://javascript.nwbox.com/IEContentLoaded/
93 | if (self === self.top) {
94 | scrollIntervalId = setInterval(function () {
95 | try {
96 | //From this ticket:
97 | //http://bugs.dojotoolkit.org/ticket/11106,
98 | //In IE HTML Application (HTA), such as in a selenium test,
99 | //javascript in the iframe can't see anything outside
100 | //of it, so self===self.top is true, but the iframe is
101 | //not the top window and doScroll will be available
102 | //before document.body is set. Test document.body
103 | //before trying the doScroll trick.
104 | if (document.body) {
105 | document.documentElement.doScroll("left");
106 | pageLoaded();
107 | }
108 | } catch (e) {}
109 | }, 30);
110 | }
111 | }
112 |
113 | //Check if document already complete, and if so, just trigger page load
114 | //listeners.
115 | if (document.readyState === "complete") {
116 | pageLoaded();
117 | }
118 | }
119 |
120 | /** START OF PUBLIC API **/
121 |
122 | /**
123 | * Registers a callback for DOM ready. If DOM is already ready, the
124 | * callback is called immediately.
125 | * @param {Function} callback
126 | */
127 | function domReady(callback) {
128 | if (isPageLoaded) {
129 | callback(doc);
130 | } else {
131 | readyCalls.push(callback);
132 | }
133 | return domReady;
134 | }
135 |
136 | /**
137 | * Callback that waits for DOM ready as well as any outstanding
138 | * loader resources. Useful when there are implicit dependencies.
139 | * This method should be avoided, and always use explicit
140 | * dependency resolution, with just regular DOM ready callbacks.
141 | * The callback passed to this method will be called immediately
142 | * if the DOM and loader are already ready.
143 | * @param {Function} callback
144 | */
145 | domReady.withResources = function (callback) {
146 | if (isPageLoaded && req.resourcesDone) {
147 | callback(doc);
148 | } else {
149 | readyLoaderCalls.push(callback);
150 | }
151 | return domReady;
152 | };
153 |
154 | domReady.version = '0.1.0';
155 |
156 | /**
157 | * Loader Plugin API method
158 | */
159 | domReady.load = function (name, req, onLoad, config) {
160 | if (config.isBuild) {
161 | onLoad(null);
162 | } else {
163 | domReady(onLoad);
164 | }
165 | };
166 |
167 | /** END OF PUBLIC API **/
168 |
169 | return domReady;
170 | });
171 |
--------------------------------------------------------------------------------
/cs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license cs 0.5.0 Copyright jQuery Foundation and other contributors.
3 | * Released under MIT license, http://github.com/requirejs/requirejs/LICENSE
4 | */
5 |
6 | /*global define, window, XMLHttpRequest, importScripts, Packages, java,
7 | ActiveXObject, process, require */
8 | /**
9 | *
10 | * Base64 encode / decode
11 | * http://www.webtoolkit.info/
12 | *
13 | **/
14 |
15 | var Base64 = {
16 |
17 | // private property
18 | _keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
19 |
20 | // public method for encoding
21 | encode : function (input) {
22 | var output = "";
23 | var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
24 | var i = 0;
25 |
26 | input = Base64._utf8_encode(input);
27 |
28 | while (i < input.length) {
29 |
30 | chr1 = input.charCodeAt(i++);
31 | chr2 = input.charCodeAt(i++);
32 | chr3 = input.charCodeAt(i++);
33 |
34 | enc1 = chr1 >> 2;
35 | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
36 | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
37 | enc4 = chr3 & 63;
38 |
39 | if (isNaN(chr2)) {
40 | enc3 = enc4 = 64;
41 | } else if (isNaN(chr3)) {
42 | enc4 = 64;
43 | }
44 |
45 | output = output +
46 | this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
47 | this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
48 |
49 | }
50 |
51 | return output;
52 | },
53 |
54 | // public method for decoding
55 | decode : function (input) {
56 | var output = "";
57 | var chr1, chr2, chr3;
58 | var enc1, enc2, enc3, enc4;
59 | var i = 0;
60 |
61 | input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
62 |
63 | while (i < input.length) {
64 |
65 | enc1 = this._keyStr.indexOf(input.charAt(i++));
66 | enc2 = this._keyStr.indexOf(input.charAt(i++));
67 | enc3 = this._keyStr.indexOf(input.charAt(i++));
68 | enc4 = this._keyStr.indexOf(input.charAt(i++));
69 |
70 | chr1 = (enc1 << 2) | (enc2 >> 4);
71 | chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
72 | chr3 = ((enc3 & 3) << 6) | enc4;
73 |
74 | output = output + String.fromCharCode(chr1);
75 |
76 | if (enc3 != 64) {
77 | output = output + String.fromCharCode(chr2);
78 | }
79 | if (enc4 != 64) {
80 | output = output + String.fromCharCode(chr3);
81 | }
82 |
83 | }
84 |
85 | output = Base64._utf8_decode(output);
86 |
87 | return output;
88 |
89 | },
90 |
91 | // private method for UTF-8 encoding
92 | _utf8_encode : function (string) {
93 | string = string.replace(/\r\n/g,"\n");
94 | var utftext = "";
95 |
96 | for (var n = 0; n < string.length; n++) {
97 |
98 | var c = string.charCodeAt(n);
99 |
100 | if (c < 128) {
101 | utftext += String.fromCharCode(c);
102 | }
103 | else if((c > 127) && (c < 2048)) {
104 | utftext += String.fromCharCode((c >> 6) | 192);
105 | utftext += String.fromCharCode((c & 63) | 128);
106 | }
107 | else {
108 | utftext += String.fromCharCode((c >> 12) | 224);
109 | utftext += String.fromCharCode(((c >> 6) & 63) | 128);
110 | utftext += String.fromCharCode((c & 63) | 128);
111 | }
112 |
113 | }
114 |
115 | return utftext;
116 | },
117 |
118 | // private method for UTF-8 decoding
119 | _utf8_decode : function (utftext) {
120 | var string = "";
121 | var i = 0;
122 | var c = c1 = c2 = 0;
123 |
124 | while ( i < utftext.length ) {
125 |
126 | c = utftext.charCodeAt(i);
127 |
128 | if (c < 128) {
129 | string += String.fromCharCode(c);
130 | i++;
131 | }
132 | else if((c > 191) && (c < 224)) {
133 | c2 = utftext.charCodeAt(i+1);
134 | string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
135 | i += 2;
136 | }
137 | else {
138 | c2 = utftext.charCodeAt(i+1);
139 | c3 = utftext.charCodeAt(i+2);
140 | string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
141 | i += 3;
142 | }
143 |
144 | }
145 |
146 | return string;
147 | }
148 |
149 | }
150 |
151 | define(['coffee-script'], function (CoffeeScript) {
152 | 'use strict';
153 | var fs, getXhr,
154 | progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
155 | fetchText = function () {
156 | throw new Error('Environment unsupported.');
157 | },
158 | buildMap = {};
159 |
160 | if (typeof process !== "undefined" &&
161 | process.versions &&
162 | !!process.versions.node) {
163 | //Using special require.nodeRequire, something added by r.js.
164 | fs = require.nodeRequire('fs');
165 | fetchText = function (path, callback) {
166 | callback(fs.readFileSync(path, 'utf8'));
167 | };
168 | } else if ((typeof window !== "undefined" && window.navigator && window.document) || typeof importScripts !== "undefined") {
169 | // Browser action
170 | getXhr = function () {
171 | //Would love to dump the ActiveX crap in here. Need IE 6 to die first.
172 | var xhr, i, progId;
173 | if (typeof XMLHttpRequest !== "undefined") {
174 | return new XMLHttpRequest();
175 | } else {
176 | for (i = 0; i < 3; i += 1) {
177 | progId = progIds[i];
178 | try {
179 | xhr = new ActiveXObject(progId);
180 | } catch (e) {}
181 |
182 | if (xhr) {
183 | progIds = [progId]; // so faster next time
184 | break;
185 | }
186 | }
187 | }
188 |
189 | if (!xhr) {
190 | throw new Error("getXhr(): XMLHttpRequest not available");
191 | }
192 |
193 | return xhr;
194 | };
195 |
196 | fetchText = function (url, callback) {
197 | var xhr = getXhr();
198 | xhr.open('GET', url, true);
199 | xhr.onreadystatechange = function (evt) {
200 | //Do not explicitly handle errors, those should be
201 | //visible via console output in the browser.
202 | if (xhr.readyState === 4) {
203 | callback(xhr.responseText);
204 | }
205 | };
206 | xhr.send(null);
207 | };
208 | // end browser.js adapters
209 | } else if (typeof Packages !== 'undefined') {
210 | //Why Java, why is this so awkward?
211 | fetchText = function (path, callback) {
212 | var stringBuffer, line,
213 | encoding = "utf-8",
214 | file = new java.io.File(path),
215 | lineSeparator = java.lang.System.getProperty("line.separator"),
216 | input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
217 | content = '';
218 | try {
219 | stringBuffer = new java.lang.StringBuffer();
220 | line = input.readLine();
221 |
222 | // Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
223 | // http://www.unicode.org/faq/utf_bom.html
224 |
225 | // Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
226 | // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
227 | if (line && line.length() && line.charAt(0) === 0xfeff) {
228 | // Eat the BOM, since we've already found the encoding on this file,
229 | // and we plan to concatenating this buffer with others; the BOM should
230 | // only appear at the top of a file.
231 | line = line.substring(1);
232 | }
233 |
234 | stringBuffer.append(line);
235 |
236 | while ((line = input.readLine()) !== null) {
237 | stringBuffer.append(lineSeparator);
238 | stringBuffer.append(line);
239 | }
240 | //Make sure we return a JavaScript string and not a Java string.
241 | content = String(stringBuffer.toString()); //String
242 | } finally {
243 | input.close();
244 | }
245 | callback(content);
246 | };
247 | }
248 |
249 | return {
250 | fetchText: fetchText,
251 |
252 | get: function () {
253 | return CoffeeScript;
254 | },
255 |
256 | write: function (pluginName, name, write) {
257 | if (buildMap.hasOwnProperty(name)) {
258 | var text = buildMap[name];
259 | write.asModule(pluginName + "!" + name, text);
260 | }
261 | },
262 |
263 | version: '0.4.3',
264 |
265 | load: function (name, parentRequire, load, config) {
266 | // preserve existing logic with new literate coffeescript extensions (*.litcoffee or *.coffee.md).
267 | // if name passes check, use it, as-is. otherwise, behave as before, appending .coffee to the
268 | // requirejs binding.
269 | var fullName = CoffeeScript.helpers.isCoffee(name) ? name : name + '.coffee';
270 | var path = parentRequire.toUrl(fullName);
271 | fetchText(path, function (text) {
272 | // preserve existing logic. integrate new 'literate' compile flag with any requirejs configs.
273 | var opts = config.CoffeeScript || {};
274 | opts.literate = CoffeeScript.helpers.isLiterate(fullName);
275 | opts.sourceMap = true;
276 | opts.header = true;
277 | opts.inline = true;
278 | opts.sourceFiles = [name + opts.literate ? '' : '.coffee'];
279 | opts.generatedFile = name + opts.literate ? '' : '.coffee';
280 |
281 | var compiled;
282 | //Do CoffeeScript transform.
283 | try {
284 | compiled = CoffeeScript.compile(text, opts);
285 | } catch (err) {
286 | var msg = err.message;
287 | var loc = err.location;
288 | err.message = path;
289 |
290 | if(loc.first_line === loc.last_line) {
291 | err.message += ', line ' + (loc.first_line + 1);
292 | }
293 | else {
294 | err.message += ', lines ' + (loc.first_line + 1);
295 | if(isNaN(loc.last_line)) {
296 | err.message += '+';
297 | }
298 | else {
299 | err.message += '-' + (loc.last_line + 1);
300 | }
301 | }
302 |
303 | err.message += ': ' + msg;
304 | throw err;
305 | }
306 | text = compiled.js;
307 |
308 | //IE with conditional comments on cannot handle the
309 | //sourceURL trick, so skip it if enabled.
310 | /*@if (@_jscript) @else @*/
311 | if (!config.isBuild) {
312 | text += '\n//# sourceMappingURL=data:application/json;base64,' + Base64.encode(compiled.v3SourceMap || '') + '\n//# sourceURL=' + path;
313 | }
314 | /*@end@*/
315 |
316 | //Hold on to the transformed text if a build.
317 | if (config.isBuild) {
318 | buildMap[name] = text;
319 | }
320 |
321 | load.fromText(name, text);
322 | });
323 | }
324 | };
325 | });
326 |
--------------------------------------------------------------------------------
/demo/lib/require.js:
--------------------------------------------------------------------------------
1 | /** vim: et:ts=4:sw=4:sts=4
2 | * @license RequireJS 2.1.4 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
3 | * Available via the MIT or new BSD license.
4 | * see: http://github.com/jrburke/requirejs for details
5 | */
6 | //Not using strict: uneven strict support in browsers, #392, and causes
7 | //problems with requirejs.exec()/transpiler plugins that may not be strict.
8 | /*jslint regexp: true, nomen: true, sloppy: true */
9 | /*global window, navigator, document, importScripts, setTimeout, opera */
10 |
11 | var requirejs, require, define;
12 | (function (global) {
13 | var req, s, head, baseElement, dataMain, src,
14 | interactiveScript, currentlyAddingScript, mainScript, subPath,
15 | version = '2.1.4',
16 | commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
17 | cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
18 | jsSuffixRegExp = /\.js$/,
19 | currDirRegExp = /^\.\//,
20 | op = Object.prototype,
21 | ostring = op.toString,
22 | hasOwn = op.hasOwnProperty,
23 | ap = Array.prototype,
24 | apsp = ap.splice,
25 | isBrowser = !!(typeof window !== 'undefined' && navigator && document),
26 | isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
27 | //PS3 indicates loaded and complete, but need to wait for complete
28 | //specifically. Sequence is 'loading', 'loaded', execution,
29 | // then 'complete'. The UA check is unfortunate, but not sure how
30 | //to feature test w/o causing perf issues.
31 | readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
32 | /^complete$/ : /^(complete|loaded)$/,
33 | defContextName = '_',
34 | //Oh the tragedy, detecting opera. See the usage of isOpera for reason.
35 | isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',
36 | contexts = {},
37 | cfg = {},
38 | globalDefQueue = [],
39 | useInteractive = false;
40 |
41 | function isFunction(it) {
42 | return ostring.call(it) === '[object Function]';
43 | }
44 |
45 | function isArray(it) {
46 | return ostring.call(it) === '[object Array]';
47 | }
48 |
49 | /**
50 | * Helper function for iterating over an array. If the func returns
51 | * a true value, it will break out of the loop.
52 | */
53 | function each(ary, func) {
54 | if (ary) {
55 | var i;
56 | for (i = 0; i < ary.length; i += 1) {
57 | if (ary[i] && func(ary[i], i, ary)) {
58 | break;
59 | }
60 | }
61 | }
62 | }
63 |
64 | /**
65 | * Helper function for iterating over an array backwards. If the func
66 | * returns a true value, it will break out of the loop.
67 | */
68 | function eachReverse(ary, func) {
69 | if (ary) {
70 | var i;
71 | for (i = ary.length - 1; i > -1; i -= 1) {
72 | if (ary[i] && func(ary[i], i, ary)) {
73 | break;
74 | }
75 | }
76 | }
77 | }
78 |
79 | function hasProp(obj, prop) {
80 | return hasOwn.call(obj, prop);
81 | }
82 |
83 | function getOwn(obj, prop) {
84 | return hasProp(obj, prop) && obj[prop];
85 | }
86 |
87 | /**
88 | * Cycles over properties in an object and calls a function for each
89 | * property value. If the function returns a truthy value, then the
90 | * iteration is stopped.
91 | */
92 | function eachProp(obj, func) {
93 | var prop;
94 | for (prop in obj) {
95 | if (hasProp(obj, prop)) {
96 | if (func(obj[prop], prop)) {
97 | break;
98 | }
99 | }
100 | }
101 | }
102 |
103 | /**
104 | * Simple function to mix in properties from source into target,
105 | * but only if target does not already have a property of the same name.
106 | */
107 | function mixin(target, source, force, deepStringMixin) {
108 | if (source) {
109 | eachProp(source, function (value, prop) {
110 | if (force || !hasProp(target, prop)) {
111 | if (deepStringMixin && typeof value !== 'string') {
112 | if (!target[prop]) {
113 | target[prop] = {};
114 | }
115 | mixin(target[prop], value, force, deepStringMixin);
116 | } else {
117 | target[prop] = value;
118 | }
119 | }
120 | });
121 | }
122 | return target;
123 | }
124 |
125 | //Similar to Function.prototype.bind, but the 'this' object is specified
126 | //first, since it is easier to read/figure out what 'this' will be.
127 | function bind(obj, fn) {
128 | return function () {
129 | return fn.apply(obj, arguments);
130 | };
131 | }
132 |
133 | function scripts() {
134 | return document.getElementsByTagName('script');
135 | }
136 |
137 | //Allow getting a global that expressed in
138 | //dot notation, like 'a.b.c'.
139 | function getGlobal(value) {
140 | if (!value) {
141 | return value;
142 | }
143 | var g = global;
144 | each(value.split('.'), function (part) {
145 | g = g[part];
146 | });
147 | return g;
148 | }
149 |
150 | /**
151 | * Constructs an error with a pointer to an URL with more information.
152 | * @param {String} id the error ID that maps to an ID on a web page.
153 | * @param {String} message human readable error.
154 | * @param {Error} [err] the original error, if there is one.
155 | *
156 | * @returns {Error}
157 | */
158 | function makeError(id, msg, err, requireModules) {
159 | var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
160 | e.requireType = id;
161 | e.requireModules = requireModules;
162 | if (err) {
163 | e.originalError = err;
164 | }
165 | return e;
166 | }
167 |
168 | if (typeof define !== 'undefined') {
169 | //If a define is already in play via another AMD loader,
170 | //do not overwrite.
171 | return;
172 | }
173 |
174 | if (typeof requirejs !== 'undefined') {
175 | if (isFunction(requirejs)) {
176 | //Do not overwrite and existing requirejs instance.
177 | return;
178 | }
179 | cfg = requirejs;
180 | requirejs = undefined;
181 | }
182 |
183 | //Allow for a require config object
184 | if (typeof require !== 'undefined' && !isFunction(require)) {
185 | //assume it is a config object.
186 | cfg = require;
187 | require = undefined;
188 | }
189 |
190 | function newContext(contextName) {
191 | var inCheckLoaded, Module, context, handlers,
192 | checkLoadedTimeoutId,
193 | config = {
194 | waitSeconds: 7,
195 | baseUrl: './',
196 | paths: {},
197 | pkgs: {},
198 | shim: {},
199 | map: {},
200 | config: {}
201 | },
202 | registry = {},
203 | undefEvents = {},
204 | defQueue = [],
205 | defined = {},
206 | urlFetched = {},
207 | requireCounter = 1,
208 | unnormalizedCounter = 1;
209 |
210 | /**
211 | * Trims the . and .. from an array of path segments.
212 | * It will keep a leading path segment if a .. will become
213 | * the first path segment, to help with module name lookups,
214 | * which act like paths, but can be remapped. But the end result,
215 | * all paths that use this function should look normalized.
216 | * NOTE: this method MODIFIES the input array.
217 | * @param {Array} ary the array of path segments.
218 | */
219 | function trimDots(ary) {
220 | var i, part;
221 | for (i = 0; ary[i]; i += 1) {
222 | part = ary[i];
223 | if (part === '.') {
224 | ary.splice(i, 1);
225 | i -= 1;
226 | } else if (part === '..') {
227 | if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
228 | //End of the line. Keep at least one non-dot
229 | //path segment at the front so it can be mapped
230 | //correctly to disk. Otherwise, there is likely
231 | //no path mapping for a path starting with '..'.
232 | //This can still fail, but catches the most reasonable
233 | //uses of ..
234 | break;
235 | } else if (i > 0) {
236 | ary.splice(i - 1, 2);
237 | i -= 2;
238 | }
239 | }
240 | }
241 | }
242 |
243 | /**
244 | * Given a relative module name, like ./something, normalize it to
245 | * a real name that can be mapped to a path.
246 | * @param {String} name the relative name
247 | * @param {String} baseName a real name that the name arg is relative
248 | * to.
249 | * @param {Boolean} applyMap apply the map config to the value. Should
250 | * only be done if this normalization is for a dependency ID.
251 | * @returns {String} normalized name
252 | */
253 | function normalize(name, baseName, applyMap) {
254 | var pkgName, pkgConfig, mapValue, nameParts, i, j, nameSegment,
255 | foundMap, foundI, foundStarMap, starI,
256 | baseParts = baseName && baseName.split('/'),
257 | normalizedBaseParts = baseParts,
258 | map = config.map,
259 | starMap = map && map['*'];
260 |
261 | //Adjust any relative paths.
262 | if (name && name.charAt(0) === '.') {
263 | //If have a base name, try to normalize against it,
264 | //otherwise, assume it is a top-level require that will
265 | //be relative to baseUrl in the end.
266 | if (baseName) {
267 | if (getOwn(config.pkgs, baseName)) {
268 | //If the baseName is a package name, then just treat it as one
269 | //name to concat the name with.
270 | normalizedBaseParts = baseParts = [baseName];
271 | } else {
272 | //Convert baseName to array, and lop off the last part,
273 | //so that . matches that 'directory' and not name of the baseName's
274 | //module. For instance, baseName of 'one/two/three', maps to
275 | //'one/two/three.js', but we want the directory, 'one/two' for
276 | //this normalization.
277 | normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
278 | }
279 |
280 | name = normalizedBaseParts.concat(name.split('/'));
281 | trimDots(name);
282 |
283 | //Some use of packages may use a . path to reference the
284 | //'main' module name, so normalize for that.
285 | pkgConfig = getOwn(config.pkgs, (pkgName = name[0]));
286 | name = name.join('/');
287 | if (pkgConfig && name === pkgName + '/' + pkgConfig.main) {
288 | name = pkgName;
289 | }
290 | } else if (name.indexOf('./') === 0) {
291 | // No baseName, so this is ID is resolved relative
292 | // to baseUrl, pull off the leading dot.
293 | name = name.substring(2);
294 | }
295 | }
296 |
297 | //Apply map config if available.
298 | if (applyMap && (baseParts || starMap) && map) {
299 | nameParts = name.split('/');
300 |
301 | for (i = nameParts.length; i > 0; i -= 1) {
302 | nameSegment = nameParts.slice(0, i).join('/');
303 |
304 | if (baseParts) {
305 | //Find the longest baseName segment match in the config.
306 | //So, do joins on the biggest to smallest lengths of baseParts.
307 | for (j = baseParts.length; j > 0; j -= 1) {
308 | mapValue = getOwn(map, baseParts.slice(0, j).join('/'));
309 |
310 | //baseName segment has config, find if it has one for
311 | //this name.
312 | if (mapValue) {
313 | mapValue = getOwn(mapValue, nameSegment);
314 | if (mapValue) {
315 | //Match, update name to the new value.
316 | foundMap = mapValue;
317 | foundI = i;
318 | break;
319 | }
320 | }
321 | }
322 | }
323 |
324 | if (foundMap) {
325 | break;
326 | }
327 |
328 | //Check for a star map match, but just hold on to it,
329 | //if there is a shorter segment match later in a matching
330 | //config, then favor over this star map.
331 | if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {
332 | foundStarMap = getOwn(starMap, nameSegment);
333 | starI = i;
334 | }
335 | }
336 |
337 | if (!foundMap && foundStarMap) {
338 | foundMap = foundStarMap;
339 | foundI = starI;
340 | }
341 |
342 | if (foundMap) {
343 | nameParts.splice(0, foundI, foundMap);
344 | name = nameParts.join('/');
345 | }
346 | }
347 |
348 | return name;
349 | }
350 |
351 | function removeScript(name) {
352 | if (isBrowser) {
353 | each(scripts(), function (scriptNode) {
354 | if (scriptNode.getAttribute('data-requiremodule') === name &&
355 | scriptNode.getAttribute('data-requirecontext') === context.contextName) {
356 | scriptNode.parentNode.removeChild(scriptNode);
357 | return true;
358 | }
359 | });
360 | }
361 | }
362 |
363 | function hasPathFallback(id) {
364 | var pathConfig = getOwn(config.paths, id);
365 | if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
366 | removeScript(id);
367 | //Pop off the first array value, since it failed, and
368 | //retry
369 | pathConfig.shift();
370 | context.require.undef(id);
371 | context.require([id]);
372 | return true;
373 | }
374 | }
375 |
376 | //Turns a plugin!resource to [plugin, resource]
377 | //with the plugin being undefined if the name
378 | //did not have a plugin prefix.
379 | function splitPrefix(name) {
380 | var prefix,
381 | index = name ? name.indexOf('!') : -1;
382 | if (index > -1) {
383 | prefix = name.substring(0, index);
384 | name = name.substring(index + 1, name.length);
385 | }
386 | return [prefix, name];
387 | }
388 |
389 | /**
390 | * Creates a module mapping that includes plugin prefix, module
391 | * name, and path. If parentModuleMap is provided it will
392 | * also normalize the name via require.normalize()
393 | *
394 | * @param {String} name the module name
395 | * @param {String} [parentModuleMap] parent module map
396 | * for the module name, used to resolve relative names.
397 | * @param {Boolean} isNormalized: is the ID already normalized.
398 | * This is true if this call is done for a define() module ID.
399 | * @param {Boolean} applyMap: apply the map config to the ID.
400 | * Should only be true if this map is for a dependency.
401 | *
402 | * @returns {Object}
403 | */
404 | function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
405 | var url, pluginModule, suffix, nameParts,
406 | prefix = null,
407 | parentName = parentModuleMap ? parentModuleMap.name : null,
408 | originalName = name,
409 | isDefine = true,
410 | normalizedName = '';
411 |
412 | //If no name, then it means it is a require call, generate an
413 | //internal name.
414 | if (!name) {
415 | isDefine = false;
416 | name = '_@r' + (requireCounter += 1);
417 | }
418 |
419 | nameParts = splitPrefix(name);
420 | prefix = nameParts[0];
421 | name = nameParts[1];
422 |
423 | if (prefix) {
424 | prefix = normalize(prefix, parentName, applyMap);
425 | pluginModule = getOwn(defined, prefix);
426 | }
427 |
428 | //Account for relative paths if there is a base name.
429 | if (name) {
430 | if (prefix) {
431 | if (pluginModule && pluginModule.normalize) {
432 | //Plugin is loaded, use its normalize method.
433 | normalizedName = pluginModule.normalize(name, function (name) {
434 | return normalize(name, parentName, applyMap);
435 | });
436 | } else {
437 | normalizedName = normalize(name, parentName, applyMap);
438 | }
439 | } else {
440 | //A regular module.
441 | normalizedName = normalize(name, parentName, applyMap);
442 |
443 | //Normalized name may be a plugin ID due to map config
444 | //application in normalize. The map config values must
445 | //already be normalized, so do not need to redo that part.
446 | nameParts = splitPrefix(normalizedName);
447 | prefix = nameParts[0];
448 | normalizedName = nameParts[1];
449 | isNormalized = true;
450 |
451 | url = context.nameToUrl(normalizedName);
452 | }
453 | }
454 |
455 | //If the id is a plugin id that cannot be determined if it needs
456 | //normalization, stamp it with a unique ID so two matching relative
457 | //ids that may conflict can be separate.
458 | suffix = prefix && !pluginModule && !isNormalized ?
459 | '_unnormalized' + (unnormalizedCounter += 1) :
460 | '';
461 |
462 | return {
463 | prefix: prefix,
464 | name: normalizedName,
465 | parentMap: parentModuleMap,
466 | unnormalized: !!suffix,
467 | url: url,
468 | originalName: originalName,
469 | isDefine: isDefine,
470 | id: (prefix ?
471 | prefix + '!' + normalizedName :
472 | normalizedName) + suffix
473 | };
474 | }
475 |
476 | function getModule(depMap) {
477 | var id = depMap.id,
478 | mod = getOwn(registry, id);
479 |
480 | if (!mod) {
481 | mod = registry[id] = new context.Module(depMap);
482 | }
483 |
484 | return mod;
485 | }
486 |
487 | function on(depMap, name, fn) {
488 | var id = depMap.id,
489 | mod = getOwn(registry, id);
490 |
491 | if (hasProp(defined, id) &&
492 | (!mod || mod.defineEmitComplete)) {
493 | if (name === 'defined') {
494 | fn(defined[id]);
495 | }
496 | } else {
497 | getModule(depMap).on(name, fn);
498 | }
499 | }
500 |
501 | function onError(err, errback) {
502 | var ids = err.requireModules,
503 | notified = false;
504 |
505 | if (errback) {
506 | errback(err);
507 | } else {
508 | each(ids, function (id) {
509 | var mod = getOwn(registry, id);
510 | if (mod) {
511 | //Set error on module, so it skips timeout checks.
512 | mod.error = err;
513 | if (mod.events.error) {
514 | notified = true;
515 | mod.emit('error', err);
516 | }
517 | }
518 | });
519 |
520 | if (!notified) {
521 | req.onError(err);
522 | }
523 | }
524 | }
525 |
526 | /**
527 | * Internal method to transfer globalQueue items to this context's
528 | * defQueue.
529 | */
530 | function takeGlobalQueue() {
531 | //Push all the globalDefQueue items into the context's defQueue
532 | if (globalDefQueue.length) {
533 | //Array splice in the values since the context code has a
534 | //local var ref to defQueue, so cannot just reassign the one
535 | //on context.
536 | apsp.apply(defQueue,
537 | [defQueue.length - 1, 0].concat(globalDefQueue));
538 | globalDefQueue = [];
539 | }
540 | }
541 |
542 | handlers = {
543 | 'require': function (mod) {
544 | if (mod.require) {
545 | return mod.require;
546 | } else {
547 | return (mod.require = context.makeRequire(mod.map));
548 | }
549 | },
550 | 'exports': function (mod) {
551 | mod.usingExports = true;
552 | if (mod.map.isDefine) {
553 | if (mod.exports) {
554 | return mod.exports;
555 | } else {
556 | return (mod.exports = defined[mod.map.id] = {});
557 | }
558 | }
559 | },
560 | 'module': function (mod) {
561 | if (mod.module) {
562 | return mod.module;
563 | } else {
564 | return (mod.module = {
565 | id: mod.map.id,
566 | uri: mod.map.url,
567 | config: function () {
568 | return (config.config && getOwn(config.config, mod.map.id)) || {};
569 | },
570 | exports: defined[mod.map.id]
571 | });
572 | }
573 | }
574 | };
575 |
576 | function cleanRegistry(id) {
577 | //Clean up machinery used for waiting modules.
578 | delete registry[id];
579 | }
580 |
581 | function breakCycle(mod, traced, processed) {
582 | var id = mod.map.id;
583 |
584 | if (mod.error) {
585 | mod.emit('error', mod.error);
586 | } else {
587 | traced[id] = true;
588 | each(mod.depMaps, function (depMap, i) {
589 | var depId = depMap.id,
590 | dep = getOwn(registry, depId);
591 |
592 | //Only force things that have not completed
593 | //being defined, so still in the registry,
594 | //and only if it has not been matched up
595 | //in the module already.
596 | if (dep && !mod.depMatched[i] && !processed[depId]) {
597 | if (getOwn(traced, depId)) {
598 | mod.defineDep(i, defined[depId]);
599 | mod.check(); //pass false?
600 | } else {
601 | breakCycle(dep, traced, processed);
602 | }
603 | }
604 | });
605 | processed[id] = true;
606 | }
607 | }
608 |
609 | function checkLoaded() {
610 | var map, modId, err, usingPathFallback,
611 | waitInterval = config.waitSeconds * 1000,
612 | //It is possible to disable the wait interval by using waitSeconds of 0.
613 | expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
614 | noLoads = [],
615 | reqCalls = [],
616 | stillLoading = false,
617 | needCycleCheck = true;
618 |
619 | //Do not bother if this call was a result of a cycle break.
620 | if (inCheckLoaded) {
621 | return;
622 | }
623 |
624 | inCheckLoaded = true;
625 |
626 | //Figure out the state of all the modules.
627 | eachProp(registry, function (mod) {
628 | map = mod.map;
629 | modId = map.id;
630 |
631 | //Skip things that are not enabled or in error state.
632 | if (!mod.enabled) {
633 | return;
634 | }
635 |
636 | if (!map.isDefine) {
637 | reqCalls.push(mod);
638 | }
639 |
640 | if (!mod.error) {
641 | //If the module should be executed, and it has not
642 | //been inited and time is up, remember it.
643 | if (!mod.inited && expired) {
644 | if (hasPathFallback(modId)) {
645 | usingPathFallback = true;
646 | stillLoading = true;
647 | } else {
648 | noLoads.push(modId);
649 | removeScript(modId);
650 | }
651 | } else if (!mod.inited && mod.fetched && map.isDefine) {
652 | stillLoading = true;
653 | if (!map.prefix) {
654 | //No reason to keep looking for unfinished
655 | //loading. If the only stillLoading is a
656 | //plugin resource though, keep going,
657 | //because it may be that a plugin resource
658 | //is waiting on a non-plugin cycle.
659 | return (needCycleCheck = false);
660 | }
661 | }
662 | }
663 | });
664 |
665 | if (expired && noLoads.length) {
666 | //If wait time expired, throw error of unloaded modules.
667 | err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);
668 | err.contextName = context.contextName;
669 | return onError(err);
670 | }
671 |
672 | //Not expired, check for a cycle.
673 | if (needCycleCheck) {
674 | each(reqCalls, function (mod) {
675 | breakCycle(mod, {}, {});
676 | });
677 | }
678 |
679 | //If still waiting on loads, and the waiting load is something
680 | //other than a plugin resource, or there are still outstanding
681 | //scripts, then just try back later.
682 | if ((!expired || usingPathFallback) && stillLoading) {
683 | //Something is still waiting to load. Wait for it, but only
684 | //if a timeout is not already in effect.
685 | if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
686 | checkLoadedTimeoutId = setTimeout(function () {
687 | checkLoadedTimeoutId = 0;
688 | checkLoaded();
689 | }, 50);
690 | }
691 | }
692 |
693 | inCheckLoaded = false;
694 | }
695 |
696 | Module = function (map) {
697 | this.events = getOwn(undefEvents, map.id) || {};
698 | this.map = map;
699 | this.shim = getOwn(config.shim, map.id);
700 | this.depExports = [];
701 | this.depMaps = [];
702 | this.depMatched = [];
703 | this.pluginMaps = {};
704 | this.depCount = 0;
705 |
706 | /* this.exports this.factory
707 | this.depMaps = [],
708 | this.enabled, this.fetched
709 | */
710 | };
711 |
712 | Module.prototype = {
713 | init: function (depMaps, factory, errback, options) {
714 | options = options || {};
715 |
716 | //Do not do more inits if already done. Can happen if there
717 | //are multiple define calls for the same module. That is not
718 | //a normal, common case, but it is also not unexpected.
719 | if (this.inited) {
720 | return;
721 | }
722 |
723 | this.factory = factory;
724 |
725 | if (errback) {
726 | //Register for errors on this module.
727 | this.on('error', errback);
728 | } else if (this.events.error) {
729 | //If no errback already, but there are error listeners
730 | //on this module, set up an errback to pass to the deps.
731 | errback = bind(this, function (err) {
732 | this.emit('error', err);
733 | });
734 | }
735 |
736 | //Do a copy of the dependency array, so that
737 | //source inputs are not modified. For example
738 | //"shim" deps are passed in here directly, and
739 | //doing a direct modification of the depMaps array
740 | //would affect that config.
741 | this.depMaps = depMaps && depMaps.slice(0);
742 |
743 | this.errback = errback;
744 |
745 | //Indicate this module has be initialized
746 | this.inited = true;
747 |
748 | this.ignore = options.ignore;
749 |
750 | //Could have option to init this module in enabled mode,
751 | //or could have been previously marked as enabled. However,
752 | //the dependencies are not known until init is called. So
753 | //if enabled previously, now trigger dependencies as enabled.
754 | if (options.enabled || this.enabled) {
755 | //Enable this module and dependencies.
756 | //Will call this.check()
757 | this.enable();
758 | } else {
759 | this.check();
760 | }
761 | },
762 |
763 | defineDep: function (i, depExports) {
764 | //Because of cycles, defined callback for a given
765 | //export can be called more than once.
766 | if (!this.depMatched[i]) {
767 | this.depMatched[i] = true;
768 | this.depCount -= 1;
769 | this.depExports[i] = depExports;
770 | }
771 | },
772 |
773 | fetch: function () {
774 | if (this.fetched) {
775 | return;
776 | }
777 | this.fetched = true;
778 |
779 | context.startTime = (new Date()).getTime();
780 |
781 | var map = this.map;
782 |
783 | //If the manager is for a plugin managed resource,
784 | //ask the plugin to load it now.
785 | if (this.shim) {
786 | context.makeRequire(this.map, {
787 | enableBuildCallback: true
788 | })(this.shim.deps || [], bind(this, function () {
789 | return map.prefix ? this.callPlugin() : this.load();
790 | }));
791 | } else {
792 | //Regular dependency.
793 | return map.prefix ? this.callPlugin() : this.load();
794 | }
795 | },
796 |
797 | load: function () {
798 | var url = this.map.url;
799 |
800 | //Regular dependency.
801 | if (!urlFetched[url]) {
802 | urlFetched[url] = true;
803 | context.load(this.map.id, url);
804 | }
805 | },
806 |
807 | /**
808 | * Checks is the module is ready to define itself, and if so,
809 | * define it.
810 | */
811 | check: function () {
812 | if (!this.enabled || this.enabling) {
813 | return;
814 | }
815 |
816 | var err, cjsModule,
817 | id = this.map.id,
818 | depExports = this.depExports,
819 | exports = this.exports,
820 | factory = this.factory;
821 |
822 | if (!this.inited) {
823 | this.fetch();
824 | } else if (this.error) {
825 | this.emit('error', this.error);
826 | } else if (!this.defining) {
827 | //The factory could trigger another require call
828 | //that would result in checking this module to
829 | //define itself again. If already in the process
830 | //of doing that, skip this work.
831 | this.defining = true;
832 |
833 | if (this.depCount < 1 && !this.defined) {
834 | if (isFunction(factory)) {
835 | //If there is an error listener, favor passing
836 | //to that instead of throwing an error.
837 | if (this.events.error) {
838 | try {
839 | exports = context.execCb(id, factory, depExports, exports);
840 | } catch (e) {
841 | err = e;
842 | }
843 | } else {
844 | exports = context.execCb(id, factory, depExports, exports);
845 | }
846 |
847 | if (this.map.isDefine) {
848 | //If setting exports via 'module' is in play,
849 | //favor that over return value and exports. After that,
850 | //favor a non-undefined return value over exports use.
851 | cjsModule = this.module;
852 | if (cjsModule &&
853 | cjsModule.exports !== undefined &&
854 | //Make sure it is not already the exports value
855 | cjsModule.exports !== this.exports) {
856 | exports = cjsModule.exports;
857 | } else if (exports === undefined && this.usingExports) {
858 | //exports already set the defined value.
859 | exports = this.exports;
860 | }
861 | }
862 |
863 | if (err) {
864 | err.requireMap = this.map;
865 | err.requireModules = [this.map.id];
866 | err.requireType = 'define';
867 | return onError((this.error = err));
868 | }
869 |
870 | } else {
871 | //Just a literal value
872 | exports = factory;
873 | }
874 |
875 | this.exports = exports;
876 |
877 | if (this.map.isDefine && !this.ignore) {
878 | defined[id] = exports;
879 |
880 | if (req.onResourceLoad) {
881 | req.onResourceLoad(context, this.map, this.depMaps);
882 | }
883 | }
884 |
885 | //Clean up
886 | delete registry[id];
887 |
888 | this.defined = true;
889 | }
890 |
891 | //Finished the define stage. Allow calling check again
892 | //to allow define notifications below in the case of a
893 | //cycle.
894 | this.defining = false;
895 |
896 | if (this.defined && !this.defineEmitted) {
897 | this.defineEmitted = true;
898 | this.emit('defined', this.exports);
899 | this.defineEmitComplete = true;
900 | }
901 |
902 | }
903 | },
904 |
905 | callPlugin: function () {
906 | var map = this.map,
907 | id = map.id,
908 | //Map already normalized the prefix.
909 | pluginMap = makeModuleMap(map.prefix);
910 |
911 | //Mark this as a dependency for this plugin, so it
912 | //can be traced for cycles.
913 | this.depMaps.push(pluginMap);
914 |
915 | on(pluginMap, 'defined', bind(this, function (plugin) {
916 | var load, normalizedMap, normalizedMod,
917 | name = this.map.name,
918 | parentName = this.map.parentMap ? this.map.parentMap.name : null,
919 | localRequire = context.makeRequire(map.parentMap, {
920 | enableBuildCallback: true
921 | });
922 |
923 | //If current map is not normalized, wait for that
924 | //normalized name to load instead of continuing.
925 | if (this.map.unnormalized) {
926 | //Normalize the ID if the plugin allows it.
927 | if (plugin.normalize) {
928 | name = plugin.normalize(name, function (name) {
929 | return normalize(name, parentName, true);
930 | }) || '';
931 | }
932 |
933 | //prefix and name should already be normalized, no need
934 | //for applying map config again either.
935 | normalizedMap = makeModuleMap(map.prefix + '!' + name,
936 | this.map.parentMap);
937 | on(normalizedMap,
938 | 'defined', bind(this, function (value) {
939 | this.init([], function () { return value; }, null, {
940 | enabled: true,
941 | ignore: true
942 | });
943 | }));
944 |
945 | normalizedMod = getOwn(registry, normalizedMap.id);
946 | if (normalizedMod) {
947 | //Mark this as a dependency for this plugin, so it
948 | //can be traced for cycles.
949 | this.depMaps.push(normalizedMap);
950 |
951 | if (this.events.error) {
952 | normalizedMod.on('error', bind(this, function (err) {
953 | this.emit('error', err);
954 | }));
955 | }
956 | normalizedMod.enable();
957 | }
958 |
959 | return;
960 | }
961 |
962 | load = bind(this, function (value) {
963 | this.init([], function () { return value; }, null, {
964 | enabled: true
965 | });
966 | });
967 |
968 | load.error = bind(this, function (err) {
969 | this.inited = true;
970 | this.error = err;
971 | err.requireModules = [id];
972 |
973 | //Remove temp unnormalized modules for this module,
974 | //since they will never be resolved otherwise now.
975 | eachProp(registry, function (mod) {
976 | if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
977 | cleanRegistry(mod.map.id);
978 | }
979 | });
980 |
981 | onError(err);
982 | });
983 |
984 | //Allow plugins to load other code without having to know the
985 | //context or how to 'complete' the load.
986 | load.fromText = bind(this, function (text, textAlt) {
987 | /*jslint evil: true */
988 | var moduleName = map.name,
989 | moduleMap = makeModuleMap(moduleName),
990 | hasInteractive = useInteractive;
991 |
992 | //As of 2.1.0, support just passing the text, to reinforce
993 | //fromText only being called once per resource. Still
994 | //support old style of passing moduleName but discard
995 | //that moduleName in favor of the internal ref.
996 | if (textAlt) {
997 | text = textAlt;
998 | }
999 |
1000 | //Turn off interactive script matching for IE for any define
1001 | //calls in the text, then turn it back on at the end.
1002 | if (hasInteractive) {
1003 | useInteractive = false;
1004 | }
1005 |
1006 | //Prime the system by creating a module instance for
1007 | //it.
1008 | getModule(moduleMap);
1009 |
1010 | //Transfer any config to this other module.
1011 | if (hasProp(config.config, id)) {
1012 | config.config[moduleName] = config.config[id];
1013 | }
1014 |
1015 | try {
1016 | req.exec(text);
1017 | } catch (e) {
1018 | return onError(makeError('fromtexteval',
1019 | 'fromText eval for ' + id +
1020 | ' failed: ' + e,
1021 | e,
1022 | [id]));
1023 | }
1024 |
1025 | if (hasInteractive) {
1026 | useInteractive = true;
1027 | }
1028 |
1029 | //Mark this as a dependency for the plugin
1030 | //resource
1031 | this.depMaps.push(moduleMap);
1032 |
1033 | //Support anonymous modules.
1034 | context.completeLoad(moduleName);
1035 |
1036 | //Bind the value of that module to the value for this
1037 | //resource ID.
1038 | localRequire([moduleName], load);
1039 | });
1040 |
1041 | //Use parentName here since the plugin's name is not reliable,
1042 | //could be some weird string with no path that actually wants to
1043 | //reference the parentName's path.
1044 | plugin.load(map.name, localRequire, load, config);
1045 | }));
1046 |
1047 | context.enable(pluginMap, this);
1048 | this.pluginMaps[pluginMap.id] = pluginMap;
1049 | },
1050 |
1051 | enable: function () {
1052 | this.enabled = true;
1053 |
1054 | //Set flag mentioning that the module is enabling,
1055 | //so that immediate calls to the defined callbacks
1056 | //for dependencies do not trigger inadvertent load
1057 | //with the depCount still being zero.
1058 | this.enabling = true;
1059 |
1060 | //Enable each dependency
1061 | each(this.depMaps, bind(this, function (depMap, i) {
1062 | var id, mod, handler;
1063 |
1064 | if (typeof depMap === 'string') {
1065 | //Dependency needs to be converted to a depMap
1066 | //and wired up to this module.
1067 | depMap = makeModuleMap(depMap,
1068 | (this.map.isDefine ? this.map : this.map.parentMap),
1069 | false,
1070 | !this.skipMap);
1071 | this.depMaps[i] = depMap;
1072 |
1073 | handler = getOwn(handlers, depMap.id);
1074 |
1075 | if (handler) {
1076 | this.depExports[i] = handler(this);
1077 | return;
1078 | }
1079 |
1080 | this.depCount += 1;
1081 |
1082 | on(depMap, 'defined', bind(this, function (depExports) {
1083 | this.defineDep(i, depExports);
1084 | this.check();
1085 | }));
1086 |
1087 | if (this.errback) {
1088 | on(depMap, 'error', this.errback);
1089 | }
1090 | }
1091 |
1092 | id = depMap.id;
1093 | mod = registry[id];
1094 |
1095 | //Skip special modules like 'require', 'exports', 'module'
1096 | //Also, don't call enable if it is already enabled,
1097 | //important in circular dependency cases.
1098 | if (!hasProp(handlers, id) && mod && !mod.enabled) {
1099 | context.enable(depMap, this);
1100 | }
1101 | }));
1102 |
1103 | //Enable each plugin that is used in
1104 | //a dependency
1105 | eachProp(this.pluginMaps, bind(this, function (pluginMap) {
1106 | var mod = getOwn(registry, pluginMap.id);
1107 | if (mod && !mod.enabled) {
1108 | context.enable(pluginMap, this);
1109 | }
1110 | }));
1111 |
1112 | this.enabling = false;
1113 |
1114 | this.check();
1115 | },
1116 |
1117 | on: function (name, cb) {
1118 | var cbs = this.events[name];
1119 | if (!cbs) {
1120 | cbs = this.events[name] = [];
1121 | }
1122 | cbs.push(cb);
1123 | },
1124 |
1125 | emit: function (name, evt) {
1126 | each(this.events[name], function (cb) {
1127 | cb(evt);
1128 | });
1129 | if (name === 'error') {
1130 | //Now that the error handler was triggered, remove
1131 | //the listeners, since this broken Module instance
1132 | //can stay around for a while in the registry.
1133 | delete this.events[name];
1134 | }
1135 | }
1136 | };
1137 |
1138 | function callGetModule(args) {
1139 | //Skip modules already defined.
1140 | if (!hasProp(defined, args[0])) {
1141 | getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
1142 | }
1143 | }
1144 |
1145 | function removeListener(node, func, name, ieName) {
1146 | //Favor detachEvent because of IE9
1147 | //issue, see attachEvent/addEventListener comment elsewhere
1148 | //in this file.
1149 | if (node.detachEvent && !isOpera) {
1150 | //Probably IE. If not it will throw an error, which will be
1151 | //useful to know.
1152 | if (ieName) {
1153 | node.detachEvent(ieName, func);
1154 | }
1155 | } else {
1156 | node.removeEventListener(name, func, false);
1157 | }
1158 | }
1159 |
1160 | /**
1161 | * Given an event from a script node, get the requirejs info from it,
1162 | * and then removes the event listeners on the node.
1163 | * @param {Event} evt
1164 | * @returns {Object}
1165 | */
1166 | function getScriptData(evt) {
1167 | //Using currentTarget instead of target for Firefox 2.0's sake. Not
1168 | //all old browsers will be supported, but this one was easy enough
1169 | //to support and still makes sense.
1170 | var node = evt.currentTarget || evt.srcElement;
1171 |
1172 | //Remove the listeners once here.
1173 | removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');
1174 | removeListener(node, context.onScriptError, 'error');
1175 |
1176 | return {
1177 | node: node,
1178 | id: node && node.getAttribute('data-requiremodule')
1179 | };
1180 | }
1181 |
1182 | function intakeDefines() {
1183 | var args;
1184 |
1185 | //Any defined modules in the global queue, intake them now.
1186 | takeGlobalQueue();
1187 |
1188 | //Make sure any remaining defQueue items get properly processed.
1189 | while (defQueue.length) {
1190 | args = defQueue.shift();
1191 | if (args[0] === null) {
1192 | return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' + args[args.length - 1]));
1193 | } else {
1194 | //args are id, deps, factory. Should be normalized by the
1195 | //define() function.
1196 | callGetModule(args);
1197 | }
1198 | }
1199 | }
1200 |
1201 | context = {
1202 | config: config,
1203 | contextName: contextName,
1204 | registry: registry,
1205 | defined: defined,
1206 | urlFetched: urlFetched,
1207 | defQueue: defQueue,
1208 | Module: Module,
1209 | makeModuleMap: makeModuleMap,
1210 | nextTick: req.nextTick,
1211 |
1212 | /**
1213 | * Set a configuration for the context.
1214 | * @param {Object} cfg config object to integrate.
1215 | */
1216 | configure: function (cfg) {
1217 | //Make sure the baseUrl ends in a slash.
1218 | if (cfg.baseUrl) {
1219 | if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {
1220 | cfg.baseUrl += '/';
1221 | }
1222 | }
1223 |
1224 | //Save off the paths and packages since they require special processing,
1225 | //they are additive.
1226 | var pkgs = config.pkgs,
1227 | shim = config.shim,
1228 | objs = {
1229 | paths: true,
1230 | config: true,
1231 | map: true
1232 | };
1233 |
1234 | eachProp(cfg, function (value, prop) {
1235 | if (objs[prop]) {
1236 | if (prop === 'map') {
1237 | mixin(config[prop], value, true, true);
1238 | } else {
1239 | mixin(config[prop], value, true);
1240 | }
1241 | } else {
1242 | config[prop] = value;
1243 | }
1244 | });
1245 |
1246 | //Merge shim
1247 | if (cfg.shim) {
1248 | eachProp(cfg.shim, function (value, id) {
1249 | //Normalize the structure
1250 | if (isArray(value)) {
1251 | value = {
1252 | deps: value
1253 | };
1254 | }
1255 | if ((value.exports || value.init) && !value.exportsFn) {
1256 | value.exportsFn = context.makeShimExports(value);
1257 | }
1258 | shim[id] = value;
1259 | });
1260 | config.shim = shim;
1261 | }
1262 |
1263 | //Adjust packages if necessary.
1264 | if (cfg.packages) {
1265 | each(cfg.packages, function (pkgObj) {
1266 | var location;
1267 |
1268 | pkgObj = typeof pkgObj === 'string' ? { name: pkgObj } : pkgObj;
1269 | location = pkgObj.location;
1270 |
1271 | //Create a brand new object on pkgs, since currentPackages can
1272 | //be passed in again, and config.pkgs is the internal transformed
1273 | //state for all package configs.
1274 | pkgs[pkgObj.name] = {
1275 | name: pkgObj.name,
1276 | location: location || pkgObj.name,
1277 | //Remove leading dot in main, so main paths are normalized,
1278 | //and remove any trailing .js, since different package
1279 | //envs have different conventions: some use a module name,
1280 | //some use a file name.
1281 | main: (pkgObj.main || 'main')
1282 | .replace(currDirRegExp, '')
1283 | .replace(jsSuffixRegExp, '')
1284 | };
1285 | });
1286 |
1287 | //Done with modifications, assing packages back to context config
1288 | config.pkgs = pkgs;
1289 | }
1290 |
1291 | //If there are any "waiting to execute" modules in the registry,
1292 | //update the maps for them, since their info, like URLs to load,
1293 | //may have changed.
1294 | eachProp(registry, function (mod, id) {
1295 | //If module already has init called, since it is too
1296 | //late to modify them, and ignore unnormalized ones
1297 | //since they are transient.
1298 | if (!mod.inited && !mod.map.unnormalized) {
1299 | mod.map = makeModuleMap(id);
1300 | }
1301 | });
1302 |
1303 | //If a deps array or a config callback is specified, then call
1304 | //require with those args. This is useful when require is defined as a
1305 | //config object before require.js is loaded.
1306 | if (cfg.deps || cfg.callback) {
1307 | context.require(cfg.deps || [], cfg.callback);
1308 | }
1309 | },
1310 |
1311 | makeShimExports: function (value) {
1312 | function fn() {
1313 | var ret;
1314 | if (value.init) {
1315 | ret = value.init.apply(global, arguments);
1316 | }
1317 | return ret || (value.exports && getGlobal(value.exports));
1318 | }
1319 | return fn;
1320 | },
1321 |
1322 | makeRequire: function (relMap, options) {
1323 | options = options || {};
1324 |
1325 | function localRequire(deps, callback, errback) {
1326 | var id, map, requireMod;
1327 |
1328 | if (options.enableBuildCallback && callback && isFunction(callback)) {
1329 | callback.__requireJsBuild = true;
1330 | }
1331 |
1332 | if (typeof deps === 'string') {
1333 | if (isFunction(callback)) {
1334 | //Invalid call
1335 | return onError(makeError('requireargs', 'Invalid require call'), errback);
1336 | }
1337 |
1338 | //If require|exports|module are requested, get the
1339 | //value for them from the special handlers. Caveat:
1340 | //this only works while module is being defined.
1341 | if (relMap && hasProp(handlers, deps)) {
1342 | return handlers[deps](registry[relMap.id]);
1343 | }
1344 |
1345 | //Synchronous access to one module. If require.get is
1346 | //available (as in the Node adapter), prefer that.
1347 | if (req.get) {
1348 | return req.get(context, deps, relMap);
1349 | }
1350 |
1351 | //Normalize module name, if it contains . or ..
1352 | map = makeModuleMap(deps, relMap, false, true);
1353 | id = map.id;
1354 |
1355 | if (!hasProp(defined, id)) {
1356 | return onError(makeError('notloaded', 'Module name "' +
1357 | id +
1358 | '" has not been loaded yet for context: ' +
1359 | contextName +
1360 | (relMap ? '' : '. Use require([])')));
1361 | }
1362 | return defined[id];
1363 | }
1364 |
1365 | //Grab defines waiting in the global queue.
1366 | intakeDefines();
1367 |
1368 | //Mark all the dependencies as needing to be loaded.
1369 | context.nextTick(function () {
1370 | //Some defines could have been added since the
1371 | //require call, collect them.
1372 | intakeDefines();
1373 |
1374 | requireMod = getModule(makeModuleMap(null, relMap));
1375 |
1376 | //Store if map config should be applied to this require
1377 | //call for dependencies.
1378 | requireMod.skipMap = options.skipMap;
1379 |
1380 | requireMod.init(deps, callback, errback, {
1381 | enabled: true
1382 | });
1383 |
1384 | checkLoaded();
1385 | });
1386 |
1387 | return localRequire;
1388 | }
1389 |
1390 | mixin(localRequire, {
1391 | isBrowser: isBrowser,
1392 |
1393 | /**
1394 | * Converts a module name + .extension into an URL path.
1395 | * *Requires* the use of a module name. It does not support using
1396 | * plain URLs like nameToUrl.
1397 | */
1398 | toUrl: function (moduleNamePlusExt) {
1399 | var ext, url,
1400 | index = moduleNamePlusExt.lastIndexOf('.'),
1401 | segment = moduleNamePlusExt.split('/')[0],
1402 | isRelative = segment === '.' || segment === '..';
1403 |
1404 | //Have a file extension alias, and it is not the
1405 | //dots from a relative path.
1406 | if (index !== -1 && (!isRelative || index > 1)) {
1407 | ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
1408 | moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
1409 | }
1410 |
1411 | url = context.nameToUrl(normalize(moduleNamePlusExt,
1412 | relMap && relMap.id, true), ext || '.fake');
1413 | return ext ? url : url.substring(0, url.length - 5);
1414 | },
1415 |
1416 | defined: function (id) {
1417 | return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
1418 | },
1419 |
1420 | specified: function (id) {
1421 | id = makeModuleMap(id, relMap, false, true).id;
1422 | return hasProp(defined, id) || hasProp(registry, id);
1423 | }
1424 | });
1425 |
1426 | //Only allow undef on top level require calls
1427 | if (!relMap) {
1428 | localRequire.undef = function (id) {
1429 | //Bind any waiting define() calls to this context,
1430 | //fix for #408
1431 | takeGlobalQueue();
1432 |
1433 | var map = makeModuleMap(id, relMap, true),
1434 | mod = getOwn(registry, id);
1435 |
1436 | delete defined[id];
1437 | delete urlFetched[map.url];
1438 | delete undefEvents[id];
1439 |
1440 | if (mod) {
1441 | //Hold on to listeners in case the
1442 | //module will be attempted to be reloaded
1443 | //using a different config.
1444 | if (mod.events.defined) {
1445 | undefEvents[id] = mod.events;
1446 | }
1447 |
1448 | cleanRegistry(id);
1449 | }
1450 | };
1451 | }
1452 |
1453 | return localRequire;
1454 | },
1455 |
1456 | /**
1457 | * Called to enable a module if it is still in the registry
1458 | * awaiting enablement. A second arg, parent, the parent module,
1459 | * is passed in for context, when this method is overriden by
1460 | * the optimizer. Not shown here to keep code compact.
1461 | */
1462 | enable: function (depMap) {
1463 | var mod = getOwn(registry, depMap.id);
1464 | if (mod) {
1465 | getModule(depMap).enable();
1466 | }
1467 | },
1468 |
1469 | /**
1470 | * Internal method used by environment adapters to complete a load event.
1471 | * A load event could be a script load or just a load pass from a synchronous
1472 | * load call.
1473 | * @param {String} moduleName the name of the module to potentially complete.
1474 | */
1475 | completeLoad: function (moduleName) {
1476 | var found, args, mod,
1477 | shim = getOwn(config.shim, moduleName) || {},
1478 | shExports = shim.exports;
1479 |
1480 | takeGlobalQueue();
1481 |
1482 | while (defQueue.length) {
1483 | args = defQueue.shift();
1484 | if (args[0] === null) {
1485 | args[0] = moduleName;
1486 | //If already found an anonymous module and bound it
1487 | //to this name, then this is some other anon module
1488 | //waiting for its completeLoad to fire.
1489 | if (found) {
1490 | break;
1491 | }
1492 | found = true;
1493 | } else if (args[0] === moduleName) {
1494 | //Found matching define call for this script!
1495 | found = true;
1496 | }
1497 |
1498 | callGetModule(args);
1499 | }
1500 |
1501 | //Do this after the cycle of callGetModule in case the result
1502 | //of those calls/init calls changes the registry.
1503 | mod = getOwn(registry, moduleName);
1504 |
1505 | if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {
1506 | if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
1507 | if (hasPathFallback(moduleName)) {
1508 | return;
1509 | } else {
1510 | return onError(makeError('nodefine',
1511 | 'No define call for ' + moduleName,
1512 | null,
1513 | [moduleName]));
1514 | }
1515 | } else {
1516 | //A script that does not call define(), so just simulate
1517 | //the call for it.
1518 | callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);
1519 | }
1520 | }
1521 |
1522 | checkLoaded();
1523 | },
1524 |
1525 | /**
1526 | * Converts a module name to a file path. Supports cases where
1527 | * moduleName may actually be just an URL.
1528 | * Note that it **does not** call normalize on the moduleName,
1529 | * it is assumed to have already been normalized. This is an
1530 | * internal API, not a public one. Use toUrl for the public API.
1531 | */
1532 | nameToUrl: function (moduleName, ext) {
1533 | var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url,
1534 | parentPath;
1535 |
1536 | //If a colon is in the URL, it indicates a protocol is used and it is just
1537 | //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
1538 | //or ends with .js, then assume the user meant to use an url and not a module id.
1539 | //The slash is important for protocol-less URLs as well as full paths.
1540 | if (req.jsExtRegExp.test(moduleName)) {
1541 | //Just a plain path, not module name lookup, so just return it.
1542 | //Add extension if it is included. This is a bit wonky, only non-.js things pass
1543 | //an extension, this method probably needs to be reworked.
1544 | url = moduleName + (ext || '');
1545 | } else {
1546 | //A module that needs to be converted to a path.
1547 | paths = config.paths;
1548 | pkgs = config.pkgs;
1549 |
1550 | syms = moduleName.split('/');
1551 | //For each module name segment, see if there is a path
1552 | //registered for it. Start with most specific name
1553 | //and work up from it.
1554 | for (i = syms.length; i > 0; i -= 1) {
1555 | parentModule = syms.slice(0, i).join('/');
1556 | pkg = getOwn(pkgs, parentModule);
1557 | parentPath = getOwn(paths, parentModule);
1558 | if (parentPath) {
1559 | //If an array, it means there are a few choices,
1560 | //Choose the one that is desired
1561 | if (isArray(parentPath)) {
1562 | parentPath = parentPath[0];
1563 | }
1564 | syms.splice(0, i, parentPath);
1565 | break;
1566 | } else if (pkg) {
1567 | //If module name is just the package name, then looking
1568 | //for the main module.
1569 | if (moduleName === pkg.name) {
1570 | pkgPath = pkg.location + '/' + pkg.main;
1571 | } else {
1572 | pkgPath = pkg.location;
1573 | }
1574 | syms.splice(0, i, pkgPath);
1575 | break;
1576 | }
1577 | }
1578 |
1579 | //Join the path parts together, then figure out if baseUrl is needed.
1580 | url = syms.join('/');
1581 | url += (ext || (/\?/.test(url) ? '' : '.js'));
1582 | url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
1583 | }
1584 |
1585 | return config.urlArgs ? url +
1586 | ((url.indexOf('?') === -1 ? '?' : '&') +
1587 | config.urlArgs) : url;
1588 | },
1589 |
1590 | //Delegates to req.load. Broken out as a separate function to
1591 | //allow overriding in the optimizer.
1592 | load: function (id, url) {
1593 | req.load(context, id, url);
1594 | },
1595 |
1596 | /**
1597 | * Executes a module callack function. Broken out as a separate function
1598 | * solely to allow the build system to sequence the files in the built
1599 | * layer in the right sequence.
1600 | *
1601 | * @private
1602 | */
1603 | execCb: function (name, callback, args, exports) {
1604 | return callback.apply(exports, args);
1605 | },
1606 |
1607 | /**
1608 | * callback for script loads, used to check status of loading.
1609 | *
1610 | * @param {Event} evt the event from the browser for the script
1611 | * that was loaded.
1612 | */
1613 | onScriptLoad: function (evt) {
1614 | //Using currentTarget instead of target for Firefox 2.0's sake. Not
1615 | //all old browsers will be supported, but this one was easy enough
1616 | //to support and still makes sense.
1617 | if (evt.type === 'load' ||
1618 | (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
1619 | //Reset interactive script so a script node is not held onto for
1620 | //to long.
1621 | interactiveScript = null;
1622 |
1623 | //Pull out the name of the module and the context.
1624 | var data = getScriptData(evt);
1625 | context.completeLoad(data.id);
1626 | }
1627 | },
1628 |
1629 | /**
1630 | * Callback for script errors.
1631 | */
1632 | onScriptError: function (evt) {
1633 | var data = getScriptData(evt);
1634 | if (!hasPathFallback(data.id)) {
1635 | return onError(makeError('scripterror', 'Script error', evt, [data.id]));
1636 | }
1637 | }
1638 | };
1639 |
1640 | context.require = context.makeRequire();
1641 | return context;
1642 | }
1643 |
1644 | /**
1645 | * Main entry point.
1646 | *
1647 | * If the only argument to require is a string, then the module that
1648 | * is represented by that string is fetched for the appropriate context.
1649 | *
1650 | * If the first argument is an array, then it will be treated as an array
1651 | * of dependency string names to fetch. An optional function callback can
1652 | * be specified to execute when all of those dependencies are available.
1653 | *
1654 | * Make a local req variable to help Caja compliance (it assumes things
1655 | * on a require that are not standardized), and to give a short
1656 | * name for minification/local scope use.
1657 | */
1658 | req = requirejs = function (deps, callback, errback, optional) {
1659 |
1660 | //Find the right context, use default
1661 | var context, config,
1662 | contextName = defContextName;
1663 |
1664 | // Determine if have config object in the call.
1665 | if (!isArray(deps) && typeof deps !== 'string') {
1666 | // deps is a config object
1667 | config = deps;
1668 | if (isArray(callback)) {
1669 | // Adjust args if there are dependencies
1670 | deps = callback;
1671 | callback = errback;
1672 | errback = optional;
1673 | } else {
1674 | deps = [];
1675 | }
1676 | }
1677 |
1678 | if (config && config.context) {
1679 | contextName = config.context;
1680 | }
1681 |
1682 | context = getOwn(contexts, contextName);
1683 | if (!context) {
1684 | context = contexts[contextName] = req.s.newContext(contextName);
1685 | }
1686 |
1687 | if (config) {
1688 | context.configure(config);
1689 | }
1690 |
1691 | return context.require(deps, callback, errback);
1692 | };
1693 |
1694 | /**
1695 | * Support require.config() to make it easier to cooperate with other
1696 | * AMD loaders on globally agreed names.
1697 | */
1698 | req.config = function (config) {
1699 | return req(config);
1700 | };
1701 |
1702 | /**
1703 | * Execute something after the current tick
1704 | * of the event loop. Override for other envs
1705 | * that have a better solution than setTimeout.
1706 | * @param {Function} fn function to execute later.
1707 | */
1708 | req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
1709 | setTimeout(fn, 4);
1710 | } : function (fn) { fn(); };
1711 |
1712 | /**
1713 | * Export require as a global, but only if it does not already exist.
1714 | */
1715 | if (!require) {
1716 | require = req;
1717 | }
1718 |
1719 | req.version = version;
1720 |
1721 | //Used to filter out dependencies that are already paths.
1722 | req.jsExtRegExp = /^\/|:|\?|\.js$/;
1723 | req.isBrowser = isBrowser;
1724 | s = req.s = {
1725 | contexts: contexts,
1726 | newContext: newContext
1727 | };
1728 |
1729 | //Create default context.
1730 | req({});
1731 |
1732 | //Exports some context-sensitive methods on global require.
1733 | each([
1734 | 'toUrl',
1735 | 'undef',
1736 | 'defined',
1737 | 'specified'
1738 | ], function (prop) {
1739 | //Reference from contexts instead of early binding to default context,
1740 | //so that during builds, the latest instance of the default context
1741 | //with its config gets used.
1742 | req[prop] = function () {
1743 | var ctx = contexts[defContextName];
1744 | return ctx.require[prop].apply(ctx, arguments);
1745 | };
1746 | });
1747 |
1748 | if (isBrowser) {
1749 | head = s.head = document.getElementsByTagName('head')[0];
1750 | //If BASE tag is in play, using appendChild is a problem for IE6.
1751 | //When that browser dies, this can be removed. Details in this jQuery bug:
1752 | //http://dev.jquery.com/ticket/2709
1753 | baseElement = document.getElementsByTagName('base')[0];
1754 | if (baseElement) {
1755 | head = s.head = baseElement.parentNode;
1756 | }
1757 | }
1758 |
1759 | /**
1760 | * Any errors that require explicitly generates will be passed to this
1761 | * function. Intercept/override it if you want custom error handling.
1762 | * @param {Error} err the error object.
1763 | */
1764 | req.onError = function (err) {
1765 | throw err;
1766 | };
1767 |
1768 | /**
1769 | * Does the request to load a module for the browser case.
1770 | * Make this a separate function to allow other environments
1771 | * to override it.
1772 | *
1773 | * @param {Object} context the require context to find state.
1774 | * @param {String} moduleName the name of the module.
1775 | * @param {Object} url the URL to the module.
1776 | */
1777 | req.load = function (context, moduleName, url) {
1778 | var config = (context && context.config) || {},
1779 | node;
1780 | if (isBrowser) {
1781 | //In the browser so use a script tag
1782 | node = config.xhtml ?
1783 | document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
1784 | document.createElement('script');
1785 | node.type = config.scriptType || 'text/javascript';
1786 | node.charset = 'utf-8';
1787 | node.async = true;
1788 |
1789 | node.setAttribute('data-requirecontext', context.contextName);
1790 | node.setAttribute('data-requiremodule', moduleName);
1791 |
1792 | //Set up load listener. Test attachEvent first because IE9 has
1793 | //a subtle issue in its addEventListener and script onload firings
1794 | //that do not match the behavior of all other browsers with
1795 | //addEventListener support, which fire the onload event for a
1796 | //script right after the script execution. See:
1797 | //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
1798 | //UNFORTUNATELY Opera implements attachEvent but does not follow the script
1799 | //script execution mode.
1800 | if (node.attachEvent &&
1801 | //Check if node.attachEvent is artificially added by custom script or
1802 | //natively supported by browser
1803 | //read https://github.com/jrburke/requirejs/issues/187
1804 | //if we can NOT find [native code] then it must NOT natively supported.
1805 | //in IE8, node.attachEvent does not have toString()
1806 | //Note the test for "[native code" with no closing brace, see:
1807 | //https://github.com/jrburke/requirejs/issues/273
1808 | !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
1809 | !isOpera) {
1810 | //Probably IE. IE (at least 6-8) do not fire
1811 | //script onload right after executing the script, so
1812 | //we cannot tie the anonymous define call to a name.
1813 | //However, IE reports the script as being in 'interactive'
1814 | //readyState at the time of the define call.
1815 | useInteractive = true;
1816 |
1817 | node.attachEvent('onreadystatechange', context.onScriptLoad);
1818 | //It would be great to add an error handler here to catch
1819 | //404s in IE9+. However, onreadystatechange will fire before
1820 | //the error handler, so that does not help. If addEvenListener
1821 | //is used, then IE will fire error before load, but we cannot
1822 | //use that pathway given the connect.microsoft.com issue
1823 | //mentioned above about not doing the 'script execute,
1824 | //then fire the script load event listener before execute
1825 | //next script' that other browsers do.
1826 | //Best hope: IE10 fixes the issues,
1827 | //and then destroys all installs of IE 6-9.
1828 | //node.attachEvent('onerror', context.onScriptError);
1829 | } else {
1830 | node.addEventListener('load', context.onScriptLoad, false);
1831 | node.addEventListener('error', context.onScriptError, false);
1832 | }
1833 | node.src = url;
1834 |
1835 | //For some cache cases in IE 6-8, the script executes before the end
1836 | //of the appendChild execution, so to tie an anonymous define
1837 | //call to the module name (which is stored on the node), hold on
1838 | //to a reference to this node, but clear after the DOM insertion.
1839 | currentlyAddingScript = node;
1840 | if (baseElement) {
1841 | head.insertBefore(node, baseElement);
1842 | } else {
1843 | head.appendChild(node);
1844 | }
1845 | currentlyAddingScript = null;
1846 |
1847 | return node;
1848 | } else if (isWebWorker) {
1849 | //In a web worker, use importScripts. This is not a very
1850 | //efficient use of importScripts, importScripts will block until
1851 | //its script is downloaded and evaluated. However, if web workers
1852 | //are in play, the expectation that a build has been done so that
1853 | //only one script needs to be loaded anyway. This may need to be
1854 | //reevaluated if other use cases become common.
1855 | importScripts(url);
1856 |
1857 | //Account for anonymous modules
1858 | context.completeLoad(moduleName);
1859 | }
1860 | };
1861 |
1862 | function getInteractiveScript() {
1863 | if (interactiveScript && interactiveScript.readyState === 'interactive') {
1864 | return interactiveScript;
1865 | }
1866 |
1867 | eachReverse(scripts(), function (script) {
1868 | if (script.readyState === 'interactive') {
1869 | return (interactiveScript = script);
1870 | }
1871 | });
1872 | return interactiveScript;
1873 | }
1874 |
1875 | //Look for a data-main script attribute, which could also adjust the baseUrl.
1876 | if (isBrowser) {
1877 | //Figure out baseUrl. Get it from the script tag with require.js in it.
1878 | eachReverse(scripts(), function (script) {
1879 | //Set the 'head' where we can append children by
1880 | //using the script's parent.
1881 | if (!head) {
1882 | head = script.parentNode;
1883 | }
1884 |
1885 | //Look for a data-main attribute to set main script for the page
1886 | //to load. If it is there, the path to data main becomes the
1887 | //baseUrl, if it is not already set.
1888 | dataMain = script.getAttribute('data-main');
1889 | if (dataMain) {
1890 | //Set final baseUrl if there is not already an explicit one.
1891 | if (!cfg.baseUrl) {
1892 | //Pull off the directory of data-main for use as the
1893 | //baseUrl.
1894 | src = dataMain.split('/');
1895 | mainScript = src.pop();
1896 | subPath = src.length ? src.join('/') + '/' : './';
1897 |
1898 | cfg.baseUrl = subPath;
1899 | dataMain = mainScript;
1900 | }
1901 |
1902 | //Strip off any trailing .js since dataMain is now
1903 | //like a module name.
1904 | dataMain = dataMain.replace(jsSuffixRegExp, '');
1905 |
1906 | //Put the data-main script in the files to load.
1907 | cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain];
1908 |
1909 | return true;
1910 | }
1911 | });
1912 | }
1913 |
1914 | /**
1915 | * The function that handles definitions of modules. Differs from
1916 | * require() in that a string for the module should be the first argument,
1917 | * and the function to execute after dependencies are loaded should
1918 | * return a value to define the module corresponding to the first argument's
1919 | * name.
1920 | */
1921 | define = function (name, deps, callback) {
1922 | var node, context;
1923 |
1924 | //Allow for anonymous modules
1925 | if (typeof name !== 'string') {
1926 | //Adjust args appropriately
1927 | callback = deps;
1928 | deps = name;
1929 | name = null;
1930 | }
1931 |
1932 | //This module may not have dependencies
1933 | if (!isArray(deps)) {
1934 | callback = deps;
1935 | deps = [];
1936 | }
1937 |
1938 | //If no name, and callback is a function, then figure out if it a
1939 | //CommonJS thing with dependencies.
1940 | if (!deps.length && isFunction(callback)) {
1941 | //Remove comments from the callback string,
1942 | //look for require calls, and pull them into the dependencies,
1943 | //but only if there are function args.
1944 | if (callback.length) {
1945 | callback
1946 | .toString()
1947 | .replace(commentRegExp, '')
1948 | .replace(cjsRequireRegExp, function (match, dep) {
1949 | deps.push(dep);
1950 | });
1951 |
1952 | //May be a CommonJS thing even without require calls, but still
1953 | //could use exports, and module. Avoid doing exports and module
1954 | //work though if it just needs require.
1955 | //REQUIRES the function to expect the CommonJS variables in the
1956 | //order listed below.
1957 | deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
1958 | }
1959 | }
1960 |
1961 | //If in IE 6-8 and hit an anonymous define() call, do the interactive
1962 | //work.
1963 | if (useInteractive) {
1964 | node = currentlyAddingScript || getInteractiveScript();
1965 | if (node) {
1966 | if (!name) {
1967 | name = node.getAttribute('data-requiremodule');
1968 | }
1969 | context = contexts[node.getAttribute('data-requirecontext')];
1970 | }
1971 | }
1972 |
1973 | //Always save off evaluating the def call until the script onload handler.
1974 | //This allows multiple modules to be in a file without prematurely
1975 | //tracing dependencies, and allows for anonymous module support,
1976 | //where the module name is not known until the script onload event
1977 | //occurs. If no context, use the global queue, and get it processed
1978 | //in the onscript load callback.
1979 | (context ? context.defQueue : globalDefQueue).push([name, deps, callback]);
1980 | };
1981 |
1982 | define.amd = {
1983 | jQuery: true
1984 | };
1985 |
1986 |
1987 | /**
1988 | * Executes the text. Normally just uses eval, but can be modified
1989 | * to use a better, environment-specific call. Only used for transpiling
1990 | * loader plugins, not for plain JS modules.
1991 | * @param {String} text the text to execute/evaluate.
1992 | */
1993 | req.exec = function (text) {
1994 | /*jslint evil: true */
1995 | return eval(text);
1996 | };
1997 |
1998 | //Set up with config info.
1999 | req(cfg);
2000 | }(this));
2001 |
--------------------------------------------------------------------------------