inkcite 1.14.0 → 1.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/assets/init/config.yml +2 -0
  3. data/assets/social/facebook.png +0 -0
  4. data/assets/social/instagram.png +0 -0
  5. data/assets/social/pintrest.png +0 -0
  6. data/assets/social/twitter.png +0 -0
  7. data/inkcite.gemspec +2 -2
  8. data/lib/inkcite.rb +1 -0
  9. data/lib/inkcite/cli/base.rb +32 -6
  10. data/lib/inkcite/cli/preview.rb +24 -28
  11. data/lib/inkcite/cli/server.rb +22 -19
  12. data/lib/inkcite/cli/test.rb +1 -1
  13. data/lib/inkcite/email.rb +8 -4
  14. data/lib/inkcite/facade/animation.rb +4 -0
  15. data/lib/inkcite/facade/keyframe.rb +26 -3
  16. data/lib/inkcite/image/base.rb +38 -0
  17. data/lib/inkcite/image/guetzli_minifier.rb +62 -0
  18. data/lib/inkcite/image/image_minifier.rb +143 -0
  19. data/lib/inkcite/image/image_optim_minifier.rb +90 -0
  20. data/lib/inkcite/image/mozjpeg_minifier.rb +92 -0
  21. data/lib/inkcite/mailer.rb +201 -112
  22. data/lib/inkcite/minifier.rb +2 -146
  23. data/lib/inkcite/post_processor.rb +13 -0
  24. data/lib/inkcite/renderer.rb +19 -0
  25. data/lib/inkcite/renderer/background.rb +53 -14
  26. data/lib/inkcite/renderer/base.rb +29 -15
  27. data/lib/inkcite/renderer/button.rb +1 -1
  28. data/lib/inkcite/renderer/carousel.rb +245 -0
  29. data/lib/inkcite/renderer/container_base.rb +10 -0
  30. data/lib/inkcite/renderer/div.rb +1 -3
  31. data/lib/inkcite/renderer/fireworks.rb +54 -40
  32. data/lib/inkcite/renderer/footnote.rb +22 -2
  33. data/lib/inkcite/renderer/image.rb +11 -0
  34. data/lib/inkcite/renderer/image_base.rb +3 -6
  35. data/lib/inkcite/renderer/in_browser.rb +4 -0
  36. data/lib/inkcite/renderer/link.rb +39 -12
  37. data/lib/inkcite/renderer/mobile_image.rb +1 -1
  38. data/lib/inkcite/renderer/responsive.rb +9 -1
  39. data/lib/inkcite/renderer/social.rb +31 -3
  40. data/lib/inkcite/renderer/special_effect.rb +22 -13
  41. data/lib/inkcite/renderer/sup.rb +32 -0
  42. data/lib/inkcite/renderer/table_base.rb +3 -0
  43. data/lib/inkcite/renderer/topic.rb +76 -0
  44. data/lib/inkcite/renderer/trademark.rb +47 -0
  45. data/lib/inkcite/renderer/video_preview.rb +3 -2
  46. data/lib/inkcite/uploader.rb +2 -3
  47. data/lib/inkcite/util.rb +51 -0
  48. data/lib/inkcite/version.rb +1 -1
  49. data/lib/inkcite/view.rb +140 -54
  50. data/lib/inkcite/view/context.rb +1 -31
  51. data/lib/inkcite/view/media_query.rb +6 -0
  52. data/test/animation_spec.rb +7 -0
  53. data/test/parser_spec.rb +1 -1
  54. data/test/renderer/background_spec.rb +16 -12
  55. data/test/renderer/div_spec.rb +11 -0
  56. data/test/renderer/footnote_spec.rb +5 -1
  57. data/test/renderer/image_spec.rb +51 -28
  58. data/test/renderer/link_spec.rb +20 -8
  59. data/test/renderer/lorem_spec.rb +2 -2
  60. data/test/renderer/mobile_image_spec.rb +6 -0
  61. data/test/renderer/mobile_style_spec.rb +3 -3
  62. data/test/renderer/redacted_spec.rb +2 -2
  63. data/test/renderer/social_spec.rb +6 -6
  64. data/test/renderer/table_spec.rb +4 -0
  65. data/test/renderer/topic_spec.rb +28 -0
  66. data/test/renderer/trademark_spec.rb +40 -0
  67. data/test/renderer/video_preview_spec.rb +1 -1
  68. data/test/test_helper.rb +14 -0
  69. data/test/view_spec.rb +4 -0
  70. metadata +26 -12
  71. data/assets/init/image_optim.yml +0 -37
@@ -10,12 +10,12 @@ describe Inkcite::Renderer::Redacted do
10
10
 
11
11
  it 'triggers an error when included' do
12
12
  Inkcite::Renderer.render('{redacted text="This is redacted text."}', @view)
13
- @view.errors.must_include('Email contains redacted content (line 0)')
13
+ assert_error @view, 'Email contains redacted content'
14
14
  end
15
15
 
16
16
  it 'does not trigger an error when included and forced' do
17
17
  Inkcite::Renderer.render('{redacted force text="This is redacted text."}', @view)
18
- @view.errors.must_be_nil
18
+ assert_no_errors @view
19
19
  end
20
20
 
21
21
  end
@@ -11,12 +11,12 @@ describe Inkcite::Renderer::Social do
11
11
  # in non-linear order
12
12
  twitter_icon = @email.image_path('twitter.png')
13
13
  File.delete(twitter_icon) if File.exist?(twitter_icon)
14
- Inkcite::Renderer.render('{twitter noicon href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter"}', @view).must_equal('<a href="https://twitter.com/share?url=http://inkcite.readme.io&text=Inkcite%20%23MakeEmailBetter" style="color:#0099cc;text-decoration:none" target=_blank>Tweet</a>')
14
+ Inkcite::Renderer.render('{twitter noicon href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter"}', @view).must_equal('<a href="https://twitter.com/intent/tweet?text=Inkcite%20%23MakeEmailBetter&url=http://inkcite.readme.io" style="color:#0099cc;text-decoration:none" target=_blank>Tweet</a>')
15
15
  File.exist?(@view.email.image_path('twitter.png')).must_equal(false)
16
16
  end
17
17
 
18
18
  it 'supports sharing on Twitter' do
19
- Inkcite::Renderer.render('{twitter href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter"}', @view).must_equal('<a href="https://twitter.com/share?url=http://inkcite.readme.io&text=Inkcite%20%23MakeEmailBetter" style="color:#0099cc;font-size:15px;line-height:15px;text-decoration:none" target=_blank><img align=absmiddle alt="Twitter" border=0 height=15 src="images/twitter.png" style="display:inline;vertical-align:middle" width=19> Tweet</a>')
19
+ Inkcite::Renderer.render('{twitter href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter"}', @view).must_equal('<a href="https://twitter.com/intent/tweet?text=Inkcite%20%23MakeEmailBetter&url=http://inkcite.readme.io" style="color:#0099cc;font-size:15px;line-height:15px;text-decoration:none" target=_blank><img align=absmiddle alt="Twitter" border=0 height=15 id="OWATemporaryImageDivContainer1" src="images/twitter.png" style="display:inline;vertical-align:middle" width=19> Tweet</a>')
20
20
  end
21
21
 
22
22
  it 'copies the social sharing icons into the project' do
@@ -25,19 +25,19 @@ describe Inkcite::Renderer::Social do
25
25
  end
26
26
 
27
27
  it 'supports a configurable icon size' do
28
- Inkcite::Renderer.render('{twitter size=11 href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter"}', @view).must_equal('<a href="https://twitter.com/share?url=http://inkcite.readme.io&text=Inkcite%20%23MakeEmailBetter" style="color:#0099cc;font-size:11px;line-height:11px;text-decoration:none" target=_blank><img align=absmiddle alt="Twitter" border=0 height=11 src="images/twitter.png" style="display:inline;vertical-align:middle" width=14> Tweet</a>')
28
+ Inkcite::Renderer.render('{twitter size=11 href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter"}', @view).must_equal('<a href="https://twitter.com/intent/tweet?text=Inkcite%20%23MakeEmailBetter&url=http://inkcite.readme.io" style="color:#0099cc;font-size:11px;line-height:11px;text-decoration:none" target=_blank><img align=absmiddle alt="Twitter" border=0 height=11 id="OWATemporaryImageDivContainer1" src="images/twitter.png" style="display:inline;vertical-align:middle" width=14> Tweet</a>')
29
29
  end
30
30
 
31
31
  it 'supports sharing on Facebook' do
32
- Inkcite::Renderer.render('{facebook href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter"}', @view).must_equal('<a href="https://www.facebook.com/sharer/sharer.php?u=http://inkcite.readme.io&t=Inkcite%20%23MakeEmailBetter" style="color:#0099cc;font-size:15px;line-height:15px;text-decoration:none" target=_blank><img align=absmiddle alt="Facebook" border=0 height=15 src="images/facebook.png" style="display:inline;vertical-align:middle" width=15> Share</a>')
32
+ Inkcite::Renderer.render('{facebook href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter"}', @view).must_equal('<a href="https://www.facebook.com/sharer/sharer.php?u=http://inkcite.readme.io&t=Inkcite%20%23MakeEmailBetter" style="color:#0099cc;font-size:15px;line-height:15px;text-decoration:none" target=_blank><img align=absmiddle alt="Facebook" border=0 height=15 id="OWATemporaryImageDivContainer1" src="images/facebook.png" style="display:inline;vertical-align:middle" width=15> Share</a>')
33
33
  end
34
34
 
35
35
  it 'supports sharing on Pintrest' do
36
- Inkcite::Renderer.render('{pintrest href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter" media="http://c1.staticflickr.com/9/8683/16620137238_71e78abd1d_n.jpg"}', @view).must_equal('<a href="https://www.pinterest.com/pin/create/button/?url=http://inkcite.readme.io&media=http://c1.staticflickr.com/9/8683/16620137238_71e78abd1d_n.jpg&description=Inkcite%20%23MakeEmailBetter" style="color:#CB2027;font-size:15px;line-height:15px;text-decoration:none" target=_blank><img align=absmiddle alt="Pintrest" border=0 height=15 src="images/pintrest.png" style="display:inline;vertical-align:middle" width=15> Pin it</a>')
36
+ Inkcite::Renderer.render('{pintrest href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter" media="http://c1.staticflickr.com/9/8683/16620137238_71e78abd1d_n.jpg"}', @view).must_equal('<a href="https://www.pinterest.com/pin/create/button/?url=http://inkcite.readme.io&media=http://c1.staticflickr.com/9/8683/16620137238_71e78abd1d_n.jpg&description=Inkcite%20%23MakeEmailBetter" style="color:#CB2027;font-size:15px;line-height:15px;text-decoration:none" target=_blank><img align=absmiddle alt="Pintrest" border=0 height=15 id="OWATemporaryImageDivContainer1" src="images/pintrest.png" style="display:inline;vertical-align:middle" width=15> Pin it</a>')
37
37
  end
38
38
 
39
39
  it 'supports the nowrap attribute' do
40
- Inkcite::Renderer.render('{twitter href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter" nowrap}', @view).must_equal('<a href="https://twitter.com/share?url=http://inkcite.readme.io&text=Inkcite%20%23MakeEmailBetter" style="color:#0099cc;font-size:15px;line-height:15px;text-decoration:none;white-space:nowrap" target=_blank><img align=absmiddle alt="Twitter" border=0 height=15 src="images/twitter.png" style="display:inline;vertical-align:middle" width=19> Tweet</a>')
40
+ Inkcite::Renderer.render('{twitter href="http://inkcite.readme.io" text="Inkcite #MakeEmailBetter" nowrap}', @view).must_equal('<a href="https://twitter.com/intent/tweet?text=Inkcite%20%23MakeEmailBetter&url=http://inkcite.readme.io" style="color:#0099cc;font-size:15px;line-height:15px;text-decoration:none;white-space:nowrap" target=_blank><img align=absmiddle alt="Twitter" border=0 height=15 id="OWATemporaryImageDivContainer1" src="images/twitter.png" style="display:inline;vertical-align:middle" width=19> Tweet</a>')
41
41
  end
42
42
 
43
43
  Minitest.after_run do
@@ -82,4 +82,8 @@ describe Inkcite::Renderer::Table do
82
82
  Inkcite::Renderer.render('{table tr-transition="all .5s cubic-bezier(0.075, 0.82, 0.165, 1)"}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0><tr style="transition:all .5s cubic-bezier(0.075, 0.82, 0.165, 1)">')
83
83
  end
84
84
 
85
+ it 'supports background gradients' do
86
+ Inkcite::Renderer.render('{table bgcolor=#f00 bggradient=#00f}', @view).must_equal('<table bgcolor=#ff0000 border=0 cellpadding=0 cellspacing=0 style="background-image:radial-gradient(circle at center, #ff0000, #0000ff)"><tr>')
87
+ end
88
+
85
89
  end
@@ -0,0 +1,28 @@
1
+ describe Inkcite::Renderer::Topic do
2
+
3
+ before do
4
+ @view = Inkcite::Email.new('test/project/').view(:development, :email)
5
+ end
6
+
7
+ it 'requires a name' do
8
+ Inkcite::Renderer.render('{topic}{topic name="Ipsum"}', @view)
9
+ assert_error @view, 'Every topic must have a name'
10
+ end
11
+
12
+ it 'renders a list of topics' do
13
+ html = Inkcite::Renderer.render('{topic-list} and more!{topic name="Lorem"}{topic name="Ipsum"}', @view)
14
+ Inkcite::PostProcessor.run_all(html, @view).must_equal('Lorem, Ipsum and more!')
15
+ end
16
+
17
+ it 'supports topic priority' do
18
+ html = Inkcite::Renderer.render('{topic-list} and more!{topic name="Lorem"}{topic name="Ipsum" priority=1}{topic name="Dolor"}', @view)
19
+ Inkcite::PostProcessor.run_all(html, @view).must_equal('Ipsum, Lorem, Dolor and more!')
20
+ end
21
+
22
+ it 'warns if no topics are defined' do
23
+ html = Inkcite::Renderer.render('{topic-list}', @view)
24
+ Inkcite::PostProcessor.run_all(html, @view)
25
+ assert_error @view, '{topic-list} included but no topics defined'
26
+ end
27
+
28
+ end
@@ -0,0 +1,40 @@
1
+ describe Inkcite::Renderer::Trademark do
2
+
3
+ before do
4
+ @view = Inkcite::Email.new('test/project/').view(:development, :email)
5
+ end
6
+
7
+ it 'warns if an id is not provided' do
8
+ Inkcite::Renderer.render('{tm}', @view)
9
+ assert_error @view, 'Missing id on trademark/registered symbol'
10
+ end
11
+
12
+ it 'renders a ™ symbol' do
13
+ Inkcite::Renderer.render('{tm}', @view).must_equal('<sup style="font-size:10px;line-height:10px;vertical-align:top">&trade;</sup>')
14
+ end
15
+
16
+ it 'renders a ™ symbol once' do
17
+ Inkcite::Renderer.render('{tm id="pandora"}{tm id="pandora"}', @view).must_equal('<sup style="font-size:10px;line-height:10px;vertical-align:top">&trade;</sup>')
18
+ end
19
+
20
+ it 'renders a ® symbol' do
21
+ Inkcite::Renderer.render('{r}', @view).must_equal('<sup style="font-size:10px;line-height:10px;vertical-align:top">&reg;</sup>')
22
+ end
23
+
24
+ it 'renders a ® symbol once' do
25
+ Inkcite::Renderer.render('{r id="aha"}{r id="aha"}', @view).must_equal('<sup style="font-size:10px;line-height:10px;vertical-align:top">&reg;</sup>')
26
+ end
27
+
28
+ it 'renders different ® symbols at the same time' do
29
+ Inkcite::Renderer.render('{r id="aha"}{tm id="pandora"}', @view).must_equal('<sup style="font-size:10px;line-height:10px;vertical-align:top">&reg;</sup><sup style="font-size:10px;line-height:10px;vertical-align:top">&trade;</sup>')
30
+ end
31
+
32
+ it 'allows superscripting to be disabled with the no-sup attribute' do
33
+ Inkcite::Renderer.render('{r id="aha" no-sup}', @view).must_equal('&reg;')
34
+ end
35
+
36
+ it 'supports an associated footnote' do
37
+ Inkcite::Renderer.render('{r id="leatherman" footnote="Leatherman is a trademark of Leatherman Tool Group, inc."}', @view).must_equal('<sup style="font-size:10px;line-height:10px;vertical-align:top">&reg;1</sup>')
38
+ end
39
+
40
+ end
@@ -6,7 +6,7 @@ describe Inkcite::Renderer::VideoPreview do
6
6
 
7
7
  it 'renders an animated video preview' do
8
8
  Inkcite::Renderer.render('{video-preview id="ripcurl" href="https://www.campaignmonitor.com/customers/ripcurl" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame%1.jpg" width=600 height=337 frames=3 bgcolor="#5b5f66" gradient="#1d1f21"}', @view).must_equal(%Q(<!--[if !mso]><!-- -->\n<a class="video" href="https://www.campaignmonitor.com/customers/ripcurl" style="background-color:#5b5f66;background-image:radial-gradient(circle at center, #5b5f66, #1d1f21);color:#0099cc;display:block;text-decoration:none" target=_blank>\n<table border=0 cellpadding=0 cellspacing=0 style="-webkit-animation:15s ease infinite video1-frames;animation:15s ease infinite video1-frames;background:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) 0% 0% / cover no-repeat" width=100%><tr style="transition:all .5s cubic-bezier(0.075, 0.82, 0.165, 1)">\n<td width=25%><img alt="" border=0 src=images/vp-150x337.png style="display:block;height:auto;opacity:0;visibility:hidden" width=100%></td>\n<td align=center valign=middle width=50%>\n<div class="play-button" style="background-image: linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.1)); border: 4px solid white; border-radius: 50%; box-shadow: 0 1px 2px rgba(0,0,0,0.3), inset 0 1px 2px rgba(0,0,0,0.3); height: 34px; margin: 0 auto; padding: 18px 16px 18px 24px; transition: transform .5s cubic-bezier(0.075, 0.82, 0.165, 1); width: 34px;">\n<div style="border-color: transparent transparent transparent white; border-style: solid; border-width: 17px 0 17px 30px; display: block; font-size: 0; height: 0; Margin: 0 auto; width: 0;">&nbsp;</div>\n</div>\n</td>\n<td width=25%>&nbsp;</td>\n</tr></table>\n</a>\n<div style="background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg),url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg),url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg);display:none"></div>\n<!--<![endif]-->\n<!--[if mso]>\n<v:group xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="urn:schemas-microsoft-com:office:word" coordsize="600,337" coordorigin="0,0" href="https://www.campaignmonitor.com/customers/ripcurl" style="width:600px;height:337px;">\n<v:rect fill="t" stroked="f" style="position:absolute;width:600;height:337;"><v:fill src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg" type="frame"/></v:rect>\n<v:oval fill="t" strokecolor="white" strokeweight="4px" style="position:absolute;left:261;top:129;width:78;height:78"><v:fill color="black" opacity="30%"/></v:oval>\n<v:shape coordsize="24,32" path="m,l,32,24,16,xe" fillcolor="white" stroked="f" style="position:absolute;left:285;top:153;width:30;height:30;"/>\n</v:group>\n<![endif]-->))
9
- @view.styles.first.must_equal(%Q(.video:hover .play-button {\n transform: scale(1.1);\n}\n.video:hover tr {\n background-color: rgba(255, 255, 255, .2);\n}\n@keyframes video1-frames {\n0% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n@-moz-keyframes video1-frames {\n0% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n@-ms-keyframes video1-frames {\n0% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n@-o-keyframes video1-frames {\n0% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n@-webkit-keyframes video1-frames {\n0% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n))
9
+ @view.styles.first.must_equal(%Q(.video:hover .play-button {\n transform: scale(1.1);\n}\n.video:hover tr {\n background-color: rgba(255, 255, 255, .2);\n}\n@keyframes video1-frames {\n0%, 22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33%, 55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66%, 88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n@-moz-keyframes video1-frames {\n0%, 22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33%, 55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66%, 88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n@-ms-keyframes video1-frames {\n0%, 22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33%, 55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66%, 88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n@-o-keyframes video1-frames {\n0%, 22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33%, 55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66%, 88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n@-webkit-keyframes video1-frames {\n0%, 22% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n33%, 55% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame2.jpg) }\n66%, 88% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame3.jpg) }\n100% { background-image:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/103009/frame1.jpg) }\n}\n))
10
10
 
11
11
  # Verify that the transparent spacer image was created and then
12
12
  # clean it up.
@@ -5,3 +5,17 @@ silence_warnings do
5
5
  require 'minitest/autorun'
6
6
  require 'inkcite'
7
7
  end
8
+
9
+ def assert_contains string, expected_substring, *args
10
+ assert string.include?(expected_substring), *args
11
+ end
12
+
13
+ def assert_error view, *message
14
+ view.errors.any? { |e|
15
+ message.all? { |m| assert_contains(e, m) }
16
+ }.must_equal(true)
17
+ end
18
+
19
+ def assert_no_errors view
20
+ view.errors.must_be_nil
21
+ end
@@ -37,4 +37,8 @@ describe Inkcite::View do
37
37
  Inkcite::Renderer.render('{not-vml}All except VML-aware clients{/not-vml}', @view).must_equal('<!--[if !vml]><!-- -->All except VML-aware clients<!--<![endif]-->')
38
38
  end
39
39
 
40
+ it 'removes invisible line separator unicode characters' do
41
+ Inkcite::Renderer.fix_illegal_characters("\u2028".encode('utf-8'), @view).must_equal('')
42
+ end
43
+
40
44
  end
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.14.0
4
+ version: 1.15.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-03-03 00:00:00.000000000 Z
11
+ date: 2017-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: faker
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - '='
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: 1.7.2
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - '='
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: 1.7.2
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: guard
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -151,7 +151,7 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: kraken-io
154
+ name: listen
155
155
  requirement: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - ">="
@@ -165,7 +165,7 @@ dependencies:
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
167
  - !ruby/object:Gem::Dependency
168
- name: listen
168
+ name: litmus
169
169
  requirement: !ruby/object:Gem::Requirement
170
170
  requirements:
171
171
  - - ">="
@@ -179,7 +179,7 @@ dependencies:
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
181
  - !ruby/object:Gem::Dependency
182
- name: litmus
182
+ name: mail
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
185
  - - ">="
@@ -193,7 +193,7 @@ dependencies:
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
195
  - !ruby/object:Gem::Dependency
196
- name: mail
196
+ name: mailgun-ruby
197
197
  requirement: !ruby/object:Gem::Requirement
198
198
  requirements:
199
199
  - - ">="
@@ -207,7 +207,7 @@ dependencies:
207
207
  - !ruby/object:Gem::Version
208
208
  version: '0'
209
209
  - !ruby/object:Gem::Dependency
210
- name: mailgun-ruby
210
+ name: mozjpeg
211
211
  requirement: !ruby/object:Gem::Requirement
212
212
  requirements:
213
213
  - - ">="
@@ -367,9 +367,9 @@ files:
367
367
  - assets/facebook-like.js
368
368
  - assets/init/config.yml
369
369
  - assets/init/helpers.tsv
370
- - assets/init/image_optim.yml
371
370
  - assets/init/source.html
372
371
  - assets/social/facebook.png
372
+ - assets/social/instagram.png
373
373
  - assets/social/pintrest.png
374
374
  - assets/social/twitter.png
375
375
  - bin/inkcite
@@ -389,13 +389,20 @@ files:
389
389
  - lib/inkcite/facade/element.rb
390
390
  - lib/inkcite/facade/keyframe.rb
391
391
  - 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
392
397
  - lib/inkcite/mailer.rb
393
398
  - lib/inkcite/minifier.rb
394
399
  - lib/inkcite/parser.rb
400
+ - lib/inkcite/post_processor.rb
395
401
  - lib/inkcite/renderer.rb
396
402
  - lib/inkcite/renderer/background.rb
397
403
  - lib/inkcite/renderer/base.rb
398
404
  - lib/inkcite/renderer/button.rb
405
+ - lib/inkcite/renderer/carousel.rb
399
406
  - lib/inkcite/renderer/container_base.rb
400
407
  - lib/inkcite/renderer/div.rb
401
408
  - lib/inkcite/renderer/fireworks.rb
@@ -423,9 +430,12 @@ files:
423
430
  - lib/inkcite/renderer/span.rb
424
431
  - lib/inkcite/renderer/sparkle.rb
425
432
  - lib/inkcite/renderer/special_effect.rb
433
+ - lib/inkcite/renderer/sup.rb
426
434
  - lib/inkcite/renderer/table.rb
427
435
  - lib/inkcite/renderer/table_base.rb
428
436
  - lib/inkcite/renderer/td.rb
437
+ - lib/inkcite/renderer/topic.rb
438
+ - lib/inkcite/renderer/trademark.rb
429
439
  - lib/inkcite/renderer/video_preview.rb
430
440
  - lib/inkcite/uploader.rb
431
441
  - lib/inkcite/util.rb
@@ -459,6 +469,8 @@ files:
459
469
  - test/renderer/span_spec.rb
460
470
  - test/renderer/table_spec.rb
461
471
  - test/renderer/td_spec.rb
472
+ - test/renderer/topic_spec.rb
473
+ - test/renderer/trademark_spec.rb
462
474
  - test/renderer/video_preview_spec.rb
463
475
  - test/renderer_spec.rb
464
476
  - test/test_helper.rb
@@ -514,6 +526,8 @@ test_files:
514
526
  - test/renderer/span_spec.rb
515
527
  - test/renderer/table_spec.rb
516
528
  - test/renderer/td_spec.rb
529
+ - test/renderer/topic_spec.rb
530
+ - test/renderer/trademark_spec.rb
517
531
  - test/renderer/video_preview_spec.rb
518
532
  - test/renderer_spec.rb
519
533
  - test/test_helper.rb
@@ -1,37 +0,0 @@
1
- # If you have enabled image optimization in config.yml you can control the
2
- # exact inner-workings of the process through these settings. Additional
3
- # documentation available here:
4
- # https://github.com/toy/image_optim
5
-
6
- allow_lossy: true # Small images through lossy compression
7
- verbose: false # Verbose output
8
-
9
- # Worker/optimizer-specific configurations follow
10
-
11
- advpng:
12
- level: 4 # Compression level: 0 - don't compress, 1 - fast, 2 - normal, 3 - extra, 4 - extreme
13
-
14
- gifsicle:
15
- level: 3 # Compression level: 1 - light and fast, 2 - normal, 3 - heavy (slower)
16
- careful: false # Avoid bugs with some software (defaults to false)
17
-
18
- jpegoptim:
19
- max_quality: 50 # Maximum image quality factor 0..100, ignored in default/lossless mode
20
-
21
- jpegrecompress:
22
- quality: 1 # JPEG quality preset: 0 - low, 1 - medium, 2 - high, 3 - veryhigh
23
-
24
- optipng:
25
- level: 5 # Optimization level preset: 0 - least, 7 - best
26
-
27
- pngquant:
28
- quality: !ruby/range 0..50 # Quality min..max - don't save below min, use less colors below max
29
- speed: 1 # Speed/quality trade-off: 1 - slow, 3 - default, 11 - fast & rough
30
-
31
- # Note: PNGOUT is free to use even in commercial soft, but you can not
32
- # redistribute, repackage or reuse it without consent and agreement of creator.
33
- # Enable PNGOUT optimization by downloading and installing the binaries available
34
- # from http://www.jonof.id.au/kenutils
35
- pngout: false
36
-
37
- svgo: false