esvg 1.1.2 → 2.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 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