esvg 1.1.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22b09f33bb221a8e3e0ca935a7e1ee2b958d4503
4
- data.tar.gz: d0415a87014d73b3363fc29f5879bbb06e81bf55
3
+ metadata.gz: f91ffc4405922601e5479caba9d427a28d643a03
4
+ data.tar.gz: 9bb5670d1a45fd37173b0fe311feddb04c47a17b
5
5
  SHA512:
6
- metadata.gz: bc4b112d6b50c3189dfdad7c16493b4c79fddb4dd3671b2b8422d8bc208abd431141736d70ade7a50613de0df1c96d4da6e0a4c5c757228867191027774c01e6
7
- data.tar.gz: f3a7e00e22411e3dd4ab823be0077fd0509aae1ce9df3eefae7a2014a74828bb33d30f49c5e6d3d26465bbe365218080047e214d5a21d2f7f54925d34ea62442
6
+ metadata.gz: c14ff33cbb42652bd23dd6514e682705e5d9fd0278f1b31793ae230c0d14c3d7e24c5ab1865cde2fda0ec0e874c5839d949f08e7cbd142adf9643efe995963aa
7
+ data.tar.gz: 5bd5b90cb67ea78cd5125577a129bd219830202afbbfb2ab2e0837de93f3c3464bd75ac62b0efbeff143932ba783d8713b3fd8e2c4256a08c778f462c573d1f8
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ /test/build
@@ -2,3 +2,4 @@ language: ruby
2
2
  rvm:
3
3
  - 2.1.2
4
4
  before_install: gem install bundler -v 1.10.3
5
+ script: bundle exec clash
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ### 2.0.0 (2015-07-10)
4
+ - New: Embed via JS for cacheable icon symbols
5
+ - New: Better integration with Rails
6
+ - Change: CLI flags and options have been updated.
7
+ - Change: CSS instead of Sass, for Stylesheet output.
8
+
3
9
  ### 1.1.2 (2015-06-30)
4
10
 
5
11
  - Fix: Measuring modified time works better now.
data/README.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # Esvg
2
2
 
3
- Easily embed optimized SVGs in HTML or CSS. Use as a standalone tool or with Rails.
3
+ Easily embed optimized SVGs in JS, HTML, or CSS. Use as a standalone tool or with Rails.
4
+
5
+ 1. Converts a directory full of SVGs into a single optimized SVG using symbols.
6
+ 2. Uses Javascript to inject SVGs into pages, so it's easily cacheable.
7
+ 3. Offers Rails application helpers for placing icons in your views.
4
8
 
5
9
  [![Gem Version](http://img.shields.io/gem/v/esvg.svg)](https://rubygems.org/gems/esvg)
10
+ [![Build Status](http://img.shields.io/travis/imathis/esvg.svg)](https://travis-ci.org/imathis/esvg)
6
11
  [![License](http://img.shields.io/:license-mit-blue.svg)](http://imathis.mit-license.org)
7
12
 
8
13
  ## Installation
@@ -23,23 +28,27 @@ Or install it yourself as:
23
28
 
24
29
  ## Usage: Rails
25
30
 
26
- Add SVG files to your `app/assets/svg_icons/` directory, then embed these SVGs in your application layout at the top of the `<body>`, like this:
31
+ First, add SVG files to your `app/assets/svg_icons/` directory.
32
+
33
+ ### Inject SVG symbols
34
+
35
+ Then create an `esvg.js.erb` in your `app/assets/javascripts/` and add the following:
27
36
 
28
37
  ```
29
- <body>
30
- <%= embed_svgs %>
31
- ...
32
- </body>
38
+ <%= Esvg.embed %>
33
39
  ```
34
40
 
35
- To include only a subset of SVG icons on a page you can pass an array of icon names like this.
41
+ Finally add the following to your `application.js`
36
42
 
37
43
  ```
38
- # Say we're on user/show
39
- <%= embed_svgs %w(siloutte gear menu) %>
44
+ //= require esvg
40
45
  ```
41
46
 
42
- To place an SVG icon, use the `svg_icon` helper.
47
+ This script will inject your SVG symbols at the top of your site's `<body>` as soon as the DOM is ready, and after any Turbolinks `page:change` event.
48
+
49
+ ### Place an icon
50
+
51
+ To place an SVG icon, use the `svg_icon` helper. This helper will embed an SVG `use` tag which will reference the appropriate symbol. Here's how it works.
43
52
 
44
53
  ```
45
54
  # Syntax: svg_icon name, [options]
@@ -73,42 +82,27 @@ To place an SVG icon, use the `svg_icon` helper.
73
82
  $ esvg PATH [options]
74
83
 
75
84
  # Examples:
76
- $ esvg # Read icons from current directory, write HTML to ./esvg.html
77
- $ esvg icons --output embedded # Read icons from 'icons' directory, write HTML to embedded/esvg.html
78
- $ esvg --stylesheet # Embed icons in Stylesheet and write to ./esvg.scss
79
- $ esvg --config foo.yml # Read confguration from foo.yml
85
+ $ esvg # Read icons from current directory, write js to ./esvg.js
86
+ $ esvg icons # Read icons from 'icons' directory, write js to ./esvg.js
87
+ $ esvg --output embedded # Read icons from current directory, write js to embedded/esvg.js
88
+ $ esvg -f --format # Embed icons in Stylesheet and write to ./esvg.scss
89
+ $ esvg -c --config foo.yml # Read confguration from foo.yml (otherwise, defaults to esvg.yml, or config/esvg.yml)
80
90
  ```
81
91
 
82
- ## Configuration: Rails
83
-
84
- Esvg reads configuration from `config/esvg.yml` if used with Rails.
85
-
86
- Options when used with Rails:
87
-
88
- ```
89
- path: app/assets/svg_icons # Where to find SVG icons
90
- namespace: icon # Add to the filename when creating symbol ids
91
- namespace_after: true # Add after the name, e.g. kitten-icon
92
-
93
-
94
- stylesheet_embed: false # Embed as a stylesheet
95
- font_size: 1em # Default size for SVGs (if embeded in stylesheets)
96
- ```
97
-
98
- ## Configuration: stand-alone CLI
92
+ ## Configuration
99
93
 
100
94
  If you're using esvg from the command line, configuration files are read from `./esvg.yml` or you can pass a path with the `--config` option to read the config file from elsewhere.
101
95
 
102
96
  ```
103
- path: . # Where to find SVG icons
104
- namespace: icon # Add to the filename when creating symbol ids
105
- namespace_after: true # Add after the name, e.g. kitten-icon
97
+ path: . # Where to find SVG icons (Rails defaults to app/assets/esvg)
98
+ output_path: . # Where to write output files (CLI only)
99
+ format: js # Format for output (js, html, css)
106
100
 
101
+ base_class: svg-icon # Select all icons with this base classname
102
+ namespace: icon # Namespace for symbol ids or CSS classnames
103
+ namespace_before: true # Add namespace before, e.g. icon-kitten
107
104
 
108
- stylesheet_embed: false # Embed as a stylesheet
109
105
  font_size: 1em # Default size for SVGs (if embeded in stylesheets)
110
-
111
- output_path: . # Where to write output files
112
106
  ```
113
107
 
114
108
  ## Contributing
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "bundler", "~> 1.10"
24
24
  spec.add_development_dependency "rake", "~> 10.0"
25
25
  spec.add_development_dependency "pry-byebug"
26
+ spec.add_development_dependency "clash"
26
27
  end
data/exe/esvg CHANGED
@@ -8,25 +8,19 @@ require 'esvg'
8
8
  options = {}
9
9
 
10
10
  OptionParser.new do |opts|
11
- opts.on("-s", "--stylesheet", "Embed SVGs in Sass file") do
12
- options[:stylesheet_embed] = true
11
+ opts.on("-f", "--format TYPE", String, "Options: css, js, html (defaults to js)") do |format|
12
+ options[:format] = format
13
13
  end
14
14
 
15
- opts.on("-c", "--config PATH", String, "Path to a config file (default: esvg.yml or config/esvg.yml)") do |path|
16
- options[:config_file] = path
15
+ opts.on("-o", "--output PATH", String, "Where should JS/SCSS/HTML files be written, (default: current directory)") do |path|
16
+ options[:output_path] = path
17
17
  end
18
18
 
19
- opts.on("-o", "--output PATH", String, "Where should SCSS/HTML files be written, (default: current directory)") do |path|
20
- options[:output_path] = path
19
+ opts.on("-c", "--config PATH", String, "Path to a config file (default: esvg.yml, config/esvg.yml)") do |path|
20
+ options[:config_file] = path
21
21
  end
22
22
  end.parse!
23
23
 
24
24
  options[:path] = ARGV.shift
25
25
 
26
- esvg = Esvg::SVG.new(options)
27
-
28
- if options[:stylesheet_embed]
29
- esvg.write_stylesheet
30
- else
31
- esvg.write_html
32
- end
26
+ esvg = Esvg::SVG.new(options).write
@@ -13,7 +13,7 @@ module Esvg
13
13
  extend self
14
14
 
15
15
  def icons(options={})
16
- @icons ||= SVG.new(options)
16
+ @icons = SVG.new(options)
17
17
 
18
18
  if rails? && ::Rails.env != 'production' && @icons.modified?
19
19
  @icons.read_icons
@@ -22,8 +22,8 @@ module Esvg
22
22
  @icons
23
23
  end
24
24
 
25
- def embed_svgs(names=[])
26
- icons.html(names).html_safe
25
+ def embed(options={})
26
+ icons(options).embed
27
27
  end
28
28
 
29
29
  def svg_icon(name, options={})
@@ -1,6 +1,6 @@
1
1
  module Esvg::Helpers
2
- def embed_svgs(names=[])
3
- Esvg.embed_svgs(names)
2
+ def embed_svgs(options={})
3
+ Esvg.embed(options).html_safe
4
4
  end
5
5
 
6
6
  def svg_icon(name, options={})
@@ -6,16 +6,15 @@ module Esvg
6
6
  path: Dir.pwd,
7
7
  base_class: 'svg-icon',
8
8
  namespace: 'icon',
9
- namespace_after: true,
9
+ namespace_before: true,
10
10
  font_size: '1em',
11
- stylesheet_embed: false,
12
- output_path: Dir.pwd
11
+ output_path: Dir.pwd,
12
+ names: [],
13
+ format: 'js'
13
14
  }
14
15
 
15
16
  CONFIG_RAILS = {
16
- path: "app/assets/svg_icons",
17
- css_path: "app/assets/stylesheets/_svg_icons.scss",
18
- html_path: "app/views/shared/_svg_icons.html"
17
+ path: "app/assets/esvg"
19
18
  }
20
19
 
21
20
  def initialize(options={})
@@ -23,6 +22,17 @@ module Esvg
23
22
  read_icons
24
23
  end
25
24
 
25
+ def embed
26
+ case config[:format]
27
+ when "html"
28
+ html
29
+ when "js"
30
+ js
31
+ when "css"
32
+ css
33
+ end
34
+ end
35
+
26
36
  def modified?
27
37
  mtime = File.mtime(find_files.last)
28
38
  @mtime != mtime
@@ -42,36 +52,52 @@ module Esvg
42
52
  end
43
53
  end
44
54
 
45
- def write_stylesheet
55
+ def write
56
+ case config[:format]
57
+ when "html"
58
+ write_html
59
+ when "js"
60
+ write_js
61
+ when "css"
62
+ write_css
63
+ end
64
+ end
65
+
66
+ def write_file(path, contents)
67
+ FileUtils.mkdir_p(File.expand_path(File.dirname(path)))
68
+ File.open(path, 'w') do |io|
69
+ io.write(contents)
70
+ end
71
+ end
72
+
73
+ def write_js
46
74
  unless @files.empty?
47
- FileUtils.mkdir_p(File.expand_path(File.dirname(config[:css_path])))
75
+ write_file config[:js_path], js
76
+ end
77
+ end
48
78
 
49
- File.open(config[:css_path], 'w') do |io|
50
- io.write(stylesheet)
51
- end
79
+ def write_css
80
+ unless @files.empty?
81
+ write_file config[:css_path], css
52
82
  end
53
83
  end
54
84
 
55
85
  def write_html
56
86
  unless @files.empty?
57
- FileUtils.mkdir_p(File.expand_path(File.dirname(config[:html_path])))
58
-
59
- File.open(config[:html_path], 'w') do |io|
60
- io.write(html)
61
- end
87
+ write_file config[:html_path], html
62
88
  end
63
89
  end
64
90
 
65
- def stylesheet
91
+ def css
66
92
  styles = []
67
- preamble = %Q{%svg-icon {
93
+
94
+ classes = files.keys.map{|k| ".#{icon_name(k)}"}.join(', ')
95
+ preamble = %Q{#{classes} {
68
96
  clip: auto;
69
97
  font-size: #{config[:font_size]};
70
- background: {
71
- size: auto 1em;
72
- repeat: no-repeat;
73
- position: center center;
74
- }
98
+ background-size: auto 1em;
99
+ background-repeat: no-repeat;
100
+ background-position: center center;
75
101
  display: inline-block;
76
102
  overflow: hidden;
77
103
  height: 1em;
@@ -86,13 +112,13 @@ module Esvg
86
112
  .gsub(/>/, '%3E') # escape >
87
113
  .gsub(/#/, '%23') # escape #
88
114
  .gsub(/\n/,'') # remove newlines
89
- styles << ".#{icon_name(name)} { background-image: url('data:image/svg+xml;utf-8,#{f}'); @extend %svg-icon; }"
115
+ styles << ".#{icon_name(name)} { background-image: url('data:image/svg+xml;utf-8,#{f}'); }"
90
116
  end
91
117
  styles.join("\n")
92
118
  end
93
119
 
94
- def html(names=[])
95
- names = Array(names) # In case a single string is passed
120
+ def html
121
+ names = Array(config[:names]) # In case a single string is passed
96
122
 
97
123
  if @files.empty?
98
124
  ''
@@ -112,10 +138,30 @@ module Esvg
112
138
  icons = @svgs.select { |k,v| names.include?(k) }
113
139
  end
114
140
 
115
- %Q{<svg class="icon-symbols" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none">#{icons.values.join("\n")}</svg>}
141
+ %Q{<svg id="esvg-symbols" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display:none">#{icons.values.join("\n")}</svg>}
116
142
  end
117
143
  end
118
144
 
145
+ def js
146
+ %Q{var esvg = {
147
+ embed: function(){
148
+ if (!document.querySelector('#esvg-symbols')) {
149
+ document.querySelector('body').insertAdjacentHTML('afterbegin', '#{html.gsub(/\n/,'').gsub("'"){"\\'"}}')
150
+ }
151
+ }
152
+ }
153
+
154
+ // If DOM is already ready, embed SVGs
155
+ if (document.readyState == 'interactive') { esvg.embed() }
156
+
157
+ // Handle Turbolinks (or other things that fire page change events)
158
+ document.addEventListener("page:change", function(event) { esvg.embed() })
159
+
160
+ // Handle standard DOM ready events
161
+ document.addEventListener("DOMContentLoaded", function(event) { esvg.embed() })
162
+ }
163
+ end
164
+
119
165
  def svg_icon(file, options={})
120
166
  name = icon_name(file)
121
167
  %Q{<svg class="#{config[:base_class]} #{name} #{options[:class] || ""}" #{dimensions(@files[file])}><use xlink:href="##{name}"/>#{title(options)}#{desc(options)}</svg>}.html_safe
@@ -138,15 +184,16 @@ module Esvg
138
184
  paths = [options[:config_file], 'config/esvg.yml', 'esvg.yml'].compact
139
185
 
140
186
  config = if path = paths.select{ |p| File.exist?(p)}.first
141
- CONFIG.merge(symbolize_keys(YAML.load(File.read(path) || {}))).merge(options)
187
+ CONFIG.merge(symbolize_keys(YAML.load(File.read(path) || {})))
142
188
  else
143
- CONFIG.merge(options)
189
+ CONFIG
144
190
  end
145
191
 
146
192
  config.merge!(CONFIG_RAILS) if Esvg.rails?
147
- config.merge(options)
193
+ config.merge!(options)
148
194
 
149
- config[:css_path] ||= File.join(config[:output_path], 'esvg.scss')
195
+ config[:js_path] ||= File.join(config[:output_path], 'esvg.js')
196
+ config[:css_path] ||= File.join(config[:output_path], 'esvg.css')
150
197
  config[:html_path] ||= File.join(config[:output_path], 'esvg.html')
151
198
  config.delete(:output_path)
152
199
 
@@ -172,12 +219,15 @@ module Esvg
172
219
  if @files[name].nil?
173
220
  raise "No icon named #{name} exists at #{config[:path]}"
174
221
  end
222
+ classname(name)
223
+ end
175
224
 
225
+ def classname(name)
176
226
  name = dasherize(name)
177
- if config[:namespace_after]
178
- "#{name}-#{config[:namespace]}"
179
- else
227
+ if config[:namespace_before]
180
228
  "#{config[:namespace]}-#{name}"
229
+ else
230
+ "#{name}-#{config[:namespace]}"
181
231
  end
182
232
  end
183
233
 
@@ -1,3 +1,3 @@
1
1
  module Esvg
2
- VERSION = "1.1.2"
2
+ VERSION = "2.0.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: esvg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Mathis
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-06-30 00:00:00.000000000 Z
11
+ date: 2015-07-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: svg_optimizer
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: clash
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  description:
70
84
  email:
71
85
  - brandon@imathis.com