inkcite 1.15.0 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -1
  3. data/inkcite.gemspec +0 -3
  4. data/lib/inkcite.rb +0 -1
  5. data/lib/inkcite/cli/base.rb +12 -8
  6. data/lib/inkcite/cli/preview.rb +0 -10
  7. data/lib/inkcite/cli/server.rb +9 -1
  8. data/lib/inkcite/email.rb +5 -10
  9. data/lib/inkcite/facade/animation.rb +4 -1
  10. data/lib/inkcite/image_minifier.rb +96 -0
  11. data/lib/inkcite/mailer.rb +2 -2
  12. data/lib/inkcite/minifier.rb +1 -1
  13. data/lib/inkcite/renderer.rb +10 -0
  14. data/lib/inkcite/renderer/base.rb +47 -2
  15. data/lib/inkcite/renderer/button.rb +15 -5
  16. data/lib/inkcite/renderer/container_base.rb +15 -1
  17. data/lib/inkcite/renderer/image.rb +1 -1
  18. data/lib/inkcite/renderer/image_base.rb +8 -0
  19. data/lib/inkcite/renderer/list.rb +104 -0
  20. data/lib/inkcite/renderer/mobile_image.rb +3 -0
  21. data/lib/inkcite/renderer/responsive.rb +2 -0
  22. data/lib/inkcite/renderer/slant.rb +207 -0
  23. data/lib/inkcite/renderer/snow.rb +15 -1
  24. data/lib/inkcite/renderer/special_effect.rb +7 -0
  25. data/lib/inkcite/renderer/sup.rb +18 -4
  26. data/lib/inkcite/renderer/table.rb +9 -1
  27. data/lib/inkcite/renderer/table_base.rb +20 -2
  28. data/lib/inkcite/renderer/td.rb +7 -2
  29. data/lib/inkcite/renderer/video_preview.rb +1 -1
  30. data/lib/inkcite/uploader.rb +40 -27
  31. data/lib/inkcite/version.rb +1 -1
  32. data/lib/inkcite/view.rb +133 -13
  33. data/lib/inkcite/view/context.rb +6 -1
  34. data/lib/inkcite/view/developer_scripts.rb +56 -0
  35. data/test/renderer/background_spec.rb +4 -4
  36. data/test/renderer/button_spec.rb +14 -8
  37. data/test/renderer/div_spec.rb +26 -3
  38. data/test/renderer/image_spec.rb +9 -4
  39. data/test/renderer/list_spec.rb +36 -0
  40. data/test/renderer/mobile_image_spec.rb +5 -0
  41. data/test/renderer/slant_spec.rb +47 -0
  42. data/test/renderer/span_spec.rb +12 -1
  43. data/test/renderer/table_spec.rb +1 -1
  44. data/test/renderer/td_spec.rb +24 -8
  45. data/test/renderer/trademark_spec.rb +6 -6
  46. metadata +11 -50
  47. data/lib/inkcite/image/base.rb +0 -38
  48. data/lib/inkcite/image/guetzli_minifier.rb +0 -62
  49. data/lib/inkcite/image/image_minifier.rb +0 -143
  50. data/lib/inkcite/image/image_optim_minifier.rb +0 -90
  51. data/lib/inkcite/image/mozjpeg_minifier.rb +0 -92
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inkcite
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.0
4
+ version: 1.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeffrey D. Hoffman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-05 00:00:00.000000000 Z
11
+ date: 2018-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -122,34 +122,6 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: image_optim
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :runtime
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: image_optim_pack
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :runtime
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
125
  - !ruby/object:Gem::Dependency
154
126
  name: listen
155
127
  requirement: !ruby/object:Gem::Requirement
@@ -206,20 +178,6 @@ dependencies:
206
178
  - - ">="
207
179
  - !ruby/object:Gem::Version
208
180
  version: '0'
209
- - !ruby/object:Gem::Dependency
210
- name: mozjpeg
211
- requirement: !ruby/object:Gem::Requirement
212
- requirements:
213
- - - ">="
214
- - !ruby/object:Gem::Version
215
- version: '0'
216
- type: :runtime
217
- prerelease: false
218
- version_requirements: !ruby/object:Gem::Requirement
219
- requirements:
220
- - - ">="
221
- - !ruby/object:Gem::Version
222
- version: '0'
223
181
  - !ruby/object:Gem::Dependency
224
182
  name: net-sftp
225
183
  requirement: !ruby/object:Gem::Requirement
@@ -389,11 +347,7 @@ files:
389
347
  - lib/inkcite/facade/element.rb
390
348
  - lib/inkcite/facade/keyframe.rb
391
349
  - lib/inkcite/facade/style.rb
392
- - lib/inkcite/image/base.rb
393
- - lib/inkcite/image/guetzli_minifier.rb
394
- - lib/inkcite/image/image_minifier.rb
395
- - lib/inkcite/image/image_optim_minifier.rb
396
- - lib/inkcite/image/mozjpeg_minifier.rb
350
+ - lib/inkcite/image_minifier.rb
397
351
  - lib/inkcite/mailer.rb
398
352
  - lib/inkcite/minifier.rb
399
353
  - lib/inkcite/parser.rb
@@ -414,6 +368,7 @@ files:
414
368
  - lib/inkcite/renderer/increment.rb
415
369
  - lib/inkcite/renderer/like.rb
416
370
  - lib/inkcite/renderer/link.rb
371
+ - lib/inkcite/renderer/list.rb
417
372
  - lib/inkcite/renderer/litmus_analytics.rb
418
373
  - lib/inkcite/renderer/lorem.rb
419
374
  - lib/inkcite/renderer/mobile_image.rb
@@ -425,6 +380,7 @@ files:
425
380
  - lib/inkcite/renderer/property.rb
426
381
  - lib/inkcite/renderer/redacted.rb
427
382
  - lib/inkcite/renderer/responsive.rb
383
+ - lib/inkcite/renderer/slant.rb
428
384
  - lib/inkcite/renderer/snow.rb
429
385
  - lib/inkcite/renderer/social.rb
430
386
  - lib/inkcite/renderer/span.rb
@@ -442,6 +398,7 @@ files:
442
398
  - lib/inkcite/version.rb
443
399
  - lib/inkcite/view.rb
444
400
  - lib/inkcite/view/context.rb
401
+ - lib/inkcite/view/developer_scripts.rb
445
402
  - lib/inkcite/view/media_query.rb
446
403
  - lib/inkcite/view/tag_stack.rb
447
404
  - test/animation_spec.rb
@@ -460,11 +417,13 @@ files:
460
417
  - test/renderer/footnote_spec.rb
461
418
  - test/renderer/image_spec.rb
462
419
  - test/renderer/link_spec.rb
420
+ - test/renderer/list_spec.rb
463
421
  - test/renderer/lorem_spec.rb
464
422
  - test/renderer/mobile_image_spec.rb
465
423
  - test/renderer/mobile_only_spec.rb
466
424
  - test/renderer/mobile_style_spec.rb
467
425
  - test/renderer/redacted_spec.rb
426
+ - test/renderer/slant_spec.rb
468
427
  - test/renderer/social_spec.rb
469
428
  - test/renderer/span_spec.rb
470
429
  - test/renderer/table_spec.rb
@@ -496,7 +455,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
496
455
  version: '0'
497
456
  requirements: []
498
457
  rubyforge_project:
499
- rubygems_version: 2.6.8
458
+ rubygems_version: 2.6.14
500
459
  signing_key:
501
460
  specification_version: 4
502
461
  summary: Simplifying email development
@@ -517,11 +476,13 @@ test_files:
517
476
  - test/renderer/footnote_spec.rb
518
477
  - test/renderer/image_spec.rb
519
478
  - test/renderer/link_spec.rb
479
+ - test/renderer/list_spec.rb
520
480
  - test/renderer/lorem_spec.rb
521
481
  - test/renderer/mobile_image_spec.rb
522
482
  - test/renderer/mobile_only_spec.rb
523
483
  - test/renderer/mobile_style_spec.rb
524
484
  - test/renderer/redacted_spec.rb
485
+ - test/renderer/slant_spec.rb
525
486
  - test/renderer/social_spec.rb
526
487
  - test/renderer/span_spec.rb
527
488
  - test/renderer/table_spec.rb
@@ -1,38 +0,0 @@
1
- module Inkcite
2
- module Image
3
- class ImageMinifier
4
-
5
- # Base class for all image minifiers in the optimization pipeline
6
- class Base
7
-
8
- attr_reader :name
9
-
10
- def initialize name
11
- @name = name
12
- end
13
-
14
- def minify! email, source_img, cache_img
15
- raise 'The extending class must implement this method'
16
- end
17
-
18
- protected
19
-
20
- # Common configuration names
21
- JPG_QUALITY = :'jpg-quality'
22
-
23
- # JPG quality bounds
24
- MIN_QUALITY = 0
25
- MAX_QUALITY = 100
26
-
27
- def get_jpg_quality config, override_key, default
28
- quality = (config[override_key] || config[JPG_QUALITY] || default).to_i
29
- quality = MIN_QUALITY if quality < MIN_QUALITY
30
- quality = MAX_QUALITY if quality > MAX_QUALITY
31
- quality
32
- end
33
-
34
- end
35
-
36
- end
37
- end
38
- end
@@ -1,62 +0,0 @@
1
- module Inkcite
2
- module Image
3
- class GuetzliMinifier < ImageMinifier::Base
4
-
5
- def initialize
6
- super('Guetzli')
7
- end
8
-
9
- def minify! email, source_img, cache_img
10
-
11
- # Grab the full path to the guetzli binary
12
- guetzli_path = `which guetzli`.delete("\n")
13
- unless guetzli_path.blank?
14
-
15
- cmd = []
16
- cmd << guetzli_path
17
-
18
- config = email.config
19
-
20
- quality = get_jpg_quality(config, GUETZLI_QUALITY, DEFAULT_QUALITY)
21
- if quality > 0 && quality < MAX_QUALITY
22
-
23
- # Per the Guetzli documentation, a value less than 84 isn't useful.
24
- quality = MIN_GUETZLI_QUALITY if quality < MIN_GUETZLI_QUALITY
25
- cmd << "--quality #{quality}"
26
-
27
- end
28
-
29
- cmd << %Q("#{source_img}")
30
- cmd << %Q("#{cache_img}")
31
-
32
- Util::exec(cmd)
33
-
34
- true
35
-
36
- else
37
-
38
- # No guetzli, so simply move the source image into the destination
39
- # position without compression.
40
- FileUtils.copy(source_img, cache_img)
41
-
42
- false
43
- end
44
-
45
-
46
- end
47
-
48
- private
49
-
50
- # Default quality is zero - which lets Guetzli decide how best to
51
- # optimize the image.
52
- DEFAULT_QUALITY = 0
53
-
54
- # The minimum quality setting per the Guetzli runtime.
55
- MIN_GUETZLI_QUALITY = 84
56
-
57
- # Configuration field names
58
- GUETZLI_QUALITY = :'guetzli-quality'
59
-
60
- end
61
- end
62
- end
@@ -1,143 +0,0 @@
1
- require_relative 'base'
2
- require_relative 'guetzli_minifier'
3
- require_relative 'image_optim_minifier'
4
- require_relative 'mozjpeg_minifier'
5
-
6
- module Inkcite
7
- module Image
8
- class ImageMinifier
9
-
10
- # Directory of optimized images
11
- IMAGE_CACHE = 'images-optim'
12
-
13
- # Common extensions
14
- GIF = 'gif'
15
- JPG = 'jpg'
16
- PNG = 'png'
17
-
18
- def self.minify email, img_name, force=false
19
-
20
- # Original, unoptimized source image
21
- source_img = File.join(email.image_dir, img_name)
22
-
23
- # Cached, optimized path for this image.
24
- cache_path = email.project_file(IMAGE_CACHE)
25
- cached_img = File.join(cache_path, File.basename(img_name))
26
-
27
- # Grab the first file that exists for this project.
28
- config_path = email.config_file
29
-
30
- unless force
31
-
32
- # Get the last-modified date of the image optimization config
33
- # file - if that file is newer than the image, re-optimization
34
- # is necessary because the settings have changed.
35
- config_last_modified = Util.last_modified(config_path)
36
-
37
- # Get the last-modified date of the actual image. If the source
38
- # image is newer than the cached version, we'll need to run it
39
- # through optimization again, too.
40
- cache_last_modified = Util.last_modified(cached_img)
41
- source_last_modified = Util.last_modified(source_img)
42
-
43
- # Nothing to do unless the image in the cache is older than the
44
- # source or the config file.
45
- return unless config_last_modified > cache_last_modified || source_last_modified > cache_last_modified
46
-
47
- end
48
-
49
- # Make sure the image cache directory exists
50
- FileUtils.mkpath(cache_path)
51
-
52
- # Copy the original image to the cache where it can be processed.
53
- FileUtils.copy(source_img, cached_img)
54
-
55
- # Get the file format (e.g. gif) of the file being optimized.
56
- source_ext = Util::file_extension(source_img)
57
-
58
- # This will hold the list of minifiers that will be applied to the
59
- # image, based on its extension.
60
- pipeline = []
61
-
62
- # True if ImageOptim is allowed to make lossy optimizations to the
63
- # images. When false, even if the quality settings allow it, ImageOptim
64
- # won't make lossy optimizations.
65
- allow_lossy = true
66
-
67
- if source_ext == JPG
68
- pipeline << MozjpegMinifier.new
69
- pipeline << GuetzliMinifier.new
70
- allow_lossy = false
71
- end
72
-
73
- # Always optimize with ImageOptim although for JPGs additional
74
- # lossy compression is force disabled.
75
- pipeline << ImageOptimMinifier.new(allow_lossy)
76
-
77
- original_size = File.size(source_img)
78
-
79
- msg = "Compressing #{img_name} #{Util.pretty_file_size(original_size)}"
80
-
81
- # Process the image
82
- pipeline.each do |p|
83
-
84
- # Minifiers don't work well when the source and destination images are the
85
- # same files - so move the image to a temporary file so the minifier can
86
- # optimize it back into place.
87
- temp_img = "#{cached_img}.tmp"
88
- FileUtils.move(cached_img, temp_img)
89
-
90
- temp_size = File.size(temp_img)
91
-
92
- # Let the processor compress the image
93
- p.minify!(email, temp_img, cached_img)
94
-
95
- compressed_size = File.size(cached_img)
96
- if compressed_size < temp_size
97
- msg << " >> #{p.name} #{Util.pretty_file_size(compressed_size)}"
98
-
99
- else
100
-
101
- # Occassionally the compressor does the wrong thing and
102
- # makes the image bigger (particularly ImageOptim after
103
- # Guetzli) so in that case, revert the image to its
104
- # smaller pre-optimization form.
105
- FileUtils.copy(temp_img, cached_img)
106
-
107
- end
108
-
109
- # Now remove the temp file.
110
- FileUtils.remove(temp_img) if File.exists?(temp_img)
111
-
112
- end
113
-
114
- # Get the final compressed size of the image so we can print the
115
- # resulting compression ratio.
116
- compressed_size = File.size(cached_img)
117
- msg << " (#{self.compressed_percent(original_size, compressed_size)}%)"
118
-
119
- Util.log msg
120
-
121
- end
122
-
123
- # Minifies all of the images in the provided email's project directory.
124
- def self.minify_all email, force=false
125
-
126
- images_path = File.join(email.image_dir, '*.*')
127
-
128
- # Iterate through all of the images in the project and optimize them
129
- # if necessary.
130
- Dir.glob(images_path).each do |img|
131
- self.minify(email, File.basename(img), force)
132
- end
133
-
134
- end
135
-
136
- def self.compressed_percent original_size, compressed_size
137
- ((1.0 - (compressed_size / original_size.to_f)) * 100).round(1)
138
- end
139
-
140
- end
141
- end
142
- end
143
-
@@ -1,90 +0,0 @@
1
- module Inkcite
2
- module Image
3
- class ImageOptimMinifier < ImageMinifier::Base
4
-
5
- def initialize allow_lossy=true
6
- super('ImageOptim')
7
- @allow_lossy = allow_lossy
8
- end
9
-
10
- def minify! email, source_img, cache_img
11
-
12
- config = email.config
13
-
14
- img_type = Util::file_extension(cache_img)
15
-
16
- # This will hold the settings that control how imageoptim
17
- # compresses the image, based on extension.
18
- optim_opt = {
19
- :verbose => false,
20
- :svgo => false
21
- }
22
-
23
- FileUtils.copy(source_img, cache_img)
24
-
25
- case img_type
26
- when ImageMinifier::GIF
27
- mix_gif_options email, config, optim_opt
28
- when ImageMinifier::JPG
29
- mix_jpg_options email, config, optim_opt
30
- when ImageMinifier::PNG
31
- mix_png_options email, config, optim_opt
32
- else
33
- # Don't know how to compress this type of image so
34
- # just leave it alone
35
- return
36
- end
37
-
38
- ImageOptim.new(optim_opt).optimize_image!(cache_img)
39
-
40
- end
41
-
42
- private
43
-
44
- # Name of the configuration field that controls ImageOptim's JPG quality
45
- IMAGEOPTIM_JPG_QUALITY = :'imageopt-jpg-quality'
46
-
47
- # Default JPG image quality
48
- DEFAULT_JPG_QUALITY = 85
49
-
50
- # Quality constraints
51
- MIN_QUALITY = 0
52
- MAX_QUALITY = 100
53
-
54
- def mix_gif_options email, config, opts
55
-
56
- end
57
-
58
- def mix_jpg_options email, config, opts
59
-
60
- max_quality = get_jpg_quality(config, IMAGEOPTIM_JPG_QUALITY, DEFAULT_JPG_QUALITY)
61
-
62
- # Anything less than 100% quality means lossy is enabled.
63
- lossy = @allow_lossy && max_quality < 100
64
- opts[:allow_lossy] = lossy
65
-
66
- # Additional configuration necessary only if lossy compression
67
- # is enabled. Otherwise, the defaults are acceptable.
68
- if lossy
69
- opts[:jpegoptim] = {
70
- :allow_lossy => lossy,
71
- :max_quality => max_quality
72
- }
73
-
74
- opts[:jpegrecompress] = {
75
- :allow_lossy => lossy,
76
- :quality => (max_quality / 100.0 * 3).round(0)
77
- }
78
- end
79
-
80
-
81
- end
82
-
83
- def mix_png_options email, config, opts
84
-
85
- end
86
-
87
-
88
- end
89
- end
90
- end