inkcite 1.12.1 → 1.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/inkcite/animation.rb +96 -74
- data/lib/inkcite/cli/base.rb +6 -0
- data/lib/inkcite/cli/preview.rb +1 -1
- data/lib/inkcite/cli/test.rb +3 -3
- data/lib/inkcite/renderer.rb +7 -3
- data/lib/inkcite/renderer/background.rb +153 -0
- data/lib/inkcite/renderer/base.rb +58 -29
- data/lib/inkcite/renderer/container_base.rb +11 -4
- data/lib/inkcite/renderer/div.rb +1 -2
- data/lib/inkcite/renderer/element.rb +6 -7
- data/lib/inkcite/renderer/responsive.rb +124 -37
- data/lib/inkcite/renderer/snow.rb +53 -248
- data/lib/inkcite/renderer/sparkle.rb +77 -0
- data/lib/inkcite/renderer/special_effect.rb +429 -0
- data/lib/inkcite/renderer/style.rb +81 -0
- data/lib/inkcite/renderer/table_base.rb +4 -12
- data/lib/inkcite/renderer/td.rb +6 -24
- data/lib/inkcite/renderer/video_preview.rb +17 -7
- data/lib/inkcite/version.rb +1 -1
- data/lib/inkcite/view.rb +53 -18
- data/lib/inkcite/view/media_query.rb +1 -1
- data/test/animation_spec.rb +14 -10
- data/test/renderer/background_spec.rb +59 -0
- data/test/renderer/div_spec.rb +11 -1
- data/test/renderer/image_spec.rb +1 -1
- data/test/renderer/mobile_image_spec.rb +3 -3
- data/test/renderer/mobile_style_spec.rb +1 -1
- data/test/renderer/span_spec.rb +1 -1
- data/test/renderer/table_spec.rb +22 -7
- data/test/renderer/td_spec.rb +29 -8
- data/test/renderer/video_preview_spec.rb +3 -3
- metadata +8 -5
- data/lib/inkcite/renderer/outlook_background.rb +0 -96
- data/test/renderer/outlook_background_spec.rb +0 -61
@@ -0,0 +1,81 @@
|
|
1
|
+
module Inkcite
|
2
|
+
module Renderer
|
3
|
+
class Style
|
4
|
+
|
5
|
+
def initialize name, ctx, styles={}
|
6
|
+
|
7
|
+
@name = name
|
8
|
+
@ctx = ctx
|
9
|
+
@styles = styles
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def [] key
|
14
|
+
@styles[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def []= key, val
|
18
|
+
@styles[key] = val
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_css allowed_prefixes=nil
|
22
|
+
"#{@name} { #{to_inline_css(allowed_prefixes)} }"
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_inline_css allowed_prefixes=nil
|
26
|
+
|
27
|
+
# Inherit the list of allowed prefixes from the context if
|
28
|
+
# none were provided. Otherwise, make sure we're working
|
29
|
+
# with an array.
|
30
|
+
if allowed_prefixes.nil?
|
31
|
+
allowed_prefixes = @ctx.prefixes
|
32
|
+
else
|
33
|
+
allowed_prefixes = [*allowed_prefixes]
|
34
|
+
end
|
35
|
+
|
36
|
+
# This will hold a copy of the key and values including
|
37
|
+
# all keys with prefixes.
|
38
|
+
_styles = {}
|
39
|
+
|
40
|
+
# A reusable array indicating no prefixing is necessary.
|
41
|
+
no_prefixes = ['']
|
42
|
+
|
43
|
+
@styles.each_pair do |key, val|
|
44
|
+
|
45
|
+
# Determine which list of prefixes are needed based on the
|
46
|
+
# original key (e.g. :transform) - or use the list of
|
47
|
+
# non-modifying prefixes.
|
48
|
+
prefixes = if Inkcite::Renderer::Style.needs_prefixing?(key)
|
49
|
+
allowed_prefixes
|
50
|
+
else
|
51
|
+
no_prefixes
|
52
|
+
end
|
53
|
+
|
54
|
+
# Iterate through each prefix and create a hybrid key. Then
|
55
|
+
# add the styles to the temporary list.
|
56
|
+
prefixes.each do |prefix|
|
57
|
+
prefixed_key = "#{prefix}#{key}".to_sym
|
58
|
+
_styles[prefixed_key] = val
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
Renderer.render_styles(_styles)
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_s
|
67
|
+
@name.blank? ? to_inline_css : to_css
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.needs_prefixing? key
|
71
|
+
PREFIXABLE_KEYS.include?(key.to_sym)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# Array of CSS attributes that must be prefixed (e.g. transform and animation)
|
77
|
+
PREFIXABLE_KEYS = [:animation, :transform]
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -16,6 +16,7 @@ module Inkcite
|
|
16
16
|
mix_background element, opt, ctx
|
17
17
|
mix_border element, opt, ctx
|
18
18
|
mix_dimensions element, opt, ctx
|
19
|
+
mix_margins element, opt, ctx
|
19
20
|
|
20
21
|
end
|
21
22
|
|
@@ -51,24 +52,15 @@ module Inkcite
|
|
51
52
|
# mobile version inherits from the desktop version.
|
52
53
|
mobile_background = mix_background_shorthand(
|
53
54
|
detect(opt[MOBILE_BACKGROUND_COLOR], opt[MOBILE_BGCOLOR], bgcolor),
|
54
|
-
detect(opt[MOBILE_BACKGROUND_IMAGE], opt[MOBILE_BACKGROUND], bgimage),
|
55
|
+
detect(opt[MOBILE_BACKGROUND_IMAGE], opt[MOBILE_BACKGROUND], opt[MOBILE_SRC], bgimage),
|
55
56
|
detect(opt[MOBILE_BACKGROUND_POSITION], bgposition),
|
56
57
|
detect(opt[MOBILE_BACKGROUND_REPEAT], bgrepeat),
|
57
58
|
detect(opt[MOBILE_BACKGROUND_SIZE], bgsize),
|
58
59
|
ctx
|
59
60
|
)
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
mobile_background << ' !important' unless desktop_background.blank?
|
64
|
-
|
65
|
-
# Add the responsive rule that applies to this element.
|
66
|
-
rule = Rule.new(element.tag, unique_klass(ctx), { :background => mobile_background })
|
67
|
-
|
68
|
-
# Add the rule to the view and the element
|
69
|
-
ctx.media_query << rule
|
70
|
-
element.add_rule rule
|
71
|
-
|
62
|
+
if !mobile_background.blank? && mobile_background != desktop_background
|
63
|
+
element.mobile_style[:background] = mobile_background
|
72
64
|
end
|
73
65
|
|
74
66
|
end
|
data/lib/inkcite/renderer/td.rb
CHANGED
@@ -27,10 +27,6 @@ module Inkcite
|
|
27
27
|
# Retrieve the opts that were used to open this TD.
|
28
28
|
open_opt = tag_stack.pop
|
29
29
|
|
30
|
-
# If the opening tag initiated an automatic outlook background
|
31
|
-
# then we need to inject the close tag here.
|
32
|
-
html << "{/outlook-bg}\n" if outlook_bg?(open_opt)
|
33
|
-
|
34
30
|
# Normal HTML produced by the Helper to close the cell.
|
35
31
|
html << '</td>'
|
36
32
|
|
@@ -76,6 +72,12 @@ module Inkcite
|
|
76
72
|
|
77
73
|
mobile = opt[:mobile]
|
78
74
|
|
75
|
+
# If the table defines mobile-padding, then apply the correct mobile
|
76
|
+
# style to this td - and its !important if there is padding on
|
77
|
+
# the td already.
|
78
|
+
mobile_padding = table_opt[MOBILE_PADDING] || opt[MOBILE_PADDING]
|
79
|
+
td.mobile_style[:padding] = px(mobile_padding) unless mobile_padding.blank? || mobile == HIDE
|
80
|
+
|
79
81
|
# Need to handle Fluid-Drop HTML injection here before the rest of the
|
80
82
|
# TD is formalized. Fluid-Drop removes the width attribute of the cell
|
81
83
|
# as it is wrapped in a 100%-width table.
|
@@ -170,21 +172,6 @@ module Inkcite
|
|
170
172
|
|
171
173
|
html << td.to_s
|
172
174
|
|
173
|
-
# For convenience and to keep code DRY, support the outlook-bg boolean
|
174
|
-
# attribute which causes an {outlook-bg} Helper to be injected automatically
|
175
|
-
# inside of the {td}.
|
176
|
-
if outlook_bg?(opt)
|
177
|
-
|
178
|
-
html << "\n"
|
179
|
-
html << Element.new('outlook-bg', {
|
180
|
-
:bgcolor => detect_bgcolor(opt),
|
181
|
-
:width => opt[:width],
|
182
|
-
:height => opt[:height],
|
183
|
-
:src => opt[:background]
|
184
|
-
}).to_helper
|
185
|
-
|
186
|
-
end
|
187
|
-
|
188
175
|
end
|
189
176
|
|
190
177
|
html
|
@@ -192,11 +179,6 @@ module Inkcite
|
|
192
179
|
|
193
180
|
private
|
194
181
|
|
195
|
-
# Returns true if the conditions are met that enable the
|
196
|
-
# automatic {outlook-bg} helper integration.
|
197
|
-
def outlook_bg? opt
|
198
|
-
opt && opt[OUTLOOK_BG] && !opt[:background].blank?
|
199
|
-
end
|
200
182
|
|
201
183
|
CLOSE_TD = '/td'
|
202
184
|
LEFT = 'left'
|
@@ -94,7 +94,19 @@ module Inkcite
|
|
94
94
|
:width => '100%', :background => first_frame, BACKGROUND_SIZE => 'cover',
|
95
95
|
Table::TR_TRANSITION => %q("all .5s cubic-bezier(0.075, 0.82, 0.165, 1)")
|
96
96
|
})
|
97
|
-
|
97
|
+
|
98
|
+
# Will hold the Animation if animation is enabled for this
|
99
|
+
# video-preview.
|
100
|
+
animation = nil
|
101
|
+
|
102
|
+
if has_animation
|
103
|
+
animation = Animation.new(animation_name, ctx)
|
104
|
+
animation.timing_function = Animation::EASE
|
105
|
+
animation.duration = duration
|
106
|
+
|
107
|
+
table[:animation] = quote(animation)
|
108
|
+
end
|
109
|
+
|
98
110
|
html << table.to_helper
|
99
111
|
|
100
112
|
# Transparent spacer for preserving aspect ratio.
|
@@ -218,26 +230,24 @@ module Inkcite
|
|
218
230
|
# end of the animation.
|
219
231
|
percent = 0.0
|
220
232
|
|
221
|
-
keyframes = Animation::Keyframes.new(animation_name, ctx)
|
222
|
-
|
223
233
|
# Iterate through each frame and add two keyframes, the first
|
224
234
|
# being the time at which the frame appears plus another frame
|
225
235
|
# after the duration it should be on screen.
|
226
236
|
frames.each do |f|
|
227
237
|
this_frame_url = "url(#{f})"
|
228
238
|
|
229
|
-
|
239
|
+
animation.add_keyframe(percent, { BACKGROUND_IMAGE => this_frame_url })
|
230
240
|
percent += percent_per_frame
|
231
|
-
|
241
|
+
animation.add_keyframe(percent, { BACKGROUND_IMAGE => this_frame_url })
|
232
242
|
percent += percent_per_transition
|
233
243
|
|
234
244
|
end
|
235
245
|
|
236
246
|
# Transition back to the first frame.
|
237
|
-
|
247
|
+
animation.add_keyframe(100, { BACKGROUND_IMAGE => "url(#{first_frame})" })
|
238
248
|
|
239
249
|
# Add the keyframes to the styles array.
|
240
|
-
styles <<
|
250
|
+
styles << animation.to_keyframe_css
|
241
251
|
|
242
252
|
end
|
243
253
|
|
data/lib/inkcite/version.rb
CHANGED
data/lib/inkcite/view.rb
CHANGED
@@ -335,6 +335,12 @@ module Inkcite
|
|
335
335
|
tag_stack(tag).opts
|
336
336
|
end
|
337
337
|
|
338
|
+
# Returns the array of browser prefixes that need to be included in
|
339
|
+
# CSS styles based on which version of the email this is.
|
340
|
+
def prefixes
|
341
|
+
[ '', '-webkit-' ]
|
342
|
+
end
|
343
|
+
|
338
344
|
def preview?
|
339
345
|
@environment == :preview
|
340
346
|
end
|
@@ -432,9 +438,7 @@ module Inkcite
|
|
432
438
|
# Add external styles
|
433
439
|
html += external_styles
|
434
440
|
|
435
|
-
html << '<style type="text/css">'
|
436
441
|
html << inline_styles
|
437
|
-
html << '</style>'
|
438
442
|
html << '</head>'
|
439
443
|
|
440
444
|
# Intentionally not setting the link colors because those should be entirely
|
@@ -710,7 +714,7 @@ module Inkcite
|
|
710
714
|
|
711
715
|
def inline_google_fonts
|
712
716
|
|
713
|
-
|
717
|
+
css = ''
|
714
718
|
|
715
719
|
# Google Web Fonts support courtesy of
|
716
720
|
# http://www.emaildesignreview.com/html-email-coding/web-fonts-in-email-1482/
|
@@ -729,7 +733,7 @@ module Inkcite
|
|
729
733
|
# If you use @font-face in HTML email, Outlook 07/10/13 will default all
|
730
734
|
# text back to Times New Roman.
|
731
735
|
# http://www.emaildesignreview.com/html-email-coding/web-fonts-in-email-1482/
|
732
|
-
|
736
|
+
css << '@media screen {'
|
733
737
|
|
734
738
|
# Iterate through the configured fonts. Check to see if we've already cached
|
735
739
|
# Google's response. If not, retrieve it and add it to the
|
@@ -744,16 +748,16 @@ module Inkcite
|
|
744
748
|
end
|
745
749
|
end
|
746
750
|
|
747
|
-
|
751
|
+
css << font_cache[url]
|
748
752
|
end
|
749
|
-
|
753
|
+
css << '}'
|
750
754
|
|
751
755
|
# If the fontcache was updated, update it in our sekret file.
|
752
756
|
File.write(font_cache_path, font_cache.to_yaml) if updated
|
753
757
|
|
754
758
|
end
|
755
759
|
|
756
|
-
|
760
|
+
css
|
757
761
|
end
|
758
762
|
|
759
763
|
|
@@ -779,7 +783,7 @@ module Inkcite
|
|
779
783
|
code
|
780
784
|
end
|
781
785
|
|
782
|
-
def
|
786
|
+
def inline_reset_styles
|
783
787
|
|
784
788
|
reset = []
|
785
789
|
|
@@ -820,26 +824,57 @@ module Inkcite
|
|
820
824
|
# Reset the font on every cell to the default family.
|
821
825
|
reset << "td { font-family: #{self[Renderer::Base::FONT_FAMILY]}; }"
|
822
826
|
|
823
|
-
#
|
827
|
+
# VML-specific CSS needed only if VML was used in the email.
|
824
828
|
if vml_used?
|
825
829
|
reset << 'v\:* { behavior: url(#default#VML); display: inline-block; }'
|
826
830
|
reset << 'o\:* { behavior: url(#default#VML); display: inline-block; }'
|
827
831
|
end
|
828
832
|
|
829
|
-
reset
|
833
|
+
reset.join(NEW_LINE)
|
834
|
+
end
|
835
|
+
|
836
|
+
def inline_styles
|
837
|
+
|
838
|
+
# Separating <style> blocks to prevent Gmail from filtering
|
839
|
+
# the entire CSS section because of its strict parsing.
|
840
|
+
# https://emails.hteumeuleu.com/troubleshooting-gmails-responsive-design-support-ad124178bf81#.khhj4u4b5
|
841
|
+
style_blocks = []
|
842
|
+
|
843
|
+
# Add a section for the bootstrap/reset styles common to every email
|
844
|
+
# that address common rendering issues in many clients.
|
845
|
+
style_blocks << inline_reset_styles
|
846
|
+
|
847
|
+
# Web font styles need to be in their own block because
|
848
|
+
# they have multiple @ signs which Gmail doesn't like.
|
849
|
+
style_blocks << inline_google_fonts
|
830
850
|
|
831
851
|
# Responsive styles.
|
832
|
-
|
852
|
+
style_blocks << @media_query.to_css unless @media_query.blank?
|
833
853
|
|
834
|
-
|
854
|
+
# Filter the URI-based styles and add the remaining styles as a
|
855
|
+
# separate block. Possibly need to consider making these style
|
856
|
+
# blocks separate in the future - e.g. special effects blocks
|
857
|
+
# should probably be separated since there is a high likelihood
|
858
|
+
# of @ within @
|
859
|
+
style_blocks << self.styles.select { |s| !s.is_a?(URI::HTTP) }.join(NEW_LINE)
|
835
860
|
|
836
|
-
#
|
837
|
-
|
861
|
+
# Filter empty style blocks
|
862
|
+
style_blocks.select! { |s| !s.blank? }
|
838
863
|
|
839
|
-
#
|
840
|
-
|
841
|
-
|
842
|
-
|
864
|
+
# Minify each of the blocks
|
865
|
+
style_blocks.each { |s| Minifier.css(s, self) }
|
866
|
+
|
867
|
+
# Join all of the style blocks into a single block if this
|
868
|
+
# is not an email - otherwise, keep them separate.
|
869
|
+
style_blocks = [ style_blocks.join(NEW_LINE) ] unless email?
|
870
|
+
|
871
|
+
html = []
|
872
|
+
|
873
|
+
# Iterate through the style blocks and append them
|
874
|
+
style_blocks.each do |s|
|
875
|
+
html << '<style>'
|
876
|
+
html << s
|
877
|
+
html << '</style>'
|
843
878
|
end
|
844
879
|
|
845
880
|
html.join(NEW_LINE)
|
data/test/animation_spec.rb
CHANGED
@@ -7,31 +7,35 @@ describe Inkcite::Animation do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it 'supports browser prefixing' do
|
10
|
-
Inkcite::
|
10
|
+
Inkcite::Renderer::Style.new(nil, @view, { :animation => 'video-frames 5s ease infinite' }).to_s.must_equal('-webkit-animation:video-frames 5s ease infinite;animation:video-frames 5s ease infinite')
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'supports browser prefixing specific items only' do
|
14
|
+
Inkcite::Renderer::Style.new(nil, @view, { :left => '25%', :animation => 'video-frames 5s ease infinite' }).to_s.must_equal('-webkit-animation:video-frames 5s ease infinite;animation:video-frames 5s ease infinite;left:25%')
|
11
15
|
end
|
12
16
|
|
13
17
|
it 'can instantiate an animation keyframe' do
|
14
|
-
Inkcite::Animation::Keyframe.new(5, { :top => '-10px', :left => '22%' }).
|
18
|
+
Inkcite::Animation::Keyframe.new(5, @view, { :top => '-10px', :left => '22%' }).to_css('').must_equal('5% { left:22%;top:-10px }')
|
15
19
|
end
|
16
20
|
|
17
21
|
it 'can add style to an animation keyframe' do
|
18
|
-
keyframe = Inkcite::Animation::Keyframe.new(25)
|
22
|
+
keyframe = Inkcite::Animation::Keyframe.new(25, @view)
|
19
23
|
keyframe[:top] = '-15%'
|
20
24
|
keyframe[:left] = '78px'
|
21
|
-
keyframe.
|
25
|
+
keyframe.to_css('').must_equal('25% { left:78px;top:-15% }')
|
22
26
|
end
|
23
27
|
|
24
28
|
it 'can prefix a style on a keyframe' do
|
25
|
-
keyframe = Inkcite::Animation::Keyframe.new(33)
|
26
|
-
keyframe.
|
27
|
-
keyframe.
|
29
|
+
keyframe = Inkcite::Animation::Keyframe.new(33, @view, { :transform => 'rotate(14deg)' })
|
30
|
+
keyframe.to_css('').must_equal('33% { transform:rotate(14deg) }')
|
31
|
+
keyframe.to_css('-webkit-').must_equal('33% { -webkit-transform:rotate(14deg) }')
|
28
32
|
end
|
29
33
|
|
30
34
|
it 'can instantiate an animation and add keyframes' do
|
31
|
-
anim = Inkcite::Animation
|
32
|
-
anim
|
35
|
+
anim = Inkcite::Animation.new('snowflake7', @view)
|
36
|
+
anim.add_keyframe 5, { :top => '-10px', :left => '22%', :transform => 'rotate(14deg)' }
|
33
37
|
anim.add_keyframe 25, { :top => '100%', :left => '18%' }
|
34
|
-
anim.
|
38
|
+
anim.to_keyframe_css.must_equal(%Q(@keyframes snowflake7 {\n5% { left:22%;top:-10px;transform:rotate(14deg) }\n25% { left:18%;top:100% }\n}\n@-webkit-keyframes snowflake7 {\n5% { -webkit-transform:rotate(14deg);left:22%;top:-10px }\n25% { left:18%;top:100% }\n}\n))
|
35
39
|
end
|
36
40
|
|
37
41
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
describe Inkcite::Renderer::Background do
|
2
|
+
|
3
|
+
before do
|
4
|
+
@view = Inkcite::Email.new('test/project/').view(:development, :email)
|
5
|
+
end
|
6
|
+
|
7
|
+
it 'warns when an image is missing' do
|
8
|
+
Inkcite::Renderer.render('{background src=missing.jpg}', @view)
|
9
|
+
@view.errors.must_include('Missing image (line 0) [src=missing.jpg]')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'warns when an outlook-specific image is missing' do
|
13
|
+
Inkcite::Renderer.render('{background outlook-src=also-missing.jpg}', @view)
|
14
|
+
@view.errors.must_include('Missing image (line 0) [src=also-missing.jpg]')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'defaults to filling the available horizontal space' do
|
18
|
+
Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'supports 100% width' do
|
22
|
+
Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png width=100%}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'supports fill width' do
|
26
|
+
Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png width=fill}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'supports an optional width in pixels' do
|
30
|
+
Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png width=120}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=120><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="width:120px" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'supports an optional height in pixels' do
|
34
|
+
Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png bgcolor=#7bceeb height=92 width=120}{/background}', @view).must_equal('<table bgcolor=#7bceeb border=0 cellpadding=0 cellspacing=0 height=92 style="background:#7bceeb url(https://i.imgur.com/YJOX1PC.png)" width=120><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="height:92px;width:120px" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill color="#7bceeb" src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'supports an optional background color' do
|
38
|
+
Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png bgcolor=#7bceeb width=120}{/background}', @view).must_equal('<table bgcolor=#7bceeb border=0 cellpadding=0 cellspacing=0 style="background:#7bceeb url(https://i.imgur.com/YJOX1PC.png)" width=120><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="width:120px" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill color="#7bceeb" src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'supports the font attribute' do
|
42
|
+
Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png font=large align=center}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div style="color:#ff0000;font-family:serif;font-size:24px;font-weight:bold;line-height:24px;text-align:center"></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'supports font-related attributes' do
|
46
|
+
Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png font-size=18 line-height=27}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div style="font-size:18px;line-height:27px"></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'supports a custom mobile background' do
|
50
|
+
Inkcite::Renderer.render('{background src=https://i.imgur.com/YJOX1PC.png mobile-src="https://i.imgur.com/YJOX1PC-mobile.png" mobile-background-position="top" mobile-background-size="cover"}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 class="m1" style="background:url(https://i.imgur.com/YJOX1PC.png)" width=100%><tr><td><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="https://i.imgur.com/YJOX1PC.png" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
51
|
+
@view.media_query.find_by_klass('m1').declaration_string.must_equal('background:url(https://i.imgur.com/YJOX1PC-mobile.png) top / cover no-repeat !important')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'supports mobile padding' do
|
55
|
+
Inkcite::Renderer.render('{background src=background.jpg mobile-padding=15}{/background}', @view).must_equal('<table border=0 cellpadding=0 cellspacing=0 style="background:url(images/background.jpg)" width=100%><tr><td class="m1"><!--[if mso]><v:rect fill="t" stroke="f" style="mso-width-percent:1000" xmlns:v="urn:schemas-microsoft-com:vml"><v:fill src="images/background.jpg" type="tile" /><v:textbox inset="0,0,0,0" style="mso-fit-shape-to-text:True"><![endif]--><div></div><!--[if mso]></v:textbox></v:rect><![endif]--></td></tr></table>')
|
56
|
+
@view.media_query.find_by_klass('m1').declaration_string.must_equal('padding:15px')
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|