voltron-svg 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +105 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/voltron/svg-injector.js +9 -0
- data/app/assets/javascripts/voltron-svg.js +134 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/generators/voltron/svg/install_generator.rb +48 -0
- data/lib/voltron/config/svg.rb +24 -0
- data/lib/voltron/svg/engine.rb +10 -0
- data/lib/voltron/svg/tag.rb +204 -0
- data/lib/voltron/svg/version.rb +5 -0
- data/lib/voltron/svg.rb +36 -0
- data/voltron-svg.gemspec +31 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f598518413b8870b644060d2513d0b268035abf4
|
4
|
+
data.tar.gz: 80f1438aa4a4e0e380879d52edeb87b5d83e6eba
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2318d4156adfdc86edb1fcbae14e4890a1d2b094ee7fad3683c3a41c7bfdf244b77d46f8a7aae7dcca4c37431563d562ffd4dc9b7e1cd5890b78f24b087fcfa1
|
7
|
+
data.tar.gz: 2b3a7cf4363959f3201fe2fe2c02ca9a5fff9102610f4167218ed3ff3177209f535def86f6edc615ae754f5177fb99a0664562f8d831acfa264c2ce1b2778477
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
7
|
+
|
8
|
+
We are committed to making participation in this project a harassment-free
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
12
|
+
|
13
|
+
Examples of unacceptable behavior by participants include:
|
14
|
+
|
15
|
+
* The use of sexualized language or imagery
|
16
|
+
* Personal attacks
|
17
|
+
* Trolling or insulting/derogatory comments
|
18
|
+
* Public or private harassment
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
20
|
+
addresses, without explicit permission
|
21
|
+
* Other unethical or unprofessional conduct
|
22
|
+
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
27
|
+
threatening, offensive, or harmful.
|
28
|
+
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
32
|
+
Conduct may be permanently removed from the project team.
|
33
|
+
|
34
|
+
This code of conduct applies both within project spaces and in public spaces
|
35
|
+
when an individual is representing the project or its community.
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
+
reported by contacting a project maintainer at eric.hainer@gmail.com. All
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
42
|
+
incident.
|
43
|
+
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
45
|
+
version 1.3.0, available at
|
46
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
47
|
+
|
48
|
+
[homepage]: http://contributor-covenant.org
|
49
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Eric Hainer
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/ehainer/voltron-svg.svg?branch=master)](https://travis-ci.org/ehainer/voltron-svg)
|
2
|
+
|
3
|
+
# Voltron::Svg
|
4
|
+
|
5
|
+
For lazy people who just want to work with SVG icons and have fallback images created for them.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'voltron-svg'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install voltron-svg
|
22
|
+
|
23
|
+
Then run the following to create the voltron.rb initializer (if not exists already) and add the svg config:
|
24
|
+
|
25
|
+
$ rails g voltron:svg:install
|
26
|
+
|
27
|
+
To implement the built in svg injector, include the following in `application.js`
|
28
|
+
|
29
|
+
```
|
30
|
+
//= require voltron-svg
|
31
|
+
```
|
32
|
+
|
33
|
+
The built in svg injector utilizes Iconic's [SVGInjector](https://github.com/iconic/SVGInjector) library. Refer to the github page for documentation, but note that Voltron SVG does not currently provide a way to alter the config, as it's designed to work with the markup that is output by Voltron SVG by default. See below for example:
|
34
|
+
|
35
|
+
```html
|
36
|
+
<img width="150" height="150" alt="anchor" data-svg="true" data-size="150x150" data-fallback="/assets/anchor.150x150.TEAL-8cf90f05009ceff4967786502d3c840ef14a79dcb40fa84b156c8ec94e35dfeb.png" src="/assets/anchor.TEAL-f982442b37f0c6c919e15d015d1d0ed9e8c4647116ae4a849ce48b9f7e315c13.svg">
|
37
|
+
```
|
38
|
+
|
39
|
+
If however you desire more control over the SVG injection process, feel free to not include the `//= require voltron-svg` in application.js, and then roll your own implementation. All tags output by Voltron SVG will follow the same format as the above markup, so you should have access to everything you'd need to do... whatever.
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
The following assumes the presence of the file `phone.svg` in the `Voltron.config.svg.source_directory` path.
|
44
|
+
|
45
|
+
Voltron SVG adds the method `svg_tag` to the view helpers, so in your views you can display an SVG with an identical PNG as a fallback image simple by writing:
|
46
|
+
|
47
|
+
```erb
|
48
|
+
<div class="contact">
|
49
|
+
<%= svg_tag :phone %>
|
50
|
+
<span>Call This Number</span>
|
51
|
+
</div>
|
52
|
+
```
|
53
|
+
|
54
|
+
Or specify some options to customize the output:
|
55
|
+
|
56
|
+
```erb
|
57
|
+
<div class="contact">
|
58
|
+
<%= svg_tag :phone, color: :teal, size: "50x50", quality: 100 %>
|
59
|
+
<span>Call This Number</span>
|
60
|
+
</div>
|
61
|
+
```
|
62
|
+
|
63
|
+
Or use in SASS by writing:
|
64
|
+
|
65
|
+
```sass
|
66
|
+
.contact {
|
67
|
+
width: 50px;
|
68
|
+
height: 50px;
|
69
|
+
background-image: svg-icon(phone, $color: teal, $quality: 100, $size: "50x50");
|
70
|
+
background-repeat: no-repeat;
|
71
|
+
}
|
72
|
+
```
|
73
|
+
|
74
|
+
If a color is specified, Voltron SVG will create a duplicate SVG file of the icon you want to display, and replace the color of all fills and paths with the color you defined. Any color format that would be valid in CSS is valid for the value of the color option, including, but not limited to: `#323A45`, `rebeccapurple`, or `rgba(100, 100, 100, 0.7)`
|
75
|
+
|
76
|
+
For reasons that may or may not be obvious, only the entire color of the SVG can be specified. Multi-color SVG's will receive a "color flood" if a color is provided, because sadly I don't have a way to write code for "make this line this color, but this area this color, and that line another color..." given an abstract SVG file that can have any number of path's and areas to color.
|
77
|
+
|
78
|
+
## Options
|
79
|
+
|
80
|
+
Possible options for `svg_tag` and `svg-icon`
|
81
|
+
|
82
|
+
* :color -> The color, silly
|
83
|
+
* :quality -> The generated PNG quality. Default: 90
|
84
|
+
* :width -> The width, duh
|
85
|
+
* :height -> The height, duh
|
86
|
+
* :size -> Use is same as in `image_tag`, could be specified as "50x50" or just "50" (this option takes priority if :width and :height are also provided)
|
87
|
+
* :fallback -> If you don't want it to use the default generated fallback image, provide a specific image name, i.e. - "my-more-awesome-fallback.png"
|
88
|
+
* :extension -> Likely not needed, but if you call `svg_tag :phone` but for some reason it doesn't have a *.svg extension, you can call `svg_tag :phone, extension: "flub"` to have it find "phone.flub" instead. Or just write `svg_tag "phone.flub"` in the first place.
|
89
|
+
|
90
|
+
All other options will be passed to the internal `image_tag` call, so you may also provide options like `:alt`, `:class`, or `:data` and it will be present on the generated <img /> tag. Note that Voltron SVG adds it's own `data-*` attributes (data-svg, data-size, data-fallback to be exact), but they will be merged with any data hash you provide when calling svg_tag. So basically, the 'size', 'svg', and 'fallback' data-* attributes are reserved, but any other data param is fair game.
|
91
|
+
|
92
|
+
## Development
|
93
|
+
|
94
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
95
|
+
|
96
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
97
|
+
|
98
|
+
## Contributing
|
99
|
+
|
100
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/ehainer/voltron-svg. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
101
|
+
|
102
|
+
## License
|
103
|
+
|
104
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
105
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
/**
|
2
|
+
* SVGInjector v1.1.3 - Fast, caching, dynamic inline SVG DOM injection library
|
3
|
+
* https://github.com/iconic/SVGInjector
|
4
|
+
*
|
5
|
+
* Copyright (c) 2014-2015 Waybury <hello@waybury.com>
|
6
|
+
* @license MIT
|
7
|
+
*/
|
8
|
+
!function(t,e){"use strict";function r(t){t=t.split(" ");for(var e={},r=t.length,n=[];r--;)e.hasOwnProperty(t[r])||(e[t[r]]=1,n.unshift(t[r]));return n.join(" ")}var n="file:"===t.location.protocol,i=e.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"),o=Array.prototype.forEach||function(t,e){if(void 0===this||null===this||"function"!=typeof t)throw new TypeError;var r,n=this.length>>>0;for(r=0;n>r;++r)r in this&&t.call(e,this[r],r,this)},a={},l=0,s=[],u=[],c={},f=function(t){return t.cloneNode(!0)},p=function(t,e){u[t]=u[t]||[],u[t].push(e)},d=function(t){for(var e=0,r=u[t].length;r>e;e++)!function(e){setTimeout(function(){u[t][e](f(a[t]))},0)}(e)},v=function(e,r){if(void 0!==a[e])a[e]instanceof SVGSVGElement?r(f(a[e])):p(e,r);else{if(!t.XMLHttpRequest)return r("Browser does not support XMLHttpRequest"),!1;a[e]={},p(e,r);var i=new XMLHttpRequest;i.onreadystatechange=function(){if(4===i.readyState){if(404===i.status||null===i.responseXML)return r("Unable to load SVG file: "+e),n&&r("Note: SVG injection ajax calls do not work locally without adjusting security setting in your browser. Or consider using a local webserver."),r(),!1;if(!(200===i.status||n&&0===i.status))return r("There was a problem injecting the SVG: "+i.status+" "+i.statusText),!1;if(i.responseXML instanceof Document)a[e]=i.responseXML.documentElement;else if(DOMParser&&DOMParser instanceof Function){var t;try{var o=new DOMParser;t=o.parseFromString(i.responseText,"text/xml")}catch(l){t=void 0}if(!t||t.getElementsByTagName("parsererror").length)return r("Unable to parse SVG file: "+e),!1;a[e]=t.documentElement}d(e)}},i.open("GET",e),i.overrideMimeType&&i.overrideMimeType("text/xml"),i.send()}},h=function(e,n,a,u){var f=e.getAttribute("data-src")||e.getAttribute("src");if(!/\.svg/i.test(f))return void u("Attempted to inject a file with a non-svg extension: "+f);if(!i){var p=e.getAttribute("data-fallback")||e.getAttribute("data-png");return void(p?(e.setAttribute("src",p),u(null)):a?(e.setAttribute("src",a+"/"+f.split("/").pop().replace(".svg",".png")),u(null)):u("This browser does not support SVG and no PNG fallback was defined."))}-1===s.indexOf(e)&&(s.push(e),e.setAttribute("src",""),v(f,function(i){if("undefined"==typeof i||"string"==typeof i)return u(i),!1;var a=e.getAttribute("id");a&&i.setAttribute("id",a);var p=e.getAttribute("title");p&&i.setAttribute("title",p);var d=[].concat(i.getAttribute("class")||[],"injected-svg",e.getAttribute("class")||[]).join(" ");i.setAttribute("class",r(d));var v=e.getAttribute("style");v&&i.setAttribute("style",v);var h=[].filter.call(e.attributes,function(t){return/^data-\w[\w\-]*$/.test(t.name)});o.call(h,function(t){t.name&&t.value&&i.setAttribute(t.name,t.value)});var g,m,b,y,A,w={clipPath:["clip-path"],"color-profile":["color-profile"],cursor:["cursor"],filter:["filter"],linearGradient:["fill","stroke"],marker:["marker","marker-start","marker-mid","marker-end"],mask:["mask"],pattern:["fill","stroke"],radialGradient:["fill","stroke"]};Object.keys(w).forEach(function(t){g=t,b=w[t],m=i.querySelectorAll("defs "+g+"[id]");for(var e=0,r=m.length;r>e;e++){y=m[e].id,A=y+"-"+l;var n;o.call(b,function(t){n=i.querySelectorAll("["+t+'*="'+y+'"]');for(var e=0,r=n.length;r>e;e++)n[e].setAttribute(t,"url(#"+A+")")}),m[e].id=A}}),i.removeAttribute("xmlns:a");for(var x,S,k=i.querySelectorAll("script"),j=[],G=0,T=k.length;T>G;G++)S=k[G].getAttribute("type"),S&&"application/ecmascript"!==S&&"application/javascript"!==S||(x=k[G].innerText||k[G].textContent,j.push(x),i.removeChild(k[G]));if(j.length>0&&("always"===n||"once"===n&&!c[f])){for(var M=0,V=j.length;V>M;M++)new Function(j[M])(t);c[f]=!0}var E=i.querySelectorAll("style");o.call(E,function(t){t.textContent+=""}),e.parentNode.replaceChild(i,e),delete s[s.indexOf(e)],e=null,l++,u(i)}))},g=function(t,e,r){e=e||{};var n=e.evalScripts||"always",i=e.pngFallback||!1,a=e.each;if(void 0!==t.length){var l=0;o.call(t,function(e){h(e,n,i,function(e){a&&"function"==typeof a&&a(e),r&&t.length===++l&&r(l)})})}else t?h(t,n,i,function(e){a&&"function"==typeof a&&a(e),r&&r(1),t=null}):r&&r(0)};"object"==typeof module&&"object"==typeof module.exports?module.exports=exports=g:"function"==typeof define&&define.amd?define(function(){return g}):"object"==typeof t&&(t.SVGInjector=g)}(window,document);
|
9
|
+
//# sourceMappingURL=svg-injector.map.js
|
@@ -0,0 +1,134 @@
|
|
1
|
+
//= require voltron/svg-injector
|
2
|
+
|
3
|
+
if(Voltron){
|
4
|
+
Voltron.addModule('SVG', function(){
|
5
|
+
return {
|
6
|
+
initialize: function(){
|
7
|
+
this.inject();
|
8
|
+
},
|
9
|
+
|
10
|
+
getTag: function(svg, image, options){
|
11
|
+
options = $.extend(options, { src: svg, size: '16x16', svg: true, fallback: image });
|
12
|
+
if(/^[0-9]+$/.test(options['size'].toString())) options['size'] = (options['size'] + 'x' + options['size']);
|
13
|
+
var size = options['size'].split('x');
|
14
|
+
if(!options['width']) options['width'] = size[0];
|
15
|
+
if(!options['height']) options['height'] = size[1];
|
16
|
+
return $('<img />', this.getDataAttribute(options, ['size', 'svg', 'fallback']));
|
17
|
+
},
|
18
|
+
|
19
|
+
getDataAttribute: function(options, attributes){
|
20
|
+
for(var i=0; i<attributes.length; i++){
|
21
|
+
var attr = attributes[i];
|
22
|
+
if(options[attr]){
|
23
|
+
options['data-' + attr] = options[attr];
|
24
|
+
delete options[attr];
|
25
|
+
}
|
26
|
+
}
|
27
|
+
return options;
|
28
|
+
},
|
29
|
+
|
30
|
+
inject: function(){
|
31
|
+
var svgs = document.querySelectorAll('img[data-svg="true"]:not(.injected-svg)');
|
32
|
+
var options = {
|
33
|
+
each: function(svg){
|
34
|
+
if(svg.getAttribute('data-size')){
|
35
|
+
var dims = svg.getAttribute('data-size').split('x');
|
36
|
+
svg.setAttribute('width', parseFloat(dims[0]));
|
37
|
+
svg.setAttribute('height', parseFloat(dims[1]));
|
38
|
+
}
|
39
|
+
}
|
40
|
+
};
|
41
|
+
SVGInjector(svgs, options);
|
42
|
+
}
|
43
|
+
};
|
44
|
+
}, true);
|
45
|
+
}else{
|
46
|
+
(function(funcName, baseObj) {
|
47
|
+
"use strict";
|
48
|
+
// The public function name defaults to window.docReady
|
49
|
+
// but you can modify the last line of this function to pass in a different object or method name
|
50
|
+
// if you want to put them in a different namespace and those will be used instead of
|
51
|
+
// window.docReady(...)
|
52
|
+
funcName = funcName || "docReady";
|
53
|
+
baseObj = baseObj || window;
|
54
|
+
var readyList = [];
|
55
|
+
var readyFired = false;
|
56
|
+
var readyEventHandlersInstalled = false;
|
57
|
+
|
58
|
+
// call this when the document is ready
|
59
|
+
// this function protects itself against being called more than once
|
60
|
+
function ready() {
|
61
|
+
if (!readyFired) {
|
62
|
+
// this must be set to true before we start calling callbacks
|
63
|
+
readyFired = true;
|
64
|
+
for (var i = 0; i < readyList.length; i++) {
|
65
|
+
// if a callback here happens to add new ready handlers,
|
66
|
+
// the docReady() function will see that it already fired
|
67
|
+
// and will schedule the callback to run right after
|
68
|
+
// this event loop finishes so all handlers will still execute
|
69
|
+
// in order and no new ones will be added to the readyList
|
70
|
+
// while we are processing the list
|
71
|
+
readyList[i].fn.call(window, readyList[i].ctx);
|
72
|
+
}
|
73
|
+
// allow any closures held by these functions to free
|
74
|
+
readyList = [];
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
function readyStateChange() {
|
79
|
+
if ( document.readyState === "complete" ) {
|
80
|
+
ready();
|
81
|
+
}
|
82
|
+
}
|
83
|
+
|
84
|
+
// This is the one public interface
|
85
|
+
// docReady(fn, context);
|
86
|
+
// the context argument is optional - if present, it will be passed
|
87
|
+
// as an argument to the callback
|
88
|
+
baseObj[funcName] = function(callback, context) {
|
89
|
+
// if ready has already fired, then just schedule the callback
|
90
|
+
// to fire asynchronously, but right away
|
91
|
+
if (readyFired) {
|
92
|
+
setTimeout(function() {callback(context);}, 1);
|
93
|
+
return;
|
94
|
+
} else {
|
95
|
+
// add the function and context to the list
|
96
|
+
readyList.push({fn: callback, ctx: context});
|
97
|
+
}
|
98
|
+
// if document already ready to go, schedule the ready function to run
|
99
|
+
// IE only safe when readyState is "complete", others safe when readyState is "interactive"
|
100
|
+
if (document.readyState === "complete" || (!document.attachEvent && document.readyState === "interactive")) {
|
101
|
+
setTimeout(ready, 1);
|
102
|
+
} else if (!readyEventHandlersInstalled) {
|
103
|
+
// otherwise if we don't have event handlers installed, install them
|
104
|
+
if (document.addEventListener) {
|
105
|
+
// first choice is DOMContentLoaded event
|
106
|
+
document.addEventListener("DOMContentLoaded", ready, false);
|
107
|
+
// backup is window load event
|
108
|
+
window.addEventListener("load", ready, false);
|
109
|
+
} else {
|
110
|
+
// must be IE
|
111
|
+
document.attachEvent("onreadystatechange", readyStateChange);
|
112
|
+
window.attachEvent("onload", ready);
|
113
|
+
}
|
114
|
+
readyEventHandlersInstalled = true;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
})("docReady", window);
|
118
|
+
|
119
|
+
window.injectSVG = function(){
|
120
|
+
var svgs = document.querySelectorAll('img[data-svg="true"]');
|
121
|
+
var options = {
|
122
|
+
each: function(svg){
|
123
|
+
if(svg.getAttribute('data-size')){
|
124
|
+
var dims = svg.getAttribute('data-size').split('x');
|
125
|
+
svg.setAttribute('width', parseFloat(dims[0]));
|
126
|
+
svg.setAttribute('height', parseFloat(dims[1]));
|
127
|
+
}
|
128
|
+
}
|
129
|
+
};
|
130
|
+
SVGInjector(svgs, options);
|
131
|
+
};
|
132
|
+
|
133
|
+
docReady(injectSVG);
|
134
|
+
}
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "voltron/svg"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Voltron
|
2
|
+
module Svg
|
3
|
+
module Generators
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
|
6
|
+
desc "Add Voltron SVG initializer"
|
7
|
+
|
8
|
+
def inject_initializer
|
9
|
+
|
10
|
+
voltron_initialzer_path = Rails.root.join("config", "initializers", "voltron.rb")
|
11
|
+
|
12
|
+
unless File.exist? voltron_initialzer_path
|
13
|
+
unless system("cd #{Rails.root.to_s} && rails generate voltron:install")
|
14
|
+
puts "Voltron initializer does not exist. Please ensure you have the 'voltron' gem installed and run `rails g voltron:install` to create it"
|
15
|
+
return false
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
current_initiailzer = File.read voltron_initialzer_path
|
20
|
+
|
21
|
+
unless current_initiailzer.match(Regexp.new(/# === Voltron SVG Configuration ===/))
|
22
|
+
inject_into_file(voltron_initialzer_path, after: "Voltron.setup do |config|\n") do
|
23
|
+
<<-CONTENT
|
24
|
+
|
25
|
+
# === Voltron SVG Configuration ===
|
26
|
+
|
27
|
+
# The directory that contains SVG icons from which to create PNG's
|
28
|
+
# config.svg.source_directory = Rails.root.join("app", "assets", "svg")
|
29
|
+
|
30
|
+
# The directory where generated fallback images for SVG's should reside
|
31
|
+
# config.svg.image_directory = Rails.root.join("app", "assets", "images")
|
32
|
+
|
33
|
+
# The environment(s) that svg -> png generation can occur in. Defaults to "development"
|
34
|
+
# Can specify either a single environment or an array of environments. NOT recommended for production
|
35
|
+
# config.svg.build_environment << :development
|
36
|
+
|
37
|
+
# The quality (0-100) of generated PNG's, can be overridden in SASS using:
|
38
|
+
# svg-icon(icon, $quality: 100) or in the view helper:
|
39
|
+
# svg_tag(:icon, quality: 100)
|
40
|
+
# config.svg.quality = 90
|
41
|
+
CONTENT
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Voltron
|
2
|
+
class Config
|
3
|
+
|
4
|
+
def svg
|
5
|
+
@svg ||= Svg.new
|
6
|
+
end
|
7
|
+
|
8
|
+
class Svg
|
9
|
+
|
10
|
+
attr_accessor :build_environment, :source_directory, :image_directory, :quality
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@quality ||= 90
|
14
|
+
@build_environment ||= [:development]
|
15
|
+
@source_directory ||= Rails.root.join("app", "assets", "svg")
|
16
|
+
@image_directory ||= Rails.root.join("app", "assets", "images")
|
17
|
+
end
|
18
|
+
|
19
|
+
def buildable?
|
20
|
+
[build_environment].flatten.map(&:to_s).include?(Rails.env.to_s)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require "voltron"
|
2
|
+
|
3
|
+
module Voltron
|
4
|
+
module Svg
|
5
|
+
class Tag
|
6
|
+
|
7
|
+
include ActionView::Helpers
|
8
|
+
|
9
|
+
def initialize(file, options={})
|
10
|
+
options = options.symbolize_keys
|
11
|
+
@file = file
|
12
|
+
@options = options
|
13
|
+
setup
|
14
|
+
end
|
15
|
+
|
16
|
+
def setup
|
17
|
+
# If a size is specified, extract it's width/height
|
18
|
+
@options[:width], @options[:height] = extract_dimensions(@options.delete(:size)) if @options[:size]
|
19
|
+
|
20
|
+
# Ensure the svg extension is added if a symbol was provided for icon name
|
21
|
+
@options[:extension] ||= :svg if @file.is_a?(Symbol)
|
22
|
+
|
23
|
+
# Set the default quality
|
24
|
+
@options[:quality] ||= Voltron.config.svg.quality
|
25
|
+
|
26
|
+
# Generate the SVG (if custom color) and the corresponding fallback PNG, only if running in environment that allows conversion
|
27
|
+
create_png if Voltron.config.svg.buildable?
|
28
|
+
end
|
29
|
+
|
30
|
+
def image_path
|
31
|
+
# Get the fallback image path, either using the :fallback option if specified, or use the default generated png
|
32
|
+
asset_path (@options[:fallback] || name(:png, size.to_s.downcase, color.upcase))
|
33
|
+
end
|
34
|
+
|
35
|
+
def svg_path
|
36
|
+
asset_path name(@options[:extension], color.upcase)
|
37
|
+
end
|
38
|
+
|
39
|
+
def asset_path(filename)
|
40
|
+
if Rails.application.config.assets.digest && Rails.application.config.assets.compile
|
41
|
+
filename = Rails.application.assets.find_asset(filename).try(:digest_path) || filename
|
42
|
+
end
|
43
|
+
|
44
|
+
File.join(Rails.application.config.assets.prefix, filename)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return the html <img /> tag with the needed attributes
|
48
|
+
def html
|
49
|
+
image_tag svg_path, attributes
|
50
|
+
end
|
51
|
+
|
52
|
+
def attributes
|
53
|
+
@options[:alt] ||= @file
|
54
|
+
@options[:data] ||= {}
|
55
|
+
@options[:data].merge!({ svg: true, size: size, fallback: image_path })
|
56
|
+
@options.reject { |k,v| [:color, :fallback, :quality, :extension].include?(k) }
|
57
|
+
end
|
58
|
+
|
59
|
+
# Try to get the SVG file
|
60
|
+
def svg
|
61
|
+
begin
|
62
|
+
@svg ||= ::MiniMagick::Image.open(to_svg_path)
|
63
|
+
rescue ::MiniMagick::Error => e
|
64
|
+
rescue ::Errno::ENOENT => e
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Attempt to get width from specified options, then from the source SVG file itself, and ultimately say the width is 16
|
70
|
+
def width
|
71
|
+
(@options[:width] || svg.try(:width) || 16).to_i
|
72
|
+
end
|
73
|
+
|
74
|
+
# Attempt to get height from specified options, then from the source SVG file itself, and ultimately say the height is 16
|
75
|
+
def height
|
76
|
+
(@options[:height] || svg.try(:height) || 16).to_i
|
77
|
+
end
|
78
|
+
|
79
|
+
# Get the color specified, if any, removing anything that's not alphanumeric for use in the generated filename
|
80
|
+
def color
|
81
|
+
@options[:color].to_s.gsub(/[^\dA-Z]/i, "")
|
82
|
+
end
|
83
|
+
|
84
|
+
def size
|
85
|
+
"#{width}x#{height}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def name(extension = nil, *opts)
|
89
|
+
filename = @file.to_s
|
90
|
+
|
91
|
+
if extension.nil? && (matches = filename.match(/\.(.*)$/i))
|
92
|
+
extension = matches[1]
|
93
|
+
end
|
94
|
+
|
95
|
+
# If called like `svg_tag :my_icon`, convert to "my-icon"
|
96
|
+
# If the filename "my_icon" is actually needed, call `svg_tag "my_icon"` (don't use symbol)
|
97
|
+
filename = filename.dasherize if @file.is_a?(Symbol)
|
98
|
+
|
99
|
+
pieces = filename.split(".").insert(1, opts).flatten
|
100
|
+
|
101
|
+
# Add the extension if it doesn't end with the extension, if nil it will just get removed on the next line
|
102
|
+
pieces << extension unless pieces[-1] == extension.to_s
|
103
|
+
|
104
|
+
# Remove anything that might be empty or nil
|
105
|
+
pieces.reject!(&:blank?)
|
106
|
+
|
107
|
+
# Put all the pieces together, get a name like file.50x50.RED.png
|
108
|
+
pieces.join(".")
|
109
|
+
end
|
110
|
+
|
111
|
+
# The fallback image path for the SVG
|
112
|
+
def fallback_path
|
113
|
+
File.join Voltron.config.svg.image_directory, name(:png, size.to_s.downcase, color.upcase)
|
114
|
+
end
|
115
|
+
|
116
|
+
# The source SVG path
|
117
|
+
def from_svg_path
|
118
|
+
File.join Voltron.config.svg.source_directory, name(@options[:extension])
|
119
|
+
end
|
120
|
+
|
121
|
+
# The SVG we'll ultimately use to generate the PNG, if no color was specified this will be the same as `from_svg_path`
|
122
|
+
def to_svg_path
|
123
|
+
File.join Voltron.config.svg.source_directory, name(@options[:extension], color.upcase)
|
124
|
+
end
|
125
|
+
|
126
|
+
# If a color is specified and we haven't already created the colorized SVG, generate it
|
127
|
+
def create_svg
|
128
|
+
if !color.blank? && !File.exists?(to_svg_path)
|
129
|
+
# Get the svg contents
|
130
|
+
content = File.read(from_svg_path)
|
131
|
+
|
132
|
+
# Set the color of any path/stroke in the svg
|
133
|
+
content.gsub! /fill=\"[^\"]+\"/, "fill=\"#{@options[:color]}\""
|
134
|
+
content.gsub! /stroke=\"[^\"]+\"/, "stroke=\"#{@options[:color]}\""
|
135
|
+
|
136
|
+
# Write the new svg file
|
137
|
+
File.open(to_svg_path, "w") { |f| f.puts content }
|
138
|
+
|
139
|
+
Rails.application.assets_manifest.compile name(:svg, color.upcase)
|
140
|
+
|
141
|
+
Voltron.log "Generated SVG: #{app_path(from_svg_path)} -> #{app_path(to_svg_path)}", "SVG", :light_magenta
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# If we haven't done so already, create the PNG from the SVG source file
|
146
|
+
def create_png
|
147
|
+
return false if File.exists?(fallback_path)
|
148
|
+
|
149
|
+
begin
|
150
|
+
# Ensure the SVG we will convert to a PNG exists first
|
151
|
+
create_svg
|
152
|
+
|
153
|
+
# Then convert the SVG to a PNG
|
154
|
+
::MiniMagick::Tool::Convert.new do |convert|
|
155
|
+
convert.merge! ["-gravity", "center"]
|
156
|
+
convert.merge! ["-background", "none"]
|
157
|
+
convert.merge! ["-quality", @options[:quality]]
|
158
|
+
convert.merge! ["-density", density]
|
159
|
+
convert.merge! ["-resize", size]
|
160
|
+
convert.merge! ["-extent", size]
|
161
|
+
convert << to_svg_path
|
162
|
+
convert << fallback_path
|
163
|
+
convert
|
164
|
+
end
|
165
|
+
|
166
|
+
Rails.application.assets_manifest.compile name(:png, size.to_s.downcase, color.upcase)
|
167
|
+
|
168
|
+
Voltron.log "Generated PNG: #{app_path(to_svg_path)} -> #{app_path(fallback_path)}", "SVG", :light_magenta
|
169
|
+
true
|
170
|
+
rescue ::MiniMagick::Error => e
|
171
|
+
Voltron.log e.message, "SVG", :red
|
172
|
+
false
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
protected
|
177
|
+
|
178
|
+
# Get the density of the image so the possibly enlarged SVG -> PNG does not look blurry
|
179
|
+
# Basically just the svg's original width (or 1, if an error) multiplied by the largest side
|
180
|
+
def density
|
181
|
+
if width > height
|
182
|
+
"#{(svg.try(:width) || 1)*width}x#{(svg.try(:height) || 1)*width}"
|
183
|
+
else
|
184
|
+
"#{(svg.try(:width) || 1)*height}x#{(svg.try(:height) || 1)*height}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Only used for logging, slim down the path to `path` by getting rid of everything leading up to the rails root directory
|
189
|
+
def app_path(path)
|
190
|
+
path.sub(Rails.root.to_s, "")
|
191
|
+
end
|
192
|
+
|
193
|
+
def extract_dimensions(size)
|
194
|
+
size = size.to_s
|
195
|
+
if size =~ %r{\A\d+x\d+\z}
|
196
|
+
size.split("x")
|
197
|
+
elsif size =~ %r{\A\d+\z}
|
198
|
+
[size, size]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
data/lib/voltron/svg.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "voltron/svg/version"
|
2
|
+
require "voltron/svg/tag"
|
3
|
+
require "voltron/config/svg"
|
4
|
+
require "mini_magick"
|
5
|
+
require "sass/rails"
|
6
|
+
|
7
|
+
module Voltron
|
8
|
+
module Svg
|
9
|
+
|
10
|
+
module SassHelpers
|
11
|
+
def svg_icon(source, options={})
|
12
|
+
tag = Voltron::Svg::Tag.new(source.value, { extension: :svg }.merge(map_options(options)))
|
13
|
+
|
14
|
+
::Sass::Script::String.new "url(\"#{tag.image_path}\");\nbackground-image: url(\"#{tag.svg_path}\"), linear-gradient(transparent, transparent);\nbackground-size: #{tag.width}px #{tag.height}px"
|
15
|
+
end
|
16
|
+
|
17
|
+
def map_options(options={})
|
18
|
+
::Sass::Util.map_hash(options) do |key, value|
|
19
|
+
[key.to_sym, (value.respond_to?(:representation) ? value.representation : (value.respond_to?(:value) ? value.value : value))]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
::Sass::Script::Functions.declare :svg_icon, [:source], var_kwargs: true
|
24
|
+
end
|
25
|
+
|
26
|
+
module ViewHelpers
|
27
|
+
def svg_tag(source, options={})
|
28
|
+
tag = Voltron::Svg::Tag.new(source, options)
|
29
|
+
tag.html
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
require "voltron/svg/engine" if defined?(Rails)
|
data/voltron-svg.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'voltron/svg/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "voltron-svg"
|
8
|
+
spec.version = Voltron::Svg::VERSION
|
9
|
+
spec.authors = ["Eric Hainer"]
|
10
|
+
spec.email = ["eric@commercekitchen.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Adds SVG helpers and on-the-fly generation of fallback images to rails}
|
13
|
+
spec.homepage = "https://github.com/ehainer/voltron-svg"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "voltron", ">= 0.1.0"
|
22
|
+
spec.add_dependency "mini_magick", ">= 4.4"
|
23
|
+
spec.add_dependency "sass-rails", ">= 5.0"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
28
|
+
spec.add_development_dependency "rspec-rails", ">= 3.4"
|
29
|
+
spec.add_development_dependency "sqlite3", ">= 1.2"
|
30
|
+
spec.add_development_dependency "simplecov", "0.11.0"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: voltron-svg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Hainer
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: voltron
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.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.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mini_magick
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sass-rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec-rails
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.4'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.4'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sqlite3
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.2'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.2'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - '='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.11.0
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - '='
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 0.11.0
|
139
|
+
description:
|
140
|
+
email:
|
141
|
+
- eric@commercekitchen.com
|
142
|
+
executables: []
|
143
|
+
extensions: []
|
144
|
+
extra_rdoc_files: []
|
145
|
+
files:
|
146
|
+
- ".gitignore"
|
147
|
+
- ".rspec"
|
148
|
+
- ".travis.yml"
|
149
|
+
- CODE_OF_CONDUCT.md
|
150
|
+
- Gemfile
|
151
|
+
- LICENSE.txt
|
152
|
+
- README.md
|
153
|
+
- Rakefile
|
154
|
+
- app/assets/javascripts/voltron-svg.js
|
155
|
+
- app/assets/javascripts/voltron/svg-injector.js
|
156
|
+
- bin/console
|
157
|
+
- bin/setup
|
158
|
+
- lib/generators/voltron/svg/install_generator.rb
|
159
|
+
- lib/voltron/config/svg.rb
|
160
|
+
- lib/voltron/svg.rb
|
161
|
+
- lib/voltron/svg/engine.rb
|
162
|
+
- lib/voltron/svg/tag.rb
|
163
|
+
- lib/voltron/svg/version.rb
|
164
|
+
- voltron-svg.gemspec
|
165
|
+
homepage: https://github.com/ehainer/voltron-svg
|
166
|
+
licenses:
|
167
|
+
- MIT
|
168
|
+
metadata: {}
|
169
|
+
post_install_message:
|
170
|
+
rdoc_options: []
|
171
|
+
require_paths:
|
172
|
+
- lib
|
173
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
requirements: []
|
184
|
+
rubyforge_project:
|
185
|
+
rubygems_version: 2.4.8
|
186
|
+
signing_key:
|
187
|
+
specification_version: 4
|
188
|
+
summary: Adds SVG helpers and on-the-fly generation of fallback images to rails
|
189
|
+
test_files: []
|