asset_hat 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/Gemfile.lock +37 -0
- data/HISTORY +10 -0
- data/README.rdoc +117 -75
- data/Rakefile +4 -4
- data/VERSION.yml +2 -2
- data/asset_hat.gemspec +69 -7
- data/config/assets.yml +46 -24
- data/doc/classes/AssetHat.html +183 -118
- data/doc/classes/AssetHat/CSS.html +21 -21
- data/doc/classes/AssetHat/CSS/Engines.html +10 -10
- data/doc/classes/AssetHat/JS.html +13 -13
- data/doc/classes/AssetHat/JS/Engines.html +10 -10
- data/doc/classes/AssetHat/JS/Vendors.html +85 -22
- data/doc/classes/AssetHatHelper.html +94 -19
- data/doc/created.rid +1 -1
- data/doc/files/HISTORY.html +20 -2
- data/doc/files/LICENSE.html +1 -1
- data/doc/files/README_rdoc.html +87 -31
- data/doc/files/lib/asset_hat/capistrano_rb.html +1 -1
- data/doc/files/lib/asset_hat/css_rb.html +1 -1
- data/doc/files/lib/asset_hat/initializers/action_view_rb.html +49 -0
- data/doc/files/lib/asset_hat/initializers/cache_last_commit_ids_rb.html +49 -0
- data/doc/files/lib/asset_hat/js/vendors_rb.html +1 -1
- data/doc/files/lib/asset_hat/js_rb.html +1 -1
- data/doc/files/lib/asset_hat/railtie_rb.html +61 -0
- data/doc/files/lib/asset_hat/tasks/css_rb.html +1 -1
- data/doc/files/lib/asset_hat/tasks/js_rb.html +1 -1
- data/doc/files/lib/asset_hat/tasks_rb.html +2 -1
- data/doc/files/lib/asset_hat/unicorn_rb.html +58 -0
- data/doc/files/lib/asset_hat/vcs_rb.html +1 -1
- data/doc/files/lib/asset_hat/version_rb.html +1 -1
- data/doc/files/{app/helpers → lib}/asset_hat_helper_rb.html +3 -3
- data/doc/files/lib/asset_hat_rb.html +9 -1
- data/doc/files/lib/tasks/asset_hat_rake.html +54 -0
- data/doc/fr_file_index.html +6 -1
- data/doc/fr_method_index.html +60 -52
- data/lib/asset_hat.rb +104 -59
- data/lib/asset_hat/initializers/action_view.rb +1 -0
- data/lib/asset_hat/initializers/cache_last_commit_ids.rb +1 -0
- data/lib/asset_hat/js/vendors.rb +198 -72
- data/lib/asset_hat/railtie.rb +19 -0
- data/lib/asset_hat/tasks.rb +5 -2
- data/lib/asset_hat/unicorn.rb +9 -0
- data/lib/asset_hat/vcs.rb +3 -2
- data/{app/helpers → lib}/asset_hat_helper.rb +184 -29
- data/{tasks → lib/tasks}/asset_hat.rake +0 -0
- data/rails/init.rb +2 -2
- data/test/asset_hat_helper_test.rb +731 -148
- data/test/asset_hat_test.rb +23 -2
- data/test/test_helper.rb +4 -8
- metadata +311 -30
data/doc/fr_method_index.html
CHANGED
@@ -4331,34 +4331,38 @@
|
|
4331
4331
|
|
4332
4332
|
Element.addMethods();
|
4333
4333
|
var search_index = [
|
4334
|
-
{ method: 'add_asset_commit_ids', module: 'assethat::css', html: '<a href="classes/AssetHat/CSS.html#
|
4335
|
-
{ method: 'add_asset_hosts', module: 'assethat::css', html: '<a href="classes/AssetHat/CSS.html#
|
4336
|
-
{ method: 'asset_exists?', module: 'assethat', html: '<a href="classes/AssetHat.html#
|
4334
|
+
{ method: 'add_asset_commit_ids', module: 'assethat::css', html: '<a href="classes/AssetHat/CSS.html#M000021"><span class="method_name">add_asset_commit_ids</span> <span class="module_name">(AssetHat::CSS)</span></a>' },
|
4335
|
+
{ method: 'add_asset_hosts', module: 'assethat::css', html: '<a href="classes/AssetHat/CSS.html#M000022"><span class="method_name">add_asset_hosts</span> <span class="module_name">(AssetHat::CSS)</span></a>' },
|
4336
|
+
{ method: 'asset_exists?', module: 'assethat', html: '<a href="classes/AssetHat.html#M000010"><span class="method_name">asset_exists?</span> <span class="module_name">(AssetHat)</span></a>' },
|
4337
|
+
{ method: 'asset_path', module: 'assethathelper', html: '<a href="classes/AssetHatHelper.html#M000032"><span class="method_name">asset_path</span> <span class="module_name">(AssetHatHelper)</span></a>' },
|
4337
4338
|
{ method: 'assets_dir', module: 'assethat', html: '<a href="classes/AssetHat.html#M000006"><span class="method_name">assets_dir</span> <span class="module_name">(AssetHat)</span></a>' },
|
4338
|
-
{ method: '
|
4339
|
-
{ method: '
|
4340
|
-
{ method: '
|
4341
|
-
{ method: '
|
4342
|
-
{ method: '
|
4343
|
-
{ method: '
|
4344
|
-
{ method: '
|
4339
|
+
{ method: 'assets_path', module: 'assethat', html: '<a href="classes/AssetHat.html#M000007"><span class="method_name">assets_path</span> <span class="module_name">(AssetHat)</span></a>' },
|
4340
|
+
{ method: 'bundle_filenames', module: 'assethat', html: '<a href="classes/AssetHat.html#M000014"><span class="method_name">bundle_filenames</span> <span class="module_name">(AssetHat)</span></a>' },
|
4341
|
+
{ method: 'bundle_filepaths', module: 'assethat', html: '<a href="classes/AssetHat.html#M000015"><span class="method_name">bundle_filepaths</span> <span class="module_name">(AssetHat)</span></a>' },
|
4342
|
+
{ method: 'bundles_dir', module: 'assethat', html: '<a href="classes/AssetHat.html#M000008"><span class="method_name">bundles_dir</span> <span class="module_name">(AssetHat)</span></a>' },
|
4343
|
+
{ method: 'bundles_path', module: 'assethat', html: '<a href="classes/AssetHat.html#M000009"><span class="method_name">bundles_path</span> <span class="module_name">(AssetHat)</span></a>' },
|
4344
|
+
{ method: 'cache?', module: 'assethat', html: '<a href="classes/AssetHat.html#M000011"><span class="method_name">cache?</span> <span class="module_name">(AssetHat)</span></a>' },
|
4345
|
+
{ method: 'cache_last_commit_ids', module: 'assethat', html: '<a href="classes/AssetHat.html#M000004"><span class="method_name">cache_last_commit_ids</span> <span class="module_name">(AssetHat)</span></a>' },
|
4346
|
+
{ method: 'clear_html_cache', module: 'assethat', html: '<a href="classes/AssetHat.html#M000018"><span class="method_name">clear_html_cache</span> <span class="module_name">(AssetHat)</span></a>' },
|
4347
|
+
{ method: 'compute_asset_host', module: 'assethat', html: '<a href="classes/AssetHat.html#M000016"><span class="method_name">compute_asset_host</span> <span class="module_name">(AssetHat)</span></a>' },
|
4345
4348
|
{ method: 'config', module: 'assethat', html: '<a href="classes/AssetHat.html#M000005"><span class="method_name">config</span> <span class="module_name">(AssetHat)</span></a>' },
|
4346
|
-
{ method: '
|
4347
|
-
{ method: '
|
4348
|
-
{ method: '
|
4349
|
-
{ method: '
|
4350
|
-
{ method: '
|
4351
|
-
{ method: '
|
4352
|
-
{ method: '
|
4353
|
-
{ method: 'min_filepath', module: 'assethat
|
4354
|
-
{ method: 'min_filepath', module: 'assethat', html: '<a href="classes/AssetHat.html#
|
4355
|
-
{ method: '
|
4356
|
-
{ method: 'minify', module: 'assethat::js', html: '<a href="classes/AssetHat/JS.html#
|
4357
|
-
{ method: '
|
4358
|
-
{ method: '
|
4359
|
-
{ method: '
|
4360
|
-
{ method: '
|
4361
|
-
{ method: 'weak', module: 'assethat::css::engines', html: '<a href="classes/AssetHat/CSS/Engines.html#
|
4349
|
+
{ method: 'consider_all_requests_local?', module: 'assethat', html: '<a href="classes/AssetHat.html#M000012"><span class="method_name">consider_all_requests_local?</span> <span class="module_name">(AssetHat)</span></a>' },
|
4350
|
+
{ method: 'cssmin', module: 'assethat::css::engines', html: '<a href="classes/AssetHat/CSS/Engines.html#M000024"><span class="method_name">cssmin</span> <span class="module_name">(AssetHat::CSS::Engines)</span></a>' },
|
4351
|
+
{ method: 'include_css', module: 'assethathelper', html: '<a href="classes/AssetHatHelper.html#M000030"><span class="method_name">include_css</span> <span class="module_name">(AssetHatHelper)</span></a>' },
|
4352
|
+
{ method: 'include_js', module: 'assethathelper', html: '<a href="classes/AssetHatHelper.html#M000031"><span class="method_name">include_js</span> <span class="module_name">(AssetHatHelper)</span></a>' },
|
4353
|
+
{ method: 'jsmin', module: 'assethat::js::engines', html: '<a href="classes/AssetHat/JS/Engines.html#M000029"><span class="method_name">jsmin</span> <span class="module_name">(AssetHat::JS::Engines)</span></a>' },
|
4354
|
+
{ method: 'last_bundle_commit_id', module: 'assethat', html: '<a href="classes/AssetHat.html#M000003"><span class="method_name">last_bundle_commit_id</span> <span class="module_name">(AssetHat)</span></a>' },
|
4355
|
+
{ method: 'last_commit_id', module: 'assethat', html: '<a href="classes/AssetHat.html#M000002"><span class="method_name">last_commit_id</span> <span class="module_name">(AssetHat)</span></a>' },
|
4356
|
+
{ method: 'min_filepath', module: 'assethat', html: '<a href="classes/AssetHat.html#M000013"><span class="method_name">min_filepath</span> <span class="module_name">(AssetHat)</span></a>' },
|
4357
|
+
{ method: 'min_filepath', module: 'assethat::css', html: '<a href="classes/AssetHat/CSS.html#M000019"><span class="method_name">min_filepath</span> <span class="module_name">(AssetHat::CSS)</span></a>' },
|
4358
|
+
{ method: 'min_filepath', module: 'assethat::js', html: '<a href="classes/AssetHat/JS.html#M000025"><span class="method_name">min_filepath</span> <span class="module_name">(AssetHat::JS)</span></a>' },
|
4359
|
+
{ method: 'minify', module: 'assethat::js', html: '<a href="classes/AssetHat/JS.html#M000026"><span class="method_name">minify</span> <span class="module_name">(AssetHat::JS)</span></a>' },
|
4360
|
+
{ method: 'minify', module: 'assethat::css', html: '<a href="classes/AssetHat/CSS.html#M000020"><span class="method_name">minify</span> <span class="module_name">(AssetHat::CSS)</span></a>' },
|
4361
|
+
{ method: 'source_for', module: 'assethat::js::vendors', html: '<a href="classes/AssetHat/JS/Vendors.html#M000027"><span class="method_name">source_for</span> <span class="module_name">(AssetHat::JS::Vendors)</span></a>' },
|
4362
|
+
{ method: 'ssl_asset_host_differs?', module: 'assethat', html: '<a href="classes/AssetHat.html#M000017"><span class="method_name">ssl_asset_host_differs?</span> <span class="module_name">(AssetHat)</span></a>' },
|
4363
|
+
{ method: 'version', module: 'assethat', html: '<a href="classes/AssetHat.html#M000001"><span class="method_name">version</span> <span class="module_name">(AssetHat)</span></a>' },
|
4364
|
+
{ method: 'weak', module: 'assethat::css::engines', html: '<a href="classes/AssetHat/CSS/Engines.html#M000023"><span class="method_name">weak</span> <span class="module_name">(AssetHat::CSS::Engines)</span></a>' },
|
4365
|
+
{ method: 'weak', module: 'assethat::js::engines', html: '<a href="classes/AssetHat/JS/Engines.html#M000028"><span class="method_name">weak</span> <span class="module_name">(AssetHat::JS::Engines)</span></a>' },
|
4362
4366
|
]
|
4363
4367
|
$(document).observe('dom:loaded', function() {
|
4364
4368
|
// Setup search-during-typing.
|
@@ -4429,34 +4433,38 @@
|
|
4429
4433
|
</form>
|
4430
4434
|
<ol class='methods' id='search-results' style='display: none'></ol>
|
4431
4435
|
<ol class='methods' id='index-entries'>
|
4432
|
-
<li><a href="classes/AssetHat/CSS.html#
|
4433
|
-
<li><a href="classes/AssetHat/CSS.html#
|
4434
|
-
<li><a href="classes/AssetHat.html#
|
4436
|
+
<li><a href="classes/AssetHat/CSS.html#M000021"><span class="method_name">add_asset_commit_ids</span> <span class="module_name">(AssetHat::CSS)</span></a></li>
|
4437
|
+
<li><a href="classes/AssetHat/CSS.html#M000022"><span class="method_name">add_asset_hosts</span> <span class="module_name">(AssetHat::CSS)</span></a></li>
|
4438
|
+
<li><a href="classes/AssetHat.html#M000010"><span class="method_name">asset_exists?</span> <span class="module_name">(AssetHat)</span></a></li>
|
4439
|
+
<li><a href="classes/AssetHatHelper.html#M000032"><span class="method_name">asset_path</span> <span class="module_name">(AssetHatHelper)</span></a></li>
|
4435
4440
|
<li><a href="classes/AssetHat.html#M000006"><span class="method_name">assets_dir</span> <span class="module_name">(AssetHat)</span></a></li>
|
4436
|
-
<li><a href="classes/AssetHat.html#
|
4437
|
-
<li><a href="classes/AssetHat.html#
|
4438
|
-
<li><a href="classes/AssetHat.html#
|
4439
|
-
<li><a href="classes/AssetHat.html#
|
4440
|
-
<li><a href="classes/AssetHat.html#
|
4441
|
-
<li><a href="classes/AssetHat.html#
|
4442
|
-
<li><a href="classes/AssetHat.html#
|
4441
|
+
<li><a href="classes/AssetHat.html#M000007"><span class="method_name">assets_path</span> <span class="module_name">(AssetHat)</span></a></li>
|
4442
|
+
<li><a href="classes/AssetHat.html#M000014"><span class="method_name">bundle_filenames</span> <span class="module_name">(AssetHat)</span></a></li>
|
4443
|
+
<li><a href="classes/AssetHat.html#M000015"><span class="method_name">bundle_filepaths</span> <span class="module_name">(AssetHat)</span></a></li>
|
4444
|
+
<li><a href="classes/AssetHat.html#M000008"><span class="method_name">bundles_dir</span> <span class="module_name">(AssetHat)</span></a></li>
|
4445
|
+
<li><a href="classes/AssetHat.html#M000009"><span class="method_name">bundles_path</span> <span class="module_name">(AssetHat)</span></a></li>
|
4446
|
+
<li><a href="classes/AssetHat.html#M000011"><span class="method_name">cache?</span> <span class="module_name">(AssetHat)</span></a></li>
|
4447
|
+
<li><a href="classes/AssetHat.html#M000004"><span class="method_name">cache_last_commit_ids</span> <span class="module_name">(AssetHat)</span></a></li>
|
4448
|
+
<li><a href="classes/AssetHat.html#M000018"><span class="method_name">clear_html_cache</span> <span class="module_name">(AssetHat)</span></a></li>
|
4449
|
+
<li><a href="classes/AssetHat.html#M000016"><span class="method_name">compute_asset_host</span> <span class="module_name">(AssetHat)</span></a></li>
|
4443
4450
|
<li><a href="classes/AssetHat.html#M000005"><span class="method_name">config</span> <span class="module_name">(AssetHat)</span></a></li>
|
4444
|
-
<li><a href="classes/AssetHat
|
4445
|
-
<li><a href="classes/
|
4446
|
-
<li><a href="classes/AssetHatHelper.html#
|
4447
|
-
<li><a href="classes/
|
4448
|
-
<li><a href="classes/AssetHat.html#
|
4449
|
-
<li><a href="classes/AssetHat.html#
|
4450
|
-
<li><a href="classes/AssetHat
|
4451
|
-
<li><a href="classes/AssetHat
|
4452
|
-
<li><a href="classes/AssetHat.html#
|
4453
|
-
<li><a href="classes/AssetHat/
|
4454
|
-
<li><a href="classes/AssetHat/JS.html#
|
4455
|
-
<li><a href="classes/AssetHat/
|
4456
|
-
<li><a href="classes/AssetHat.html#
|
4457
|
-
<li><a href="classes/AssetHat.html#
|
4458
|
-
<li><a href="classes/AssetHat
|
4459
|
-
<li><a href="classes/AssetHat/CSS/Engines.html#
|
4451
|
+
<li><a href="classes/AssetHat.html#M000012"><span class="method_name">consider_all_requests_local?</span> <span class="module_name">(AssetHat)</span></a></li>
|
4452
|
+
<li><a href="classes/AssetHat/CSS/Engines.html#M000024"><span class="method_name">cssmin</span> <span class="module_name">(AssetHat::CSS::Engines)</span></a></li>
|
4453
|
+
<li><a href="classes/AssetHatHelper.html#M000030"><span class="method_name">include_css</span> <span class="module_name">(AssetHatHelper)</span></a></li>
|
4454
|
+
<li><a href="classes/AssetHatHelper.html#M000031"><span class="method_name">include_js</span> <span class="module_name">(AssetHatHelper)</span></a></li>
|
4455
|
+
<li><a href="classes/AssetHat/JS/Engines.html#M000029"><span class="method_name">jsmin</span> <span class="module_name">(AssetHat::JS::Engines)</span></a></li>
|
4456
|
+
<li><a href="classes/AssetHat.html#M000003"><span class="method_name">last_bundle_commit_id</span> <span class="module_name">(AssetHat)</span></a></li>
|
4457
|
+
<li><a href="classes/AssetHat.html#M000002"><span class="method_name">last_commit_id</span> <span class="module_name">(AssetHat)</span></a></li>
|
4458
|
+
<li><a href="classes/AssetHat.html#M000013"><span class="method_name">min_filepath</span> <span class="module_name">(AssetHat)</span></a></li>
|
4459
|
+
<li><a href="classes/AssetHat/CSS.html#M000019"><span class="method_name">min_filepath</span> <span class="module_name">(AssetHat::CSS)</span></a></li>
|
4460
|
+
<li><a href="classes/AssetHat/JS.html#M000025"><span class="method_name">min_filepath</span> <span class="module_name">(AssetHat::JS)</span></a></li>
|
4461
|
+
<li><a href="classes/AssetHat/JS.html#M000026"><span class="method_name">minify</span> <span class="module_name">(AssetHat::JS)</span></a></li>
|
4462
|
+
<li><a href="classes/AssetHat/CSS.html#M000020"><span class="method_name">minify</span> <span class="module_name">(AssetHat::CSS)</span></a></li>
|
4463
|
+
<li><a href="classes/AssetHat/JS/Vendors.html#M000027"><span class="method_name">source_for</span> <span class="module_name">(AssetHat::JS::Vendors)</span></a></li>
|
4464
|
+
<li><a href="classes/AssetHat.html#M000017"><span class="method_name">ssl_asset_host_differs?</span> <span class="module_name">(AssetHat)</span></a></li>
|
4465
|
+
<li><a href="classes/AssetHat.html#M000001"><span class="method_name">version</span> <span class="module_name">(AssetHat)</span></a></li>
|
4466
|
+
<li><a href="classes/AssetHat/CSS/Engines.html#M000023"><span class="method_name">weak</span> <span class="module_name">(AssetHat::CSS::Engines)</span></a></li>
|
4467
|
+
<li><a href="classes/AssetHat/JS/Engines.html#M000028"><span class="method_name">weak</span> <span class="module_name">(AssetHat::JS::Engines)</span></a></li>
|
4460
4468
|
</ol>
|
4461
4469
|
</div>
|
4462
4470
|
</body>
|
data/lib/asset_hat.rb
CHANGED
@@ -1,54 +1,36 @@
|
|
1
|
-
%w[css js vcs].each do |
|
2
|
-
require File.join(File.dirname(__FILE__), 'asset_hat',
|
1
|
+
%w[css js vcs].each do |filename|
|
2
|
+
require File.join(File.dirname(__FILE__), 'asset_hat', filename)
|
3
3
|
end
|
4
4
|
|
5
|
-
# Your assets are covered.
|
6
|
-
#
|
7
|
-
# With Rails' default asset caching, CSS and JS are concatenated (not even
|
8
|
-
# minified) at runtime when that bundle is first requested. Not good enough.
|
9
|
-
# AssetHat can automatically:
|
10
|
-
#
|
11
|
-
# * Easily *minify* and *bundle* CSS and JS on deploy to reduce file sizes and
|
12
|
-
# HTTP requests.
|
13
|
-
# * Load popular <strong>third-party JS</strong> (like jQuery and Prototype)
|
14
|
-
# from {<strong>Google's CDN</strong>}[http://code.google.com/apis/ajaxlibs/]
|
15
|
-
# when in production, or from localhost in development.
|
16
|
-
# * Force image URLs in your CSS to use <strong>CDN subdomains</strong>, not
|
17
|
-
# just the current host.
|
18
|
-
# * Add an image's last Git[http://git-scm.com/] commit ID to its CSS URLs to
|
19
|
-
# <strong>bust browser caches</strong> (e.g.,
|
20
|
-
# <code>/images/foo.png?ab12cd3</code>).
|
21
|
-
#
|
22
|
-
# After setup, you can use these in your layouts and views:
|
23
|
-
#
|
24
|
-
# <%= include_css :bundle => 'application' %>
|
25
|
-
# # => <link href="/stylesheets/bundles/application.min.css"
|
26
|
-
# # media="screen,projection" rel="stylesheet" type="text/css" />
|
27
|
-
#
|
28
|
-
# <%= include_js :bundles => ['plugins', 'common'] %>
|
29
|
-
# # => <script src="/javascripts/bundles/plugins.min.js"
|
30
|
-
# # type="text/javascript"></script>
|
31
|
-
# # <script src="/javascripts/bundles/common.min.js"
|
32
|
-
# # type="text/javascript"></script>
|
33
|
-
#
|
34
|
-
# And this in your deploy script:
|
35
|
-
#
|
36
|
-
# rake asset_hat:minify
|
37
|
-
#
|
38
|
-
# See README.rdoc for more.
|
5
|
+
# Your assets are covered. See README.rdoc for more.
|
39
6
|
module AssetHat
|
40
|
-
|
7
|
+
if defined?(Rails) && Rails::VERSION::MAJOR >= 3
|
8
|
+
RAILS_ROOT = Rails.root || '.' #:nodoc:
|
9
|
+
require 'asset_hat/railtie'
|
10
|
+
else
|
11
|
+
RAILS_ROOT = File.join(File.dirname(__FILE__), '..') unless
|
12
|
+
defined?(RAILS_ROOT) #:nodoc:
|
13
|
+
end
|
41
14
|
|
42
15
|
# Types of supported assets; currently <code>[:css, :js]</code>.
|
43
16
|
TYPES = [:css, :js]
|
44
17
|
|
45
18
|
# Base directory in which all assets are kept, e.g., 'public/'.
|
46
|
-
ASSETS_DIR = defined?(Rails.public_path)
|
19
|
+
ASSETS_DIR = defined?(Rails.public_path) && Rails.public_path.present? ?
|
20
|
+
Rails.public_path : 'public'
|
21
|
+
|
22
|
+
# Root URL path for all stylesheets. For public-facing use.
|
23
|
+
STYLESHEETS_PATH = '/stylesheets'
|
24
|
+
|
25
|
+
# Root URL path for all JavaScripts. For public-facing use.
|
26
|
+
JAVASCRIPTS_PATH = '/javascripts'
|
47
27
|
|
48
|
-
# Directory in which all stylesheets are kept, e.g., 'public/stylesheets
|
28
|
+
# Directory in which all stylesheets are kept, e.g., 'public/stylesheets'.
|
29
|
+
# For internal filesystem use.
|
49
30
|
STYLESHEETS_DIR = File.join(ASSETS_DIR, 'stylesheets')
|
50
31
|
|
51
|
-
# Directory in which all JavaScripts are kept, e.g., 'public/javascripts
|
32
|
+
# Directory in which all JavaScripts are kept, e.g., 'public/javascripts'.
|
33
|
+
# For internal filesystem use.
|
52
34
|
JAVASCRIPTS_DIR = File.join(ASSETS_DIR, 'javascripts')
|
53
35
|
|
54
36
|
# Relative path for the config file.
|
@@ -63,6 +45,11 @@ module AssetHat
|
|
63
45
|
|
64
46
|
# Nested-hash version of <code>config/assets.yml</code>.
|
65
47
|
def self.config
|
48
|
+
unless File.exists?(CONFIG_FILEPATH)
|
49
|
+
raise '`config/assets.yml` is missing! ' +
|
50
|
+
'Run `rake asset_hat:config` to generate it.' and return
|
51
|
+
end
|
52
|
+
|
66
53
|
if !cache? || @config.blank?
|
67
54
|
@config = YAML.load(ERB.new(File.read(CONFIG_FILEPATH)).result)
|
68
55
|
end
|
@@ -70,26 +57,35 @@ module AssetHat
|
|
70
57
|
end
|
71
58
|
|
72
59
|
# Returns the relative path to the directory where the original CSS or JS
|
73
|
-
# files are stored.
|
60
|
+
# files are stored. For internal filesystem use.
|
74
61
|
#
|
75
62
|
# <code>type</code> argument: <code>:css</code> or <code>:js</code>
|
76
63
|
def self.assets_dir(type)
|
77
|
-
|
78
|
-
|
79
|
-
unless TYPES.include?(type)
|
80
|
-
raise "Unknown type \"#{type}\"; should be one of: #{TYPES.join(', ')}."
|
81
|
-
return
|
82
|
-
end
|
83
|
-
|
84
|
-
case type
|
64
|
+
case type.to_sym
|
85
65
|
when :css ; STYLESHEETS_DIR
|
86
66
|
when :js ; JAVASCRIPTS_DIR
|
87
|
-
else
|
67
|
+
else
|
68
|
+
raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.}
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns the root URL path where the original CSS or JS files are stored.
|
74
|
+
# For external URL-building use.
|
75
|
+
#
|
76
|
+
# <code>type</code> argument: <code>:css</code> or <code>:js</code>
|
77
|
+
def self.assets_path(type)
|
78
|
+
case type.to_sym
|
79
|
+
when :css ; STYLESHEETS_PATH
|
80
|
+
when :js ; JAVASCRIPTS_PATH
|
81
|
+
else
|
82
|
+
raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.}
|
83
|
+
nil
|
88
84
|
end
|
89
85
|
end
|
90
86
|
|
91
87
|
# Returns the relative path to the directory where CSS or JS bundles are
|
92
|
-
# stored.
|
88
|
+
# stored. For internal filesystem use.
|
93
89
|
#
|
94
90
|
# Usage:
|
95
91
|
#
|
@@ -116,6 +112,37 @@ module AssetHat
|
|
116
112
|
dir
|
117
113
|
end
|
118
114
|
|
115
|
+
# Returns the root URL path where CSS or JS bundles are stored. For external
|
116
|
+
# URL-building use.
|
117
|
+
#
|
118
|
+
# Usage:
|
119
|
+
#
|
120
|
+
# AssetHat.bundles_path(:css)
|
121
|
+
# # => 'public/stylesheets/bundles'
|
122
|
+
# AssetHat.bundles_path(:js, :ssl => true)
|
123
|
+
# # => 'public/javascripts/bundles/ssl
|
124
|
+
#
|
125
|
+
# Options:
|
126
|
+
#
|
127
|
+
# [ssl] Set this to <code>true</code> if the stylesheet references images
|
128
|
+
# via SSL. Defaults to <code>false</code>.
|
129
|
+
def self.bundles_path(type, options={})
|
130
|
+
type = type.to_sym
|
131
|
+
unless TYPES.include?(type)
|
132
|
+
raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.}
|
133
|
+
return
|
134
|
+
end
|
135
|
+
|
136
|
+
path = case type
|
137
|
+
when :css ; STYLESHEETS_PATH
|
138
|
+
when :js ; JAVASCRIPTS_PATH
|
139
|
+
else nil
|
140
|
+
end
|
141
|
+
path += '/bundles'
|
142
|
+
path += '/ssl' if options[:ssl]
|
143
|
+
path
|
144
|
+
end
|
145
|
+
|
119
146
|
# Returns true if the specified asset exists in the file system:
|
120
147
|
#
|
121
148
|
# AssetHat.asset_exists?('application.css', :css)
|
@@ -128,7 +155,7 @@ module AssetHat
|
|
128
155
|
# Process arguments
|
129
156
|
type = type.to_sym
|
130
157
|
unless TYPES.include?(type)
|
131
|
-
raise
|
158
|
+
raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.}
|
132
159
|
return
|
133
160
|
end
|
134
161
|
|
@@ -145,10 +172,24 @@ module AssetHat
|
|
145
172
|
# Returns <code>true</code> if bundles should be included as single minified
|
146
173
|
# files (e.g., in production), or <code>false</code> if bundles should be
|
147
174
|
# included as separate, unminified files (e.g., in development). To modify
|
148
|
-
# this value, set
|
175
|
+
# this value, set
|
176
|
+
# <code>config.action_controller.perform_caching</code> (boolean)
|
149
177
|
# in your environment.
|
150
178
|
def self.cache? ; ActionController::Base.perform_caching ; end
|
151
179
|
|
180
|
+
# Returns the value of
|
181
|
+
# <code>Rails.application.config.consider_all_requests_local</code> or its
|
182
|
+
# equivalent in older versions of Rails. To modify this value, set
|
183
|
+
# <code>config.consider_all_requests_local</code> (boolean) in your
|
184
|
+
# environment.
|
185
|
+
def self.consider_all_requests_local?
|
186
|
+
if defined?(Rails) && Rails.respond_to?(:application)
|
187
|
+
Rails.application.config.consider_all_requests_local
|
188
|
+
else # Rails 2.x
|
189
|
+
ActionController::Base.consider_all_requests_local
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
152
193
|
# Returns the expected path for the minified version of an asset:
|
153
194
|
#
|
154
195
|
# AssetHat.min_filepath('public/stylesheets/bundles/application.css', 'css')
|
@@ -163,13 +204,13 @@ module AssetHat
|
|
163
204
|
# Returns the extension-less names of files in the given bundle:
|
164
205
|
#
|
165
206
|
# AssetHat.bundle_filenames('application', :css)
|
166
|
-
# # => ['reset', 'application'
|
207
|
+
# # => ['reset', 'application']
|
167
208
|
# AssetHat.bundle_filenames('non-existent-file', :css)
|
168
209
|
# # => nil
|
169
210
|
def self.bundle_filenames(bundle, type)
|
170
211
|
# Process arguments
|
171
212
|
unless TYPES.include?(type.to_sym)
|
172
|
-
raise
|
213
|
+
raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.}
|
173
214
|
return
|
174
215
|
end
|
175
216
|
|
@@ -180,14 +221,13 @@ module AssetHat
|
|
180
221
|
#
|
181
222
|
# AssetHat.bundle_filenames('application', :css)
|
182
223
|
# # => ['/path/to/app/public/stylesheets/reset.css',
|
183
|
-
# '/path/to/app/public/stylesheets/application.css'
|
184
|
-
# '/path/to/app/public/stylesheets/clearfix.css']
|
224
|
+
# '/path/to/app/public/stylesheets/application.css']
|
185
225
|
# AssetHat.bundle_filenames('non-existent-file', :css)
|
186
226
|
# # => nil
|
187
227
|
def self.bundle_filepaths(bundle, type)
|
188
228
|
# Process arguments
|
189
229
|
unless TYPES.include?(type.to_sym)
|
190
|
-
raise
|
230
|
+
raise %{Unknown type "#{type}"; should be one of: #{TYPES.join(', ')}.}
|
191
231
|
return
|
192
232
|
end
|
193
233
|
|
@@ -226,7 +266,12 @@ module AssetHat
|
|
226
266
|
case host.is_a?(Proc) ?
|
227
267
|
host.arity : host.method(:call).arity
|
228
268
|
when 2
|
229
|
-
|
269
|
+
if defined?(ActionDispatch)
|
270
|
+
request_class = ActionDispatch::Request
|
271
|
+
else # Rails 2.x
|
272
|
+
request_class = ActionController::Request
|
273
|
+
end
|
274
|
+
request = request_class.new(
|
230
275
|
'HTTPS' => options[:ssl] ? 'on' : 'off')
|
231
276
|
host = host.call(source, request)
|
232
277
|
else
|
@@ -0,0 +1 @@
|
|
1
|
+
ActionView::Base.send(:include, ::AssetHatHelper)
|
@@ -0,0 +1 @@
|
|
1
|
+
AssetHat.cache_last_commit_ids unless defined?(::IRB)
|
data/lib/asset_hat/js/vendors.rb
CHANGED
@@ -6,101 +6,227 @@ module AssetHat
|
|
6
6
|
# A list of supported 3rd-party JavaScript plugin/vendor names.
|
7
7
|
# Homepages:
|
8
8
|
#
|
9
|
-
# *
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
9
|
+
# * Frameworks/libraries:
|
10
|
+
# * {Dojo}[http://dojotoolkit.org/]
|
11
|
+
# * {Ext Core}[http://extjs.com/products/extcore/]
|
12
|
+
# * {jQuery UI}[http://jqueryui.com/]
|
13
|
+
# * {jQuery}[http://jquery.com/]
|
14
|
+
# * {MooTools}[http://mootools.net/]
|
15
|
+
# * {Prototype}[http://www.prototypejs.org/]
|
16
|
+
# * {script.aculo.us}[http://script.aculo.us/]
|
17
|
+
# * {SWFObject}[http://code.google.com/p/swfobject/]
|
18
|
+
# * {WebFont Loader}[http://code.google.com/apis/webfonts/docs/webfont_loader.html]
|
19
|
+
# * {YUI}[http://developer.yahoo.com/yui/]
|
20
|
+
# * Loaders:
|
21
|
+
# * {LABjs}[http://labjs.com]
|
22
|
+
VENDORS_ON_GOOGLE_CDN = [
|
23
23
|
:dojo,
|
24
|
-
:swfobject,
|
25
|
-
:yui,
|
26
24
|
:ext_core,
|
27
|
-
:
|
25
|
+
:jquery,
|
26
|
+
:jquery_ui,
|
27
|
+
:mootools,
|
28
|
+
:prototype,
|
29
|
+
:scriptaculous,
|
30
|
+
:swfobject,
|
31
|
+
:webfont,
|
32
|
+
:yui
|
33
|
+
]
|
34
|
+
VENDORS_ON_CDNJS = [
|
35
|
+
:lab_js
|
28
36
|
]
|
37
|
+
VENDORS = VENDORS_ON_GOOGLE_CDN + VENDORS_ON_CDNJS
|
29
38
|
|
30
|
-
# Accepts an item from VENDORS
|
31
|
-
# asset can be found. The URL is either local (relative) or
|
32
|
-
# depending on the environment configuration
|
33
|
-
#
|
39
|
+
# Accepts an item from `VENDORS`, and returns the URL at which that
|
40
|
+
# vendor asset can be found. The URL is either local (relative) or
|
41
|
+
# remote, depending on the environment configuration:
|
42
|
+
#
|
43
|
+
# - If `AssetHat.consider_all_requests_local?` is true:
|
44
|
+
# - The local file takes precedence.
|
45
|
+
# - If the local file is missing, the remote URL in assets.yml is
|
46
|
+
# used as a fallback.
|
47
|
+
# - If there is no remote URL in assets.yml, the Google CDN URL is
|
48
|
+
# used as a fallback. (This makes setup easier: If the app doesn't
|
49
|
+
# already have a local copy of the vendor file, then it's instead
|
50
|
+
# loaded remotely.)
|
51
|
+
# - If `AssetHat.consider_all_requests_local?` is false:
|
52
|
+
# - The remote URL in assets.yml takes precedence.
|
53
|
+
# - The {Google CDN}[http://code.google.com/apis/ajaxlibs/] URL is
|
54
|
+
# used as a fallback, but only if a version number can be found
|
55
|
+
# (either in assets.yml or via the helper's `:version` option). If
|
56
|
+
# no version number is found, the remote URL cannot be built, so
|
57
|
+
# the local file (if any) is used as a fallback.
|
58
|
+
#
|
34
59
|
# Options:
|
35
60
|
#
|
36
61
|
# [ssl] Boolean for whether to include vendor JS via HTTPS. Defaults
|
37
62
|
# to false.
|
38
|
-
# [version] The vendor version, e.g., '1.
|
63
|
+
# [version] The vendor version, e.g., '1.5.0' for jQuery 1.5. By
|
39
64
|
# default, each vendor version is taken from
|
40
65
|
# <code>config/assets.yml</code>; use this option to override
|
41
66
|
# the configuration.
|
42
67
|
def self.source_for(vendor, options={})
|
43
68
|
vendor_config =
|
44
69
|
AssetHat.config['js']['vendors'][vendor.to_s] rescue nil
|
45
|
-
use_local =
|
70
|
+
use_local = AssetHat.consider_all_requests_local?
|
46
71
|
use_ssl = !!options[:ssl]
|
47
72
|
version = options[:version] || vendor_config['version'] rescue nil
|
48
73
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
74
|
+
# Prepare local path and default remote URL
|
75
|
+
srcs = Vendors.vendor_uris(vendor,
|
76
|
+
:use_ssl => use_ssl, :version => version)
|
77
|
+
local_src, remote_src = srcs[:local], srcs[:remote]
|
78
|
+
|
79
|
+
# Using the local URL requires that the vendor file exists locally. If
|
80
|
+
# the vendor file doesn't exist, use the remote URL as fallback.
|
81
|
+
use_local &&= AssetHat.asset_exists?(local_src, :js)
|
53
82
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
"http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/swfobject/#{version}/swfobject.js"
|
86
|
-
when :yui
|
87
|
-
src = use_local || version.blank? ?
|
88
|
-
"#{['yui', version].compact.join('-')}.min.js" :
|
89
|
-
"http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/yui/#{version}/build/yuiloader/yuiloader-min.js"
|
90
|
-
when :ext_core
|
91
|
-
src = use_local || version.blank? ?
|
92
|
-
"#{['ext_core', version].compact.join('-')}.min.js" :
|
93
|
-
"http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/ext-core/#{version}/ext-core.js"
|
94
|
-
when :webfont
|
95
|
-
src = use_local || version.blank? ?
|
96
|
-
"#{['webfont', version].compact.join('-')}.min.js" :
|
97
|
-
"http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/webfont/#{version}/webfont.js"
|
98
|
-
else nil # TODO: Write to log
|
83
|
+
# If no version given, can't determine the remote URL; use the local
|
84
|
+
# URL as fallback.
|
85
|
+
use_local ||= version.blank?
|
86
|
+
|
87
|
+
if use_local
|
88
|
+
src = local_src
|
89
|
+
else
|
90
|
+
# To ease setup, if no local copy of the vendor code is found,
|
91
|
+
# use a remote URL as a fallback.
|
92
|
+
|
93
|
+
# Give precedence to configured remote URLs
|
94
|
+
src = vendor_config.try(:[], 'remote_ssl_url') if use_ssl
|
95
|
+
src ||= vendor_config.try(:[], 'remote_url')
|
96
|
+
|
97
|
+
# Use default remote URL as fallback
|
98
|
+
src ||= remote_src
|
99
|
+
|
100
|
+
# Use local URL as final resort, even though the file doesn't
|
101
|
+
# exist, in hopes that the app maintainer finds the 404 (or the
|
102
|
+
# warning below) in the logs. This needs to be fixed in the app,
|
103
|
+
# rather than relying on a CDN to dynamically provide the latest
|
104
|
+
# stable vendor version.
|
105
|
+
if src.blank?
|
106
|
+
src = local_src
|
107
|
+
Rails.logger.warn "\n\nAssetHat WARNING (#{Time.now}):\n" + %{
|
108
|
+
Tried to reference the vendor JS `:#{vendor}`, but
|
109
|
+
#{AssetHat.assets_dir(:js)}/#{local_src} couldn't be found, and
|
110
|
+
couldn't use a remote fallback because no vendor version was
|
111
|
+
given in #{AssetHat::RELATIVE_CONFIG_FILEPATH}.
|
112
|
+
}.squish!
|
113
|
+
# TODO: Create `AssetHat::Logger.warn`, etc. methods
|
99
114
|
end
|
100
115
|
end
|
101
116
|
|
102
117
|
src
|
103
118
|
end
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def self.vendor_uris(vendor, options={})
|
125
|
+
# Returns a hash with keys `:local` and `:remote`.
|
126
|
+
|
127
|
+
uris = {}
|
128
|
+
use_ssl = options[:use_ssl]
|
129
|
+
version = options[:version]
|
130
|
+
|
131
|
+
case vendor
|
132
|
+
when :jquery
|
133
|
+
uris[:local ] = "#{['jquery', version].compact.join('-')}.min.js"
|
134
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/jquery/#{version}/jquery.min.js"
|
135
|
+
when :jquery_ui
|
136
|
+
uris[:local ] = "#{['jquery-ui', version].compact.join('-')}.min.js"
|
137
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/jqueryui/#{version}/jquery-ui.min.js"
|
138
|
+
when :prototype
|
139
|
+
# Prototype currently doesn't provide an official minified version.
|
140
|
+
uris[:local ] = "#{['prototype', version].compact.join('-')}.js"
|
141
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/prototype/#{version}/prototype.js"
|
142
|
+
when :scriptaculous
|
143
|
+
# script.aculo.us currently doesn't provide an official minified version.
|
144
|
+
uris[:local ] = "#{['scriptaculous', version].compact.join('-')}.js"
|
145
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/scriptaculous/#{version}/scriptaculous.js"
|
146
|
+
when :mootools
|
147
|
+
uris[:local ] = "#{['mootools', version].compact.join('-')}.min.js"
|
148
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/mootools/#{version}/mootools-yui-compressed.js"
|
149
|
+
when :dojo
|
150
|
+
uris[:local ] = "#{['dojo', version].compact.join('-')}.min.js"
|
151
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/dojo/#{version}/dojo/dojo.xd.js"
|
152
|
+
when :swfobject
|
153
|
+
uris[:local ] = "#{['swfobject', version].compact.join('-')}.min.js"
|
154
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/swfobject/#{version}/swfobject.js"
|
155
|
+
when :yui
|
156
|
+
uris[:local ] = "#{['yui', version].compact.join('-')}.min.js"
|
157
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/yui/#{version}/build/yuiloader/yuiloader-min.js"
|
158
|
+
when :ext_core
|
159
|
+
uris[:local ] = "#{['ext-core', version].compact.join('-')}.min.js"
|
160
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/ext-core/#{version}/ext-core.js"
|
161
|
+
when :webfont
|
162
|
+
uris[:local ] = "#{['webfont', version].compact.join('-')}.min.js"
|
163
|
+
uris[:remote] = "http#{'s' if use_ssl}://ajax.googleapis.com/ajax/libs/webfont/#{version}/webfont.js"
|
164
|
+
when :lab_js
|
165
|
+
uris[:local ] = "#{['LAB', version].compact.join('-')}.min.js"
|
166
|
+
|
167
|
+
remote_host =
|
168
|
+
if use_ssl
|
169
|
+
'https://d3eee1nukb5wg.cloudfront.net/'
|
170
|
+
# This must match the value in the cdnjs repo:
|
171
|
+
# https://github.com/cdnjs/cdnjs/raw/master/https_location
|
172
|
+
#
|
173
|
+
# Amazon CloudFront doesn't support SSL, as discussed here:
|
174
|
+
# - http://www.cdnjs.com/#IDComment130405257
|
175
|
+
# - https://forums.aws.amazon.com/message.jspa?messageID=141951
|
176
|
+
# As a result, the SSL certificate at <https://cdnjs.com> is
|
177
|
+
# invalid. To work around this, we instead load assets via
|
178
|
+
# cdnjs's CloudFront bucket ID. The bucket ID may change in
|
179
|
+
# the future, so it should be synced with the host published
|
180
|
+
# in the cdnjs repo, as noted above.
|
181
|
+
#
|
182
|
+
# For complete control over this, you can simply download the
|
183
|
+
# vendor JS and host it on a server where you can maintain
|
184
|
+
# SSL certificates.
|
185
|
+
else
|
186
|
+
'http://ajax.cdnjs.com'
|
187
|
+
end
|
188
|
+
uris[:remote] = "#{remote_host}/ajax/libs/labjs/#{version}/LAB.min.js"
|
189
|
+
else nil # TODO: Write to log
|
190
|
+
end
|
191
|
+
|
192
|
+
# The remote URL can only be properly determined if the version number
|
193
|
+
# is known; otherwise, discard.
|
194
|
+
uris.delete(:remote) if version.blank?
|
195
|
+
|
196
|
+
uris
|
197
|
+
end
|
198
|
+
|
199
|
+
# Usage (currently only supports LABjs):
|
200
|
+
#
|
201
|
+
# AssetHat::JS::Vendors.loader_js :lab_js,
|
202
|
+
# :urls => ['/javascripts/app.js',
|
203
|
+
# 'http://cdn.example.com/jquery.js']
|
204
|
+
#
|
205
|
+
# Returns a string of JS:
|
206
|
+
#
|
207
|
+
# window.$LABinst=$LAB.
|
208
|
+
# script('/javascripts/app.js').wait().
|
209
|
+
# script('http://cdn.example.com/jquery.js').wait();
|
210
|
+
def self.loader_js(loader, opts)
|
211
|
+
return nil unless opts[:urls]
|
212
|
+
|
213
|
+
case loader
|
214
|
+
when :lab_js
|
215
|
+
urls = opts[:urls]
|
216
|
+
lines = ['window.$LABinst=$LAB.']
|
217
|
+
urls.each_with_index do |url, i|
|
218
|
+
is_last = i >= urls.length - 1
|
219
|
+
lines << " script('#{url}').wait()#{is_last ? ';' : '.'}"
|
220
|
+
# Use `wait()` for each script to load in parallel, but
|
221
|
+
# preserve execution order by default. Alternatively, call
|
222
|
+
# `$LAB.setOptions({AlwaysPreserveOrder:true})` at the start
|
223
|
+
# of the chain, but if the list of bundles to include is short,
|
224
|
+
# this may use even more bytes.
|
225
|
+
end
|
226
|
+
lines.join("\n")
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
104
230
|
end
|
105
231
|
|
106
232
|
end
|