├── .gitignore
├── CHANGELOG.md
├── Gemfile
├── Gemfile.lock
├── MIT-LICENSE
├── README.md
├── Rakefile
├── app
└── helpers
│ └── requirejs_helper.rb
├── bin
└── r.js
├── lib
├── requirejs-rails.rb
├── requirejs
│ ├── error.rb
│ ├── rails.rb
│ └── rails
│ │ ├── builder.rb
│ │ ├── config.rb
│ │ ├── engine.rb
│ │ ├── rjs_driver.js.erb
│ │ ├── version.rb
│ │ └── view.rb
└── tasks
│ └── requirejs-rails_tasks.rake
├── requirejs-rails.gemspec
├── test
├── dummy
│ ├── .rvmrc
│ ├── Rakefile
│ ├── app
│ │ ├── assets
│ │ │ ├── javascripts
│ │ │ │ └── application.js
│ │ │ └── stylesheets
│ │ │ │ └── application.css
│ │ ├── controllers
│ │ │ └── application_controller.rb
│ │ ├── helpers
│ │ │ └── application_helper.rb
│ │ ├── mailers
│ │ │ └── .gitkeep
│ │ ├── models
│ │ │ └── .gitkeep
│ │ └── views
│ │ │ └── layouts
│ │ │ └── application.html.erb
│ ├── config.ru
│ ├── config
│ │ ├── application.rb
│ │ ├── boot.rb
│ │ ├── database.yml
│ │ ├── environment.rb
│ │ ├── environments
│ │ │ ├── development.rb
│ │ │ ├── production.rb
│ │ │ └── test.rb
│ │ ├── initializers
│ │ │ ├── backtrace_silencers.rb
│ │ │ ├── inflections.rb
│ │ │ ├── mime_types.rb
│ │ │ ├── secret_token.rb
│ │ │ ├── session_store.rb
│ │ │ └── wrap_parameters.rb
│ │ ├── locales
│ │ │ └── en.yml
│ │ └── routes.rb
│ ├── db
│ │ └── .gitkeep
│ ├── lib
│ │ └── assets
│ │ │ └── .gitkeep
│ ├── log
│ │ └── .gitkeep
│ ├── public
│ │ ├── 404.html
│ │ ├── 422.html
│ │ ├── 500.html
│ │ └── favicon.ico
│ └── script
│ │ └── rails
├── requirejs-rails_test.rb
└── test_helper.rb
└── vendor
└── assets
└── javascripts
├── almond.js
└── require.js
/.gitignore:
--------------------------------------------------------------------------------
1 | /.ruby-version
2 | /.bundle/
3 | /log/*.log
4 | /pkg/
5 | /test/dummy/db/*.sqlite3
6 | /test/dummy/log/*.log
7 | /test/dummy/tmp/
8 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## requirejs-rails changelog
4 |
5 | ### v1.0.1
6 |
7 |
8 | - Update `require.js` and `r.js` to `2.3.5`, and `almond.js` to `0.3.3`.
9 | - Add `wrapShim` to `build_config_whitelist`.
10 |
11 | ### v1.0.0
12 |
13 | - Update `require.js` and `r.js` to `2.1.22`.
14 | - Fix a `sass-rails` `3.*.*` backwards compatibility issue (credit `@merqlove`).
15 | - Fix a Sprockets `3.3.0` backwards compatibility issue (credit `@swils`).
16 |
17 | ### v0.9.9
18 |
19 | - Fix an asset digesting regression in #238 (credit @jonhyman).
20 | - Update `require.js` and `r.js` to `2.1.19`.
21 |
22 | ### v0.9.8
23 |
24 | - Fix a bad regression and yank v0.9.7.
25 |
26 | ### v0.9.7
27 |
28 | - Fix a corner case where modules could appear in the build config's `paths`.
29 | - Fix regressions introduced in v0.9.6.
30 | - Allow protocol relative urls for CDNs in the build config's `paths` (credit @remybach).
31 |
32 | ### v0.9.6
33 |
34 | - Update `require.js` and `r.js` to `2.1.17`, and `almond.js` to `0.3.1`.
35 | - Improve handling of Bower packages.
36 | - Make a small fix for Sprockets 3 support.
37 |
38 | ### v0.9.5
39 |
40 | - Update `require.js` and `r.js` to `2.1.15`, and `almond.js` to `0.3.0`.
41 | - Remove `data-main` attribute generation from `requirejs_include_tag` and replicate its functionality with an explicit
42 | `require` call. This paves the way for proper almond support.
43 | - Instead of disabling JS compression everywhere, only do so when staging `r.js` input files. This enables `require.js`
44 | itself to be compiled (or not) by the asset pipeline, like any other asset.
45 | - Add support for `bower.json` modules.
46 |
47 | ### v0.9.4
48 |
49 | - Restore compression of non-module JS assets if specified, including `require.js` itself.
50 | - Update `require.js` to `2.1.14`.
51 |
52 | ### v0.9.3
53 |
54 | - Add detection and proper handling of Bower-based modules.
55 | - Update `require.js` to `2.1.11` and `almond.js` to `0.2.9`.
56 |
57 | ### v0.9.2
58 |
59 | - Update `require.js` to `2.1.10` and `almond.js` to `0.2.5`.
60 | - Rails 4 support.
61 |
62 | ### v0.9.1
63 |
64 | - Updated to to require.js \ r.js 2.1.2, and almond 0.2.3
65 |
66 | ### v0.9.0
67 |
68 | - **BREAKING CHANGE**: Upgrade RequireJS and r.js to v2.0.0
69 | - order.js was removed. See the new [RequireJS 2.0 shim config](https://github.com/jrburke/requirejs/wiki/Upgrading-to-RequireJS-2.0#wiki-shim).
70 | - Build support for `empty:` is now handled by r.js 2.0 natively.
71 |
72 | ### v0.8.2
73 |
74 | - Fix for `requirejs_include_tag` error when `config/requirejs.yml` has no
75 | `paths` key. Thanks to @JustinLove for the issue and failing test!
76 |
77 | ### v0.8.0
78 |
79 | - Build will now substitute `empty:` for the right-hand side of
80 | `config/requirejs.yml` paths entries that are URLs.
81 | - Documented how to configure assets hosted on a CDN.
82 |
83 | ### v0.7.3
84 |
85 | - Upgrade RequireJS and r.js to v1.0.8
86 |
87 | ### v0.7.2
88 |
89 | - Add require.js to config.assets.precompile in all environments. Closes #45.
90 | This change allows builds to work in Rails environments other than
91 | 'production', e.g. 'staging'. Thanks to @hollow for the fix.
92 |
93 | ### v0.7.1
94 |
95 | - Liberalize asset path filtering. `0.7.0` added filtering on the logical
96 | asset path which was too aggressive in that only `.js` files were allowed in
97 | builds. The RequireJS config variable `logical_asset_filter` has been
98 | added, which allows `.js`, `.html`, `.txt` files by default and is user
99 | configurable.
100 |
101 | ### v0.7.0
102 |
103 | - Support for [almond](https://github.com/jrburke/almond) via
104 | `config.requirejs.loader = :almond` in application.rb.
105 | - Builds with `config.assets.initialize_on_precompile = false` now work.
106 | This supports building on Heroku, builds with Devise, etc. all of
107 | which require that setting.
108 | - We should now play much better with existing Rails Engines that
109 | leverage the asset pipeline for their needs. Thanks to @hollow for the
110 | patch.
111 |
112 | ### v0.6.1
113 |
114 | - Fix regression in production env when `paths` specified in requirejs.yml.
115 |
116 | ### v0.6.0
117 |
118 | **NOTE:** Upgrade to 0.6.1! This was yanked due to a regression.
119 |
120 | - We now generate a paths config to hit digested assets when needed (in
121 | `production` or when `config.assets.digest` is true). Fixes #20.
122 | - Support for generating additional data attributes on the require.js script
123 | tag via `requirejs_include_tag`. See [README](README.md) for details. Closes
124 | pull request #32; thanks to @hollow for the submission!
125 |
126 | ### v0.5.6
127 |
128 | - Upgrade to RequireJS and r.js 1.0.7
129 |
130 | ### v0.5.5
131 |
132 | - Support for Rails 3.2.x. Rails 3.1.x is also supported by this release.
133 |
134 | ### v0.5.4
135 |
136 | - Upgrade to RequireJS and r.js 1.0.5
137 | - Pull request #31, closes #30. Thanks @karelim!
138 |
139 | ### v0.5.3
140 |
141 | - Upgrade to RequireJS and r.js 1.0.4
142 | - Pulled #22, fix for asset compliation failure with no config/requirejs.yml.
143 | Thanks @arehberg!
144 |
145 | ### v0.5.2
146 |
147 | - Upgrade to RequireJS and r.js 1.0.3
148 |
149 | ### v0.5.1
150 |
151 | - This is a quick turn to fix an issue that could trigger an Anonymous mismatched define() error from require.js and/or r.js.
152 |
153 | The preferred way to use the helper tag is now with an argument, like
154 | so:
155 |
156 | ```erb
157 | <%= requirejs_include_tag "application" %>
158 | ```
159 |
160 | This usage ensures that the above helper will correctly generate a
161 | data-main attribute for the script tag. The requirejs_include_tag
162 | helper still works without an argument, and won't generate data-main
163 | in that case.
164 |
165 | Thanks to Andrew de Andrade for the catch.
166 |
167 | ### v0.5.0
168 |
169 | - Precompilation via `rake assets:precompile` is now implemented.
170 | - gem configuration via application.js is deprecated.
171 | - Application-specific require.js configuration lives in `config/requirejs.yml`.
172 | - See [README](README.md) for updated usage details.
173 |
174 | ### v0.0.2
175 |
176 | - Fixed stupid problems with Rails::Engine instantiation.
177 | - Test improvements
178 | - Upgrade to RequireJS 1.0.2
179 |
180 | ### v0.0.1
181 |
182 | - Birthday!
183 | - This gem makes `require.js` and the `order.js` plugin available to the Rails 3 Asset Pipeline.
184 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "http://rubygems.org"
2 |
3 | # Declare your gem's dependencies in requirejs-rails.gemspec.
4 | # Bundler will treat runtime dependencies like base dependencies, and
5 | # development dependencies will be added by default to the :development group.
6 | gemspec
7 |
8 | group :development, :test do
9 | # jquery-rails is used by the dummy application
10 | gem "jquery-rails"
11 |
12 | # ExecJS is used by our tests
13 | gem "execjs"
14 | end
15 |
16 | # Declare any dependencies that are still in development here instead of in
17 | # your gemspec. These might include edge Rails or gems from your path or
18 | # Git. Remember to move these dependencies to your gemspec before releasing
19 | # your gem to rubygems.org.
20 |
21 | # To use debugger
22 | # gem 'ruby-debug19', :require => 'ruby-debug'
23 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | PATH
2 | remote: .
3 | specs:
4 | requirejs-rails (1.0.1)
5 | railties (>= 3.1.1)
6 |
7 | GEM
8 | remote: http://rubygems.org/
9 | specs:
10 | actionmailer (4.2.1)
11 | actionpack (= 4.2.1)
12 | actionview (= 4.2.1)
13 | activejob (= 4.2.1)
14 | mail (~> 2.5, >= 2.5.4)
15 | rails-dom-testing (~> 1.0, >= 1.0.5)
16 | actionpack (4.2.1)
17 | actionview (= 4.2.1)
18 | activesupport (= 4.2.1)
19 | rack (~> 1.6)
20 | rack-test (~> 0.6.2)
21 | rails-dom-testing (~> 1.0, >= 1.0.5)
22 | rails-html-sanitizer (~> 1.0, >= 1.0.1)
23 | actionview (4.2.1)
24 | activesupport (= 4.2.1)
25 | builder (~> 3.1)
26 | erubis (~> 2.7.0)
27 | rails-dom-testing (~> 1.0, >= 1.0.5)
28 | rails-html-sanitizer (~> 1.0, >= 1.0.1)
29 | activejob (4.2.1)
30 | activesupport (= 4.2.1)
31 | globalid (>= 0.3.0)
32 | activemodel (4.2.1)
33 | activesupport (= 4.2.1)
34 | builder (~> 3.1)
35 | activerecord (4.2.1)
36 | activemodel (= 4.2.1)
37 | activesupport (= 4.2.1)
38 | arel (~> 6.0)
39 | activesupport (4.2.1)
40 | i18n (~> 0.7)
41 | json (~> 1.7, >= 1.7.7)
42 | minitest (~> 5.1)
43 | thread_safe (~> 0.3, >= 0.3.4)
44 | tzinfo (~> 1.1)
45 | arel (6.0.0)
46 | builder (3.2.2)
47 | erubis (2.7.0)
48 | execjs (2.5.2)
49 | globalid (0.3.5)
50 | activesupport (>= 4.1.0)
51 | i18n (0.7.0)
52 | jquery-rails (4.0.3)
53 | rails-dom-testing (~> 1.0)
54 | railties (>= 4.2.0)
55 | thor (>= 0.14, < 2.0)
56 | json (1.8.6)
57 | loofah (2.0.1)
58 | nokogiri (>= 1.5.9)
59 | mail (2.6.3)
60 | mime-types (>= 1.16, < 3)
61 | mime-types (2.5)
62 | mini_portile (0.6.2)
63 | minitest (5.6.1)
64 | nokogiri (1.6.6.2)
65 | mini_portile (~> 0.6.0)
66 | rack (1.6.0)
67 | rack-test (0.6.3)
68 | rack (>= 1.0)
69 | rails (4.2.1)
70 | actionmailer (= 4.2.1)
71 | actionpack (= 4.2.1)
72 | actionview (= 4.2.1)
73 | activejob (= 4.2.1)
74 | activemodel (= 4.2.1)
75 | activerecord (= 4.2.1)
76 | activesupport (= 4.2.1)
77 | bundler (>= 1.3.0, < 2.0)
78 | railties (= 4.2.1)
79 | sprockets-rails
80 | rails-deprecated_sanitizer (1.0.3)
81 | activesupport (>= 4.2.0.alpha)
82 | rails-dom-testing (1.0.6)
83 | activesupport (>= 4.2.0.beta, < 5.0)
84 | nokogiri (~> 1.6.0)
85 | rails-deprecated_sanitizer (>= 1.0.1)
86 | rails-html-sanitizer (1.0.2)
87 | loofah (~> 2.0)
88 | railties (4.2.1)
89 | actionpack (= 4.2.1)
90 | activesupport (= 4.2.1)
91 | rake (>= 0.8.7)
92 | thor (>= 0.18.1, < 2.0)
93 | rake (10.4.2)
94 | sprockets (3.0.3)
95 | rack (~> 1.0)
96 | sprockets-rails (2.2.4)
97 | actionpack (>= 3.0)
98 | activesupport (>= 3.0)
99 | sprockets (>= 2.8, < 4.0)
100 | sqlite3 (1.3.10)
101 | thor (0.19.1)
102 | thread_safe (0.3.5)
103 | tzinfo (1.2.2)
104 | thread_safe (~> 0.1)
105 |
106 | PLATFORMS
107 | ruby
108 |
109 | DEPENDENCIES
110 | execjs
111 | jquery-rails
112 | rails (>= 3.1.1)
113 | requirejs-rails!
114 | sqlite3
115 |
116 | BUNDLED WITH
117 | 1.16.0
118 |
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2011 John Whitley
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
4 | # RequireJS for Rails
5 |
6 | Integrates [RequireJS](http://requirejs.org/) into the Rails 3+ Asset Pipeline.
7 |
8 | **UPGRADE NOTES:** Users upgrading within the 0.x series should read the Changes section for relevant usage changes. We're pushing hard to 1.0, when the configuration and setup details will be declared stable. Until that time expect some bumps as things bake out.
9 |
10 | ## Usage
11 |
12 | 1. Add this to your Rails app's `Gemfile`:
13 |
14 | ```
15 | gem 'requirejs-rails'
16 | ```
17 |
18 | 2. Remove all Sprockets directives such as `//= require jquery` from `application.js` and elsewhere. Instead establish JavaScript dependencies using AMD-style `define()` and `require()` calls.
19 |
20 | 3. Use `requirejs_include_tag` at the top-level of your app's layout(s). Other modules will be pulled in dynamically by `require.js` in development and for production builds optimized by `r.js`. Here's a basic `app/views/layouts/application.html.erb` modified for `requirejs-rails`:
21 |
22 | ```erb
23 |
24 |
25 |
26 | Frobnitz Online
27 | <%= stylesheet_link_tag "application" %>
28 | <%= requirejs_include_tag "application" %>
29 | <%= csrf_meta_tags %>
30 |
31 |
32 |
33 |
34 | <%= yield %>
35 |
36 |
37 |
38 | ```
39 |
40 | 4. Organize your JavaScript or CoffeeScript code into modules using `define()`:
41 |
42 | ```coffeescript
43 | # app/assets/javascripts/views/tweet_view.js.coffee
44 |
45 | define ['backbone'], (Backbone) ->
46 | class TweetView extends Backbone.View
47 | # ...
48 | ```
49 |
50 | 5. Instantiate your app using `require()` from a top-level module such as `application.js`:
51 |
52 | ```coffeescript
53 | # app/assets/javascripts/application.js.coffee
54 |
55 | require ['jquery', 'backbone', 'TheApp'], ($, Backbone, TheApp) ->
56 |
57 | # Start up the app once the DOM is ready
58 | $ ->
59 | window.App = new TheApp()
60 | Backbone.history.start
61 | pushState: true
62 | window.App.start()
63 | ```
64 |
65 | 6. When ready, build your assets for production deployment as usual.
66 | `requirejs-rails` defaults to a single-file build of `application.js`.
67 | Additional modules and r.js layered builds may be specified via
68 | `config/requirejs.yml`; see the Configuration section below.
69 |
70 | ```rake assets:precompile```
71 |
72 | ## Configuration
73 |
74 | ### The Basics
75 |
76 | Configuration lives in `config/requirejs.yml`. These values are inspected and
77 | used by `requirejs-rails` and passed along as configuration for require.js and
78 | `r.js`. The default configuration declares `application.js` as the sole
79 | top-level module. This can be overridden by creating
80 | a `config/requirejs.yml`, such as:
81 |
82 | ```yaml
83 | modules:
84 | - name: 'mytoplevel'
85 | ```
86 |
87 | You may pass in [require.js config
88 | options](http://requirejs.org/docs/api.html#config) as needed. For example,
89 | to add path parameters:
90 |
91 | ```yaml
92 | paths:
93 | d3: "d3/d3"
94 | "d3.time": "d3/d3.time"
95 | ```
96 |
97 | ### Layered builds
98 |
99 | Only modules specified in the configuration will be created as build artifacts
100 | by `r.js`. [Layered r.js
101 | builds](http://requirejs.org/docs/faq-optimization.html#priority) be
102 | configured like so:
103 |
104 | ```yaml
105 | modules:
106 | - name: 'appcommon'
107 | - name: 'page1'
108 | exclude: ['appcommon']
109 | - name: 'page2'
110 | exclude: ['appcommon']
111 | priority: ['appcommon']
112 | ```
113 |
114 | In this example, only modules `page1` and `page2` are intended for direct
115 | loading via `requirejs_include_tag`. The `appcommon` module contains
116 | dependencies shared by the per-page modules. As a guideline, each module in
117 | the configuration should be referenced by one of:
118 |
119 | - A `requirejs_include_tag` in a template
120 | - Pulled in via a dynamic `require()` call. Modules which are solely
121 | referenced by a dynamic `require()` call (i.e. a call not optimized by r.js)
122 | **must** be specified in the modules section in order to produce a correct
123 | build.
124 | - Be a common library module like `appcommon`, listed in the `priority` config
125 | option.
126 |
127 | ### Almond support
128 |
129 | This gem supports single-file builds with
130 | [almond](https://github.com/jrburke/almond). Use the following setting in
131 | `application.rb` to enable it:
132 |
133 | ```ruby
134 | config.requirejs.loader = :almond
135 | ```
136 |
137 | Almond builds have the restriction that there must be exactly one `modules` entry in
138 | `requirejs.yml`. Typically the [wrap option](https://github.com/jrburke/r.js/blob/master/build/example.build.js#L275) will be used to create a self-contained build:
139 |
140 | ```yaml
141 | modules:
142 | - name: 'main'
143 | wrap: true
144 | ```
145 |
146 | ### Build-time asset filter
147 |
148 | The `requirejs-rails` build process uses the Asset Pipeline to assemble assets
149 | for the `r.js` build. By default, assets ending in `.js`, `.html`, and `.txt`
150 | will be made available to the build. If you have other asset suffixes to
151 | include, use the `logical_path_patterns` config setting to add them.
152 |
153 | For example, if your templates all end in `.templ` like so...
154 |
155 | ```javascript
156 | // in app/assets/javascripts/myapp.js
157 | define(function (require) {
158 | var stuff = require('text!stuff.templ');
159 | // ...
160 | });
161 | ```
162 |
163 | ... then this config setting will ensure they're picked up in the build:
164 |
165 | ```ruby
166 | # in config/application.rb
167 | config.requirejs.logical_path_patterns += [/\.templ$/]
168 | ```
169 |
170 | ## Advanced features
171 |
172 | ### Additional data attributes
173 |
174 | `requirejs_include_tag` accepts an optional block which should return a hash.
175 | This hash will be used to populate additional `data-...` attributes like so:
176 |
177 | ```erb
178 | <%= requirejs_include_tag "page1" do |controller|
179 | { 'foo' => controller.foo,
180 | 'bar' => controller.bar
181 | }
182 | end
183 | %>
184 | ```
185 |
186 | This will generate a script tag like so:
187 |
188 | ```
189 |
190 | ```
191 |
192 | ### External domain (CDN) support
193 |
194 | There are two ways in which requirejs-rails supports the use of different
195 | domains for serving built JavaScript modules, as is the case when using
196 | a [CDN](http://en.wikipedia.org/wiki/Content_delivery_network).
197 |
198 | 1. URLs in paths config in `requirejs.yml`:
199 |
200 | If requirejs-rails encounters an URL as the right-hand side of a paths
201 | configuration, it will correctly emit that as `"empty:"` during the build
202 | process so that [r.js will do the right thing](http://requirejs.org/docs/optimization.html#empty).
203 |
204 | Example:
205 |
206 | ```yaml
207 | paths:
208 | jquery: "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"
209 | ```
210 |
211 | 2. Deploying all requirejs-rails assets to a CDN:
212 |
213 | In `config/environments/production.rb` (or another environment)
214 | set the run_config as follows:
215 |
216 | ```ruby
217 | config.requirejs.run_config['baseUrl'] = 'http://mycdn.example.com/12345abc/assets'
218 | ```
219 |
220 | The [`asset_sync` gem](https://github.com/rumblelabs/asset_sync) is one
221 | tool that can be used to deploy your built assets to a CDN (S3, in this
222 | case).
223 |
224 | ## Troubleshooting
225 |
226 | ### Avoid `config.assets.precompile`
227 |
228 | Don't set `config.assets.precompile` to reference any of your AMD module code.
229 | Avoid it altogether, except to reference non-AMD code that you're loading via
230 | javascript_include_tag, and which is **never** referenced by the AMD codebase.
231 |
232 | ## Using AMD libraries
233 |
234 | I currently recommend placing your AMD libraries into
235 | `vendor/assets/javascripts`. The needs of a few specific libraries are
236 | discussed below.
237 |
238 | ### jQuery
239 |
240 | jQuery users must use jQuery 1.7 or later (`jquery-rails >= 1.0.17`) to use it as an [AMD module](https://github.com/amdjs/amdjs-api/wiki/AMD) with RequireJS. To use jQuery in a module:
241 |
242 | ```coffeescript
243 | # app/assets/javascripts/hello.js
244 |
245 | define ['jquery'], ($) ->
246 | (id) ->
247 | $(id).append('hello!
')
248 | ```
249 |
250 | ### Backbone.js
251 |
252 | Backbone 0.9.x doesn't support AMD natively. I recommend the [amdjs
253 | fork of Backbone](https://github.com/amdjs/backbone/) which adds AMD
254 | support and actively tracks mainline.
255 |
256 | ### Underscore.js
257 |
258 | Underscore 1.3.x likewise doesn't have AMD support. Again, see
259 | the [amdjs fork of Underscore](https://github.com/amdjs/underscore).
260 |
261 | ## 0.x API Changes
262 |
263 | Usage changes that may break functionality for those upgrading along the 0.x
264 | series are documented here. See [the Changelog](https://github.com/jwhitley/requirejs-rails/blob/master/CHANGELOG.md) for the full
265 | list of feature additions, bugfixes, etc.
266 |
267 | ### v0.9.2
268 |
269 | - Support for Rails 4.
270 |
271 | ### v0.9.0
272 |
273 | - The upgrade to RequireJS and r.js 2.0 includes changes that will break some
274 | apps.
275 |
276 | ### v0.5.1
277 |
278 | - `requirejs_include_tag` now generates a data-main attribute if given an argument, ala:
279 |
280 | ```erb
281 | <%= requirejs_include_tag "application" %>
282 | ```
283 |
284 | This usage is preferred to using a separate
285 | `javascript_include_tag`, which will produce errors from require.js or
286 | r.js if the included script uses define anonymously, or not at all.
287 |
288 | ### v0.5.0
289 |
290 | - `application.js` is configured as the default top-level module for r.js builds.
291 | - It is no longer necessary or desirable to specify `baseUrl` explicitly in the configuration.
292 | - Users should migrate application configuration previously in `application.js` (ala `require.config(...)`) to `config/requirejs.yml`
293 |
294 |
295 |
296 | ## TODOs
297 |
298 | Please check out [our GitHub issues page](https://github.com/jwhitley/requirejs-rails/issues)
299 | to see what's upcoming and to file feature requests and bug reports.
300 |
301 | ----
302 |
303 | Copyright 2011-2014 John Whitley. See the file MIT-LICENSE for terms.
304 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env rake
2 | begin
3 | require 'bundler/setup'
4 | rescue LoadError
5 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6 | end
7 | begin
8 | require 'rdoc/task'
9 | rescue LoadError
10 | require 'rdoc/rdoc'
11 | require 'rake/rdoctask'
12 | RDoc::Task = Rake::RDocTask
13 | end
14 |
15 | RDoc::Task.new(:rdoc) do |rdoc|
16 | rdoc.rdoc_dir = 'rdoc'
17 | rdoc.title = 'RequirejsRails'
18 | rdoc.options << '--line-numbers'
19 | rdoc.rdoc_files.include('README.rdoc')
20 | rdoc.rdoc_files.include('lib/**/*.rb')
21 | end
22 |
23 |
24 |
25 | Bundler::GemHelper.install_tasks
26 |
27 | require 'rake/testtask'
28 |
29 | Rake::TestTask.new(:test) do |t|
30 | t.libs << 'lib'
31 | t.libs << 'test'
32 | t.pattern = 'test/**/*_test.rb'
33 | t.verbose = false
34 | end
35 |
36 |
37 | task :default => :test
38 |
--------------------------------------------------------------------------------
/app/helpers/requirejs_helper.rb:
--------------------------------------------------------------------------------
1 | require "requirejs/error"
2 | require "requirejs/rails/view"
3 |
4 | module RequirejsHelper
5 | def self.included(clazz)
6 | clazz.class_eval do
7 | extend Forwardable
8 |
9 | # Delegate all JavaScript path queries to the specially modified internal view.
10 | def_delegators :view, :javascript_path
11 | end
12 | end
13 |
14 | # EXPERIMENTAL: Additional priority settings appended to
15 | # any user-specified priority setting by requirejs_include_tag.
16 | # Used for JS test suite integration.
17 | mattr_accessor :_priority
18 | @@_priority = []
19 |
20 | def requirejs_include_tag(name = nil, &block)
21 | requirejs = Rails.application.config.requirejs
22 |
23 | if requirejs.loader == :almond
24 | name = requirejs.module_name_for(requirejs.build_config['modules'][0])
25 | return almond_include_tag(name, &block)
26 | end
27 |
28 | html = ""
29 |
30 | once_guard do
31 | rjs_attributes = {
32 | src: [host_url, javascript_path("require")].join
33 | }
34 |
35 | rjs_attributes = rjs_attributes.merge(Hash[block.call(controller).map do |key, value|
36 | ["data-#{key}", value]
37 | end]) \
38 | if block
39 |
40 | html.concat(content_tag(:script, "", rjs_attributes))
41 |
42 | unless requirejs.run_config.empty?
43 | run_config = requirejs.run_config.dup
44 |
45 | unless _priority.empty?
46 | run_config = run_config.dup
47 | run_config[:priority] ||= []
48 | run_config[:priority].concat _priority
49 | end
50 |
51 | if Rails.application.config.assets.digest
52 | assets_precompiled = !Rails.application.config.assets.compile
53 | modules = requirejs.build_config["modules"].map {|m| requirejs.module_name_for m}
54 | user_paths = requirejs.build_config["paths"] || {}
55 |
56 | # Generate digestified paths from the modules spec
57 | paths = {}
58 |
59 | modules.each do |module_name|
60 | script_path = if !assets_precompiled
61 | # If modules haven't been precompiled, search for them based on their user-defined paths before using the
62 | # module name.
63 | user_paths[module_name] || module_name
64 | else
65 | # If modules have been precompiled, the script path is just the module name.
66 | module_name
67 | end
68 |
69 | normalized_script_path = javascript_path(script_path).gsub(/\.js$/, "")
70 |
71 | if !host_url
72 | paths[module_name] = normalized_script_path
73 | else
74 | paths[module_name] = [host_url, normalized_script_path].join
75 | end
76 | end
77 |
78 | if run_config.has_key? "paths"
79 | # Add paths for assets specified by full URL (on a CDN)
80 | run_config["paths"].each do |k, v|
81 | paths[k] = v if v.is_a?(Array) || v =~ /^(https?:)?\/\//
82 | end
83 | end
84 |
85 | # Override user paths, whose mappings are only relevant in dev mode
86 | # and in the build_config.
87 | run_config["paths"] = paths
88 | end
89 |
90 | run_config["baseUrl"] = [host_url, Rails.application.config.assets.prefix].join
91 |
92 | html.concat(content_tag(:script) do
93 | script = "require.config(#{run_config.to_json});"
94 |
95 | # Pass an array to `require`, since it's a top-level module about to be loaded asynchronously (see
96 | # `http://requirejs.org/docs/errors.html#notloaded`).
97 | script.concat(" require([#{name.dump}]);") \
98 | if name
99 |
100 | script.html_safe
101 | end)
102 | end
103 |
104 | html.html_safe
105 | end
106 | end
107 |
108 | private
109 |
110 | def once_guard
111 | if defined?(controller) && controller.requirejs_included
112 | raise Requirejs::MultipleIncludeError, "Only one requirejs_include_tag allowed per page."
113 | end
114 |
115 | retval = yield
116 |
117 | controller.requirejs_included = true if defined?(controller)
118 | retval
119 | end
120 |
121 | def almond_include_tag(name, &block)
122 | content_tag(:script, "", src: [host_url, javascript_path(name)].join)
123 | end
124 |
125 | # Retrieve where the assets are hosted. Assume the root path if `nil`.
126 | def host_url
127 | config = Rails.application.config
128 | action_controller_config = config.action_controller
129 | asset_host = action_controller_config.asset_host
130 |
131 | @host_url ||= if !asset_host
132 | action_controller_config.relative_url_root
133 | else
134 | asset_host
135 | end
136 | end
137 |
138 | def view
139 | @view ||= Requirejs::Rails::View.new
140 | end
141 | end
142 |
--------------------------------------------------------------------------------
/lib/requirejs-rails.rb:
--------------------------------------------------------------------------------
1 | require "requirejs/rails"
2 |
--------------------------------------------------------------------------------
/lib/requirejs/error.rb:
--------------------------------------------------------------------------------
1 | module Requirejs
2 | # Raised if requirejs_include_tag appears multiple times on a page.
3 | class MultipleIncludeError < RuntimeError; end
4 | # Raised if the configuration fails validation.
5 | class ConfigError < ArgumentError; end
6 | # Raised if the builder encounters an error.
7 | class BuildError < RuntimeError; end
8 | end
9 |
--------------------------------------------------------------------------------
/lib/requirejs/rails.rb:
--------------------------------------------------------------------------------
1 | module Requirejs
2 | module Rails
3 | require "requirejs/rails/engine"
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/lib/requirejs/rails/builder.rb:
--------------------------------------------------------------------------------
1 | require "ostruct"
2 | require "pathname"
3 |
4 | require "requirejs/rails"
5 |
6 | module Requirejs
7 | module Rails
8 | class Builder
9 | def initialize(config)
10 | @config = config
11 | end
12 |
13 | def build
14 | @config.tmp_dir
15 | end
16 |
17 | def generate_rjs_driver
18 | templ = Erubis::Eruby.new(@config.driver_template_path.read)
19 | @config.driver_path.open('w') do |f|
20 | f.write(templ.result(@config.get_binding))
21 | end
22 | end
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/lib/requirejs/rails/config.rb:
--------------------------------------------------------------------------------
1 | require "pathname"
2 |
3 | require "active_support/ordered_options"
4 | require "erubis"
5 |
6 | require "requirejs/error"
7 | require "requirejs/rails"
8 |
9 | module Requirejs
10 | module Rails
11 | class Config < ::ActiveSupport::OrderedOptions
12 | LOADERS = [:requirejs, :almond]
13 |
14 | BOWER_PATH_PATTERN = Regexp.new("\\A(.*)/(?:\\.bower|bower|component)\\.json\\z")
15 |
16 | LOGICAL_PATH_PATTERNS = [
17 | Regexp.new("\\.html\\z"),
18 | Regexp.new("\\.js\\z"),
19 | Regexp.new("\\.es6\\z"),
20 | Regexp.new("\\.txt\\z"),
21 | BOWER_PATH_PATTERN
22 | ]
23 |
24 | def initialize(application)
25 | super
26 |
27 | self.manifest = nil
28 | self.logical_path_patterns = LOGICAL_PATH_PATTERNS
29 |
30 | self.tmp_dir = application.root + 'tmp'
31 | self.bin_dir = Pathname.new(__FILE__ + '/../../../../bin').cleanpath
32 |
33 | self.source_dir = self.tmp_dir.join("requirejs/src")
34 | self.build_dir = self.tmp_dir.join("requirejs/dst")
35 |
36 | # This will be instantiated in the engine's `before_initialize` hook, because its default value is derived from
37 | # the app's configuration.
38 | self.target_dir = nil
39 |
40 | self.rjs_path = self.bin_dir + 'r.js'
41 |
42 | self.loader = :requirejs
43 |
44 | self.driver_template_path = Pathname.new(__FILE__ + '/../rjs_driver.js.erb').cleanpath
45 | self.driver_path = self.tmp_dir.join("requirejs/rjs_driver.js")
46 |
47 | self.user_config = {}
48 |
49 | self.run_config_whitelist = %w{
50 | baseUrl
51 | callback
52 | catchError
53 | config
54 | context
55 | deps
56 | jQuery
57 | locale
58 | map
59 | packages
60 | paths
61 | priority
62 | scriptType
63 | shim
64 | urlArgs
65 | waitSeconds
66 | xhtml
67 | }
68 |
69 | self.build_config_whitelist = %w{
70 | appDir
71 | baseUrl
72 | closure
73 | cssImportIgnore
74 | cssIn
75 | dir
76 | fileExclusionRegExp
77 | findNestedDependencies
78 | has
79 | hasOnSave
80 | include
81 | inlineText
82 | locale
83 | mainConfigFile
84 | map
85 | modules
86 | name
87 | namespace
88 | onBuildRead
89 | onBuildWrite
90 | optimize
91 | optimizeAllPluginResources
92 | optimizeCss
93 | out
94 | packagePaths
95 | packages
96 | paths
97 | pragmas
98 | pragmasOnSave
99 | preserveLicenseComments
100 | shim
101 | skipModuleInsertion
102 | skipPragmas
103 | uglify
104 | uglify2
105 | useStrict
106 | wrap
107 | wrapShim
108 | }
109 | end
110 |
111 | def loader=(sym)
112 | unless LOADERS.include?(sym)
113 | raise Requirejs::ConfigError, "Attempt to set unknown loader: #{sym}"
114 | end
115 | self[:loader] = sym
116 | end
117 |
118 | def build_config
119 | unless self.has_key?(:build_config)
120 | self[:build_config] = self.run_config.merge "baseUrl" => source_dir.to_s,
121 | "modules" => [{'name' => 'application'}]
122 | self[:build_config].merge!(self.user_config).slice!(*self.build_config_whitelist)
123 | case self.loader
124 | when :requirejs
125 | # nothing to do
126 | when :almond
127 | mods = self[:build_config]['modules']
128 | unless mods.length == 1
129 | raise Requirejs::ConfigError, "Almond build requires exactly one module, config has #{mods.length}."
130 | end
131 | mod = mods[0]
132 | name = mod['name']
133 | mod['name'] = 'almond'
134 | mod['include'] = name
135 | end
136 | end
137 | self[:build_config]
138 | end
139 |
140 | def run_config
141 | unless self.has_key?(:run_config)
142 | self[:run_config] = {"baseUrl" => "/assets"}
143 | self[:run_config].merge!(self.user_config).slice!(*self.run_config_whitelist)
144 | end
145 | self[:run_config]
146 | end
147 |
148 | def user_config=(cfg)
149 | if url = cfg.delete('baseUrl')
150 | raise Requirejs::ConfigError, "baseUrl is not needed or permitted in the configuration"
151 | end
152 | self[:user_config] = cfg
153 | end
154 |
155 | def module_name_for(mod)
156 | case self.loader
157 | when :almond
158 | return mod['include']
159 | when :requirejs
160 | return mod['name']
161 | end
162 | end
163 |
164 | def get_binding
165 | return binding()
166 | end
167 | end
168 | end
169 | end
170 |
--------------------------------------------------------------------------------
/lib/requirejs/rails/engine.rb:
--------------------------------------------------------------------------------
1 | require "pathname"
2 |
3 | require "requirejs/rails/config"
4 | require "requirejs/rails/view"
5 |
6 | module Requirejs
7 | module Rails
8 | class Engine < ::Rails::Engine
9 | ### Configuration setup
10 | config.before_configuration do |app|
11 | config.requirejs = Requirejs::Rails::Config.new(app)
12 | config.requirejs.precompile = [/require\.js$/]
13 | end
14 |
15 | config.before_initialize do |app|
16 | config = app.config
17 |
18 | # Process the user config file in #before_initalization (instead of #before_configuration) so that
19 | # environment-specific configuration can be injected into the user configuration file
20 | Engine.process_user_config_file(app, config)
21 |
22 | config.assets.precompile += config.requirejs.precompile
23 |
24 | # Check for the `requirejs:precompile:all` top-level Rake task and run the following initialization code.
25 | if defined?(Rake.application) && Rake.application.top_level_tasks == ["requirejs:precompile:all"]
26 | # Prevent Sprockets from freezing the assets environment, which allows JS compression to be toggled on a per-
27 | # file basis. This trick *will* fail if any of the lines linked to below change.
28 |
29 | if ::Rails::VERSION::MAJOR >= 4
30 | # For Rails 4 (see
31 | # `https://github.com/rails/sprockets-rails/blob/v2.1.2/lib/sprockets/railtie.rb#L119-121`).
32 | config.cache_classes = false
33 | else
34 | # For Rails 3 (see
35 | # `https://github.com/rails/rails/blob/v3.2.19/actionpack/lib/sprockets/bootstrap.rb#L32-34`).
36 | config.assets.digest = false
37 | end
38 | end
39 |
40 | manifest_directory = if config.assets.manifest
41 | File.basename(config.assets.manifest) =~ /\./ ? File.dirname(config.assets.manifest) : config.assets.manifest
42 | else
43 | File.join(::Rails.public_path, config.assets.prefix)
44 | end
45 |
46 | manifest_path = File.join(manifest_directory, "rjs_manifest.yml")
47 | config.requirejs.manifest_path = Pathname.new(manifest_path)
48 |
49 | config.requirejs.target_dir ||= app.root + "public" +
50 | Pathname.new(config.assets.prefix).relative_path_from(Pathname.new("/"))
51 | end
52 |
53 | ### Initializers
54 | initializer "requirejs.tag_included_state" do |app|
55 | ActiveSupport.on_load(:action_controller) do
56 | ::ActionController::Base.class_eval do
57 | attr_accessor :requirejs_included
58 | end
59 | end
60 | end
61 |
62 | # Are we running in the precompilation Rake task? If so, we need to adjust certain environmental configuration
63 | # values.
64 | if defined?(Rake.application) && Rake.application.top_level_tasks.include?("requirejs:precompile:all")
65 | initializer "requirejs.modify_environment_config", after: "load_environment_config", group: :all do |app|
66 | app.configure do
67 | # If we don't set this to true, sprockets-rails will assign `Rails.application.assets` to `nil`.
68 | config.assets.compile = true
69 |
70 | # Don't compress JavaScripts fed into the r.js optimizer.
71 | config.assets.js_compressor = false
72 |
73 | # Don't use any cache to retrieve assets.
74 | config.assets.cache = nil
75 | end
76 | end
77 | end
78 |
79 | if ::Rails::VERSION::MAJOR >= 4
80 | config.after_initialize do |app|
81 | config = app.config
82 | if config.requirejs.manifest_path.exist?
83 | rails_manifest = ::Sprockets::Railtie.build_manifest(app)
84 | rjs_digests = YAML.load(ERB.new(File.new(config.requirejs.manifest_path).read).result)
85 | rails_manifest.assets.merge!(rjs_digests)
86 | ActionView::Base.instance_eval do
87 | self.assets_manifest = rails_manifest
88 | end
89 | end
90 |
91 | # This allows requirejs-rails to serve up modules by their undigestified asset paths.
92 | Requirejs::Rails::View.instance_eval do
93 | self.check_precompiled_asset = false
94 | end
95 | end
96 | else
97 | initializer "requirejs.manifest", :after => "sprockets.environment" do |app|
98 | config = app.config
99 | if config.requirejs.manifest_path.exist? && config.assets.digests
100 | rjs_digests = YAML.load(ERB.new(File.new(config.requirejs.manifest_path).read).result)
101 | config.assets.digests.merge!(rjs_digests)
102 | end
103 | end
104 | end
105 |
106 | # Process the user-supplied config parameters, which will be
107 | # merged with the default params. It should be a YAML file with
108 | # a single top-level hash, keys/values corresponding to require.js
109 | # config parameters.
110 | def self.process_user_config_file(app, config)
111 | config_path = Pathname.new(app.paths["config"].first)
112 | config.requirejs.user_config_file = config_path + 'requirejs.yml'
113 |
114 | yaml_file_contents = nil
115 | if config.requirejs.user_config_file.exist?
116 | yaml_file_contents = config.requirejs.user_config_file.read
117 | else
118 | # if requirejs.yml doesn't exist, look for requirejs.yml.erb and process it as an erb
119 | config.requirejs.user_config_file = config_path + 'requirejs.yml.erb'
120 |
121 | if config.requirejs.user_config_file.exist?
122 | yaml_file_contents = ERB.new(config.requirejs.user_config_file.read).result
123 | end
124 | end
125 |
126 | if yaml_file_contents.nil?
127 | # If we couldn't find any matching file contents to process, empty user config
128 | config.requirejs.user_config = {}
129 | else
130 | config.requirejs.user_config = YAML.load(yaml_file_contents)
131 | end
132 | end
133 | end # class Engine
134 | end
135 | end
136 |
--------------------------------------------------------------------------------
/lib/requirejs/rails/rjs_driver.js.erb:
--------------------------------------------------------------------------------
1 | var requirejs = require(<%= rjs_path.to_s.dump %>)
2 | var baseConfig = <%=
3 | cdn_pattern = Regexp.new("\\Ahttps?://")
4 |
5 | modifiedHash = build_config.select { |k, _| k != "modules" }
6 | pathsHash = modifiedHash["paths"]
7 |
8 | case loader
9 | when :requirejs
10 | modifiedHash['dir'] = build_dir.to_s
11 | when :almond
12 | almond_module = build_config['modules'][0]
13 | modifiedHash.merge!(almond_module)
14 | modifiedHash['out'] = build_dir + (module_name_for(almond_module) + '.js')
15 | end
16 |
17 | modifiedHash["paths"] = Hash[
18 | pathsHash.map do |k, v|
19 | [k, v.is_a?(Array) || cdn_pattern.match(v) ? "empty:" : v]
20 | end
21 | ] if !pathsHash.nil?
22 |
23 | JSON.pretty_generate(modifiedHash)
24 | %>;
25 |
26 | <% unless loader == :almond %>
27 | baseConfig.modules = [
28 | <% build_config["modules"].each do |m| %>
29 | <%= JSON.pretty_generate(m) %>,
30 | <% end %>
31 | ];
32 | <% end %>
33 |
34 | requirejs.optimize(baseConfig);
35 |
--------------------------------------------------------------------------------
/lib/requirejs/rails/version.rb:
--------------------------------------------------------------------------------
1 | module Requirejs
2 | module Rails
3 | Version = "1.0.1"
4 | LibVersion = "2.1.22"
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/lib/requirejs/rails/view.rb:
--------------------------------------------------------------------------------
1 | module Requirejs
2 | module Rails
3 | class View < ::ActionView::Base
4 | end
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/lib/tasks/requirejs-rails_tasks.rake:
--------------------------------------------------------------------------------
1 | require "fileutils"
2 | require "pathname"
3 | require "tempfile"
4 |
5 | require "active_support/ordered_options"
6 | require "sprockets"
7 |
8 | require "requirejs/rails/builder"
9 | require "requirejs/rails/config"
10 |
11 | namespace :requirejs do
12 | # This method was backported from an earlier version of Sprockets.
13 | def ruby_rake_task(task, force = true)
14 | env = ENV["RAILS_ENV"] || "production"
15 | groups = ENV["RAILS_GROUPS"] || "assets"
16 | args = [$0, task, "RAILS_ENV=#{env}", "RAILS_GROUPS=#{groups}"]
17 | args << "--trace" if Rake.application.options.trace
18 | ruby *args
19 | end
20 |
21 | # From Rails 3 assets.rake; we have the same problem:
22 | #
23 | # We are currently running with no explicit bundler group
24 | # and/or no explicit environment - we have to reinvoke rake to
25 | # execute this task.
26 | def invoke_or_reboot_rake_task(task)
27 | if ENV['RAILS_GROUPS'].to_s.empty? || ENV['RAILS_ENV'].to_s.empty?
28 | ruby_rake_task task
29 | else
30 | Rake::Task[task].invoke
31 | end
32 | end
33 |
34 | requirejs = ActiveSupport::OrderedOptions.new
35 | path_extension_pattern = Regexp.new("\\.(\\w+)\\z")
36 |
37 | task clean: ["requirejs:setup"] do
38 | FileUtils.remove_entry_secure(requirejs.config.source_dir, true)
39 | FileUtils.remove_entry_secure(requirejs.driver_path, true)
40 | end
41 |
42 | task setup: ["assets:environment"] do
43 | unless defined?(::Sprockets)
44 | warn "Cannot precompile assets if sprockets is disabled. Please set config.assets.enabled to true"
45 | exit
46 | end
47 |
48 | # Ensure that action view is loaded and the appropriate
49 | # sprockets hooks get executed
50 | _ = ActionView::Base
51 |
52 | requirejs.env = Rails.application.assets
53 |
54 | # Preserve the original asset paths, as we'll be manipulating them later
55 | requirejs.env_paths = requirejs.env.paths.dup
56 | requirejs.config = Rails.application.config.requirejs
57 | requirejs.builder = Requirejs::Rails::Builder.new(requirejs.config)
58 | requirejs.manifest = {}
59 | end
60 |
61 | task :test_node do
62 | begin
63 | `node -v`
64 | rescue Errno::ENOENT
65 | STDERR.puts <<-EOM
66 | Unable to find 'node' on the current path, required for precompilation
67 | using the requirejs-ruby gem. To install node.js, see http://nodejs.org/
68 | OS X Homebrew users can use 'brew install node'.
69 | EOM
70 | exit 1
71 | end
72 | end
73 |
74 | namespace :precompile do
75 | task all: ["requirejs:precompile:digestify_and_compress"]
76 |
77 | # Invoke another ruby process if we're called from inside
78 | # assets:precompile so we don't clobber the environment
79 | #
80 | # We depend on test_node here so we'll fail early and hard if node
81 | # isn't available.
82 | task :external do
83 | ruby_rake_task "requirejs:precompile:all"
84 | end
85 |
86 | # Copy all assets to the temporary staging directory.
87 | task prepare_source: ["requirejs:setup",
88 | "requirejs:clean"] do
89 | requirejs.config.source_dir.mkpath
90 |
91 | requirejs.env.each_logical_path(requirejs.config.logical_path_patterns) do |logical_path|
92 | m = ::Requirejs::Rails::Config::BOWER_PATH_PATTERN.match(logical_path)
93 |
94 | if !m
95 | asset = requirejs.env.find_asset(logical_path)
96 |
97 | if asset
98 | file = requirejs.config.source_dir.join(asset.logical_path)
99 | file.dirname.mkpath
100 | asset.write_to(file)
101 | end
102 | else
103 | bower_logical_path = "#{Pathname.new(logical_path).dirname.to_s}.js"
104 | asset = requirejs.env.find_asset(bower_logical_path)
105 |
106 | if asset
107 | file = requirejs.config.source_dir.join(bower_logical_path)
108 | file.dirname.mkpath
109 | asset.write_to(file)
110 | end
111 | end
112 | end
113 | end
114 |
115 | task generate_rjs_driver: ["requirejs:setup"] do
116 | requirejs.builder.generate_rjs_driver
117 | end
118 |
119 | task run_rjs: ["requirejs:setup",
120 | "requirejs:test_node",
121 | "requirejs:precompile:prepare_source",
122 | "requirejs:precompile:generate_rjs_driver"] do
123 | requirejs.config.build_dir.mkpath
124 | requirejs.config.target_dir.mkpath
125 | requirejs.config.driver_path.dirname.mkpath
126 |
127 | result = `node "#{requirejs.config.driver_path}"`
128 | unless $?.success?
129 | raise RuntimeError, "Asset compilation with node failed with error:\n\n#{result}\n"
130 | end
131 | end
132 |
133 | # Copy each built asset, identified by a named module in the
134 | # build config, to its Sprockets digestified name.
135 | task digestify_and_compress: ["requirejs:precompile:run_rjs"] do
136 | requirejs.config.build_config["modules"].each do |m|
137 | module_name = requirejs.config.module_name_for(m)
138 | paths = requirejs.config.build_config["paths"] || {}
139 | module_script_name = "#{module_name}.js"
140 |
141 | # Is there a `paths` entry for the module?
142 | if !paths[module_name]
143 | asset_name = module_script_name
144 | else
145 | asset_name = "#{paths[module_name]}.js"
146 | end
147 |
148 | asset = requirejs.env.find_asset(asset_name)
149 |
150 | built_asset_path = requirejs.config.build_dir.join(asset_name)
151 |
152 | # Compute the digest based on the contents of the compiled file, *not* on the contents of the RequireJS module.
153 | file_digest = requirejs.env.file_digest(built_asset_path.to_s)
154 | hex_digest = file_digest.unpack("H*").first
155 | digest_name = asset.logical_path.gsub(path_extension_pattern) { |ext| "-#{hex_digest}#{ext}" }
156 |
157 | digest_asset_path = requirejs.config.target_dir + digest_name
158 |
159 | # Ensure that the parent directory `a/b` for modules with names like `a/b/c` exist.
160 | digest_asset_path.dirname.mkpath
161 |
162 | requirejs.manifest[module_script_name] = digest_name
163 | FileUtils.cp built_asset_path, digest_asset_path
164 |
165 | # Create the compressed versions
166 | File.open("#{built_asset_path}.gz", 'wb') do |f|
167 | zgw = Zlib::GzipWriter.new(f, Zlib::BEST_COMPRESSION)
168 | zgw.write built_asset_path.read
169 | zgw.close
170 | end
171 | FileUtils.cp "#{built_asset_path}.gz", "#{digest_asset_path}.gz"
172 |
173 | manifest_path = requirejs.config.manifest_path
174 | manifest_path.dirname.mkpath
175 |
176 | manifest_path.open('wb') do |f|
177 | YAML.dump(requirejs.manifest, f)
178 | end
179 | end
180 | end
181 | end
182 |
183 | desc "Precompile RequireJS-managed assets"
184 | task :precompile do
185 | invoke_or_reboot_rake_task "requirejs:precompile:all"
186 | end
187 | end
188 |
189 | task "assets:precompile" => ["requirejs:precompile:external"]
190 |
--------------------------------------------------------------------------------
/requirejs-rails.gemspec:
--------------------------------------------------------------------------------
1 | $:.push File.expand_path("../lib", __FILE__)
2 |
3 | # Maintain your gem's version:
4 | require "requirejs/rails/version"
5 |
6 | # Describe your gem and declare its dependencies:
7 | Gem::Specification.new do |s|
8 | s.name = "requirejs-rails"
9 | s.version = Requirejs::Rails::Version
10 | s.authors = ["John Whitley"]
11 | s.email = ["whitley@bangpath.org"]
12 | s.homepage = "http://github.com/jwhitley/requirejs-rails"
13 | s.summary = "Use RequireJS with the Rails 3+ Asset Pipeline"
14 | s.description = "This gem provides RequireJS support for your Rails 3 application."
15 |
16 | git_test_files, git_files = `git ls-files`.split("\n").partition { |f| f =~ /^test/ }
17 | s.test_files = git_test_files
18 | s.files = git_files
19 | s.require_path = 'lib'
20 |
21 | s.add_dependency "railties", ">= 3.1.1"
22 | s.add_development_dependency "rails", ">= 3.1.1"
23 | s.add_development_dependency "sqlite3"
24 |
25 | s.requirements << "node.js is required for 'rake assets:precompile', used to run the r.js build"
26 | s.requirements << "If needed, jQuery should be v1.7 or greater (jquery-rails >= 1.0.17)."
27 | end
28 |
--------------------------------------------------------------------------------
/test/dummy/.rvmrc:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # This is an RVM Project .rvmrc file, used to automatically load the ruby
4 | # development environment upon cd'ing into the directory
5 |
6 | # First we specify our desired [@], the @gemset name is optional.
7 | environment_id="ruby-1.9.3-p0@requirejs-rails"
8 |
9 | #
10 | # Uncomment following line if you want options to be set only for given project.
11 | #
12 | # PROJECT_JRUBY_OPTS=( --1.9 )
13 |
14 | #
15 | # First we attempt to load the desired environment directly from the environment
16 | # file. This is very fast and efficient compared to running through the entire
17 | # CLI and selector. If you want feedback on which environment was used then
18 | # insert the word 'use' after --create as this triggers verbose mode.
19 | #
20 | if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \
21 | && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]]
22 | then
23 | \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id"
24 |
25 | if [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]]
26 | then
27 | . "${rvm_path:-$HOME/.rvm}/hooks/after_use"
28 | fi
29 | else
30 | # If the environment file has not yet been created, use the RVM CLI to select.
31 | if ! rvm --create use "$environment_id"
32 | then
33 | echo "Failed to create RVM environment '${environment_id}'."
34 | return 1
35 | fi
36 | fi
37 |
38 | #
39 | # If you use an RVM gemset file to install a list of gems (*.gems), you can have
40 | # it be automatically loaded. Uncomment the following and adjust the filename if
41 | # necessary.
42 | #
43 | # filename=".gems"
44 | # if [[ -s "$filename" ]]
45 | # then
46 | # rvm gemset import "$filename" | grep -v already | grep -v listed | grep -v complete | sed '/^$/d'
47 | # fi
48 |
49 | # If you use bundler, this might be useful to you:
50 | # if command -v bundle && [[ -s Gemfile ]]
51 | # then
52 | # bundle install
53 | # fi
54 |
55 |
56 |
--------------------------------------------------------------------------------
/test/dummy/Rakefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env rake
2 | # Add your own tasks in files placed in lib/tasks ending in .rake,
3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4 |
5 | require File.expand_path('../config/application', __FILE__)
6 |
7 | Dummy::Application.load_tasks
8 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/javascripts/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into including all the files listed below.
2 | // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3 | // be included in the compiled file accessible from http://example.com/assets/application.js
4 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5 | // the compiled file.
6 | //
7 | //= require jquery
8 | //= require jquery_ujs
9 | //= require_tree .
10 |
--------------------------------------------------------------------------------
/test/dummy/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll automatically include all the stylesheets available in this directory
3 | * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4 | * the top of the compiled file, but it's generally better to create a new file per style scope.
5 | *= require_self
6 | *= require_tree .
7 | */
--------------------------------------------------------------------------------
/test/dummy/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | protect_from_forgery
3 | end
4 |
--------------------------------------------------------------------------------
/test/dummy/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | end
3 |
--------------------------------------------------------------------------------
/test/dummy/app/mailers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jwhitley/requirejs-rails/7a05a81d35f862becb859b5a8dd6968fb02da4d1/test/dummy/app/mailers/.gitkeep
--------------------------------------------------------------------------------
/test/dummy/app/models/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jwhitley/requirejs-rails/7a05a81d35f862becb859b5a8dd6968fb02da4d1/test/dummy/app/models/.gitkeep
--------------------------------------------------------------------------------
/test/dummy/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Dummy
5 | <%= stylesheet_link_tag "application" %>
6 | <%= javascript_include_tag "application" %>
7 | <%= csrf_meta_tags %>
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/test/dummy/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require ::File.expand_path('../config/environment', __FILE__)
4 | run Dummy::Application
5 |
--------------------------------------------------------------------------------
/test/dummy/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require 'rails/all'
4 |
5 | Bundler.require
6 | require "requirejs-rails"
7 |
8 | module Dummy
9 | class Application < Rails::Application
10 | # Settings in config/environments/* take precedence over those specified here.
11 | # Application configuration should go into files in config/initializers
12 | # -- all .rb files in that directory are automatically loaded.
13 |
14 | # Custom directories with classes and modules you want to be autoloadable.
15 | # config.autoload_paths += %W(#{config.root}/extras)
16 |
17 | # Only load the plugins named here, in the order given (default is alphabetical).
18 | # :all can be used as a placeholder for all plugins not explicitly named.
19 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
20 |
21 | # Activate observers that should always be running.
22 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
23 |
24 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
25 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
26 | # config.time_zone = 'Central Time (US & Canada)'
27 |
28 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
29 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
30 | # config.i18n.default_locale = :de
31 |
32 | # Configure the default encoding used in templates for Ruby 1.9.
33 | config.encoding = "utf-8"
34 |
35 | # Configure sensitive parameters which will be filtered from the log file.
36 | config.filter_parameters += [:password]
37 |
38 | # Enable the asset pipeline
39 | config.assets.enabled = true
40 |
41 | # Version of your assets, change this if you want to expire all your assets
42 | config.assets.version = '1.0'
43 | end
44 | end
45 |
46 |
--------------------------------------------------------------------------------
/test/dummy/config/boot.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | gemfile = File.expand_path('../../../../Gemfile', __FILE__)
3 |
4 | if File.exist?(gemfile)
5 | ENV['BUNDLE_GEMFILE'] = gemfile
6 | require 'bundler'
7 | Bundler.setup
8 | end
9 |
10 | $:.unshift File.expand_path('../../../../lib', __FILE__)
--------------------------------------------------------------------------------
/test/dummy/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite version 3.x
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem 'sqlite3'
6 | development:
7 | adapter: sqlite3
8 | database: db/development.sqlite3
9 | pool: 5
10 | timeout: 5000
11 |
12 | # Warning: The database defined as "test" will be erased and
13 | # re-generated from your development database when you run "rake".
14 | # Do not set this db to the same as development or production.
15 | test:
16 | adapter: sqlite3
17 | database: db/test.sqlite3
18 | pool: 5
19 | timeout: 5000
20 |
21 | production:
22 | adapter: sqlite3
23 | database: db/production.sqlite3
24 | pool: 5
25 | timeout: 5000
26 |
--------------------------------------------------------------------------------
/test/dummy/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the rails application
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the rails application
5 | Dummy::Application.initialize!
6 |
--------------------------------------------------------------------------------
/test/dummy/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # In the development environment your application's code is reloaded on
5 | # every request. This slows down response time but is perfect for development
6 | # since you don't have to restart the web server when you make code changes.
7 | config.cache_classes = false
8 |
9 | # Log error messages when you accidentally call methods on nil.
10 | config.whiny_nils = true
11 |
12 | # Show full error reports and disable caching
13 | config.consider_all_requests_local = true
14 | config.action_controller.perform_caching = false
15 |
16 | # Don't care if the mailer can't send
17 | config.action_mailer.raise_delivery_errors = false
18 |
19 | # Print deprecation notices to the Rails logger
20 | config.active_support.deprecation = :log
21 |
22 | # Only use best-standards-support built into browsers
23 | config.action_dispatch.best_standards_support = :builtin
24 |
25 | # Do not compress assets
26 | config.assets.compress = false
27 |
28 | # Expands the lines which load the assets
29 | config.assets.debug = true
30 | end
31 |
--------------------------------------------------------------------------------
/test/dummy/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # Code is not reloaded between requests
5 | config.cache_classes = true
6 |
7 | # Full error reports are disabled and caching is turned on
8 | config.consider_all_requests_local = false
9 | config.action_controller.perform_caching = true
10 |
11 | # Disable Rails's static asset server (Apache or nginx will already do this)
12 | config.serve_static_assets = false
13 |
14 | # Compress JavaScripts and CSS
15 | config.assets.compress = true
16 |
17 | # Don't fallback to assets pipeline if a precompiled asset is missed
18 | config.assets.compile = false
19 |
20 | # Generate digests for assets URLs
21 | config.assets.digest = true
22 |
23 | # Defaults to Rails.root.join("public/assets")
24 | # config.assets.manifest = YOUR_PATH
25 |
26 | # Specifies the header that your server uses for sending files
27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
29 |
30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
31 | # config.force_ssl = true
32 |
33 | # See everything in the log (default is :info)
34 | # config.log_level = :debug
35 |
36 | # Use a different logger for distributed setups
37 | # config.logger = SyslogLogger.new
38 |
39 | # Use a different cache store in production
40 | # config.cache_store = :mem_cache_store
41 |
42 | # Enable serving of images, stylesheets, and JavaScripts from an asset server
43 | # config.action_controller.asset_host = "http://assets.example.com"
44 |
45 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
46 | # config.assets.precompile += %w( search.js )
47 |
48 | # Disable delivery errors, bad email addresses will be ignored
49 | # config.action_mailer.raise_delivery_errors = false
50 |
51 | # Enable threaded mode
52 | # config.threadsafe!
53 |
54 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
55 | # the I18n.default_locale when a translation can not be found)
56 | config.i18n.fallbacks = true
57 |
58 | # Send deprecation notices to registered listeners
59 | config.active_support.deprecation = :notify
60 | end
61 |
--------------------------------------------------------------------------------
/test/dummy/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Configure static asset server for tests with Cache-Control for performance
11 | config.serve_static_assets = true
12 | config.static_cache_control = "public, max-age=3600"
13 |
14 | # Log error messages when you accidentally call methods on nil
15 | config.whiny_nils = true
16 |
17 | # Show full error reports and disable caching
18 | config.consider_all_requests_local = true
19 | config.action_controller.perform_caching = false
20 |
21 | # Raise exceptions instead of rendering exception templates
22 | config.action_dispatch.show_exceptions = false
23 |
24 | # Disable request forgery protection in test environment
25 | config.action_controller.allow_forgery_protection = false
26 |
27 | # Tell Action Mailer not to deliver emails to the real world.
28 | # The :test delivery method accumulates sent emails in the
29 | # ActionMailer::Base.deliveries array.
30 | config.action_mailer.delivery_method = :test
31 |
32 | # Use SQL instead of Active Record's schema dumper when creating the test database.
33 | # This is necessary if your schema can't be completely dumped by the schema dumper,
34 | # like if you have constraints or database-specific column types
35 | # config.active_record.schema_format = :sql
36 |
37 | # Print deprecation notices to the stderr
38 | config.active_support.deprecation = :stderr
39 | end
40 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format
4 | # (all these examples are active by default):
5 | # ActiveSupport::Inflector.inflections do |inflect|
6 | # inflect.plural /^(ox)$/i, '\1en'
7 | # inflect.singular /^(ox)en/i, '\1'
8 | # inflect.irregular 'person', 'people'
9 | # inflect.uncountable %w( fish sheep )
10 | # end
11 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 | # Mime::Type.register_alias "text/html", :iphone
6 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/secret_token.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 | # Make sure the secret is at least 30 characters and all random,
6 | # no regular words or you'll be exposed to dictionary attacks.
7 | Dummy::Application.config.secret_token = '770fc7d4cb239b6e3f6399c51932d715eeed2454c2f3a044a3740f5c26a8d521beeb9fe6141a5567f01775a5da3d7dff7cab75d7ba3b034c4a5638ab329bdc44'
8 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
4 |
5 | # Use the database for sessions instead of the cookie-based default,
6 | # which shouldn't be used to store highly confidential information
7 | # (create the session table with "rails generate session_migration")
8 | # Dummy::Application.config.session_store :active_record_store
9 |
--------------------------------------------------------------------------------
/test/dummy/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 | #
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json]
9 | end
10 |
11 | # Disable root element in JSON by default.
12 | ActiveSupport.on_load(:active_record) do
13 | self.include_root_in_json = false
14 | end
15 |
--------------------------------------------------------------------------------
/test/dummy/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Sample localization file for English. Add more files in this directory for other locales.
2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3 |
4 | en:
5 | hello: "Hello world"
6 |
--------------------------------------------------------------------------------
/test/dummy/config/routes.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.routes.draw do
2 | # The priority is based upon order of creation:
3 | # first created -> highest priority.
4 |
5 | # Sample of regular route:
6 | # match 'products/:id' => 'catalog#view'
7 | # Keep in mind you can assign values other than :controller and :action
8 |
9 | # Sample of named route:
10 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
11 | # This route can be invoked with purchase_url(:id => product.id)
12 |
13 | # Sample resource route (maps HTTP verbs to controller actions automatically):
14 | # resources :products
15 |
16 | # Sample resource route with options:
17 | # resources :products do
18 | # member do
19 | # get 'short'
20 | # post 'toggle'
21 | # end
22 | #
23 | # collection do
24 | # get 'sold'
25 | # end
26 | # end
27 |
28 | # Sample resource route with sub-resources:
29 | # resources :products do
30 | # resources :comments, :sales
31 | # resource :seller
32 | # end
33 |
34 | # Sample resource route with more complex sub-resources
35 | # resources :products do
36 | # resources :comments
37 | # resources :sales do
38 | # get 'recent', :on => :collection
39 | # end
40 | # end
41 |
42 | # Sample resource route within a namespace:
43 | # namespace :admin do
44 | # # Directs /admin/products/* to Admin::ProductsController
45 | # # (app/controllers/admin/products_controller.rb)
46 | # resources :products
47 | # end
48 |
49 | # You can have the root of your site routed with "root"
50 | # just remember to delete public/index.html.
51 | # root :to => 'welcome#index'
52 |
53 | # See how all your routes lay out with "rake routes"
54 |
55 | # This is a legacy wild controller route that's not recommended for RESTful applications.
56 | # Note: This route will make all actions in every controller accessible via GET requests.
57 | # match ':controller(/:action(/:id(.:format)))'
58 | end
59 |
--------------------------------------------------------------------------------
/test/dummy/db/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jwhitley/requirejs-rails/7a05a81d35f862becb859b5a8dd6968fb02da4d1/test/dummy/db/.gitkeep
--------------------------------------------------------------------------------
/test/dummy/lib/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jwhitley/requirejs-rails/7a05a81d35f862becb859b5a8dd6968fb02da4d1/test/dummy/lib/assets/.gitkeep
--------------------------------------------------------------------------------
/test/dummy/log/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jwhitley/requirejs-rails/7a05a81d35f862becb859b5a8dd6968fb02da4d1/test/dummy/log/.gitkeep
--------------------------------------------------------------------------------
/test/dummy/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
The page you were looking for doesn't exist.
23 |
You may have mistyped the address or the page may have moved.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/dummy/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
The change you wanted was rejected.
23 |
Maybe you tried to change something you didn't have access to.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/dummy/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
We're sorry, but something went wrong.
23 |
We've been notified about this issue and we'll take a look at it shortly.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/dummy/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jwhitley/requirejs-rails/7a05a81d35f862becb859b5a8dd6968fb02da4d1/test/dummy/public/favicon.ico
--------------------------------------------------------------------------------
/test/dummy/script/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3 |
4 | APP_PATH = File.expand_path('../../config/application', __FILE__)
5 | require File.expand_path('../../config/boot', __FILE__)
6 | require 'rails/commands'
7 |
--------------------------------------------------------------------------------
/test/requirejs-rails_test.rb:
--------------------------------------------------------------------------------
1 | require 'test_helper'
2 |
3 | require 'execjs'
4 | require 'pathname'
5 |
6 | class RequirejsRailsTest < ActiveSupport::TestCase
7 | test "truth" do
8 | assert_kind_of Module, Requirejs
9 | assert_kind_of Module, Requirejs::Rails
10 | assert_kind_of Class, Requirejs::Rails::Engine
11 | end
12 |
13 | test "require.js version" do
14 | require_js = Pathname.new(__FILE__+'/../../vendor/assets/javascripts/require.js').cleanpath.read
15 | context = ExecJS.compile(require_js)
16 | assert_equal Requirejs::Rails::LibVersion, context.eval("require.version")
17 | end
18 |
19 | test "CHANGELOG up to date" do
20 | changelog_match = (/^### v#{Requirejs::Rails::Version}/ =~ Pathname.new(__FILE__+'/../../CHANGELOG.md').cleanpath.read)
21 | assert changelog_match, "CHANGELOG has no section for v#{Requirejs::Rails::Version}"
22 | end
23 | end
24 |
25 | class RequirejsRailsConfigTest < ActiveSupport::TestCase
26 | def setup
27 | @cfg = Requirejs::Rails::Config.new(Rails.application)
28 | end
29 |
30 | def asset_allowed?(asset_path)
31 | !!@cfg.logical_path_patterns.find do |logical_path_pattern|
32 | logical_path_pattern.match(asset_path)
33 | end
34 | end
35 |
36 | test "config accepts known loaders" do
37 | @cfg.loader = :almond
38 | assert_equal :almond, @cfg.loader
39 | end
40 |
41 | test "config rejects bad loaders" do
42 | assert_raises Requirejs::ConfigError do
43 | @cfg.loader = :wombat
44 | end
45 | end
46 |
47 | test "matches configured logical assets" do
48 | assert_equal true, asset_allowed?("foo.js")
49 | assert_equal false, asset_allowed?("bar.frobnitz")
50 | @cfg.logical_path_patterns.push(Regexp.new("\\.frobnitz\\z"))
51 | assert_equal true, asset_allowed?("bar.frobnitz")
52 | end
53 |
54 | test "should have a default empty user_config" do
55 | assert_kind_of Hash, @cfg.user_config
56 | end
57 |
58 | test "user_config should reject baseUrl" do
59 | exc = assert_raises Requirejs::ConfigError do
60 | @cfg.user_config = {'baseUrl' => '/frobnitz'}
61 | end
62 | assert_match /baseUrl is not needed/, exc.message
63 | end
64 |
65 | test "run_config should inherit user_config settings" do
66 | @cfg.user_config = {'paths' => {'jquery' => 'lib/jquery-1.7.2.min'}}
67 | refute_nil @cfg.run_config['paths']
68 | assert_kind_of Hash, @cfg.run_config['paths']
69 | assert_equal 'lib/jquery-1.7.2.min', @cfg.run_config['paths']['jquery']
70 | end
71 |
72 | test "run_config should allow settings to be overridden" do
73 | @cfg.run_config['baseUrl'] = 'http://cdn.example.com/assets'
74 | assert_equal 'http://cdn.example.com/assets', @cfg.run_config['baseUrl']
75 | end
76 |
77 | test "build_config should inherit user_config settings" do
78 | @cfg.user_config = {'paths' => {'jquery' => 'lib/jquery-1.7.2.min'}}
79 | refute_nil @cfg.build_config['paths']
80 | assert_kind_of Hash, @cfg.build_config['paths']
81 | assert_equal 'lib/jquery-1.7.2.min', @cfg.build_config['paths']['jquery']
82 | end
83 |
84 | test "run_config should reject irrelevant settings" do
85 | @cfg.user_config = {'optimize' => 'none'}
86 | assert_nil @cfg.run_config['optimize']
87 | end
88 |
89 | test "build_config should reject irrelevant settings" do
90 | @cfg.user_config = {'priority' => %w{ foo bar baz }}
91 | assert_nil @cfg.build_config['priority']
92 | end
93 |
94 | ## Almond tests
95 | test "build_config with almond should accept one module" do
96 | @cfg.loader = :almond
97 | @cfg.user_config = {'modules' => [{'name' => 'foo'}]}
98 | assert_match 'almond', @cfg.build_config['modules'][0]['name']
99 | end
100 |
101 | test "build_config with almond must reject more than one module" do
102 | @cfg.loader = :almond
103 | @cfg.user_config = {'modules' => [{'name' => 'foo'}, {'name' => 'bar'}]}
104 | exc = assert_raises Requirejs::ConfigError do
105 | @cfg.build_config
106 | end
107 | assert_match /requires exactly one module/, exc.message
108 | end
109 | end
110 |
111 | class RequirejsHelperTest < ActionView::TestCase
112 | def setup
113 | controller.requirejs_included = false
114 | Rails.application.config.requirejs.user_config = {}
115 | Rails.application.config.requirejs.delete(:run_config)
116 | Rails.application.config.requirejs.delete(:build_config)
117 | end
118 |
119 | def with_cdn(protocol_relative = false)
120 | Rails.application.config.requirejs.user_config = {
121 | "paths" => {
122 | "jquery" => "#{ protocol_relative ? '' : 'http:' }//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"
123 | }
124 | }
125 | end
126 |
127 | def wrap(tag)
128 | "#{tag}"
129 | end
130 |
131 | test "requirejs_include_tag" do
132 | render text: wrap(requirejs_include_tag)
133 |
134 | assert_select "script:first-of-type[src=\"/javascripts/require.js\"]", count: 1
135 | assert_select "script:last-of-type", text: "require.config({\"baseUrl\":\"/assets\"});"
136 | end
137 |
138 | test "requirejs_include_tag_with_param" do
139 | render text: wrap(requirejs_include_tag("application"))
140 |
141 | assert_select "script:first-of-type[src=\"/javascripts/require.js\"]", count: 1
142 | end
143 |
144 | test "requirejs_include_tag_with_block" do
145 | result = wrap(
146 | requirejs_include_tag("application") do
147 | {"class" => controller.class.name.demodulize}
148 | end
149 | )
150 |
151 | render text: result
152 |
153 | assert_select "script:first-of-type[src=\"/javascripts/require.js\"]" \
154 | "[data-class=\"TestController\"]", count: 1
155 | end
156 |
157 | test "requirejs_include_tag can appear only once" do
158 | assert_raises Requirejs::MultipleIncludeError do
159 | requirejs_include_tag
160 | requirejs_include_tag
161 | end
162 | end
163 |
164 | test "requirejs_include_tag with digestified asset paths" do
165 | begin
166 | Rails.application.config.requirejs.user_config = {
167 | "modules" => [
168 | {"name" => "foo"}
169 | ]
170 | }
171 |
172 | saved_digest = Rails.application.config.assets.digest
173 | Rails.application.config.assets.digest = true
174 |
175 | render text: wrap(requirejs_include_tag)
176 |
177 | assert_select "script:last-of-type",
178 | text: Regexp.new("\\Arequire\\.config\\({.*\"paths\":{.*\"foo\":\"/javascripts/foo\".*}.*}\\);\\z")
179 | ensure
180 | Rails.application.config.assets.digest = saved_digest
181 | end
182 | end
183 |
184 | test "requirejs_include_tag with CDN asset in paths" do
185 | with_cdn
186 |
187 | render text: wrap(requirejs_include_tag)
188 |
189 | assert_select "script:last-of-type",
190 | text: Regexp.new("\\Arequire\\.config\\({.*\"paths\":{.*\"http://ajax\\..*\".*}.*}\\);\\z")
191 | end
192 |
193 | test "requirejs_include_tag with CDN asset and digestified asset paths" do
194 | begin
195 | with_cdn
196 |
197 | saved_digest = Rails.application.config.assets.digest
198 | Rails.application.config.assets.digest = true
199 |
200 | render text: wrap(requirejs_include_tag)
201 |
202 | assert_select "script:last-of-type",
203 | text: Regexp.new("\\Arequire\\.config\\({.*\"paths\":{.*\"http://ajax\\..*\".*}.*}\\);\\z")
204 | ensure
205 | Rails.application.config.assets.digest = saved_digest
206 | end
207 | end
208 |
209 | test "requirejs_include_tag with protocol relative CDN asset in paths" do
210 | with_cdn(true)
211 |
212 | render text: wrap(requirejs_include_tag)
213 |
214 | assert_select "script:last-of-type",
215 | text: Regexp.new("\\Arequire\\.config\\({.*\"paths\":{.*\"//ajax\\..*\".*}.*}\\);\\z")
216 | end
217 | end
218 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # Configure Rails Environment
2 | ENV["RAILS_ENV"] = "test"
3 |
4 | require File.expand_path("../dummy/config/environment.rb", __FILE__)
5 | require "rails/test_help"
6 |
7 | Rails.backtrace_cleaner.remove_silencers!
8 |
9 | # Load support files
10 | Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
11 |
--------------------------------------------------------------------------------
/vendor/assets/javascripts/almond.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
3 | * Released under MIT license, http://github.com/requirejs/almond/LICENSE
4 | */
5 | //Going sloppy to avoid 'use strict' string cost, but strict practices should
6 | //be followed.
7 | /*global setTimeout: false */
8 |
9 | var requirejs, require, define;
10 | (function (undef) {
11 | var main, req, makeMap, handlers,
12 | defined = {},
13 | waiting = {},
14 | config = {},
15 | defining = {},
16 | hasOwn = Object.prototype.hasOwnProperty,
17 | aps = [].slice,
18 | jsSuffixRegExp = /\.js$/;
19 |
20 | function hasProp(obj, prop) {
21 | return hasOwn.call(obj, prop);
22 | }
23 |
24 | /**
25 | * Given a relative module name, like ./something, normalize it to
26 | * a real name that can be mapped to a path.
27 | * @param {String} name the relative name
28 | * @param {String} baseName a real name that the name arg is relative
29 | * to.
30 | * @returns {String} normalized name
31 | */
32 | function normalize(name, baseName) {
33 | var nameParts, nameSegment, mapValue, foundMap, lastIndex,
34 | foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
35 | baseParts = baseName && baseName.split("/"),
36 | map = config.map,
37 | starMap = (map && map['*']) || {};
38 |
39 | //Adjust any relative paths.
40 | if (name) {
41 | name = name.split('/');
42 | lastIndex = name.length - 1;
43 |
44 | // If wanting node ID compatibility, strip .js from end
45 | // of IDs. Have to do this here, and not in nameToUrl
46 | // because node allows either .js or non .js to map
47 | // to same file.
48 | if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
49 | name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
50 | }
51 |
52 | // Starts with a '.' so need the baseName
53 | if (name[0].charAt(0) === '.' && baseParts) {
54 | //Convert baseName to array, and lop off the last part,
55 | //so that . matches that 'directory' and not name of the baseName's
56 | //module. For instance, baseName of 'one/two/three', maps to
57 | //'one/two/three.js', but we want the directory, 'one/two' for
58 | //this normalization.
59 | normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
60 | name = normalizedBaseParts.concat(name);
61 | }
62 |
63 | //start trimDots
64 | for (i = 0; i < name.length; i++) {
65 | part = name[i];
66 | if (part === '.') {
67 | name.splice(i, 1);
68 | i -= 1;
69 | } else if (part === '..') {
70 | // If at the start, or previous value is still ..,
71 | // keep them so that when converted to a path it may
72 | // still work when converted to a path, even though
73 | // as an ID it is less than ideal. In larger point
74 | // releases, may be better to just kick out an error.
75 | if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
76 | continue;
77 | } else if (i > 0) {
78 | name.splice(i - 1, 2);
79 | i -= 2;
80 | }
81 | }
82 | }
83 | //end trimDots
84 |
85 | name = name.join('/');
86 | }
87 |
88 | //Apply map config if available.
89 | if ((baseParts || starMap) && map) {
90 | nameParts = name.split('/');
91 |
92 | for (i = nameParts.length; i > 0; i -= 1) {
93 | nameSegment = nameParts.slice(0, i).join("/");
94 |
95 | if (baseParts) {
96 | //Find the longest baseName segment match in the config.
97 | //So, do joins on the biggest to smallest lengths of baseParts.
98 | for (j = baseParts.length; j > 0; j -= 1) {
99 | mapValue = map[baseParts.slice(0, j).join('/')];
100 |
101 | //baseName segment has config, find if it has one for
102 | //this name.
103 | if (mapValue) {
104 | mapValue = mapValue[nameSegment];
105 | if (mapValue) {
106 | //Match, update name to the new value.
107 | foundMap = mapValue;
108 | foundI = i;
109 | break;
110 | }
111 | }
112 | }
113 | }
114 |
115 | if (foundMap) {
116 | break;
117 | }
118 |
119 | //Check for a star map match, but just hold on to it,
120 | //if there is a shorter segment match later in a matching
121 | //config, then favor over this star map.
122 | if (!foundStarMap && starMap && starMap[nameSegment]) {
123 | foundStarMap = starMap[nameSegment];
124 | starI = i;
125 | }
126 | }
127 |
128 | if (!foundMap && foundStarMap) {
129 | foundMap = foundStarMap;
130 | foundI = starI;
131 | }
132 |
133 | if (foundMap) {
134 | nameParts.splice(0, foundI, foundMap);
135 | name = nameParts.join('/');
136 | }
137 | }
138 |
139 | return name;
140 | }
141 |
142 | function makeRequire(relName, forceSync) {
143 | return function () {
144 | //A version of a require function that passes a moduleName
145 | //value for items that may need to
146 | //look up paths relative to the moduleName
147 | var args = aps.call(arguments, 0);
148 |
149 | //If first arg is not require('string'), and there is only
150 | //one arg, it is the array form without a callback. Insert
151 | //a null so that the following concat is correct.
152 | if (typeof args[0] !== 'string' && args.length === 1) {
153 | args.push(null);
154 | }
155 | return req.apply(undef, args.concat([relName, forceSync]));
156 | };
157 | }
158 |
159 | function makeNormalize(relName) {
160 | return function (name) {
161 | return normalize(name, relName);
162 | };
163 | }
164 |
165 | function makeLoad(depName) {
166 | return function (value) {
167 | defined[depName] = value;
168 | };
169 | }
170 |
171 | function callDep(name) {
172 | if (hasProp(waiting, name)) {
173 | var args = waiting[name];
174 | delete waiting[name];
175 | defining[name] = true;
176 | main.apply(undef, args);
177 | }
178 |
179 | if (!hasProp(defined, name) && !hasProp(defining, name)) {
180 | throw new Error('No ' + name);
181 | }
182 | return defined[name];
183 | }
184 |
185 | //Turns a plugin!resource to [plugin, resource]
186 | //with the plugin being undefined if the name
187 | //did not have a plugin prefix.
188 | function splitPrefix(name) {
189 | var prefix,
190 | index = name ? name.indexOf('!') : -1;
191 | if (index > -1) {
192 | prefix = name.substring(0, index);
193 | name = name.substring(index + 1, name.length);
194 | }
195 | return [prefix, name];
196 | }
197 |
198 | //Creates a parts array for a relName where first part is plugin ID,
199 | //second part is resource ID. Assumes relName has already been normalized.
200 | function makeRelParts(relName) {
201 | return relName ? splitPrefix(relName) : [];
202 | }
203 |
204 | /**
205 | * Makes a name map, normalizing the name, and using a plugin
206 | * for normalization if necessary. Grabs a ref to plugin
207 | * too, as an optimization.
208 | */
209 | makeMap = function (name, relParts) {
210 | var plugin,
211 | parts = splitPrefix(name),
212 | prefix = parts[0],
213 | relResourceName = relParts[1];
214 |
215 | name = parts[1];
216 |
217 | if (prefix) {
218 | prefix = normalize(prefix, relResourceName);
219 | plugin = callDep(prefix);
220 | }
221 |
222 | //Normalize according
223 | if (prefix) {
224 | if (plugin && plugin.normalize) {
225 | name = plugin.normalize(name, makeNormalize(relResourceName));
226 | } else {
227 | name = normalize(name, relResourceName);
228 | }
229 | } else {
230 | name = normalize(name, relResourceName);
231 | parts = splitPrefix(name);
232 | prefix = parts[0];
233 | name = parts[1];
234 | if (prefix) {
235 | plugin = callDep(prefix);
236 | }
237 | }
238 |
239 | //Using ridiculous property names for space reasons
240 | return {
241 | f: prefix ? prefix + '!' + name : name, //fullName
242 | n: name,
243 | pr: prefix,
244 | p: plugin
245 | };
246 | };
247 |
248 | function makeConfig(name) {
249 | return function () {
250 | return (config && config.config && config.config[name]) || {};
251 | };
252 | }
253 |
254 | handlers = {
255 | require: function (name) {
256 | return makeRequire(name);
257 | },
258 | exports: function (name) {
259 | var e = defined[name];
260 | if (typeof e !== 'undefined') {
261 | return e;
262 | } else {
263 | return (defined[name] = {});
264 | }
265 | },
266 | module: function (name) {
267 | return {
268 | id: name,
269 | uri: '',
270 | exports: defined[name],
271 | config: makeConfig(name)
272 | };
273 | }
274 | };
275 |
276 | main = function (name, deps, callback, relName) {
277 | var cjsModule, depName, ret, map, i, relParts,
278 | args = [],
279 | callbackType = typeof callback,
280 | usingExports;
281 |
282 | //Use name if no relName
283 | relName = relName || name;
284 | relParts = makeRelParts(relName);
285 |
286 | //Call the callback to define the module, if necessary.
287 | if (callbackType === 'undefined' || callbackType === 'function') {
288 | //Pull out the defined dependencies and pass the ordered
289 | //values to the callback.
290 | //Default to [require, exports, module] if no deps
291 | deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
292 | for (i = 0; i < deps.length; i += 1) {
293 | map = makeMap(deps[i], relParts);
294 | depName = map.f;
295 |
296 | //Fast path CommonJS standard dependencies.
297 | if (depName === "require") {
298 | args[i] = handlers.require(name);
299 | } else if (depName === "exports") {
300 | //CommonJS module spec 1.1
301 | args[i] = handlers.exports(name);
302 | usingExports = true;
303 | } else if (depName === "module") {
304 | //CommonJS module spec 1.1
305 | cjsModule = args[i] = handlers.module(name);
306 | } else if (hasProp(defined, depName) ||
307 | hasProp(waiting, depName) ||
308 | hasProp(defining, depName)) {
309 | args[i] = callDep(depName);
310 | } else if (map.p) {
311 | map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
312 | args[i] = defined[depName];
313 | } else {
314 | throw new Error(name + ' missing ' + depName);
315 | }
316 | }
317 |
318 | ret = callback ? callback.apply(defined[name], args) : undefined;
319 |
320 | if (name) {
321 | //If setting exports via "module" is in play,
322 | //favor that over return value and exports. After that,
323 | //favor a non-undefined return value over exports use.
324 | if (cjsModule && cjsModule.exports !== undef &&
325 | cjsModule.exports !== defined[name]) {
326 | defined[name] = cjsModule.exports;
327 | } else if (ret !== undef || !usingExports) {
328 | //Use the return value from the function.
329 | defined[name] = ret;
330 | }
331 | }
332 | } else if (name) {
333 | //May just be an object definition for the module. Only
334 | //worry about defining if have a module name.
335 | defined[name] = callback;
336 | }
337 | };
338 |
339 | requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
340 | if (typeof deps === "string") {
341 | if (handlers[deps]) {
342 | //callback in this case is really relName
343 | return handlers[deps](callback);
344 | }
345 | //Just return the module wanted. In this scenario, the
346 | //deps arg is the module name, and second arg (if passed)
347 | //is just the relName.
348 | //Normalize module name, if it contains . or ..
349 | return callDep(makeMap(deps, makeRelParts(callback)).f);
350 | } else if (!deps.splice) {
351 | //deps is a config object, not an array.
352 | config = deps;
353 | if (config.deps) {
354 | req(config.deps, config.callback);
355 | }
356 | if (!callback) {
357 | return;
358 | }
359 |
360 | if (callback.splice) {
361 | //callback is an array, which means it is a dependency list.
362 | //Adjust args if there are dependencies
363 | deps = callback;
364 | callback = relName;
365 | relName = null;
366 | } else {
367 | deps = undef;
368 | }
369 | }
370 |
371 | //Support require(['a'])
372 | callback = callback || function () {};
373 |
374 | //If relName is a function, it is an errback handler,
375 | //so remove it.
376 | if (typeof relName === 'function') {
377 | relName = forceSync;
378 | forceSync = alt;
379 | }
380 |
381 | //Simulate async callback;
382 | if (forceSync) {
383 | main(undef, deps, callback, relName);
384 | } else {
385 | //Using a non-zero value because of concern for what old browsers
386 | //do, and latest browsers "upgrade" to 4 if lower value is used:
387 | //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
388 | //If want a value immediately, use require('id') instead -- something
389 | //that works in almond on the global level, but not guaranteed and
390 | //unlikely to work in other AMD implementations.
391 | setTimeout(function () {
392 | main(undef, deps, callback, relName);
393 | }, 4);
394 | }
395 |
396 | return req;
397 | };
398 |
399 | /**
400 | * Just drops the config on the floor, but returns req in case
401 | * the config return value is used.
402 | */
403 | req.config = function (cfg) {
404 | return req(cfg);
405 | };
406 |
407 | /**
408 | * Expose module registry for debugging and tooling
409 | */
410 | requirejs._defined = defined;
411 |
412 | define = function (name, deps, callback) {
413 | if (typeof name !== 'string') {
414 | throw new Error('See almond README: incorrect module build, no module name');
415 | }
416 |
417 | //This module may not have dependencies
418 | if (!deps.splice) {
419 | //deps is not an array, so probably means
420 | //an object literal or factory function for
421 | //the value. Adjust args.
422 | callback = deps;
423 | deps = [];
424 | }
425 |
426 | if (!hasProp(defined, name) && !hasProp(waiting, name)) {
427 | waiting[name] = [name, deps, callback];
428 | }
429 | };
430 |
431 | define.amd = {
432 | jQuery: true
433 | };
434 | }());
435 |
--------------------------------------------------------------------------------
/vendor/assets/javascripts/require.js:
--------------------------------------------------------------------------------
1 | /** vim: et:ts=4:sw=4:sts=4
2 | * @license RequireJS 2.3.5 Copyright jQuery Foundation and other contributors.
3 | * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE
4 | */
5 | //Not using strict: uneven strict support in browsers, #392, and causes
6 | //problems with requirejs.exec()/transpiler plugins that may not be strict.
7 | /*jslint regexp: true, nomen: true, sloppy: true */
8 | /*global window, navigator, document, importScripts, setTimeout, opera */
9 |
10 | var requirejs, require, define;
11 | (function (global, setTimeout) {
12 | var req, s, head, baseElement, dataMain, src,
13 | interactiveScript, currentlyAddingScript, mainScript, subPath,
14 | version = '2.3.5',
15 | commentRegExp = /\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/mg,
16 | cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
17 | jsSuffixRegExp = /\.js$/,
18 | currDirRegExp = /^\.\//,
19 | op = Object.prototype,
20 | ostring = op.toString,
21 | hasOwn = op.hasOwnProperty,
22 | isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document),
23 | isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
24 | //PS3 indicates loaded and complete, but need to wait for complete
25 | //specifically. Sequence is 'loading', 'loaded', execution,
26 | // then 'complete'. The UA check is unfortunate, but not sure how
27 | //to feature test w/o causing perf issues.
28 | readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ?
29 | /^complete$/ : /^(complete|loaded)$/,
30 | defContextName = '_',
31 | //Oh the tragedy, detecting opera. See the usage of isOpera for reason.
32 | isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]',
33 | contexts = {},
34 | cfg = {},
35 | globalDefQueue = [],
36 | useInteractive = false;
37 |
38 | //Could match something like ')//comment', do not lose the prefix to comment.
39 | function commentReplace(match, singlePrefix) {
40 | return singlePrefix || '';
41 | }
42 |
43 | function isFunction(it) {
44 | return ostring.call(it) === '[object Function]';
45 | }
46 |
47 | function isArray(it) {
48 | return ostring.call(it) === '[object Array]';
49 | }
50 |
51 | /**
52 | * Helper function for iterating over an array. If the func returns
53 | * a true value, it will break out of the loop.
54 | */
55 | function each(ary, func) {
56 | if (ary) {
57 | var i;
58 | for (i = 0; i < ary.length; i += 1) {
59 | if (ary[i] && func(ary[i], i, ary)) {
60 | break;
61 | }
62 | }
63 | }
64 | }
65 |
66 | /**
67 | * Helper function for iterating over an array backwards. If the func
68 | * returns a true value, it will break out of the loop.
69 | */
70 | function eachReverse(ary, func) {
71 | if (ary) {
72 | var i;
73 | for (i = ary.length - 1; i > -1; i -= 1) {
74 | if (ary[i] && func(ary[i], i, ary)) {
75 | break;
76 | }
77 | }
78 | }
79 | }
80 |
81 | function hasProp(obj, prop) {
82 | return hasOwn.call(obj, prop);
83 | }
84 |
85 | function getOwn(obj, prop) {
86 | return hasProp(obj, prop) && obj[prop];
87 | }
88 |
89 | /**
90 | * Cycles over properties in an object and calls a function for each
91 | * property value. If the function returns a truthy value, then the
92 | * iteration is stopped.
93 | */
94 | function eachProp(obj, func) {
95 | var prop;
96 | for (prop in obj) {
97 | if (hasProp(obj, prop)) {
98 | if (func(obj[prop], prop)) {
99 | break;
100 | }
101 | }
102 | }
103 | }
104 |
105 | /**
106 | * Simple function to mix in properties from source into target,
107 | * but only if target does not already have a property of the same name.
108 | */
109 | function mixin(target, source, force, deepStringMixin) {
110 | if (source) {
111 | eachProp(source, function (value, prop) {
112 | if (force || !hasProp(target, prop)) {
113 | if (deepStringMixin && typeof value === 'object' && value &&
114 | !isArray(value) && !isFunction(value) &&
115 | !(value instanceof RegExp)) {
116 |
117 | if (!target[prop]) {
118 | target[prop] = {};
119 | }
120 | mixin(target[prop], value, force, deepStringMixin);
121 | } else {
122 | target[prop] = value;
123 | }
124 | }
125 | });
126 | }
127 | return target;
128 | }
129 |
130 | //Similar to Function.prototype.bind, but the 'this' object is specified
131 | //first, since it is easier to read/figure out what 'this' will be.
132 | function bind(obj, fn) {
133 | return function () {
134 | return fn.apply(obj, arguments);
135 | };
136 | }
137 |
138 | function scripts() {
139 | return document.getElementsByTagName('script');
140 | }
141 |
142 | function defaultOnError(err) {
143 | throw err;
144 | }
145 |
146 | //Allow getting a global that is expressed in
147 | //dot notation, like 'a.b.c'.
148 | function getGlobal(value) {
149 | if (!value) {
150 | return value;
151 | }
152 | var g = global;
153 | each(value.split('.'), function (part) {
154 | g = g[part];
155 | });
156 | return g;
157 | }
158 |
159 | /**
160 | * Constructs an error with a pointer to an URL with more information.
161 | * @param {String} id the error ID that maps to an ID on a web page.
162 | * @param {String} message human readable error.
163 | * @param {Error} [err] the original error, if there is one.
164 | *
165 | * @returns {Error}
166 | */
167 | function makeError(id, msg, err, requireModules) {
168 | var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#' + id);
169 | e.requireType = id;
170 | e.requireModules = requireModules;
171 | if (err) {
172 | e.originalError = err;
173 | }
174 | return e;
175 | }
176 |
177 | if (typeof define !== 'undefined') {
178 | //If a define is already in play via another AMD loader,
179 | //do not overwrite.
180 | return;
181 | }
182 |
183 | if (typeof requirejs !== 'undefined') {
184 | if (isFunction(requirejs)) {
185 | //Do not overwrite an existing requirejs instance.
186 | return;
187 | }
188 | cfg = requirejs;
189 | requirejs = undefined;
190 | }
191 |
192 | //Allow for a require config object
193 | if (typeof require !== 'undefined' && !isFunction(require)) {
194 | //assume it is a config object.
195 | cfg = require;
196 | require = undefined;
197 | }
198 |
199 | function newContext(contextName) {
200 | var inCheckLoaded, Module, context, handlers,
201 | checkLoadedTimeoutId,
202 | config = {
203 | //Defaults. Do not set a default for map
204 | //config to speed up normalize(), which
205 | //will run faster if there is no default.
206 | waitSeconds: 7,
207 | baseUrl: './',
208 | paths: {},
209 | bundles: {},
210 | pkgs: {},
211 | shim: {},
212 | config: {}
213 | },
214 | registry = {},
215 | //registry of just enabled modules, to speed
216 | //cycle breaking code when lots of modules
217 | //are registered, but not activated.
218 | enabledRegistry = {},
219 | undefEvents = {},
220 | defQueue = [],
221 | defined = {},
222 | urlFetched = {},
223 | bundlesMap = {},
224 | requireCounter = 1,
225 | unnormalizedCounter = 1;
226 |
227 | /**
228 | * Trims the . and .. from an array of path segments.
229 | * It will keep a leading path segment if a .. will become
230 | * the first path segment, to help with module name lookups,
231 | * which act like paths, but can be remapped. But the end result,
232 | * all paths that use this function should look normalized.
233 | * NOTE: this method MODIFIES the input array.
234 | * @param {Array} ary the array of path segments.
235 | */
236 | function trimDots(ary) {
237 | var i, part;
238 | for (i = 0; i < ary.length; i++) {
239 | part = ary[i];
240 | if (part === '.') {
241 | ary.splice(i, 1);
242 | i -= 1;
243 | } else if (part === '..') {
244 | // If at the start, or previous value is still ..,
245 | // keep them so that when converted to a path it may
246 | // still work when converted to a path, even though
247 | // as an ID it is less than ideal. In larger point
248 | // releases, may be better to just kick out an error.
249 | if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') {
250 | continue;
251 | } else if (i > 0) {
252 | ary.splice(i - 1, 2);
253 | i -= 2;
254 | }
255 | }
256 | }
257 | }
258 |
259 | /**
260 | * Given a relative module name, like ./something, normalize it to
261 | * a real name that can be mapped to a path.
262 | * @param {String} name the relative name
263 | * @param {String} baseName a real name that the name arg is relative
264 | * to.
265 | * @param {Boolean} applyMap apply the map config to the value. Should
266 | * only be done if this normalization is for a dependency ID.
267 | * @returns {String} normalized name
268 | */
269 | function normalize(name, baseName, applyMap) {
270 | var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex,
271 | foundMap, foundI, foundStarMap, starI, normalizedBaseParts,
272 | baseParts = (baseName && baseName.split('/')),
273 | map = config.map,
274 | starMap = map && map['*'];
275 |
276 | //Adjust any relative paths.
277 | if (name) {
278 | name = name.split('/');
279 | lastIndex = name.length - 1;
280 |
281 | // If wanting node ID compatibility, strip .js from end
282 | // of IDs. Have to do this here, and not in nameToUrl
283 | // because node allows either .js or non .js to map
284 | // to same file.
285 | if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
286 | name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
287 | }
288 |
289 | // Starts with a '.' so need the baseName
290 | if (name[0].charAt(0) === '.' && baseParts) {
291 | //Convert baseName to array, and lop off the last part,
292 | //so that . matches that 'directory' and not name of the baseName's
293 | //module. For instance, baseName of 'one/two/three', maps to
294 | //'one/two/three.js', but we want the directory, 'one/two' for
295 | //this normalization.
296 | normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
297 | name = normalizedBaseParts.concat(name);
298 | }
299 |
300 | trimDots(name);
301 | name = name.join('/');
302 | }
303 |
304 | //Apply map config if available.
305 | if (applyMap && map && (baseParts || starMap)) {
306 | nameParts = name.split('/');
307 |
308 | outerLoop: for (i = nameParts.length; i > 0; i -= 1) {
309 | nameSegment = nameParts.slice(0, i).join('/');
310 |
311 | if (baseParts) {
312 | //Find the longest baseName segment match in the config.
313 | //So, do joins on the biggest to smallest lengths of baseParts.
314 | for (j = baseParts.length; j > 0; j -= 1) {
315 | mapValue = getOwn(map, baseParts.slice(0, j).join('/'));
316 |
317 | //baseName segment has config, find if it has one for
318 | //this name.
319 | if (mapValue) {
320 | mapValue = getOwn(mapValue, nameSegment);
321 | if (mapValue) {
322 | //Match, update name to the new value.
323 | foundMap = mapValue;
324 | foundI = i;
325 | break outerLoop;
326 | }
327 | }
328 | }
329 | }
330 |
331 | //Check for a star map match, but just hold on to it,
332 | //if there is a shorter segment match later in a matching
333 | //config, then favor over this star map.
334 | if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) {
335 | foundStarMap = getOwn(starMap, nameSegment);
336 | starI = i;
337 | }
338 | }
339 |
340 | if (!foundMap && foundStarMap) {
341 | foundMap = foundStarMap;
342 | foundI = starI;
343 | }
344 |
345 | if (foundMap) {
346 | nameParts.splice(0, foundI, foundMap);
347 | name = nameParts.join('/');
348 | }
349 | }
350 |
351 | // If the name points to a package's name, use
352 | // the package main instead.
353 | pkgMain = getOwn(config.pkgs, name);
354 |
355 | return pkgMain ? pkgMain : name;
356 | }
357 |
358 | function removeScript(name) {
359 | if (isBrowser) {
360 | each(scripts(), function (scriptNode) {
361 | if (scriptNode.getAttribute('data-requiremodule') === name &&
362 | scriptNode.getAttribute('data-requirecontext') === context.contextName) {
363 | scriptNode.parentNode.removeChild(scriptNode);
364 | return true;
365 | }
366 | });
367 | }
368 | }
369 |
370 | function hasPathFallback(id) {
371 | var pathConfig = getOwn(config.paths, id);
372 | if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) {
373 | //Pop off the first array value, since it failed, and
374 | //retry
375 | pathConfig.shift();
376 | context.require.undef(id);
377 |
378 | //Custom require that does not do map translation, since
379 | //ID is "absolute", already mapped/resolved.
380 | context.makeRequire(null, {
381 | skipMap: true
382 | })([id]);
383 |
384 | return true;
385 | }
386 | }
387 |
388 | //Turns a plugin!resource to [plugin, resource]
389 | //with the plugin being undefined if the name
390 | //did not have a plugin prefix.
391 | function splitPrefix(name) {
392 | var prefix,
393 | index = name ? name.indexOf('!') : -1;
394 | if (index > -1) {
395 | prefix = name.substring(0, index);
396 | name = name.substring(index + 1, name.length);
397 | }
398 | return [prefix, name];
399 | }
400 |
401 | /**
402 | * Creates a module mapping that includes plugin prefix, module
403 | * name, and path. If parentModuleMap is provided it will
404 | * also normalize the name via require.normalize()
405 | *
406 | * @param {String} name the module name
407 | * @param {String} [parentModuleMap] parent module map
408 | * for the module name, used to resolve relative names.
409 | * @param {Boolean} isNormalized: is the ID already normalized.
410 | * This is true if this call is done for a define() module ID.
411 | * @param {Boolean} applyMap: apply the map config to the ID.
412 | * Should only be true if this map is for a dependency.
413 | *
414 | * @returns {Object}
415 | */
416 | function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) {
417 | var url, pluginModule, suffix, nameParts,
418 | prefix = null,
419 | parentName = parentModuleMap ? parentModuleMap.name : null,
420 | originalName = name,
421 | isDefine = true,
422 | normalizedName = '';
423 |
424 | //If no name, then it means it is a require call, generate an
425 | //internal name.
426 | if (!name) {
427 | isDefine = false;
428 | name = '_@r' + (requireCounter += 1);
429 | }
430 |
431 | nameParts = splitPrefix(name);
432 | prefix = nameParts[0];
433 | name = nameParts[1];
434 |
435 | if (prefix) {
436 | prefix = normalize(prefix, parentName, applyMap);
437 | pluginModule = getOwn(defined, prefix);
438 | }
439 |
440 | //Account for relative paths if there is a base name.
441 | if (name) {
442 | if (prefix) {
443 | if (isNormalized) {
444 | normalizedName = name;
445 | } else if (pluginModule && pluginModule.normalize) {
446 | //Plugin is loaded, use its normalize method.
447 | normalizedName = pluginModule.normalize(name, function (name) {
448 | return normalize(name, parentName, applyMap);
449 | });
450 | } else {
451 | // If nested plugin references, then do not try to
452 | // normalize, as it will not normalize correctly. This
453 | // places a restriction on resourceIds, and the longer
454 | // term solution is not to normalize until plugins are
455 | // loaded and all normalizations to allow for async
456 | // loading of a loader plugin. But for now, fixes the
457 | // common uses. Details in #1131
458 | normalizedName = name.indexOf('!') === -1 ?
459 | normalize(name, parentName, applyMap) :
460 | name;
461 | }
462 | } else {
463 | //A regular module.
464 | normalizedName = normalize(name, parentName, applyMap);
465 |
466 | //Normalized name may be a plugin ID due to map config
467 | //application in normalize. The map config values must
468 | //already be normalized, so do not need to redo that part.
469 | nameParts = splitPrefix(normalizedName);
470 | prefix = nameParts[0];
471 | normalizedName = nameParts[1];
472 | isNormalized = true;
473 |
474 | url = context.nameToUrl(normalizedName);
475 | }
476 | }
477 |
478 | //If the id is a plugin id that cannot be determined if it needs
479 | //normalization, stamp it with a unique ID so two matching relative
480 | //ids that may conflict can be separate.
481 | suffix = prefix && !pluginModule && !isNormalized ?
482 | '_unnormalized' + (unnormalizedCounter += 1) :
483 | '';
484 |
485 | return {
486 | prefix: prefix,
487 | name: normalizedName,
488 | parentMap: parentModuleMap,
489 | unnormalized: !!suffix,
490 | url: url,
491 | originalName: originalName,
492 | isDefine: isDefine,
493 | id: (prefix ?
494 | prefix + '!' + normalizedName :
495 | normalizedName) + suffix
496 | };
497 | }
498 |
499 | function getModule(depMap) {
500 | var id = depMap.id,
501 | mod = getOwn(registry, id);
502 |
503 | if (!mod) {
504 | mod = registry[id] = new context.Module(depMap);
505 | }
506 |
507 | return mod;
508 | }
509 |
510 | function on(depMap, name, fn) {
511 | var id = depMap.id,
512 | mod = getOwn(registry, id);
513 |
514 | if (hasProp(defined, id) &&
515 | (!mod || mod.defineEmitComplete)) {
516 | if (name === 'defined') {
517 | fn(defined[id]);
518 | }
519 | } else {
520 | mod = getModule(depMap);
521 | if (mod.error && name === 'error') {
522 | fn(mod.error);
523 | } else {
524 | mod.on(name, fn);
525 | }
526 | }
527 | }
528 |
529 | function onError(err, errback) {
530 | var ids = err.requireModules,
531 | notified = false;
532 |
533 | if (errback) {
534 | errback(err);
535 | } else {
536 | each(ids, function (id) {
537 | var mod = getOwn(registry, id);
538 | if (mod) {
539 | //Set error on module, so it skips timeout checks.
540 | mod.error = err;
541 | if (mod.events.error) {
542 | notified = true;
543 | mod.emit('error', err);
544 | }
545 | }
546 | });
547 |
548 | if (!notified) {
549 | req.onError(err);
550 | }
551 | }
552 | }
553 |
554 | /**
555 | * Internal method to transfer globalQueue items to this context's
556 | * defQueue.
557 | */
558 | function takeGlobalQueue() {
559 | //Push all the globalDefQueue items into the context's defQueue
560 | if (globalDefQueue.length) {
561 | each(globalDefQueue, function(queueItem) {
562 | var id = queueItem[0];
563 | if (typeof id === 'string') {
564 | context.defQueueMap[id] = true;
565 | }
566 | defQueue.push(queueItem);
567 | });
568 | globalDefQueue = [];
569 | }
570 | }
571 |
572 | handlers = {
573 | 'require': function (mod) {
574 | if (mod.require) {
575 | return mod.require;
576 | } else {
577 | return (mod.require = context.makeRequire(mod.map));
578 | }
579 | },
580 | 'exports': function (mod) {
581 | mod.usingExports = true;
582 | if (mod.map.isDefine) {
583 | if (mod.exports) {
584 | return (defined[mod.map.id] = mod.exports);
585 | } else {
586 | return (mod.exports = defined[mod.map.id] = {});
587 | }
588 | }
589 | },
590 | 'module': function (mod) {
591 | if (mod.module) {
592 | return mod.module;
593 | } else {
594 | return (mod.module = {
595 | id: mod.map.id,
596 | uri: mod.map.url,
597 | config: function () {
598 | return getOwn(config.config, mod.map.id) || {};
599 | },
600 | exports: mod.exports || (mod.exports = {})
601 | });
602 | }
603 | }
604 | };
605 |
606 | function cleanRegistry(id) {
607 | //Clean up machinery used for waiting modules.
608 | delete registry[id];
609 | delete enabledRegistry[id];
610 | }
611 |
612 | function breakCycle(mod, traced, processed) {
613 | var id = mod.map.id;
614 |
615 | if (mod.error) {
616 | mod.emit('error', mod.error);
617 | } else {
618 | traced[id] = true;
619 | each(mod.depMaps, function (depMap, i) {
620 | var depId = depMap.id,
621 | dep = getOwn(registry, depId);
622 |
623 | //Only force things that have not completed
624 | //being defined, so still in the registry,
625 | //and only if it has not been matched up
626 | //in the module already.
627 | if (dep && !mod.depMatched[i] && !processed[depId]) {
628 | if (getOwn(traced, depId)) {
629 | mod.defineDep(i, defined[depId]);
630 | mod.check(); //pass false?
631 | } else {
632 | breakCycle(dep, traced, processed);
633 | }
634 | }
635 | });
636 | processed[id] = true;
637 | }
638 | }
639 |
640 | function checkLoaded() {
641 | var err, usingPathFallback,
642 | waitInterval = config.waitSeconds * 1000,
643 | //It is possible to disable the wait interval by using waitSeconds of 0.
644 | expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(),
645 | noLoads = [],
646 | reqCalls = [],
647 | stillLoading = false,
648 | needCycleCheck = true;
649 |
650 | //Do not bother if this call was a result of a cycle break.
651 | if (inCheckLoaded) {
652 | return;
653 | }
654 |
655 | inCheckLoaded = true;
656 |
657 | //Figure out the state of all the modules.
658 | eachProp(enabledRegistry, function (mod) {
659 | var map = mod.map,
660 | modId = map.id;
661 |
662 | //Skip things that are not enabled or in error state.
663 | if (!mod.enabled) {
664 | return;
665 | }
666 |
667 | if (!map.isDefine) {
668 | reqCalls.push(mod);
669 | }
670 |
671 | if (!mod.error) {
672 | //If the module should be executed, and it has not
673 | //been inited and time is up, remember it.
674 | if (!mod.inited && expired) {
675 | if (hasPathFallback(modId)) {
676 | usingPathFallback = true;
677 | stillLoading = true;
678 | } else {
679 | noLoads.push(modId);
680 | removeScript(modId);
681 | }
682 | } else if (!mod.inited && mod.fetched && map.isDefine) {
683 | stillLoading = true;
684 | if (!map.prefix) {
685 | //No reason to keep looking for unfinished
686 | //loading. If the only stillLoading is a
687 | //plugin resource though, keep going,
688 | //because it may be that a plugin resource
689 | //is waiting on a non-plugin cycle.
690 | return (needCycleCheck = false);
691 | }
692 | }
693 | }
694 | });
695 |
696 | if (expired && noLoads.length) {
697 | //If wait time expired, throw error of unloaded modules.
698 | err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads);
699 | err.contextName = context.contextName;
700 | return onError(err);
701 | }
702 |
703 | //Not expired, check for a cycle.
704 | if (needCycleCheck) {
705 | each(reqCalls, function (mod) {
706 | breakCycle(mod, {}, {});
707 | });
708 | }
709 |
710 | //If still waiting on loads, and the waiting load is something
711 | //other than a plugin resource, or there are still outstanding
712 | //scripts, then just try back later.
713 | if ((!expired || usingPathFallback) && stillLoading) {
714 | //Something is still waiting to load. Wait for it, but only
715 | //if a timeout is not already in effect.
716 | if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) {
717 | checkLoadedTimeoutId = setTimeout(function () {
718 | checkLoadedTimeoutId = 0;
719 | checkLoaded();
720 | }, 50);
721 | }
722 | }
723 |
724 | inCheckLoaded = false;
725 | }
726 |
727 | Module = function (map) {
728 | this.events = getOwn(undefEvents, map.id) || {};
729 | this.map = map;
730 | this.shim = getOwn(config.shim, map.id);
731 | this.depExports = [];
732 | this.depMaps = [];
733 | this.depMatched = [];
734 | this.pluginMaps = {};
735 | this.depCount = 0;
736 |
737 | /* this.exports this.factory
738 | this.depMaps = [],
739 | this.enabled, this.fetched
740 | */
741 | };
742 |
743 | Module.prototype = {
744 | init: function (depMaps, factory, errback, options) {
745 | options = options || {};
746 |
747 | //Do not do more inits if already done. Can happen if there
748 | //are multiple define calls for the same module. That is not
749 | //a normal, common case, but it is also not unexpected.
750 | if (this.inited) {
751 | return;
752 | }
753 |
754 | this.factory = factory;
755 |
756 | if (errback) {
757 | //Register for errors on this module.
758 | this.on('error', errback);
759 | } else if (this.events.error) {
760 | //If no errback already, but there are error listeners
761 | //on this module, set up an errback to pass to the deps.
762 | errback = bind(this, function (err) {
763 | this.emit('error', err);
764 | });
765 | }
766 |
767 | //Do a copy of the dependency array, so that
768 | //source inputs are not modified. For example
769 | //"shim" deps are passed in here directly, and
770 | //doing a direct modification of the depMaps array
771 | //would affect that config.
772 | this.depMaps = depMaps && depMaps.slice(0);
773 |
774 | this.errback = errback;
775 |
776 | //Indicate this module has be initialized
777 | this.inited = true;
778 |
779 | this.ignore = options.ignore;
780 |
781 | //Could have option to init this module in enabled mode,
782 | //or could have been previously marked as enabled. However,
783 | //the dependencies are not known until init is called. So
784 | //if enabled previously, now trigger dependencies as enabled.
785 | if (options.enabled || this.enabled) {
786 | //Enable this module and dependencies.
787 | //Will call this.check()
788 | this.enable();
789 | } else {
790 | this.check();
791 | }
792 | },
793 |
794 | defineDep: function (i, depExports) {
795 | //Because of cycles, defined callback for a given
796 | //export can be called more than once.
797 | if (!this.depMatched[i]) {
798 | this.depMatched[i] = true;
799 | this.depCount -= 1;
800 | this.depExports[i] = depExports;
801 | }
802 | },
803 |
804 | fetch: function () {
805 | if (this.fetched) {
806 | return;
807 | }
808 | this.fetched = true;
809 |
810 | context.startTime = (new Date()).getTime();
811 |
812 | var map = this.map;
813 |
814 | //If the manager is for a plugin managed resource,
815 | //ask the plugin to load it now.
816 | if (this.shim) {
817 | context.makeRequire(this.map, {
818 | enableBuildCallback: true
819 | })(this.shim.deps || [], bind(this, function () {
820 | return map.prefix ? this.callPlugin() : this.load();
821 | }));
822 | } else {
823 | //Regular dependency.
824 | return map.prefix ? this.callPlugin() : this.load();
825 | }
826 | },
827 |
828 | load: function () {
829 | var url = this.map.url;
830 |
831 | //Regular dependency.
832 | if (!urlFetched[url]) {
833 | urlFetched[url] = true;
834 | context.load(this.map.id, url);
835 | }
836 | },
837 |
838 | /**
839 | * Checks if the module is ready to define itself, and if so,
840 | * define it.
841 | */
842 | check: function () {
843 | if (!this.enabled || this.enabling) {
844 | return;
845 | }
846 |
847 | var err, cjsModule,
848 | id = this.map.id,
849 | depExports = this.depExports,
850 | exports = this.exports,
851 | factory = this.factory;
852 |
853 | if (!this.inited) {
854 | // Only fetch if not already in the defQueue.
855 | if (!hasProp(context.defQueueMap, id)) {
856 | this.fetch();
857 | }
858 | } else if (this.error) {
859 | this.emit('error', this.error);
860 | } else if (!this.defining) {
861 | //The factory could trigger another require call
862 | //that would result in checking this module to
863 | //define itself again. If already in the process
864 | //of doing that, skip this work.
865 | this.defining = true;
866 |
867 | if (this.depCount < 1 && !this.defined) {
868 | if (isFunction(factory)) {
869 | //If there is an error listener, favor passing
870 | //to that instead of throwing an error. However,
871 | //only do it for define()'d modules. require
872 | //errbacks should not be called for failures in
873 | //their callbacks (#699). However if a global
874 | //onError is set, use that.
875 | if ((this.events.error && this.map.isDefine) ||
876 | req.onError !== defaultOnError) {
877 | try {
878 | exports = context.execCb(id, factory, depExports, exports);
879 | } catch (e) {
880 | err = e;
881 | }
882 | } else {
883 | exports = context.execCb(id, factory, depExports, exports);
884 | }
885 |
886 | // Favor return value over exports. If node/cjs in play,
887 | // then will not have a return value anyway. Favor
888 | // module.exports assignment over exports object.
889 | if (this.map.isDefine && exports === undefined) {
890 | cjsModule = this.module;
891 | if (cjsModule) {
892 | exports = cjsModule.exports;
893 | } else if (this.usingExports) {
894 | //exports already set the defined value.
895 | exports = this.exports;
896 | }
897 | }
898 |
899 | if (err) {
900 | err.requireMap = this.map;
901 | err.requireModules = this.map.isDefine ? [this.map.id] : null;
902 | err.requireType = this.map.isDefine ? 'define' : 'require';
903 | return onError((this.error = err));
904 | }
905 |
906 | } else {
907 | //Just a literal value
908 | exports = factory;
909 | }
910 |
911 | this.exports = exports;
912 |
913 | if (this.map.isDefine && !this.ignore) {
914 | defined[id] = exports;
915 |
916 | if (req.onResourceLoad) {
917 | var resLoadMaps = [];
918 | each(this.depMaps, function (depMap) {
919 | resLoadMaps.push(depMap.normalizedMap || depMap);
920 | });
921 | req.onResourceLoad(context, this.map, resLoadMaps);
922 | }
923 | }
924 |
925 | //Clean up
926 | cleanRegistry(id);
927 |
928 | this.defined = true;
929 | }
930 |
931 | //Finished the define stage. Allow calling check again
932 | //to allow define notifications below in the case of a
933 | //cycle.
934 | this.defining = false;
935 |
936 | if (this.defined && !this.defineEmitted) {
937 | this.defineEmitted = true;
938 | this.emit('defined', this.exports);
939 | this.defineEmitComplete = true;
940 | }
941 |
942 | }
943 | },
944 |
945 | callPlugin: function () {
946 | var map = this.map,
947 | id = map.id,
948 | //Map already normalized the prefix.
949 | pluginMap = makeModuleMap(map.prefix);
950 |
951 | //Mark this as a dependency for this plugin, so it
952 | //can be traced for cycles.
953 | this.depMaps.push(pluginMap);
954 |
955 | on(pluginMap, 'defined', bind(this, function (plugin) {
956 | var load, normalizedMap, normalizedMod,
957 | bundleId = getOwn(bundlesMap, this.map.id),
958 | name = this.map.name,
959 | parentName = this.map.parentMap ? this.map.parentMap.name : null,
960 | localRequire = context.makeRequire(map.parentMap, {
961 | enableBuildCallback: true
962 | });
963 |
964 | //If current map is not normalized, wait for that
965 | //normalized name to load instead of continuing.
966 | if (this.map.unnormalized) {
967 | //Normalize the ID if the plugin allows it.
968 | if (plugin.normalize) {
969 | name = plugin.normalize(name, function (name) {
970 | return normalize(name, parentName, true);
971 | }) || '';
972 | }
973 |
974 | //prefix and name should already be normalized, no need
975 | //for applying map config again either.
976 | normalizedMap = makeModuleMap(map.prefix + '!' + name,
977 | this.map.parentMap,
978 | true);
979 | on(normalizedMap,
980 | 'defined', bind(this, function (value) {
981 | this.map.normalizedMap = normalizedMap;
982 | this.init([], function () { return value; }, null, {
983 | enabled: true,
984 | ignore: true
985 | });
986 | }));
987 |
988 | normalizedMod = getOwn(registry, normalizedMap.id);
989 | if (normalizedMod) {
990 | //Mark this as a dependency for this plugin, so it
991 | //can be traced for cycles.
992 | this.depMaps.push(normalizedMap);
993 |
994 | if (this.events.error) {
995 | normalizedMod.on('error', bind(this, function (err) {
996 | this.emit('error', err);
997 | }));
998 | }
999 | normalizedMod.enable();
1000 | }
1001 |
1002 | return;
1003 | }
1004 |
1005 | //If a paths config, then just load that file instead to
1006 | //resolve the plugin, as it is built into that paths layer.
1007 | if (bundleId) {
1008 | this.map.url = context.nameToUrl(bundleId);
1009 | this.load();
1010 | return;
1011 | }
1012 |
1013 | load = bind(this, function (value) {
1014 | this.init([], function () { return value; }, null, {
1015 | enabled: true
1016 | });
1017 | });
1018 |
1019 | load.error = bind(this, function (err) {
1020 | this.inited = true;
1021 | this.error = err;
1022 | err.requireModules = [id];
1023 |
1024 | //Remove temp unnormalized modules for this module,
1025 | //since they will never be resolved otherwise now.
1026 | eachProp(registry, function (mod) {
1027 | if (mod.map.id.indexOf(id + '_unnormalized') === 0) {
1028 | cleanRegistry(mod.map.id);
1029 | }
1030 | });
1031 |
1032 | onError(err);
1033 | });
1034 |
1035 | //Allow plugins to load other code without having to know the
1036 | //context or how to 'complete' the load.
1037 | load.fromText = bind(this, function (text, textAlt) {
1038 | /*jslint evil: true */
1039 | var moduleName = map.name,
1040 | moduleMap = makeModuleMap(moduleName),
1041 | hasInteractive = useInteractive;
1042 |
1043 | //As of 2.1.0, support just passing the text, to reinforce
1044 | //fromText only being called once per resource. Still
1045 | //support old style of passing moduleName but discard
1046 | //that moduleName in favor of the internal ref.
1047 | if (textAlt) {
1048 | text = textAlt;
1049 | }
1050 |
1051 | //Turn off interactive script matching for IE for any define
1052 | //calls in the text, then turn it back on at the end.
1053 | if (hasInteractive) {
1054 | useInteractive = false;
1055 | }
1056 |
1057 | //Prime the system by creating a module instance for
1058 | //it.
1059 | getModule(moduleMap);
1060 |
1061 | //Transfer any config to this other module.
1062 | if (hasProp(config.config, id)) {
1063 | config.config[moduleName] = config.config[id];
1064 | }
1065 |
1066 | try {
1067 | req.exec(text);
1068 | } catch (e) {
1069 | return onError(makeError('fromtexteval',
1070 | 'fromText eval for ' + id +
1071 | ' failed: ' + e,
1072 | e,
1073 | [id]));
1074 | }
1075 |
1076 | if (hasInteractive) {
1077 | useInteractive = true;
1078 | }
1079 |
1080 | //Mark this as a dependency for the plugin
1081 | //resource
1082 | this.depMaps.push(moduleMap);
1083 |
1084 | //Support anonymous modules.
1085 | context.completeLoad(moduleName);
1086 |
1087 | //Bind the value of that module to the value for this
1088 | //resource ID.
1089 | localRequire([moduleName], load);
1090 | });
1091 |
1092 | //Use parentName here since the plugin's name is not reliable,
1093 | //could be some weird string with no path that actually wants to
1094 | //reference the parentName's path.
1095 | plugin.load(map.name, localRequire, load, config);
1096 | }));
1097 |
1098 | context.enable(pluginMap, this);
1099 | this.pluginMaps[pluginMap.id] = pluginMap;
1100 | },
1101 |
1102 | enable: function () {
1103 | enabledRegistry[this.map.id] = this;
1104 | this.enabled = true;
1105 |
1106 | //Set flag mentioning that the module is enabling,
1107 | //so that immediate calls to the defined callbacks
1108 | //for dependencies do not trigger inadvertent load
1109 | //with the depCount still being zero.
1110 | this.enabling = true;
1111 |
1112 | //Enable each dependency
1113 | each(this.depMaps, bind(this, function (depMap, i) {
1114 | var id, mod, handler;
1115 |
1116 | if (typeof depMap === 'string') {
1117 | //Dependency needs to be converted to a depMap
1118 | //and wired up to this module.
1119 | depMap = makeModuleMap(depMap,
1120 | (this.map.isDefine ? this.map : this.map.parentMap),
1121 | false,
1122 | !this.skipMap);
1123 | this.depMaps[i] = depMap;
1124 |
1125 | handler = getOwn(handlers, depMap.id);
1126 |
1127 | if (handler) {
1128 | this.depExports[i] = handler(this);
1129 | return;
1130 | }
1131 |
1132 | this.depCount += 1;
1133 |
1134 | on(depMap, 'defined', bind(this, function (depExports) {
1135 | if (this.undefed) {
1136 | return;
1137 | }
1138 | this.defineDep(i, depExports);
1139 | this.check();
1140 | }));
1141 |
1142 | if (this.errback) {
1143 | on(depMap, 'error', bind(this, this.errback));
1144 | } else if (this.events.error) {
1145 | // No direct errback on this module, but something
1146 | // else is listening for errors, so be sure to
1147 | // propagate the error correctly.
1148 | on(depMap, 'error', bind(this, function(err) {
1149 | this.emit('error', err);
1150 | }));
1151 | }
1152 | }
1153 |
1154 | id = depMap.id;
1155 | mod = registry[id];
1156 |
1157 | //Skip special modules like 'require', 'exports', 'module'
1158 | //Also, don't call enable if it is already enabled,
1159 | //important in circular dependency cases.
1160 | if (!hasProp(handlers, id) && mod && !mod.enabled) {
1161 | context.enable(depMap, this);
1162 | }
1163 | }));
1164 |
1165 | //Enable each plugin that is used in
1166 | //a dependency
1167 | eachProp(this.pluginMaps, bind(this, function (pluginMap) {
1168 | var mod = getOwn(registry, pluginMap.id);
1169 | if (mod && !mod.enabled) {
1170 | context.enable(pluginMap, this);
1171 | }
1172 | }));
1173 |
1174 | this.enabling = false;
1175 |
1176 | this.check();
1177 | },
1178 |
1179 | on: function (name, cb) {
1180 | var cbs = this.events[name];
1181 | if (!cbs) {
1182 | cbs = this.events[name] = [];
1183 | }
1184 | cbs.push(cb);
1185 | },
1186 |
1187 | emit: function (name, evt) {
1188 | each(this.events[name], function (cb) {
1189 | cb(evt);
1190 | });
1191 | if (name === 'error') {
1192 | //Now that the error handler was triggered, remove
1193 | //the listeners, since this broken Module instance
1194 | //can stay around for a while in the registry.
1195 | delete this.events[name];
1196 | }
1197 | }
1198 | };
1199 |
1200 | function callGetModule(args) {
1201 | //Skip modules already defined.
1202 | if (!hasProp(defined, args[0])) {
1203 | getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]);
1204 | }
1205 | }
1206 |
1207 | function removeListener(node, func, name, ieName) {
1208 | //Favor detachEvent because of IE9
1209 | //issue, see attachEvent/addEventListener comment elsewhere
1210 | //in this file.
1211 | if (node.detachEvent && !isOpera) {
1212 | //Probably IE. If not it will throw an error, which will be
1213 | //useful to know.
1214 | if (ieName) {
1215 | node.detachEvent(ieName, func);
1216 | }
1217 | } else {
1218 | node.removeEventListener(name, func, false);
1219 | }
1220 | }
1221 |
1222 | /**
1223 | * Given an event from a script node, get the requirejs info from it,
1224 | * and then removes the event listeners on the node.
1225 | * @param {Event} evt
1226 | * @returns {Object}
1227 | */
1228 | function getScriptData(evt) {
1229 | //Using currentTarget instead of target for Firefox 2.0's sake. Not
1230 | //all old browsers will be supported, but this one was easy enough
1231 | //to support and still makes sense.
1232 | var node = evt.currentTarget || evt.srcElement;
1233 |
1234 | //Remove the listeners once here.
1235 | removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange');
1236 | removeListener(node, context.onScriptError, 'error');
1237 |
1238 | return {
1239 | node: node,
1240 | id: node && node.getAttribute('data-requiremodule')
1241 | };
1242 | }
1243 |
1244 | function intakeDefines() {
1245 | var args;
1246 |
1247 | //Any defined modules in the global queue, intake them now.
1248 | takeGlobalQueue();
1249 |
1250 | //Make sure any remaining defQueue items get properly processed.
1251 | while (defQueue.length) {
1252 | args = defQueue.shift();
1253 | if (args[0] === null) {
1254 | return onError(makeError('mismatch', 'Mismatched anonymous define() module: ' +
1255 | args[args.length - 1]));
1256 | } else {
1257 | //args are id, deps, factory. Should be normalized by the
1258 | //define() function.
1259 | callGetModule(args);
1260 | }
1261 | }
1262 | context.defQueueMap = {};
1263 | }
1264 |
1265 | context = {
1266 | config: config,
1267 | contextName: contextName,
1268 | registry: registry,
1269 | defined: defined,
1270 | urlFetched: urlFetched,
1271 | defQueue: defQueue,
1272 | defQueueMap: {},
1273 | Module: Module,
1274 | makeModuleMap: makeModuleMap,
1275 | nextTick: req.nextTick,
1276 | onError: onError,
1277 |
1278 | /**
1279 | * Set a configuration for the context.
1280 | * @param {Object} cfg config object to integrate.
1281 | */
1282 | configure: function (cfg) {
1283 | //Make sure the baseUrl ends in a slash.
1284 | if (cfg.baseUrl) {
1285 | if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') {
1286 | cfg.baseUrl += '/';
1287 | }
1288 | }
1289 |
1290 | // Convert old style urlArgs string to a function.
1291 | if (typeof cfg.urlArgs === 'string') {
1292 | var urlArgs = cfg.urlArgs;
1293 | cfg.urlArgs = function(id, url) {
1294 | return (url.indexOf('?') === -1 ? '?' : '&') + urlArgs;
1295 | };
1296 | }
1297 |
1298 | //Save off the paths since they require special processing,
1299 | //they are additive.
1300 | var shim = config.shim,
1301 | objs = {
1302 | paths: true,
1303 | bundles: true,
1304 | config: true,
1305 | map: true
1306 | };
1307 |
1308 | eachProp(cfg, function (value, prop) {
1309 | if (objs[prop]) {
1310 | if (!config[prop]) {
1311 | config[prop] = {};
1312 | }
1313 | mixin(config[prop], value, true, true);
1314 | } else {
1315 | config[prop] = value;
1316 | }
1317 | });
1318 |
1319 | //Reverse map the bundles
1320 | if (cfg.bundles) {
1321 | eachProp(cfg.bundles, function (value, prop) {
1322 | each(value, function (v) {
1323 | if (v !== prop) {
1324 | bundlesMap[v] = prop;
1325 | }
1326 | });
1327 | });
1328 | }
1329 |
1330 | //Merge shim
1331 | if (cfg.shim) {
1332 | eachProp(cfg.shim, function (value, id) {
1333 | //Normalize the structure
1334 | if (isArray(value)) {
1335 | value = {
1336 | deps: value
1337 | };
1338 | }
1339 | if ((value.exports || value.init) && !value.exportsFn) {
1340 | value.exportsFn = context.makeShimExports(value);
1341 | }
1342 | shim[id] = value;
1343 | });
1344 | config.shim = shim;
1345 | }
1346 |
1347 | //Adjust packages if necessary.
1348 | if (cfg.packages) {
1349 | each(cfg.packages, function (pkgObj) {
1350 | var location, name;
1351 |
1352 | pkgObj = typeof pkgObj === 'string' ? {name: pkgObj} : pkgObj;
1353 |
1354 | name = pkgObj.name;
1355 | location = pkgObj.location;
1356 | if (location) {
1357 | config.paths[name] = pkgObj.location;
1358 | }
1359 |
1360 | //Save pointer to main module ID for pkg name.
1361 | //Remove leading dot in main, so main paths are normalized,
1362 | //and remove any trailing .js, since different package
1363 | //envs have different conventions: some use a module name,
1364 | //some use a file name.
1365 | config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main')
1366 | .replace(currDirRegExp, '')
1367 | .replace(jsSuffixRegExp, '');
1368 | });
1369 | }
1370 |
1371 | //If there are any "waiting to execute" modules in the registry,
1372 | //update the maps for them, since their info, like URLs to load,
1373 | //may have changed.
1374 | eachProp(registry, function (mod, id) {
1375 | //If module already has init called, since it is too
1376 | //late to modify them, and ignore unnormalized ones
1377 | //since they are transient.
1378 | if (!mod.inited && !mod.map.unnormalized) {
1379 | mod.map = makeModuleMap(id, null, true);
1380 | }
1381 | });
1382 |
1383 | //If a deps array or a config callback is specified, then call
1384 | //require with those args. This is useful when require is defined as a
1385 | //config object before require.js is loaded.
1386 | if (cfg.deps || cfg.callback) {
1387 | context.require(cfg.deps || [], cfg.callback);
1388 | }
1389 | },
1390 |
1391 | makeShimExports: function (value) {
1392 | function fn() {
1393 | var ret;
1394 | if (value.init) {
1395 | ret = value.init.apply(global, arguments);
1396 | }
1397 | return ret || (value.exports && getGlobal(value.exports));
1398 | }
1399 | return fn;
1400 | },
1401 |
1402 | makeRequire: function (relMap, options) {
1403 | options = options || {};
1404 |
1405 | function localRequire(deps, callback, errback) {
1406 | var id, map, requireMod;
1407 |
1408 | if (options.enableBuildCallback && callback && isFunction(callback)) {
1409 | callback.__requireJsBuild = true;
1410 | }
1411 |
1412 | if (typeof deps === 'string') {
1413 | if (isFunction(callback)) {
1414 | //Invalid call
1415 | return onError(makeError('requireargs', 'Invalid require call'), errback);
1416 | }
1417 |
1418 | //If require|exports|module are requested, get the
1419 | //value for them from the special handlers. Caveat:
1420 | //this only works while module is being defined.
1421 | if (relMap && hasProp(handlers, deps)) {
1422 | return handlers[deps](registry[relMap.id]);
1423 | }
1424 |
1425 | //Synchronous access to one module. If require.get is
1426 | //available (as in the Node adapter), prefer that.
1427 | if (req.get) {
1428 | return req.get(context, deps, relMap, localRequire);
1429 | }
1430 |
1431 | //Normalize module name, if it contains . or ..
1432 | map = makeModuleMap(deps, relMap, false, true);
1433 | id = map.id;
1434 |
1435 | if (!hasProp(defined, id)) {
1436 | return onError(makeError('notloaded', 'Module name "' +
1437 | id +
1438 | '" has not been loaded yet for context: ' +
1439 | contextName +
1440 | (relMap ? '' : '. Use require([])')));
1441 | }
1442 | return defined[id];
1443 | }
1444 |
1445 | //Grab defines waiting in the global queue.
1446 | intakeDefines();
1447 |
1448 | //Mark all the dependencies as needing to be loaded.
1449 | context.nextTick(function () {
1450 | //Some defines could have been added since the
1451 | //require call, collect them.
1452 | intakeDefines();
1453 |
1454 | requireMod = getModule(makeModuleMap(null, relMap));
1455 |
1456 | //Store if map config should be applied to this require
1457 | //call for dependencies.
1458 | requireMod.skipMap = options.skipMap;
1459 |
1460 | requireMod.init(deps, callback, errback, {
1461 | enabled: true
1462 | });
1463 |
1464 | checkLoaded();
1465 | });
1466 |
1467 | return localRequire;
1468 | }
1469 |
1470 | mixin(localRequire, {
1471 | isBrowser: isBrowser,
1472 |
1473 | /**
1474 | * Converts a module name + .extension into an URL path.
1475 | * *Requires* the use of a module name. It does not support using
1476 | * plain URLs like nameToUrl.
1477 | */
1478 | toUrl: function (moduleNamePlusExt) {
1479 | var ext,
1480 | index = moduleNamePlusExt.lastIndexOf('.'),
1481 | segment = moduleNamePlusExt.split('/')[0],
1482 | isRelative = segment === '.' || segment === '..';
1483 |
1484 | //Have a file extension alias, and it is not the
1485 | //dots from a relative path.
1486 | if (index !== -1 && (!isRelative || index > 1)) {
1487 | ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
1488 | moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
1489 | }
1490 |
1491 | return context.nameToUrl(normalize(moduleNamePlusExt,
1492 | relMap && relMap.id, true), ext, true);
1493 | },
1494 |
1495 | defined: function (id) {
1496 | return hasProp(defined, makeModuleMap(id, relMap, false, true).id);
1497 | },
1498 |
1499 | specified: function (id) {
1500 | id = makeModuleMap(id, relMap, false, true).id;
1501 | return hasProp(defined, id) || hasProp(registry, id);
1502 | }
1503 | });
1504 |
1505 | //Only allow undef on top level require calls
1506 | if (!relMap) {
1507 | localRequire.undef = function (id) {
1508 | //Bind any waiting define() calls to this context,
1509 | //fix for #408
1510 | takeGlobalQueue();
1511 |
1512 | var map = makeModuleMap(id, relMap, true),
1513 | mod = getOwn(registry, id);
1514 |
1515 | mod.undefed = true;
1516 | removeScript(id);
1517 |
1518 | delete defined[id];
1519 | delete urlFetched[map.url];
1520 | delete undefEvents[id];
1521 |
1522 | //Clean queued defines too. Go backwards
1523 | //in array so that the splices do not
1524 | //mess up the iteration.
1525 | eachReverse(defQueue, function(args, i) {
1526 | if (args[0] === id) {
1527 | defQueue.splice(i, 1);
1528 | }
1529 | });
1530 | delete context.defQueueMap[id];
1531 |
1532 | if (mod) {
1533 | //Hold on to listeners in case the
1534 | //module will be attempted to be reloaded
1535 | //using a different config.
1536 | if (mod.events.defined) {
1537 | undefEvents[id] = mod.events;
1538 | }
1539 |
1540 | cleanRegistry(id);
1541 | }
1542 | };
1543 | }
1544 |
1545 | return localRequire;
1546 | },
1547 |
1548 | /**
1549 | * Called to enable a module if it is still in the registry
1550 | * awaiting enablement. A second arg, parent, the parent module,
1551 | * is passed in for context, when this method is overridden by
1552 | * the optimizer. Not shown here to keep code compact.
1553 | */
1554 | enable: function (depMap) {
1555 | var mod = getOwn(registry, depMap.id);
1556 | if (mod) {
1557 | getModule(depMap).enable();
1558 | }
1559 | },
1560 |
1561 | /**
1562 | * Internal method used by environment adapters to complete a load event.
1563 | * A load event could be a script load or just a load pass from a synchronous
1564 | * load call.
1565 | * @param {String} moduleName the name of the module to potentially complete.
1566 | */
1567 | completeLoad: function (moduleName) {
1568 | var found, args, mod,
1569 | shim = getOwn(config.shim, moduleName) || {},
1570 | shExports = shim.exports;
1571 |
1572 | takeGlobalQueue();
1573 |
1574 | while (defQueue.length) {
1575 | args = defQueue.shift();
1576 | if (args[0] === null) {
1577 | args[0] = moduleName;
1578 | //If already found an anonymous module and bound it
1579 | //to this name, then this is some other anon module
1580 | //waiting for its completeLoad to fire.
1581 | if (found) {
1582 | break;
1583 | }
1584 | found = true;
1585 | } else if (args[0] === moduleName) {
1586 | //Found matching define call for this script!
1587 | found = true;
1588 | }
1589 |
1590 | callGetModule(args);
1591 | }
1592 | context.defQueueMap = {};
1593 |
1594 | //Do this after the cycle of callGetModule in case the result
1595 | //of those calls/init calls changes the registry.
1596 | mod = getOwn(registry, moduleName);
1597 |
1598 | if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) {
1599 | if (config.enforceDefine && (!shExports || !getGlobal(shExports))) {
1600 | if (hasPathFallback(moduleName)) {
1601 | return;
1602 | } else {
1603 | return onError(makeError('nodefine',
1604 | 'No define call for ' + moduleName,
1605 | null,
1606 | [moduleName]));
1607 | }
1608 | } else {
1609 | //A script that does not call define(), so just simulate
1610 | //the call for it.
1611 | callGetModule([moduleName, (shim.deps || []), shim.exportsFn]);
1612 | }
1613 | }
1614 |
1615 | checkLoaded();
1616 | },
1617 |
1618 | /**
1619 | * Converts a module name to a file path. Supports cases where
1620 | * moduleName may actually be just an URL.
1621 | * Note that it **does not** call normalize on the moduleName,
1622 | * it is assumed to have already been normalized. This is an
1623 | * internal API, not a public one. Use toUrl for the public API.
1624 | */
1625 | nameToUrl: function (moduleName, ext, skipExt) {
1626 | var paths, syms, i, parentModule, url,
1627 | parentPath, bundleId,
1628 | pkgMain = getOwn(config.pkgs, moduleName);
1629 |
1630 | if (pkgMain) {
1631 | moduleName = pkgMain;
1632 | }
1633 |
1634 | bundleId = getOwn(bundlesMap, moduleName);
1635 |
1636 | if (bundleId) {
1637 | return context.nameToUrl(bundleId, ext, skipExt);
1638 | }
1639 |
1640 | //If a colon is in the URL, it indicates a protocol is used and it is just
1641 | //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?)
1642 | //or ends with .js, then assume the user meant to use an url and not a module id.
1643 | //The slash is important for protocol-less URLs as well as full paths.
1644 | if (req.jsExtRegExp.test(moduleName)) {
1645 | //Just a plain path, not module name lookup, so just return it.
1646 | //Add extension if it is included. This is a bit wonky, only non-.js things pass
1647 | //an extension, this method probably needs to be reworked.
1648 | url = moduleName + (ext || '');
1649 | } else {
1650 | //A module that needs to be converted to a path.
1651 | paths = config.paths;
1652 |
1653 | syms = moduleName.split('/');
1654 | //For each module name segment, see if there is a path
1655 | //registered for it. Start with most specific name
1656 | //and work up from it.
1657 | for (i = syms.length; i > 0; i -= 1) {
1658 | parentModule = syms.slice(0, i).join('/');
1659 |
1660 | parentPath = getOwn(paths, parentModule);
1661 | if (parentPath) {
1662 | //If an array, it means there are a few choices,
1663 | //Choose the one that is desired
1664 | if (isArray(parentPath)) {
1665 | parentPath = parentPath[0];
1666 | }
1667 | syms.splice(0, i, parentPath);
1668 | break;
1669 | }
1670 | }
1671 |
1672 | //Join the path parts together, then figure out if baseUrl is needed.
1673 | url = syms.join('/');
1674 | url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js'));
1675 | url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
1676 | }
1677 |
1678 | return config.urlArgs && !/^blob\:/.test(url) ?
1679 | url + config.urlArgs(moduleName, url) : url;
1680 | },
1681 |
1682 | //Delegates to req.load. Broken out as a separate function to
1683 | //allow overriding in the optimizer.
1684 | load: function (id, url) {
1685 | req.load(context, id, url);
1686 | },
1687 |
1688 | /**
1689 | * Executes a module callback function. Broken out as a separate function
1690 | * solely to allow the build system to sequence the files in the built
1691 | * layer in the right sequence.
1692 | *
1693 | * @private
1694 | */
1695 | execCb: function (name, callback, args, exports) {
1696 | return callback.apply(exports, args);
1697 | },
1698 |
1699 | /**
1700 | * callback for script loads, used to check status of loading.
1701 | *
1702 | * @param {Event} evt the event from the browser for the script
1703 | * that was loaded.
1704 | */
1705 | onScriptLoad: function (evt) {
1706 | //Using currentTarget instead of target for Firefox 2.0's sake. Not
1707 | //all old browsers will be supported, but this one was easy enough
1708 | //to support and still makes sense.
1709 | if (evt.type === 'load' ||
1710 | (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) {
1711 | //Reset interactive script so a script node is not held onto for
1712 | //to long.
1713 | interactiveScript = null;
1714 |
1715 | //Pull out the name of the module and the context.
1716 | var data = getScriptData(evt);
1717 | context.completeLoad(data.id);
1718 | }
1719 | },
1720 |
1721 | /**
1722 | * Callback for script errors.
1723 | */
1724 | onScriptError: function (evt) {
1725 | var data = getScriptData(evt);
1726 | if (!hasPathFallback(data.id)) {
1727 | var parents = [];
1728 | eachProp(registry, function(value, key) {
1729 | if (key.indexOf('_@r') !== 0) {
1730 | each(value.depMaps, function(depMap) {
1731 | if (depMap.id === data.id) {
1732 | parents.push(key);
1733 | return true;
1734 | }
1735 | });
1736 | }
1737 | });
1738 | return onError(makeError('scripterror', 'Script error for "' + data.id +
1739 | (parents.length ?
1740 | '", needed by: ' + parents.join(', ') :
1741 | '"'), evt, [data.id]));
1742 | }
1743 | }
1744 | };
1745 |
1746 | context.require = context.makeRequire();
1747 | return context;
1748 | }
1749 |
1750 | /**
1751 | * Main entry point.
1752 | *
1753 | * If the only argument to require is a string, then the module that
1754 | * is represented by that string is fetched for the appropriate context.
1755 | *
1756 | * If the first argument is an array, then it will be treated as an array
1757 | * of dependency string names to fetch. An optional function callback can
1758 | * be specified to execute when all of those dependencies are available.
1759 | *
1760 | * Make a local req variable to help Caja compliance (it assumes things
1761 | * on a require that are not standardized), and to give a short
1762 | * name for minification/local scope use.
1763 | */
1764 | req = requirejs = function (deps, callback, errback, optional) {
1765 |
1766 | //Find the right context, use default
1767 | var context, config,
1768 | contextName = defContextName;
1769 |
1770 | // Determine if have config object in the call.
1771 | if (!isArray(deps) && typeof deps !== 'string') {
1772 | // deps is a config object
1773 | config = deps;
1774 | if (isArray(callback)) {
1775 | // Adjust args if there are dependencies
1776 | deps = callback;
1777 | callback = errback;
1778 | errback = optional;
1779 | } else {
1780 | deps = [];
1781 | }
1782 | }
1783 |
1784 | if (config && config.context) {
1785 | contextName = config.context;
1786 | }
1787 |
1788 | context = getOwn(contexts, contextName);
1789 | if (!context) {
1790 | context = contexts[contextName] = req.s.newContext(contextName);
1791 | }
1792 |
1793 | if (config) {
1794 | context.configure(config);
1795 | }
1796 |
1797 | return context.require(deps, callback, errback);
1798 | };
1799 |
1800 | /**
1801 | * Support require.config() to make it easier to cooperate with other
1802 | * AMD loaders on globally agreed names.
1803 | */
1804 | req.config = function (config) {
1805 | return req(config);
1806 | };
1807 |
1808 | /**
1809 | * Execute something after the current tick
1810 | * of the event loop. Override for other envs
1811 | * that have a better solution than setTimeout.
1812 | * @param {Function} fn function to execute later.
1813 | */
1814 | req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) {
1815 | setTimeout(fn, 4);
1816 | } : function (fn) { fn(); };
1817 |
1818 | /**
1819 | * Export require as a global, but only if it does not already exist.
1820 | */
1821 | if (!require) {
1822 | require = req;
1823 | }
1824 |
1825 | req.version = version;
1826 |
1827 | //Used to filter out dependencies that are already paths.
1828 | req.jsExtRegExp = /^\/|:|\?|\.js$/;
1829 | req.isBrowser = isBrowser;
1830 | s = req.s = {
1831 | contexts: contexts,
1832 | newContext: newContext
1833 | };
1834 |
1835 | //Create default context.
1836 | req({});
1837 |
1838 | //Exports some context-sensitive methods on global require.
1839 | each([
1840 | 'toUrl',
1841 | 'undef',
1842 | 'defined',
1843 | 'specified'
1844 | ], function (prop) {
1845 | //Reference from contexts instead of early binding to default context,
1846 | //so that during builds, the latest instance of the default context
1847 | //with its config gets used.
1848 | req[prop] = function () {
1849 | var ctx = contexts[defContextName];
1850 | return ctx.require[prop].apply(ctx, arguments);
1851 | };
1852 | });
1853 |
1854 | if (isBrowser) {
1855 | head = s.head = document.getElementsByTagName('head')[0];
1856 | //If BASE tag is in play, using appendChild is a problem for IE6.
1857 | //When that browser dies, this can be removed. Details in this jQuery bug:
1858 | //http://dev.jquery.com/ticket/2709
1859 | baseElement = document.getElementsByTagName('base')[0];
1860 | if (baseElement) {
1861 | head = s.head = baseElement.parentNode;
1862 | }
1863 | }
1864 |
1865 | /**
1866 | * Any errors that require explicitly generates will be passed to this
1867 | * function. Intercept/override it if you want custom error handling.
1868 | * @param {Error} err the error object.
1869 | */
1870 | req.onError = defaultOnError;
1871 |
1872 | /**
1873 | * Creates the node for the load command. Only used in browser envs.
1874 | */
1875 | req.createNode = function (config, moduleName, url) {
1876 | var node = config.xhtml ?
1877 | document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
1878 | document.createElement('script');
1879 | node.type = config.scriptType || 'text/javascript';
1880 | node.charset = 'utf-8';
1881 | node.async = true;
1882 | return node;
1883 | };
1884 |
1885 | /**
1886 | * Does the request to load a module for the browser case.
1887 | * Make this a separate function to allow other environments
1888 | * to override it.
1889 | *
1890 | * @param {Object} context the require context to find state.
1891 | * @param {String} moduleName the name of the module.
1892 | * @param {Object} url the URL to the module.
1893 | */
1894 | req.load = function (context, moduleName, url) {
1895 | var config = (context && context.config) || {},
1896 | node;
1897 | if (isBrowser) {
1898 | //In the browser so use a script tag
1899 | node = req.createNode(config, moduleName, url);
1900 |
1901 | node.setAttribute('data-requirecontext', context.contextName);
1902 | node.setAttribute('data-requiremodule', moduleName);
1903 |
1904 | //Set up load listener. Test attachEvent first because IE9 has
1905 | //a subtle issue in its addEventListener and script onload firings
1906 | //that do not match the behavior of all other browsers with
1907 | //addEventListener support, which fire the onload event for a
1908 | //script right after the script execution. See:
1909 | //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution
1910 | //UNFORTUNATELY Opera implements attachEvent but does not follow the script
1911 | //script execution mode.
1912 | if (node.attachEvent &&
1913 | //Check if node.attachEvent is artificially added by custom script or
1914 | //natively supported by browser
1915 | //read https://github.com/requirejs/requirejs/issues/187
1916 | //if we can NOT find [native code] then it must NOT natively supported.
1917 | //in IE8, node.attachEvent does not have toString()
1918 | //Note the test for "[native code" with no closing brace, see:
1919 | //https://github.com/requirejs/requirejs/issues/273
1920 | !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) &&
1921 | !isOpera) {
1922 | //Probably IE. IE (at least 6-8) do not fire
1923 | //script onload right after executing the script, so
1924 | //we cannot tie the anonymous define call to a name.
1925 | //However, IE reports the script as being in 'interactive'
1926 | //readyState at the time of the define call.
1927 | useInteractive = true;
1928 |
1929 | node.attachEvent('onreadystatechange', context.onScriptLoad);
1930 | //It would be great to add an error handler here to catch
1931 | //404s in IE9+. However, onreadystatechange will fire before
1932 | //the error handler, so that does not help. If addEventListener
1933 | //is used, then IE will fire error before load, but we cannot
1934 | //use that pathway given the connect.microsoft.com issue
1935 | //mentioned above about not doing the 'script execute,
1936 | //then fire the script load event listener before execute
1937 | //next script' that other browsers do.
1938 | //Best hope: IE10 fixes the issues,
1939 | //and then destroys all installs of IE 6-9.
1940 | //node.attachEvent('onerror', context.onScriptError);
1941 | } else {
1942 | node.addEventListener('load', context.onScriptLoad, false);
1943 | node.addEventListener('error', context.onScriptError, false);
1944 | }
1945 | node.src = url;
1946 |
1947 | //Calling onNodeCreated after all properties on the node have been
1948 | //set, but before it is placed in the DOM.
1949 | if (config.onNodeCreated) {
1950 | config.onNodeCreated(node, config, moduleName, url);
1951 | }
1952 |
1953 | //For some cache cases in IE 6-8, the script executes before the end
1954 | //of the appendChild execution, so to tie an anonymous define
1955 | //call to the module name (which is stored on the node), hold on
1956 | //to a reference to this node, but clear after the DOM insertion.
1957 | currentlyAddingScript = node;
1958 | if (baseElement) {
1959 | head.insertBefore(node, baseElement);
1960 | } else {
1961 | head.appendChild(node);
1962 | }
1963 | currentlyAddingScript = null;
1964 |
1965 | return node;
1966 | } else if (isWebWorker) {
1967 | try {
1968 | //In a web worker, use importScripts. This is not a very
1969 | //efficient use of importScripts, importScripts will block until
1970 | //its script is downloaded and evaluated. However, if web workers
1971 | //are in play, the expectation is that a build has been done so
1972 | //that only one script needs to be loaded anyway. This may need
1973 | //to be reevaluated if other use cases become common.
1974 |
1975 | // Post a task to the event loop to work around a bug in WebKit
1976 | // where the worker gets garbage-collected after calling
1977 | // importScripts(): https://webkit.org/b/153317
1978 | setTimeout(function() {}, 0);
1979 | importScripts(url);
1980 |
1981 | //Account for anonymous modules
1982 | context.completeLoad(moduleName);
1983 | } catch (e) {
1984 | context.onError(makeError('importscripts',
1985 | 'importScripts failed for ' +
1986 | moduleName + ' at ' + url,
1987 | e,
1988 | [moduleName]));
1989 | }
1990 | }
1991 | };
1992 |
1993 | function getInteractiveScript() {
1994 | if (interactiveScript && interactiveScript.readyState === 'interactive') {
1995 | return interactiveScript;
1996 | }
1997 |
1998 | eachReverse(scripts(), function (script) {
1999 | if (script.readyState === 'interactive') {
2000 | return (interactiveScript = script);
2001 | }
2002 | });
2003 | return interactiveScript;
2004 | }
2005 |
2006 | //Look for a data-main script attribute, which could also adjust the baseUrl.
2007 | if (isBrowser && !cfg.skipDataMain) {
2008 | //Figure out baseUrl. Get it from the script tag with require.js in it.
2009 | eachReverse(scripts(), function (script) {
2010 | //Set the 'head' where we can append children by
2011 | //using the script's parent.
2012 | if (!head) {
2013 | head = script.parentNode;
2014 | }
2015 |
2016 | //Look for a data-main attribute to set main script for the page
2017 | //to load. If it is there, the path to data main becomes the
2018 | //baseUrl, if it is not already set.
2019 | dataMain = script.getAttribute('data-main');
2020 | if (dataMain) {
2021 | //Preserve dataMain in case it is a path (i.e. contains '?')
2022 | mainScript = dataMain;
2023 |
2024 | //Set final baseUrl if there is not already an explicit one,
2025 | //but only do so if the data-main value is not a loader plugin
2026 | //module ID.
2027 | if (!cfg.baseUrl && mainScript.indexOf('!') === -1) {
2028 | //Pull off the directory of data-main for use as the
2029 | //baseUrl.
2030 | src = mainScript.split('/');
2031 | mainScript = src.pop();
2032 | subPath = src.length ? src.join('/') + '/' : './';
2033 |
2034 | cfg.baseUrl = subPath;
2035 | }
2036 |
2037 | //Strip off any trailing .js since mainScript is now
2038 | //like a module name.
2039 | mainScript = mainScript.replace(jsSuffixRegExp, '');
2040 |
2041 | //If mainScript is still a path, fall back to dataMain
2042 | if (req.jsExtRegExp.test(mainScript)) {
2043 | mainScript = dataMain;
2044 | }
2045 |
2046 | //Put the data-main script in the files to load.
2047 | cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];
2048 |
2049 | return true;
2050 | }
2051 | });
2052 | }
2053 |
2054 | /**
2055 | * The function that handles definitions of modules. Differs from
2056 | * require() in that a string for the module should be the first argument,
2057 | * and the function to execute after dependencies are loaded should
2058 | * return a value to define the module corresponding to the first argument's
2059 | * name.
2060 | */
2061 | define = function (name, deps, callback) {
2062 | var node, context;
2063 |
2064 | //Allow for anonymous modules
2065 | if (typeof name !== 'string') {
2066 | //Adjust args appropriately
2067 | callback = deps;
2068 | deps = name;
2069 | name = null;
2070 | }
2071 |
2072 | //This module may not have dependencies
2073 | if (!isArray(deps)) {
2074 | callback = deps;
2075 | deps = null;
2076 | }
2077 |
2078 | //If no name, and callback is a function, then figure out if it a
2079 | //CommonJS thing with dependencies.
2080 | if (!deps && isFunction(callback)) {
2081 | deps = [];
2082 | //Remove comments from the callback string,
2083 | //look for require calls, and pull them into the dependencies,
2084 | //but only if there are function args.
2085 | if (callback.length) {
2086 | callback
2087 | .toString()
2088 | .replace(commentRegExp, commentReplace)
2089 | .replace(cjsRequireRegExp, function (match, dep) {
2090 | deps.push(dep);
2091 | });
2092 |
2093 | //May be a CommonJS thing even without require calls, but still
2094 | //could use exports, and module. Avoid doing exports and module
2095 | //work though if it just needs require.
2096 | //REQUIRES the function to expect the CommonJS variables in the
2097 | //order listed below.
2098 | deps = (callback.length === 1 ? ['require'] : ['require', 'exports', 'module']).concat(deps);
2099 | }
2100 | }
2101 |
2102 | //If in IE 6-8 and hit an anonymous define() call, do the interactive
2103 | //work.
2104 | if (useInteractive) {
2105 | node = currentlyAddingScript || getInteractiveScript();
2106 | if (node) {
2107 | if (!name) {
2108 | name = node.getAttribute('data-requiremodule');
2109 | }
2110 | context = contexts[node.getAttribute('data-requirecontext')];
2111 | }
2112 | }
2113 |
2114 | //Always save off evaluating the def call until the script onload handler.
2115 | //This allows multiple modules to be in a file without prematurely
2116 | //tracing dependencies, and allows for anonymous module support,
2117 | //where the module name is not known until the script onload event
2118 | //occurs. If no context, use the global queue, and get it processed
2119 | //in the onscript load callback.
2120 | if (context) {
2121 | context.defQueue.push([name, deps, callback]);
2122 | context.defQueueMap[name] = true;
2123 | } else {
2124 | globalDefQueue.push([name, deps, callback]);
2125 | }
2126 | };
2127 |
2128 | define.amd = {
2129 | jQuery: true
2130 | };
2131 |
2132 | /**
2133 | * Executes the text. Normally just uses eval, but can be modified
2134 | * to use a better, environment-specific call. Only used for transpiling
2135 | * loader plugins, not for plain JS modules.
2136 | * @param {String} text the text to execute/evaluate.
2137 | */
2138 | req.exec = function (text) {
2139 | /*jslint evil: true */
2140 | return eval(text);
2141 | };
2142 |
2143 | //Set up with config info.
2144 | req(cfg);
2145 | }(this, (typeof setTimeout === 'undefined' ? undefined : setTimeout)));
2146 |
--------------------------------------------------------------------------------