sprockets-preload 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +136 -0
- data/Rakefile +6 -0
- data/assets/sprockets/preload/assets.js.erb +10 -0
- data/assets/sprockets/preload/load.coffee.erb +121 -0
- data/lib/sprockets/preload/context.rb +19 -0
- data/lib/sprockets/preload/directive_processor.rb +28 -0
- data/lib/sprockets/preload/engine.rb +16 -0
- data/lib/sprockets/preload/errors.rb +5 -0
- data/lib/sprockets/preload/version.rb +5 -0
- data/lib/sprockets/preload.rb +87 -0
- data/spec/helpers/assets/circular/circular.js +1 -0
- data/spec/helpers/assets/circular/test1.js +2 -0
- data/spec/helpers/assets/circular/test2.coffee +1 -0
- data/spec/helpers/assets/direct/direct.js +3 -0
- data/spec/helpers/assets/direct/test1.js +1 -0
- data/spec/helpers/assets/direct/test2.js +1 -0
- data/spec/helpers/assets/forced/forced.js +4 -0
- data/spec/helpers/assets/forced/test1.js +1 -0
- data/spec/helpers/assets/forced/test2.js +1 -0
- data/spec/helpers/assets/nested/nested.js +1 -0
- data/spec/helpers/assets/nested/test1.js +2 -0
- data/spec/helpers/assets/nested/test2.js +1 -0
- data/spec/helpers/boot.rb +45 -0
- data/spec/integrational/circular_spec.rb +17 -0
- data/spec/integrational/direct_spec.rb +29 -0
- data/spec/integrational/forced_spec.rb +29 -0
- data/spec/integrational/nested_spec.rb +30 -0
- data/sprockets-preload.gemspec +28 -0
- metadata +135 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9aa6c3e861748967179166f9e5eec2641432f274
|
4
|
+
data.tar.gz: df369157c3ee8cefcda79d361c43fa5f26c5522f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 724a9ba684c9a94d3ecea83615aa402fe54d7cbaf75df98553c3e306f876910c41b07e6bdbe8dd7d643f312af7ab783e15f1bd63bf6be31a1a889b44718ba795
|
7
|
+
data.tar.gz: be1d272adb7cd4bfa2d77ae4528a04f64ad751c60fe78b5942588988228e7a9719159f5a544e4329c2f5ab417492d284052896b1864124a5b06f8354b6c406b5
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Boris Staal
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
# Sprockets::Preload
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/sprockets-preload)
|
4
|
+
[](https://travis-ci.org/inossidabile/sprockets-preload)
|
5
|
+
|
6
|
+
Ever had heavy Javascript assets that were taking a while to download? **Sprockets::Preload** allows you to preload it using only the directives of **Sprockets**.
|
7
|
+
|
8
|
+
Show your users nice loading bar instead of just white loading screen!
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
Imagine that you are riding on Rails and have the following `application.js` where `jquery`, `jquery-ui` and `front` (MVC front-end application) take around 500kb compressed altogether:
|
13
|
+
|
14
|
+
```javascript
|
15
|
+
//= include helpers
|
16
|
+
//= include jquery
|
17
|
+
//= include jquery-ui
|
18
|
+
//= include front
|
19
|
+
|
20
|
+
// Starting application
|
21
|
+
$ -> Front.start()
|
22
|
+
```
|
23
|
+
|
24
|
+
Let's make user experience smooth:
|
25
|
+
|
26
|
+
1. Add `sprockets-preload` to your `Gemfile` and run `bundle install`
|
27
|
+
|
28
|
+
2. Change `//= include` to `//= preload` for the assets you want to detouch:
|
29
|
+
|
30
|
+
```javascript
|
31
|
+
//= include helpers
|
32
|
+
//= preload jquery
|
33
|
+
//= preload jquery-ui
|
34
|
+
//= preload front
|
35
|
+
|
36
|
+
// Starting application
|
37
|
+
$ -> Front.start()
|
38
|
+
```
|
39
|
+
|
40
|
+
3. Delay initialization to the moment when detouched assets are loaded:
|
41
|
+
|
42
|
+
```javascript
|
43
|
+
//= include helpers
|
44
|
+
//= preload jquery
|
45
|
+
//= preload jquery-ui
|
46
|
+
//= preload front
|
47
|
+
|
48
|
+
SprocketsPreload.success = function() {
|
49
|
+
// Starting application
|
50
|
+
$ -> Front.start()
|
51
|
+
}
|
52
|
+
```
|
53
|
+
|
54
|
+
4. Track loading and show progress to user
|
55
|
+
|
56
|
+
```javascript
|
57
|
+
//= include helpers
|
58
|
+
//= preload jquery
|
59
|
+
//= preload jquery-ui
|
60
|
+
//= preload front
|
61
|
+
|
62
|
+
SprocketsPreload.success = function() {
|
63
|
+
// Starting application
|
64
|
+
$ -> Front.start()
|
65
|
+
}
|
66
|
+
|
67
|
+
SprocketsPreload.progress = function(percent) {
|
68
|
+
// User isn't going to see percents at console
|
69
|
+
// but that's just an example after all
|
70
|
+
console.log(percent);
|
71
|
+
}
|
72
|
+
```
|
73
|
+
|
74
|
+
5. **IMPORTANT**: Rails development environment uses stub to ease debugging. Thus while things keep working, assets don't really get detouched. To force production-grade loading (just to make sure things work fine) add `//= preload!` to your manifest:
|
75
|
+
|
76
|
+
```javascript
|
77
|
+
//= preload!
|
78
|
+
//= include helpers
|
79
|
+
//= preload jquery
|
80
|
+
//= preload jquery-ui
|
81
|
+
//= preload front
|
82
|
+
|
83
|
+
SprocketsPreload.success = function() {
|
84
|
+
// Starting application
|
85
|
+
$ -> Front.start()
|
86
|
+
}
|
87
|
+
|
88
|
+
SprocketsPreload.progress = function(percent) {
|
89
|
+
// User isn't going to see percents at console
|
90
|
+
// but that's just an example after all
|
91
|
+
console.log(percent);
|
92
|
+
}
|
93
|
+
```
|
94
|
+
|
95
|
+
Make sure to remove `//= preload!` when your tests are done.
|
96
|
+
|
97
|
+
## Caching options
|
98
|
+
|
99
|
+
To make loading progress tracking smooth and cache manually controllable, **Sprockets::Preload** uses `localStorage` to cache assets (it falls back to default browser cache automatically). **Sprockets** provides digests and logic-aware dependency system that work much better and much more predictable than more common default HTTP caching.
|
100
|
+
|
101
|
+
That's said – you really want to keep `localStorage` strategy in the vast majority of cases. If however for some reason you still want to make it use default browser cache, set `SprocketsPreload.localStorage` to `false` like this:
|
102
|
+
|
103
|
+
```javascript
|
104
|
+
//= preload!
|
105
|
+
//= include helpers
|
106
|
+
//= preload jquery
|
107
|
+
//= preload jquery-ui
|
108
|
+
//= preload front
|
109
|
+
|
110
|
+
SprocketsPreload.localStorage = false;
|
111
|
+
|
112
|
+
SprocketsPreload.success = function() {
|
113
|
+
// Starting application
|
114
|
+
$ -> Front.start()
|
115
|
+
}
|
116
|
+
|
117
|
+
SprocketsPreload.progress = function(percent) {
|
118
|
+
// User isn't going to see percents at console
|
119
|
+
// but that's just an example after all
|
120
|
+
console.log(percent);
|
121
|
+
}
|
122
|
+
```
|
123
|
+
|
124
|
+
**Note** that default caching strategy will still try to emulate loading progress tracking but it works MUCH worse.
|
125
|
+
|
126
|
+
## Compatibility
|
127
|
+
|
128
|
+
**Sprockets::Preload** does not depend on Rails. However it has proper rail-ties and is fully-functional on Rails out of box. If you want to use it outside of Rails with clean **Sprockets** – see `lib/sprockets/preload/engine.rb` for required initialization settings.
|
129
|
+
|
130
|
+
## Contributing
|
131
|
+
|
132
|
+
1. Fork it
|
133
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
134
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
135
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
136
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
<%
|
2
|
+
|
3
|
+
# we have to check all base-level assets to find out what exactly is preloading
|
4
|
+
Sprockets::Preload.each_logical_path do |logical_path, environment|
|
5
|
+
Sprockets::Preload.collect(environment, logical_path).each do |dependency|
|
6
|
+
require_asset dependency
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
%>
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#= depend_on_asset sprockets/preload/assets
|
2
|
+
|
3
|
+
@SprocketsPreload =
|
4
|
+
|
5
|
+
onload: (callback) ->
|
6
|
+
@localStorage = true unless @localStorage?
|
7
|
+
|
8
|
+
return callback() if document && document.readyState is "complete"
|
9
|
+
|
10
|
+
if window.addEventListener
|
11
|
+
window.addEventListener "DOMContentLoaded", callback, false
|
12
|
+
else
|
13
|
+
window.attachEvent "onload", handler if window.attachEvent
|
14
|
+
|
15
|
+
#
|
16
|
+
# Dispatches events through `document`
|
17
|
+
#
|
18
|
+
trigger: (name, data) ->
|
19
|
+
if document.createEvent
|
20
|
+
event = document.createEvent('Events')
|
21
|
+
event.data = data if data
|
22
|
+
event.initEvent name, true, true
|
23
|
+
document.dispatchEvent event
|
24
|
+
else if document.createEventObject
|
25
|
+
event = document.createEventObject()
|
26
|
+
event.data = data if data
|
27
|
+
document.fireEvent "on" + name, event
|
28
|
+
|
29
|
+
#
|
30
|
+
# Happens from time to time during downloading (but only when localStorage caching enabled)
|
31
|
+
#
|
32
|
+
triggerProgress: (percent) ->
|
33
|
+
@progress? percent
|
34
|
+
@trigger 'sprockets:progress', percent: percent
|
35
|
+
|
36
|
+
#
|
37
|
+
# Happens when preloading assets are loaded
|
38
|
+
#
|
39
|
+
triggerSuccess: ->
|
40
|
+
@success?()
|
41
|
+
@trigger 'sprockets:loaded'
|
42
|
+
|
43
|
+
#
|
44
|
+
# Creates `script` tag with given attributes and adds it to head
|
45
|
+
#
|
46
|
+
inject: (attributes={}) ->
|
47
|
+
node = document.createElement "script"
|
48
|
+
node[k] = v for k, v of attributes
|
49
|
+
document.getElementsByTagName("head")[0].appendChild node
|
50
|
+
|
51
|
+
#
|
52
|
+
# Loads asset using localStorage as a manual cache
|
53
|
+
#
|
54
|
+
loadCached: (url, version, size) ->
|
55
|
+
attempt = localStorage['sprockets-preload']
|
56
|
+
attempt = JSON.parse(attempt) if attempt
|
57
|
+
|
58
|
+
if attempt?.version == version
|
59
|
+
@inject defer: true, text: attempt.source
|
60
|
+
@triggerProgress 100
|
61
|
+
@triggerSuccess 100
|
62
|
+
else
|
63
|
+
xhr = @_ajax 'GET', url, (xhr) =>
|
64
|
+
clearInterval poller
|
65
|
+
localStorage['sprockets-preload'] = JSON.stringify
|
66
|
+
version: version
|
67
|
+
source: xhr.responseText
|
68
|
+
|
69
|
+
@inject defer: true, text: xhr.responseText
|
70
|
+
@triggerProgress 100
|
71
|
+
@triggerSuccess()
|
72
|
+
|
73
|
+
if size > 0
|
74
|
+
poller = setInterval (=>
|
75
|
+
@triggerProgress Math.round(xhr.responseText.length / size * 100 * 100) / 100
|
76
|
+
), 100
|
77
|
+
|
78
|
+
#
|
79
|
+
# Loads asset using built-in browser caching
|
80
|
+
#
|
81
|
+
loadSimple: (url) ->
|
82
|
+
script = document.createElement "script"
|
83
|
+
done = false
|
84
|
+
self = @
|
85
|
+
|
86
|
+
proceed = ->
|
87
|
+
if !done && (!@readyState? || @readyState == "loaded" || @readyState == "complete")
|
88
|
+
done = true; script.onload = script.onreadystatechange = null
|
89
|
+
self.triggerSuccess()
|
90
|
+
|
91
|
+
@inject src: url, onload: proceed, onreadystatechange: proceed
|
92
|
+
|
93
|
+
#
|
94
|
+
# Starring custom XHR wrapper
|
95
|
+
#
|
96
|
+
_ajax: (method, url, callback) ->
|
97
|
+
if window.XMLHttpRequest
|
98
|
+
xhr = new XMLHttpRequest
|
99
|
+
else
|
100
|
+
xhr = new ActiveXObject 'Microsoft.XMLHTTP'
|
101
|
+
|
102
|
+
xhr.onreadystatechange = -> callback?(xhr) if xhr.readyState > 3
|
103
|
+
xhr.open method, url, 1
|
104
|
+
xhr.send()
|
105
|
+
|
106
|
+
xhr
|
107
|
+
|
108
|
+
@SprocketsPreload.onload ->
|
109
|
+
if SprocketsPreload.inline
|
110
|
+
delete localStorage['sprockets-preload'] if window.localStorage?
|
111
|
+
SprocketsPreload.triggerProgress 100
|
112
|
+
SprocketsPreload.triggerSuccess()
|
113
|
+
else if SprocketsPreload.localStorage && window.localStorage
|
114
|
+
SprocketsPreload.loadCached(
|
115
|
+
<%= javascript_path('sprockets/preload/assets').to_json %>,
|
116
|
+
<%= Sprockets::Preload['sprockets/preload/assets'].digest.to_json %>,
|
117
|
+
<%= Sprockets::Preload['sprockets/preload/assets'].length.to_json %>
|
118
|
+
)
|
119
|
+
else
|
120
|
+
delete localStorage['sprockets-preload'] if window.localStorage?
|
121
|
+
SprocketsPreload.loadSimple(<%= javascript_path('sprockets/preload/assets').to_json %>)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#
|
2
|
+
# Extends asset context with storage for assets to preload
|
3
|
+
#
|
4
|
+
module Sprockets
|
5
|
+
module Preload
|
6
|
+
module Context
|
7
|
+
def self.included(mod)
|
8
|
+
mod.instance_eval do
|
9
|
+
attr_accessor :_assets_to_preload
|
10
|
+
attr_accessor :_force_preload
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def preload?
|
15
|
+
_force_preload || !Sprockets::Preload.inline
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#
|
2
|
+
# Adds `#= preload {path}` and `#= preload!` directives
|
3
|
+
#
|
4
|
+
module Sprockets
|
5
|
+
module Preload
|
6
|
+
module DirectiveProcessor
|
7
|
+
def process_preload_directive(path)
|
8
|
+
if context.content_type != 'application/javascript'
|
9
|
+
process_require_directive path
|
10
|
+
else
|
11
|
+
unless context._assets_to_preload
|
12
|
+
process_require_directive 'sprockets/preload/load'
|
13
|
+
context._assets_to_preload = []
|
14
|
+
end
|
15
|
+
|
16
|
+
context.require_asset path
|
17
|
+
context.stub_asset path if context.preload?
|
18
|
+
|
19
|
+
context._assets_to_preload.push path
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
define_method :"process_preload!_directive" do
|
24
|
+
context._force_preload = true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#
|
2
|
+
# Defines Rails-based entries for Sprockets instance and the list of base-level assets
|
3
|
+
#
|
4
|
+
module Sprockets
|
5
|
+
module Preload
|
6
|
+
class Engine < ::Rails::Engine
|
7
|
+
initializer "sprockets.preload" do |app|
|
8
|
+
Sprockets::Preload.inline = ::Rails.env.development?
|
9
|
+
Sprockets::Preload.environment = app.assets
|
10
|
+
Sprockets::Preload.precompiles = app.config.assets.precompile
|
11
|
+
|
12
|
+
app.config.assets.precompile += ['sprockets/preload/assets', 'sprockets/preload/load']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
require 'sprockets'
|
3
|
+
require 'sprockets/preload/directive_processor'
|
4
|
+
require 'sprockets/preload/context'
|
5
|
+
require 'sprockets/preload/version'
|
6
|
+
require 'sprockets/preload/errors'
|
7
|
+
require 'sprockets/preload/engine' if defined?(Rails)
|
8
|
+
|
9
|
+
Sprockets::DirectiveProcessor.send :include, Sprockets::Preload::DirectiveProcessor
|
10
|
+
Sprockets::Context.send :include, Sprockets::Preload::Context
|
11
|
+
|
12
|
+
Sprockets.append_path File.expand_path('../../../assets', __FILE__)
|
13
|
+
|
14
|
+
# Pass in current environment condition to mark if loading should be stubbed
|
15
|
+
Sprockets.register_postprocessor 'application/javascript', :preload do |context, data|
|
16
|
+
if context._assets_to_preload
|
17
|
+
data << "SprocketsPreload.inline = true;" unless context.preload?
|
18
|
+
end
|
19
|
+
|
20
|
+
data
|
21
|
+
end
|
22
|
+
|
23
|
+
module Sprockets
|
24
|
+
module Preload
|
25
|
+
class <<self
|
26
|
+
attr_accessor :inline
|
27
|
+
attr_accessor :environment
|
28
|
+
attr_accessor :precompiles
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Forks circular calls protection to allow cross-tree assets interactions
|
33
|
+
#
|
34
|
+
def self.[](path)
|
35
|
+
calls = Thread.current[:sprockets_circular_calls]
|
36
|
+
Thread.current[:sprockets_circular_calls] = Set.new
|
37
|
+
environment[path]
|
38
|
+
ensure
|
39
|
+
Thread.current[:sprockets_circular_calls] = calls
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Iterates through all JS base-level assets of an application
|
44
|
+
#
|
45
|
+
def self.each_logical_path(&block)
|
46
|
+
paths = environment.each_logical_path(*precompiles).to_a +
|
47
|
+
precompiles.flatten.select{ |fn| Pathname.new(fn).absolute? if fn.is_a?(String) }
|
48
|
+
|
49
|
+
paths.each do |path|
|
50
|
+
yield(path, environment) if environment.content_type_of(path) == 'application/javascript'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# Recursively collects #= preload directives from given logical path
|
56
|
+
#
|
57
|
+
def self.collect(environment, logical_path)
|
58
|
+
pathname = environment.resolve logical_path
|
59
|
+
context = environment.context_class.new(environment, logical_path, pathname)
|
60
|
+
template = Sprockets::DirectiveProcessor.new(pathname.to_s)
|
61
|
+
template.render(context, {})
|
62
|
+
|
63
|
+
to_preload = context._assets_to_preload || []
|
64
|
+
|
65
|
+
# Files marked for preloading should not have nested preload directives
|
66
|
+
to_preload.each do |dependency|
|
67
|
+
nesteds = collect(environment, dependency)
|
68
|
+
if nesteds.length > 0
|
69
|
+
raise CircularPreloadError.new("Circular preloading detected: #{dependency} -> #{nesteds.join(',')}")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Going deeper
|
74
|
+
dependencies = context._required_paths.map do |dependency|
|
75
|
+
environment.attributes_for(dependency).logical_path
|
76
|
+
end
|
77
|
+
|
78
|
+
dependencies -= context._stubbed_assets.to_a
|
79
|
+
|
80
|
+
dependencies.each do |dependency|
|
81
|
+
to_preload += collect(environment, dependency)
|
82
|
+
end
|
83
|
+
|
84
|
+
to_preload
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
//= preload circular/test1
|
@@ -0,0 +1 @@
|
|
1
|
+
test2
|
@@ -0,0 +1 @@
|
|
1
|
+
test1
|
@@ -0,0 +1 @@
|
|
1
|
+
test2
|
@@ -0,0 +1 @@
|
|
1
|
+
test1
|
@@ -0,0 +1 @@
|
|
1
|
+
test2
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require nested/test1
|
@@ -0,0 +1 @@
|
|
1
|
+
test2
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
Bundler.require
|
4
|
+
|
5
|
+
Sprockets::Context.class_eval do
|
6
|
+
def asset_path(path, options={})
|
7
|
+
"/#{path}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
Sprockets::Preload.precompiles = []
|
12
|
+
Sprockets.append_path File.expand_path('../assets', __FILE__)
|
13
|
+
|
14
|
+
RSpec.configure do |config|
|
15
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
16
|
+
config.run_all_when_everything_filtered = true
|
17
|
+
config.filter_run :focus
|
18
|
+
config.order = 'random:59695'
|
19
|
+
|
20
|
+
config.before(:each) do
|
21
|
+
Sprockets::Preload.environment = Sprockets::Environment.new
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
shared_context "inlined", inline: true do
|
26
|
+
before(:all) do
|
27
|
+
@inline_condition = Sprockets::Preload.inline
|
28
|
+
Sprockets::Preload.inline = true
|
29
|
+
end
|
30
|
+
|
31
|
+
after(:all) do
|
32
|
+
Sprockets::Preload.inline = @inline_condition
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
shared_context "detouched", inline: false do
|
37
|
+
before(:all) do
|
38
|
+
@inline_condition = Sprockets::Preload.inline
|
39
|
+
Sprockets::Preload.inline = false
|
40
|
+
end
|
41
|
+
|
42
|
+
after(:all) do
|
43
|
+
Sprockets::Preload.inline = @inline_condition
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'helpers/boot'
|
2
|
+
|
3
|
+
describe "Circular dependency" do
|
4
|
+
before(:all) do
|
5
|
+
Sprockets::Preload.precompiles += ["circular/circular.js"]
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
Sprockets::Preload.precompiles -= ["circular/circular.js"]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "throws" do
|
13
|
+
expect{
|
14
|
+
Sprockets::Preload.environment['sprockets/preload/assets']
|
15
|
+
}.to raise_error Sprockets::Preload::CircularPreloadError
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'helpers/boot'
|
2
|
+
|
3
|
+
describe "Direct dependency" do
|
4
|
+
before(:all) do
|
5
|
+
Sprockets::Preload.precompiles += ["direct/direct.js"]
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
Sprockets::Preload.precompiles -= ["direct/direct.js"]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "serves detouched" do
|
13
|
+
Sprockets::Preload.environment['sprockets/preload/assets'].source.should == "test1\n;\ntest2\n;\n\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
context "inlined", inline: true do
|
17
|
+
it "keeps inlines" do
|
18
|
+
Sprockets::Preload.environment['direct/direct'].source.should include("test1", "test2")
|
19
|
+
Sprockets::Preload.environment['direct/direct'].source.should include("SprocketsPreload.inline = true")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "detouched", inline: false do
|
24
|
+
it "keeps inlines" do
|
25
|
+
Sprockets::Preload.environment['direct/direct'].source.should_not include("test1", "test2")
|
26
|
+
Sprockets::Preload.environment['direct/direct'].source.should_not include("SprocketsPreload.inline = true")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'helpers/boot'
|
2
|
+
|
3
|
+
describe "Direct dependency" do
|
4
|
+
before(:all) do
|
5
|
+
Sprockets::Preload.precompiles += ["forced/forced.js"]
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
Sprockets::Preload.precompiles -= ["forced/forced.js"]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "serves detouched" do
|
13
|
+
Sprockets::Preload.environment['sprockets/preload/assets'].source.should == "test1\n;\ntest2\n;\n\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
context "inlined", inline: true do
|
17
|
+
it "keeps inlines" do
|
18
|
+
Sprockets::Preload.environment['forced/forced'].source.should_not include("test1", "test2")
|
19
|
+
Sprockets::Preload.environment['forced/forced'].source.should_not include("SprocketsPreload.inline = true")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "detouched", inline: false do
|
24
|
+
it "keeps inlines" do
|
25
|
+
Sprockets::Preload.environment['forced/forced'].source.should_not include("test1", "test2")
|
26
|
+
Sprockets::Preload.environment['forced/forced'].source.should_not include("SprocketsPreload.inline = true")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'helpers/boot'
|
2
|
+
|
3
|
+
describe "Nested dependency" do
|
4
|
+
before(:all) do
|
5
|
+
Sprockets::Preload.precompiles += ["nested/nested.js"]
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
Sprockets::Preload.precompiles -= ["nested/nested.js"]
|
10
|
+
end
|
11
|
+
|
12
|
+
it "serves detouched" do
|
13
|
+
Sprockets::Preload.environment['sprockets/preload/assets'].source.should == "test2\n;\n\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
context "inlined", inline: true do
|
17
|
+
it "keeps inlines" do
|
18
|
+
Sprockets::Preload.environment['nested/nested'].source.should include("test1", "test2")
|
19
|
+
Sprockets::Preload.environment['nested/nested'].source.should include("SprocketsPreload.inline = true")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "detouched", inline: false do
|
24
|
+
it "keeps inlines" do
|
25
|
+
Sprockets::Preload.environment['nested/nested'].source.should include("test1")
|
26
|
+
Sprockets::Preload.environment['nested/nested'].source.should_not include("test2")
|
27
|
+
Sprockets::Preload.environment['nested/nested'].source.should_not include("SprocketsPreload.inline = true")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sprockets/preload/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sprockets-preload"
|
8
|
+
spec.version = Sprockets::Preload::VERSION
|
9
|
+
spec.authors = ["Boris Staal"]
|
10
|
+
spec.email = ["boris@staal.io"]
|
11
|
+
spec.description = %q{Macros-based JS preloader for Sprockets}
|
12
|
+
spec.summary = %q{
|
13
|
+
The gem extends Sprockets with helpers allowing you to
|
14
|
+
controllably load huge JS assets with the support of
|
15
|
+
progress tracking and localStorage caching.
|
16
|
+
}
|
17
|
+
spec.homepage = "https://github.com/joosy/sprockets-preload"
|
18
|
+
spec.license = "MIT"
|
19
|
+
|
20
|
+
spec.files = `git ls-files`.split($/)
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
|
25
|
+
spec.add_dependency "sprockets"
|
26
|
+
spec.add_dependency "activesupport"
|
27
|
+
spec.add_dependency "coffee-script"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sprockets-preload
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Boris Staal
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sprockets
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: coffee-script
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Macros-based JS preloader for Sprockets
|
56
|
+
email:
|
57
|
+
- boris@staal.io
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- assets/sprockets/preload/assets.js.erb
|
68
|
+
- assets/sprockets/preload/load.coffee.erb
|
69
|
+
- lib/sprockets/preload.rb
|
70
|
+
- lib/sprockets/preload/context.rb
|
71
|
+
- lib/sprockets/preload/directive_processor.rb
|
72
|
+
- lib/sprockets/preload/engine.rb
|
73
|
+
- lib/sprockets/preload/errors.rb
|
74
|
+
- lib/sprockets/preload/version.rb
|
75
|
+
- spec/helpers/assets/circular/circular.js
|
76
|
+
- spec/helpers/assets/circular/test1.js
|
77
|
+
- spec/helpers/assets/circular/test2.coffee
|
78
|
+
- spec/helpers/assets/direct/direct.js
|
79
|
+
- spec/helpers/assets/direct/test1.js
|
80
|
+
- spec/helpers/assets/direct/test2.js
|
81
|
+
- spec/helpers/assets/forced/forced.js
|
82
|
+
- spec/helpers/assets/forced/test1.js
|
83
|
+
- spec/helpers/assets/forced/test2.js
|
84
|
+
- spec/helpers/assets/nested/nested.js
|
85
|
+
- spec/helpers/assets/nested/test1.js
|
86
|
+
- spec/helpers/assets/nested/test2.js
|
87
|
+
- spec/helpers/boot.rb
|
88
|
+
- spec/integrational/circular_spec.rb
|
89
|
+
- spec/integrational/direct_spec.rb
|
90
|
+
- spec/integrational/forced_spec.rb
|
91
|
+
- spec/integrational/nested_spec.rb
|
92
|
+
- sprockets-preload.gemspec
|
93
|
+
homepage: https://github.com/joosy/sprockets-preload
|
94
|
+
licenses:
|
95
|
+
- MIT
|
96
|
+
metadata: {}
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 2.0.6
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: The gem extends Sprockets with helpers allowing you to controllably load
|
117
|
+
huge JS assets with the support of progress tracking and localStorage caching.
|
118
|
+
test_files:
|
119
|
+
- spec/helpers/assets/circular/circular.js
|
120
|
+
- spec/helpers/assets/circular/test1.js
|
121
|
+
- spec/helpers/assets/circular/test2.coffee
|
122
|
+
- spec/helpers/assets/direct/direct.js
|
123
|
+
- spec/helpers/assets/direct/test1.js
|
124
|
+
- spec/helpers/assets/direct/test2.js
|
125
|
+
- spec/helpers/assets/forced/forced.js
|
126
|
+
- spec/helpers/assets/forced/test1.js
|
127
|
+
- spec/helpers/assets/forced/test2.js
|
128
|
+
- spec/helpers/assets/nested/nested.js
|
129
|
+
- spec/helpers/assets/nested/test1.js
|
130
|
+
- spec/helpers/assets/nested/test2.js
|
131
|
+
- spec/helpers/boot.rb
|
132
|
+
- spec/integrational/circular_spec.rb
|
133
|
+
- spec/integrational/direct_spec.rb
|
134
|
+
- spec/integrational/forced_spec.rb
|
135
|
+
- spec/integrational/nested_spec.rb
|