assets_include 1.0.0
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/.travis.yml +9 -0
- data/Gemfile +9 -0
- data/History.md +9 -0
- data/LICENSE +19 -0
- data/README.md +76 -0
- data/Rakefile +43 -0
- data/assets_include.gemspec +15 -0
- data/examples/sinatra/Gemfile +4 -0
- data/examples/sinatra/Gemfile.lock +23 -0
- data/examples/sinatra/README.md +32 -0
- data/examples/sinatra/app.rb +43 -0
- data/examples/sinatra/assets.yml +10 -0
- data/examples/sinatra/package.json +9 -0
- data/examples/sinatra/public/javascripts/inline.js +7 -0
- data/examples/sinatra/public/javascripts/main.js +5 -0
- data/examples/sinatra/public/javascripts/vendor/hex-rgb.src.js +64 -0
- data/examples/sinatra/public/javascripts/vendor/microajax.js +66 -0
- data/examples/sinatra/public/stylesheets/base.css +7 -0
- data/examples/sinatra/public/stylesheets/normalize.css +91 -0
- data/lib/assets_include.rb +10 -0
- data/lib/assets_include/base.rb +120 -0
- data/lib/assets_include/cache.rb +23 -0
- data/lib/assets_include/proxy.rb +15 -0
- data/lib/assets_include/version.rb +7 -0
- data/test/assets_include/base_test.rb +235 -0
- data/test/assets_include/cache_test.rb +55 -0
- data/test/assets_include/proxy_test.rb +37 -0
- data/test/fixtures/assets.yml +4 -0
- data/test/fixtures/package.json +9 -0
- data/test/fixtures/public/stylesheets/bundled/all.css +1 -0
- data/test/fixtures/public/stylesheets/one.css +3 -0
- data/test/fixtures/public/stylesheets/two.css +3 -0
- data/test/test_helper.rb +13 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8f31bd237abed00c9d7a4c13f7dccd4175f7f47d
|
4
|
+
data.tar.gz: 10cade04984960cfc65857d6b97b603287d0c916
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9bb76bb165e7d40c5f1d7e279457a8de9843011b6f72b2d6b946cc9bbf3cc09ad4e43402f735f6417f0897b122f20f83e957c68a1ecd5afd696b2e7e2462cfc2
|
7
|
+
data.tar.gz: 616792110b62b0bb624d8306aab8c8eea65ad497401f76d68c7bdd643ca42655adb7256ef2ef1b3ffcae343b085265a365c4170d5aa6f28df2ef532a42bce17e
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/History.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
1.0.0 / 2014-03-15
|
2
|
+
==================
|
3
|
+
|
4
|
+
* Provides 1:1 mapping with `assetsinc` 1.1 API.
|
5
|
+
* Provides Sinatra helpers providing the same features as node version.
|
6
|
+
* Provides Sinatra examples.
|
7
|
+
* Provides a #reset option to empty includer's cache.
|
8
|
+
* Defaults to bundled mode if RACK_ENV variable is set to production.
|
9
|
+
* Defaults cache_boosters to true as it is a more sane option.
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2011-2014 GoalSmashers.com
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is furnished
|
8
|
+
to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
14
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
15
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
16
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
17
|
+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
18
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
19
|
+
DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
[](https://travis-ci.org/GoalSmashers/assets-include-ruby)
|
2
|
+
[](https://codeclimate.com/github/GoalSmashers/assets-include-ruby)
|
3
|
+
[](https://codeclimate.com/github/GoalSmashers/assets-include-ruby)
|
4
|
+
|
5
|
+
## What is assets-include-ruby?
|
6
|
+
|
7
|
+
Assets-include is a Ruby wrapper around [Assets-Include](https://github.com/GoalSmashers/assets-include) for including your assets in HTML views.
|
8
|
+
|
9
|
+
See [example apps](https://github.com/GoalSmashers/assets-include-ruby/tree/master/examples) for real-world use cases.
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
### What are the requirements?
|
14
|
+
|
15
|
+
```
|
16
|
+
Ruby 1.9.3+
|
17
|
+
Node.js 0.8.0+
|
18
|
+
```
|
19
|
+
|
20
|
+
### How to install assets-include-ruby?
|
21
|
+
|
22
|
+
```
|
23
|
+
gem install assets_include
|
24
|
+
```
|
25
|
+
|
26
|
+
### How to use assets-include-ruby?
|
27
|
+
|
28
|
+
With [Sinatra](https://github.com/sinatra/sinatra):
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
require 'sinatra'
|
32
|
+
require 'assets_include'
|
33
|
+
|
34
|
+
# Adds assets.(group|list|inline) helpers
|
35
|
+
helpers AssetsInclude.helpers
|
36
|
+
|
37
|
+
get '/' do
|
38
|
+
erb :index
|
39
|
+
end
|
40
|
+
|
41
|
+
__END__
|
42
|
+
|
43
|
+
@@ layout
|
44
|
+
<html>
|
45
|
+
<head>
|
46
|
+
<%= assets.group('stylesheets/all.css') %>
|
47
|
+
</head>
|
48
|
+
<body>
|
49
|
+
<%= yield %>
|
50
|
+
<%= assets.group('javascripts/all.js') %>
|
51
|
+
</body>
|
52
|
+
</html>
|
53
|
+
|
54
|
+
@@ index
|
55
|
+
<h1>Yay, all assets are in</h1>
|
56
|
+
```
|
57
|
+
|
58
|
+
AssetsInclude.helpers accepts an options hash, i.e.,
|
59
|
+
|
60
|
+
* `bundled` - whether to serve bundled (production) or expanded (development) assets. Defaults based on ENV['RACK_ENV'] value.
|
61
|
+
* `config` - path to configuration file, defaults to ./assets.yml
|
62
|
+
* `root` - root path of all assets, defaults to ./public under config's path
|
63
|
+
* `cache_boosters` - `true` for cache boosters (timestamp in dev mode, md5 for bundled, production files)
|
64
|
+
* `asset_hosts` - prefixes all paths with given asset host(s)
|
65
|
+
* `loading_mode` - `async` or `defer` for JavaScript assets' loading mode
|
66
|
+
|
67
|
+
and adds the following methods to your views:
|
68
|
+
|
69
|
+
* `assets.group(locator)` - returns a list of `<script>` or `<link>` tags for JavaScript or CSS assets respectively
|
70
|
+
* `assets.inline(locator)` - returns inlined JavaScript or CSS assets. In development mode works the same way as `#group`.
|
71
|
+
* `assets.list(locator)` - returns an array of assets files to easily embed them into JavaScript or data attributes.
|
72
|
+
* `assets.reset` - empties includer's cache
|
73
|
+
|
74
|
+
## License
|
75
|
+
|
76
|
+
Assets-include-ruby is released under the [MIT License](https://github.com/GoalSmashers/assets-include-ruby/blob/master/LICENSE).
|
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
task default: :test
|
6
|
+
task spec: :test
|
7
|
+
|
8
|
+
task :test_setup do
|
9
|
+
`cd test/fixtures && npm install`
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::TestTask.new(test: :test_setup) do |t|
|
13
|
+
t.test_files = FileList['test/**/*_test.rb']
|
14
|
+
t.ruby_opts = ['-rubygems'] if defined? Gem
|
15
|
+
t.ruby_opts << '-Ilib:test'
|
16
|
+
t.warning = true
|
17
|
+
end
|
18
|
+
|
19
|
+
if defined?(Gem)
|
20
|
+
directory('pkg/')
|
21
|
+
|
22
|
+
def spec
|
23
|
+
require 'rubygems' unless defined? Gem::Specification
|
24
|
+
@spec ||= eval(File.read('assets_include.gemspec'))
|
25
|
+
end
|
26
|
+
|
27
|
+
def package
|
28
|
+
%{pkg/assets_include-#{spec.version}.gem}
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Build packages'
|
32
|
+
task package: package
|
33
|
+
|
34
|
+
desc 'Build and install as a local gem'
|
35
|
+
task install: package do
|
36
|
+
sh %{gem install #{package}}
|
37
|
+
end
|
38
|
+
|
39
|
+
file package => %w[pkg/ assets_include.gemspec] do |f|
|
40
|
+
sh 'gem build assets_include.gemspec'
|
41
|
+
mv File.basename(f.name), f.name
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
require 'assets_include/version'
|
3
|
+
|
4
|
+
Gem::Specification.new('assets_include', AssetsInclude::VERSION) do |s|
|
5
|
+
s.description = 'Include assets in your views with a single line of code.'
|
6
|
+
s.summary = 'Ruby bindings for assets-include node.js library.'
|
7
|
+
s.authors = ['Jakub Pawlowicz']
|
8
|
+
s.email = 'jakub.pawlowicz@goalsmashers.com'
|
9
|
+
s.homepage = 'https://github.com/GoalSmashers/assets-include-ruby'
|
10
|
+
s.license = 'MIT'
|
11
|
+
s.files = `git ls-files`.split("\n") - %w(.gitignore)
|
12
|
+
|
13
|
+
s.add_development_dependency 'minitest', '~> 4.7.0'
|
14
|
+
s.add_development_dependency 'flexmock', '~> 1.3.0'
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../..
|
3
|
+
specs:
|
4
|
+
assets_include (0.0.1)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
rack (1.5.2)
|
10
|
+
rack-protection (1.5.2)
|
11
|
+
rack
|
12
|
+
sinatra (1.4.4)
|
13
|
+
rack (~> 1.4)
|
14
|
+
rack-protection (~> 1.4)
|
15
|
+
tilt (~> 1.3, >= 1.3.4)
|
16
|
+
tilt (1.4.1)
|
17
|
+
|
18
|
+
PLATFORMS
|
19
|
+
ruby
|
20
|
+
|
21
|
+
DEPENDENCIES
|
22
|
+
assets_include!
|
23
|
+
sinatra (~> 1.4.0)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
## Example of how to include assets in a Sintra app
|
2
|
+
|
3
|
+
### What are the requirements?
|
4
|
+
|
5
|
+
* Ruby 1.9.3+
|
6
|
+
* node.js 0.8+
|
7
|
+
|
8
|
+
### How to set it up?
|
9
|
+
|
10
|
+
Given you have Ruby and node.js available run:
|
11
|
+
|
12
|
+
```bash
|
13
|
+
bundle install
|
14
|
+
npm install
|
15
|
+
```
|
16
|
+
|
17
|
+
### How to run in in development mode?
|
18
|
+
|
19
|
+
```
|
20
|
+
ruby app.rb
|
21
|
+
```
|
22
|
+
|
23
|
+
and point your browser to [localhost:4567](http://localhost:4567)
|
24
|
+
|
25
|
+
### How to run in in production mode?
|
26
|
+
|
27
|
+
```bash
|
28
|
+
./node_modules/.bin/assetspkg -b -c assets.yml
|
29
|
+
RACK_ENV=production ruby app.rb
|
30
|
+
```
|
31
|
+
|
32
|
+
and point your browser to [localhost:4567](http://localhost:4567)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
Bundler.setup
|
3
|
+
|
4
|
+
require 'sinatra'
|
5
|
+
require 'assets_include'
|
6
|
+
|
7
|
+
helpers AssetsInclude.helpers
|
8
|
+
|
9
|
+
get '/' do
|
10
|
+
erb :index
|
11
|
+
end
|
12
|
+
|
13
|
+
__END__
|
14
|
+
|
15
|
+
@@ layout
|
16
|
+
<html>
|
17
|
+
<head>
|
18
|
+
<title>Showcase</title>
|
19
|
+
<%= assets.group('stylesheets/all.css') %>
|
20
|
+
</head>
|
21
|
+
<body>
|
22
|
+
<%= yield %>
|
23
|
+
<%= assets.group('javascripts/all.js') %>
|
24
|
+
</body>
|
25
|
+
</html>
|
26
|
+
|
27
|
+
@@ index
|
28
|
+
<h1>Assets-includer-ruby showcase</h1>
|
29
|
+
<p>CSS and JavaScript are included via <span class="pre">assets.group</span> calls (see source in app.rb)</p>
|
30
|
+
<p>Here's a list of all CSS assets (you can get it programaticaly):</p>
|
31
|
+
<ol>
|
32
|
+
<% assets.list('stylesheets/all.css').each do |asset| %>
|
33
|
+
<li><%= asset %></li>
|
34
|
+
<% end %>
|
35
|
+
</ol>
|
36
|
+
<p>and a list of all JavaScript ones:</p>
|
37
|
+
<ol>
|
38
|
+
<% assets.list('javascripts/all.js').each do |asset| %>
|
39
|
+
<li><%= asset %></li>
|
40
|
+
<% end %>
|
41
|
+
</ol>
|
42
|
+
<p class="js-inline-placeholder"></p>
|
43
|
+
<%= assets.inline('javascripts/inline.js') %>
|
@@ -0,0 +1,64 @@
|
|
1
|
+
/*!
|
2
|
+
* HEX <=> RGB Conversion
|
3
|
+
* Copyright(c) 2011 Daniel Lamb <daniellmb.com>
|
4
|
+
* MIT Licensed
|
5
|
+
*/
|
6
|
+
|
7
|
+
(function (context) {
|
8
|
+
|
9
|
+
context['toRGB'] = function (/* String */ color) {
|
10
|
+
// summary:
|
11
|
+
// Converts a 6 digit Hexadecimal string value to an RGB integer array.
|
12
|
+
// Important! input must be a 6 digit Hexadecimal string "bad" will
|
13
|
+
// not convert correctly but "bbaadd" will. To keep the function as
|
14
|
+
// light as possible there is no idiot-proofing, if you pass in bad
|
15
|
+
// data I'm not fixing it for you :-)
|
16
|
+
//
|
17
|
+
// color: String
|
18
|
+
// 6 digit Hexadecimal string value
|
19
|
+
//
|
20
|
+
// returns: Array
|
21
|
+
// An array containing the RGB integers in the following format [red, green, blue]
|
22
|
+
//
|
23
|
+
// example:
|
24
|
+
// Convert the Hexadecimal value "c0ffee" (blue color) to RGB integers.
|
25
|
+
// The variable "rgb" will be equal to [192, 255, 238]
|
26
|
+
//
|
27
|
+
// var rgb = toRGB("c0ffee");
|
28
|
+
|
29
|
+
//convert string to base 16 number
|
30
|
+
var num = parseInt(color, 16);
|
31
|
+
|
32
|
+
//return the red, green and blue values as a new array
|
33
|
+
return [num >> 16, num >> 8 & 255, num & 255];
|
34
|
+
};
|
35
|
+
|
36
|
+
context['toHex'] = function (/* Number */ red, /* Number */ green, /* Number */ blue) {
|
37
|
+
// summary:
|
38
|
+
// Converts 3 RGB integer values into a Hexadecimal string.
|
39
|
+
// Important! input must be integers with a range of 0 to 255.
|
40
|
+
// To keep the function as light as possible there is no idiot-proofing,
|
41
|
+
// if you pass in bad data I'm not fixing it for you :-)
|
42
|
+
//
|
43
|
+
// red: Number
|
44
|
+
// number ranging from 0 to 255 indicating the amount of red
|
45
|
+
// green: Number
|
46
|
+
// number ranging from 0 to 255 indicating the amount of green
|
47
|
+
// blue: Number
|
48
|
+
// number ranging from 0 to 255 indicating the amount of blue
|
49
|
+
//
|
50
|
+
// returns: String
|
51
|
+
// 6 digit Hexadecimal string value
|
52
|
+
//
|
53
|
+
// example:
|
54
|
+
// Convert the RGB values [192, 255, 238] (blue color) to Hexadecimal string.
|
55
|
+
// The variable "hex" will be equal to "c0ffee"
|
56
|
+
//
|
57
|
+
// var hex = toHex(192, 255, 238);
|
58
|
+
|
59
|
+
//return 6 digit Hexadecimal string
|
60
|
+
return ((blue | green << 8 | red << 16) | 1 << 24).toString(16).slice(1);
|
61
|
+
};
|
62
|
+
|
63
|
+
})(this);
|
64
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
/*
|
2
|
+
Copyright (c) 2008 Stefan Lange-Hegermann
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
of this software and associated documentation files (the "Software"), to deal
|
6
|
+
in the Software without restriction, including without limitation the rights
|
7
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the Software is
|
9
|
+
furnished to do so, subject to the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be included in
|
12
|
+
all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
THE SOFTWARE.
|
21
|
+
*/
|
22
|
+
|
23
|
+
function microAjax(url, callbackFunction)
|
24
|
+
{
|
25
|
+
this.bindFunction = function (caller, object) {
|
26
|
+
return function() {
|
27
|
+
return caller.apply(object, [object]);
|
28
|
+
};
|
29
|
+
};
|
30
|
+
|
31
|
+
this.stateChange = function (object) {
|
32
|
+
if (this.request.readyState==4)
|
33
|
+
this.callbackFunction(this.request.responseText);
|
34
|
+
};
|
35
|
+
|
36
|
+
this.getRequest = function() {
|
37
|
+
if (window.ActiveXObject)
|
38
|
+
return new ActiveXObject('Microsoft.XMLHTTP');
|
39
|
+
else if (window.XMLHttpRequest)
|
40
|
+
return new XMLHttpRequest();
|
41
|
+
return false;
|
42
|
+
};
|
43
|
+
|
44
|
+
this.postBody = (arguments[2] || "");
|
45
|
+
|
46
|
+
this.callbackFunction=callbackFunction;
|
47
|
+
this.url=url;
|
48
|
+
this.request = this.getRequest();
|
49
|
+
|
50
|
+
if(this.request) {
|
51
|
+
var req = this.request;
|
52
|
+
req.onreadystatechange = this.bindFunction(this.stateChange, this);
|
53
|
+
|
54
|
+
if (this.postBody!=="") {
|
55
|
+
req.open("POST", url, true);
|
56
|
+
req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
57
|
+
req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
58
|
+
req.setRequestHeader('Connection', 'close');
|
59
|
+
} else {
|
60
|
+
req.open("GET", url, true);
|
61
|
+
}
|
62
|
+
|
63
|
+
req.send(this.postBody);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
/*! normalize.css v2.1.3 | MIT License | git.io/normalize */
|
2
|
+
|
3
|
+
/* ==========================================================================
|
4
|
+
HTML5 display definitions
|
5
|
+
========================================================================== */
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Correct `block` display not defined in IE 8/9.
|
9
|
+
*/
|
10
|
+
|
11
|
+
article,
|
12
|
+
aside,
|
13
|
+
details,
|
14
|
+
figcaption,
|
15
|
+
figure,
|
16
|
+
footer,
|
17
|
+
header,
|
18
|
+
hgroup,
|
19
|
+
main,
|
20
|
+
nav,
|
21
|
+
section,
|
22
|
+
summary {
|
23
|
+
display: block;
|
24
|
+
}
|
25
|
+
|
26
|
+
/* ==========================================================================
|
27
|
+
Base
|
28
|
+
========================================================================== */
|
29
|
+
|
30
|
+
/**
|
31
|
+
* 1. Set default font family to sans-serif.
|
32
|
+
* 2. Prevent iOS text size adjust after orientation change, without disabling
|
33
|
+
* user zoom.
|
34
|
+
*/
|
35
|
+
|
36
|
+
html {
|
37
|
+
font-family: sans-serif; /* 1 */
|
38
|
+
-ms-text-size-adjust: 100%; /* 2 */
|
39
|
+
-webkit-text-size-adjust: 100%; /* 2 */
|
40
|
+
}
|
41
|
+
|
42
|
+
/**
|
43
|
+
* Remove default margin.
|
44
|
+
*/
|
45
|
+
|
46
|
+
body {
|
47
|
+
margin: 0;
|
48
|
+
}
|
49
|
+
|
50
|
+
/* ==========================================================================
|
51
|
+
Links
|
52
|
+
========================================================================== */
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Remove the gray background color from active links in IE 10.
|
56
|
+
*/
|
57
|
+
|
58
|
+
a {
|
59
|
+
background: transparent;
|
60
|
+
}
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Address `outline` inconsistency between Chrome and other browsers.
|
64
|
+
*/
|
65
|
+
|
66
|
+
a:focus {
|
67
|
+
outline: thin dotted;
|
68
|
+
}
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Improve readability when focused and also mouse hovered in all browsers.
|
72
|
+
*/
|
73
|
+
|
74
|
+
a:active,
|
75
|
+
a:hover {
|
76
|
+
outline: 0;
|
77
|
+
}
|
78
|
+
|
79
|
+
/* ==========================================================================
|
80
|
+
Typography
|
81
|
+
========================================================================== */
|
82
|
+
|
83
|
+
/**
|
84
|
+
* Address variable `h1` font-size and margin within `section` and `article`
|
85
|
+
* contexts in Firefox 4+, Safari 5, and Chrome.
|
86
|
+
*/
|
87
|
+
|
88
|
+
h1 {
|
89
|
+
font-size: 2em;
|
90
|
+
margin: 0.67em 0;
|
91
|
+
}
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require_relative 'cache'
|
2
|
+
|
3
|
+
module AssetsInclude
|
4
|
+
|
5
|
+
class Base
|
6
|
+
attr_accessor :bundled, :asset_hosts, :root, :config, :cache_boosters
|
7
|
+
attr_accessor :binary
|
8
|
+
|
9
|
+
def initialize(&block)
|
10
|
+
@cache = Cache.new
|
11
|
+
@config = default_assets_location
|
12
|
+
@bundled = production?
|
13
|
+
@cache_boosters = true
|
14
|
+
|
15
|
+
yield(self) if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def group(locator, options = {})
|
19
|
+
assets(locator, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
def list(locator)
|
23
|
+
assets(locator, list: true).strip.split(',')
|
24
|
+
end
|
25
|
+
|
26
|
+
def inline(locator)
|
27
|
+
assets(locator, inline: true)
|
28
|
+
end
|
29
|
+
|
30
|
+
def reset
|
31
|
+
cache.empty
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
attr_reader :cache
|
37
|
+
|
38
|
+
def assets(locator, options)
|
39
|
+
cache.empty unless bundled
|
40
|
+
|
41
|
+
cache.add("#{locator}-#{options.to_s.hash}") do
|
42
|
+
IO.popen(command(locator, options).join(' ')).read
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def default_assets_location
|
47
|
+
File.join(Dir.pwd, 'assets.yml')
|
48
|
+
end
|
49
|
+
|
50
|
+
def production?
|
51
|
+
ENV['RACK_ENV'] == 'production'
|
52
|
+
end
|
53
|
+
|
54
|
+
def command(locator, options = {})
|
55
|
+
parts = []
|
56
|
+
parts << includer_binary
|
57
|
+
parts << root_switch
|
58
|
+
parts << config_switch
|
59
|
+
parts << bundled_switch
|
60
|
+
parts << cache_boosters_switch
|
61
|
+
parts << list_switch(options)
|
62
|
+
parts << inline_switch(options)
|
63
|
+
parts << asset_hosts_switch
|
64
|
+
parts << loading_mode_switch(options)
|
65
|
+
parts << locator
|
66
|
+
parts.compact
|
67
|
+
end
|
68
|
+
|
69
|
+
def includer_binary
|
70
|
+
@binary ||= binary_locations.find { |path|
|
71
|
+
IO.popen("which #{path}")
|
72
|
+
$?.to_i == 0
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
def binary_locations
|
77
|
+
[
|
78
|
+
File.join(implicit_root, '..', 'node_modules', '.bin', 'assetsinc'),
|
79
|
+
File.join(implicit_root, 'node_modules', '.bin', 'assetsinc'),
|
80
|
+
'assetsinc'
|
81
|
+
]
|
82
|
+
end
|
83
|
+
|
84
|
+
def implicit_root
|
85
|
+
root || File.join(Dir.pwd, 'public')
|
86
|
+
end
|
87
|
+
|
88
|
+
def root_switch
|
89
|
+
root ? "-r #{root}" : nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def config_switch
|
93
|
+
"-c #{config}"
|
94
|
+
end
|
95
|
+
|
96
|
+
def bundled_switch
|
97
|
+
bundled ? '-b' : nil
|
98
|
+
end
|
99
|
+
|
100
|
+
def cache_boosters_switch
|
101
|
+
cache_boosters ? '-s' : nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def list_switch(options = {})
|
105
|
+
options[:list] ? '-l' : nil
|
106
|
+
end
|
107
|
+
|
108
|
+
def inline_switch(options = {})
|
109
|
+
options[:inline] ? '-i' : nil
|
110
|
+
end
|
111
|
+
|
112
|
+
def asset_hosts_switch
|
113
|
+
asset_hosts ? "-a #{asset_hosts}" : nil
|
114
|
+
end
|
115
|
+
|
116
|
+
def loading_mode_switch(options = {})
|
117
|
+
options[:loading_mode] ? "-m #{options[:loading_mode]}" : nil
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module AssetsInclude
|
2
|
+
class Cache
|
3
|
+
def initialize
|
4
|
+
@store = {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def add(key, &block)
|
8
|
+
store[key] ||= yield
|
9
|
+
end
|
10
|
+
|
11
|
+
def get(key)
|
12
|
+
store[key]
|
13
|
+
end
|
14
|
+
|
15
|
+
def empty
|
16
|
+
store.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :store
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,235 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'assets_include/base'
|
4
|
+
|
5
|
+
describe AssetsInclude::Base do
|
6
|
+
include FlexMock::TestCase
|
7
|
+
|
8
|
+
def after
|
9
|
+
flexmock_teardown
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#initialize' do
|
15
|
+
it 'should make binary customizable' do
|
16
|
+
flexmock(IO)
|
17
|
+
.should_receive(:popen)
|
18
|
+
.once
|
19
|
+
.with(['assetsinc', "-r #{root}", "-c #{config}", '-b', group].join(' '))
|
20
|
+
.and_return(flexmock(read: ''))
|
21
|
+
|
22
|
+
includer(binary: 'assetsinc').group(group)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should default `root` and `config`' do
|
26
|
+
flexmock(IO)
|
27
|
+
.should_receive(:popen)
|
28
|
+
.once
|
29
|
+
.with([binary, "-c #{File.join(Dir.pwd, 'assets.yml')}", group].join(' '))
|
30
|
+
.and_return(flexmock(read: ''))
|
31
|
+
|
32
|
+
described_class.new { |inc|
|
33
|
+
inc.binary = binary
|
34
|
+
inc.cache_boosters = false
|
35
|
+
}.group(group)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should set `cache_boosters` to true by default' do
|
39
|
+
described_class.new.cache_boosters.must_equal true
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should set `bundled` to false by default' do
|
43
|
+
described_class.new.bundled.must_equal false
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should set `bundled` to true on production' do
|
47
|
+
begin
|
48
|
+
ENV['RACK_ENV'] = 'production'
|
49
|
+
|
50
|
+
described_class.new.bundled.must_equal true
|
51
|
+
ensure
|
52
|
+
ENV['RACK_ENV'] = 'test'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#group' do
|
58
|
+
it 'should proxy a call to assetsinc and return correct result' do
|
59
|
+
should_run_includer_with(options: ['-b', group])
|
60
|
+
|
61
|
+
includer.group(group).must_equal(:assets)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should cache any subsequent calls' do
|
65
|
+
should_run_includer_with(options: ['-b', group])
|
66
|
+
|
67
|
+
includer.group(group)
|
68
|
+
includer.group(group).must_equal(:assets)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should cache results based on passed locator' do
|
72
|
+
should_run_includer_with(
|
73
|
+
options: ['-b', group],
|
74
|
+
output: :assets_1
|
75
|
+
)
|
76
|
+
|
77
|
+
should_run_includer_with(
|
78
|
+
options: ['-b', group('page')],
|
79
|
+
output: :assets_2
|
80
|
+
)
|
81
|
+
|
82
|
+
includer.group(group).must_equal(:assets_1)
|
83
|
+
includer.group(group('page')).must_equal(:assets_2)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should empty cache if not bundled' do
|
87
|
+
should_run_includer_with(
|
88
|
+
options: [group],
|
89
|
+
repeat: 2
|
90
|
+
)
|
91
|
+
|
92
|
+
2.times do
|
93
|
+
includer(bundled: false).group(group)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should use cache boosters' do
|
98
|
+
should_run_includer_with(options: ['-b', '-s', group])
|
99
|
+
|
100
|
+
includer(cache_boosters: true).group(group)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should use asset hosts' do
|
104
|
+
should_run_includer_with(options: ['-b', '-a goalsmashers.com', group])
|
105
|
+
|
106
|
+
includer(asset_hosts: 'goalsmashers.com').group(group)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should use loading mode' do
|
110
|
+
should_run_includer_with(options: ['-b', '-m async', group])
|
111
|
+
|
112
|
+
includer.group(group, loading_mode: 'async')
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should do a real call and get a list of tags' do
|
116
|
+
assets = [
|
117
|
+
%{<link href="#{file_with_timestamp('one.css')}" media="screen" rel="stylesheet"/>},
|
118
|
+
%{<link href="#{file_with_timestamp('two.css')}" media="screen" rel="stylesheet"/>}
|
119
|
+
]
|
120
|
+
|
121
|
+
includer(bundled: false).group(group).strip.must_equal(assets.join)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#list' do
|
126
|
+
it 'should proxy a call to assetsinc and return correct result' do
|
127
|
+
should_run_includer_with(
|
128
|
+
options: ['-b', '-l', group],
|
129
|
+
output: 'list'
|
130
|
+
)
|
131
|
+
|
132
|
+
includer.list(group).must_equal(['list'])
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should do a real call and get a list of assets' do
|
136
|
+
assets = [
|
137
|
+
file_with_timestamp('one.css'),
|
138
|
+
file_with_timestamp('two.css')
|
139
|
+
]
|
140
|
+
|
141
|
+
includer(bundled: false).list(group).must_equal(assets)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#inline' do
|
146
|
+
it 'should proxy a call to assetsinc and return correct result' do
|
147
|
+
should_run_includer_with(
|
148
|
+
options: ['-b', '-i', group],
|
149
|
+
output: :inline
|
150
|
+
)
|
151
|
+
|
152
|
+
includer.inline(group).must_equal(:inline)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should do a real call and get an inline style' do
|
156
|
+
inline = '<style type="text/css">.one,.two{color:red}</style>'
|
157
|
+
|
158
|
+
includer(bundled: true).inline(group).strip.must_equal(inline)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#reset' do
|
163
|
+
it 'should empty cache' do
|
164
|
+
should_run_includer_with(
|
165
|
+
options: ['-b', group],
|
166
|
+
repeat: 2
|
167
|
+
)
|
168
|
+
|
169
|
+
includer.group(group)
|
170
|
+
includer.reset
|
171
|
+
includer.group(group)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
private
|
176
|
+
|
177
|
+
def includer(options = {})
|
178
|
+
@includer ||= described_class.new do |inc|
|
179
|
+
inc.root = root
|
180
|
+
inc.config = config
|
181
|
+
inc.bundled = true
|
182
|
+
inc.cache_boosters = false
|
183
|
+
inc.binary = binary
|
184
|
+
|
185
|
+
options.each do |key, value|
|
186
|
+
inc.public_send("#{key}=", value)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def should_run_includer_with(opts = {})
|
192
|
+
flexmock(IO)
|
193
|
+
.should_receive(:popen)
|
194
|
+
.times(opts[:repeat] || 1)
|
195
|
+
.with(command(opts[:options]).join(' '))
|
196
|
+
.and_return(flexmock(read: opts[:output] || :assets))
|
197
|
+
end
|
198
|
+
|
199
|
+
def command(options = {})
|
200
|
+
[
|
201
|
+
binary,
|
202
|
+
"-r #{root}",
|
203
|
+
"-c #{config}",
|
204
|
+
options
|
205
|
+
].flatten.compact.uniq
|
206
|
+
end
|
207
|
+
|
208
|
+
def file_with_timestamp(name)
|
209
|
+
local_path = File.join('stylesheets', name)
|
210
|
+
absolute_path = File.join(root, local_path)
|
211
|
+
relative_path = absolute_path.sub(root, '')
|
212
|
+
|
213
|
+
"#{relative_path}?#{File.mtime(absolute_path).to_i * 1000}"
|
214
|
+
end
|
215
|
+
|
216
|
+
def group(name = 'all')
|
217
|
+
"stylesheets/#{name}.css"
|
218
|
+
end
|
219
|
+
|
220
|
+
def binary
|
221
|
+
File.join(root, '..', 'node_modules', '.bin', 'assetsinc')
|
222
|
+
end
|
223
|
+
|
224
|
+
def root
|
225
|
+
File.join(Dir.pwd, 'test', 'fixtures', 'public')
|
226
|
+
end
|
227
|
+
|
228
|
+
def config
|
229
|
+
File.join(root, '..', 'assets.yml')
|
230
|
+
end
|
231
|
+
|
232
|
+
def described_class
|
233
|
+
AssetsInclude::Base
|
234
|
+
end
|
235
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'assets_include/cache'
|
4
|
+
|
5
|
+
describe AssetsInclude::Cache do
|
6
|
+
describe 'initialize' do
|
7
|
+
it 'is empty by default' do
|
8
|
+
cache.get(:key).must_equal nil
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#add' do
|
13
|
+
it 'adds an item to cache' do
|
14
|
+
cache.add(:key) { :value }
|
15
|
+
|
16
|
+
cache.get(:key).must_equal :value
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'does not overwrite item in cache' do
|
20
|
+
2.times do |i|
|
21
|
+
cache.add(:key) { i }
|
22
|
+
end
|
23
|
+
|
24
|
+
cache.get(:key).must_equal 0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#get' do
|
29
|
+
it 'does not remove item from cache' do
|
30
|
+
cache.add(:key) { :value }
|
31
|
+
|
32
|
+
cache.get(:key).must_equal :value
|
33
|
+
cache.get(:key).must_equal :value
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#empty' do
|
38
|
+
it 'empties the cache' do
|
39
|
+
cache.add(:key) { :value }
|
40
|
+
|
41
|
+
cache.empty
|
42
|
+
cache.get(:key).must_equal nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def cache
|
49
|
+
@cache ||= described_class.new
|
50
|
+
end
|
51
|
+
|
52
|
+
def described_class
|
53
|
+
AssetsInclude::Cache
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'assets_include/proxy'
|
4
|
+
|
5
|
+
describe AssetsInclude::Proxy do
|
6
|
+
describe '#module' do
|
7
|
+
it 'should be a module' do
|
8
|
+
proxy.class.must_equal(Module)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should be a Proxy module' do
|
12
|
+
proxy.is_a?(described_class).must_equal true
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should expose Base via assets' do
|
16
|
+
proxy.assets.class.must_equal(AssetsInclude::Base)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'AssetsInclude.helpers' do
|
21
|
+
it 'should yield the Proxy module' do
|
22
|
+
AssetsInclude.helpers.is_a?(described_class).must_equal true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def proxy
|
29
|
+
described_class.tap do |p|
|
30
|
+
p.assets = AssetsInclude::Base.new
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def described_class
|
35
|
+
AssetsInclude::Proxy
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
.one,.two{color:red}
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'codeclimate-test-reporter'
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
|
4
|
+
ENV['RACK_ENV'] = 'test'
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'bundler/setup'
|
8
|
+
Bundler.setup
|
9
|
+
Bundler.require(:default, :test)
|
10
|
+
|
11
|
+
gem 'minitest'
|
12
|
+
require 'minitest/autorun'
|
13
|
+
require 'flexmock'
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: assets_include
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jakub Pawlowicz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.7.0
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.7.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: flexmock
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.3.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.3.0
|
41
|
+
description: Include assets in your views with a single line of code.
|
42
|
+
email: jakub.pawlowicz@goalsmashers.com
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- .travis.yml
|
48
|
+
- Gemfile
|
49
|
+
- History.md
|
50
|
+
- LICENSE
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- assets_include.gemspec
|
54
|
+
- examples/sinatra/Gemfile
|
55
|
+
- examples/sinatra/Gemfile.lock
|
56
|
+
- examples/sinatra/README.md
|
57
|
+
- examples/sinatra/app.rb
|
58
|
+
- examples/sinatra/assets.yml
|
59
|
+
- examples/sinatra/package.json
|
60
|
+
- examples/sinatra/public/javascripts/inline.js
|
61
|
+
- examples/sinatra/public/javascripts/main.js
|
62
|
+
- examples/sinatra/public/javascripts/vendor/hex-rgb.src.js
|
63
|
+
- examples/sinatra/public/javascripts/vendor/microajax.js
|
64
|
+
- examples/sinatra/public/stylesheets/base.css
|
65
|
+
- examples/sinatra/public/stylesheets/normalize.css
|
66
|
+
- lib/assets_include.rb
|
67
|
+
- lib/assets_include/base.rb
|
68
|
+
- lib/assets_include/cache.rb
|
69
|
+
- lib/assets_include/proxy.rb
|
70
|
+
- lib/assets_include/version.rb
|
71
|
+
- test/assets_include/base_test.rb
|
72
|
+
- test/assets_include/cache_test.rb
|
73
|
+
- test/assets_include/proxy_test.rb
|
74
|
+
- test/fixtures/assets.yml
|
75
|
+
- test/fixtures/package.json
|
76
|
+
- test/fixtures/public/stylesheets/bundled/all.css
|
77
|
+
- test/fixtures/public/stylesheets/one.css
|
78
|
+
- test/fixtures/public/stylesheets/two.css
|
79
|
+
- test/test_helper.rb
|
80
|
+
homepage: https://github.com/GoalSmashers/assets-include-ruby
|
81
|
+
licenses:
|
82
|
+
- MIT
|
83
|
+
metadata: {}
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - '>='
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
requirements: []
|
99
|
+
rubyforge_project:
|
100
|
+
rubygems_version: 2.0.3
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Ruby bindings for assets-include node.js library.
|
104
|
+
test_files: []
|