inkcite 1.2.0 → 1.3.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: dff1fb6ce80d821e6c797a6c691e904ed6dfb60d
4
- data.tar.gz: dcea60b5e3efe7edabc97186822e09e8cf43c8d5
3
+ metadata.gz: b0303ddbd80b228a0fd359eb646834a24e0c8e37
4
+ data.tar.gz: 720d1a683829b80e35e1b21162ab0e54120763af
5
5
  SHA512:
6
- metadata.gz: 8b19819db8870689817a7947159c7d30ff14e7a237c485dd42d43443691da47f2af0573e34df9f1873cdb14c8a20b71516ff0a23e6b9abdf06eac3747fd7a315
7
- data.tar.gz: 118adc599578c2d779d841ea78c8808a8a49334b084809e48eae9e6499e505d93218e5c5ab25026c7cf14b34ec930c39b4bc45401a928d3562eaed823f43aa80
6
+ metadata.gz: 0babd93ce009462a59b296af9c5675d4c41e2d2e96c307bbbc7bac093496bdd523bde613b823a18d450c576ca57a6bfe5e120b35afdbf099188539db39741a57
7
+ data.tar.gz: 915e2f2941af36147805a1c0b5ac3383c28b4933bd08eeb20d560eab3b735364b205c236d773f7700556098af3179fffed5f57d7214635a1225b912e81d0d9ef
@@ -39,6 +39,15 @@ smtp:
39
39
  password: ''
40
40
  from: 'Your Name <email@domain.com>'
41
41
 
42
+ # Mailgun settings for sending previews via their 3x faster API. Sign up for
43
+ # a free account and retrieve your API key and sending domain from your
44
+ # Mailgun account dashboard.
45
+ #
46
+ # mailgun:
47
+ # api-key: 'key-your-api-key'
48
+ # domain: 'mg.sending-domain.com'
49
+ # from: 'Your Name <email@domain.com>'
50
+
42
51
  # Specify the distribution lists for preview versions of your email.
43
52
  recipients:
44
53
  client:
@@ -13,7 +13,7 @@ require_relative 'renderer/in_browser'
13
13
  require_relative 'renderer/increment'
14
14
  require_relative 'renderer/like'
15
15
  require_relative 'renderer/link'
16
- require_relative 'renderer/litmus'
16
+ require_relative 'renderer/litmus_analytics'
17
17
  require_relative 'renderer/lorem'
18
18
  require_relative 'renderer/mobile_image'
19
19
  require_relative 'renderer/mobile_style'
@@ -161,7 +161,7 @@ module Inkcite
161
161
  :'in-browser' => InBrowser.new,
162
162
  :include => Partial.new,
163
163
  :like => Like.new,
164
- :litmus => Litmus.new,
164
+ :litmus => LitmusAnalytics.new,
165
165
  :lorem => Lorem.new,
166
166
  :'mobile-img' => MobileImage.new,
167
167
  :'mobile-style' => MobileStyle.new,
@@ -17,10 +17,16 @@ module Inkcite
17
17
  # when the {footnotes} tag is rendered.
18
18
  attr_reader :text
19
19
 
20
- def initialize id, symbol, text
20
+ # True if this footnote is active. By default all footnotes are
21
+ # activate but those read from footnotes.tsv are inactive until
22
+ # referenced in the source.
23
+ attr_accessor :active
24
+
25
+ def initialize id, symbol, text, active=true
21
26
  @id = id
22
27
  @symbol = symbol.to_s
23
28
  @text = text
29
+ @active = active
24
30
  end
25
31
 
26
32
  def number
@@ -33,6 +39,10 @@ module Inkcite
33
39
  @symbol == @symbol.to_i.to_s
34
40
  end
35
41
 
42
+ def symbol=symbol
43
+ @symbol = symbol.to_s
44
+ end
45
+
36
46
  def symbol?
37
47
  !numeric?
38
48
  end
@@ -59,19 +69,13 @@ module Inkcite
59
69
  # this isn't specified count the number of existing numeric footnotes
60
70
  # and increment it for this new footnote's symbol.
61
71
  symbol = opt[:symbol]
62
- if symbol.blank?
63
-
64
- # Grab the last numeric footnote that was specified and, assuming
65
- # there is one, increment the count. Otherwise, start the count
66
- # off at one.
67
- last_instance = ctx.footnotes.select(&:numeric?).last
68
- symbol = last_instance.nil? ? 1 : last_instance.symbol.to_i + 1
69
-
70
- end
71
72
 
72
73
  # Grab the text associated with this footnote.
73
74
  text = opt[:text]
74
- ctx.error("Footnote requires text attribute", { :id => id, :symbol => symbol }) if text.blank?
75
+ if text.blank?
76
+ ctx.error("Footnote requires text attribute", { :id => id, :symbol => symbol })
77
+ return
78
+ end
75
79
 
76
80
  # Create a new Footnote instance
77
81
  instance = Instance.new(id, symbol, text)
@@ -81,6 +85,24 @@ module Inkcite
81
85
 
82
86
  end
83
87
 
88
+ # Check to see if the footnote's symbol is blank (either because one
89
+ # wasn't defined in the source.html or because the one read from the
90
+ # footnotes.tsv had no symbol associated with it) and if so, generate
91
+ # one based on the number of previously declared numeric footnotes.
92
+ if instance.symbol.blank?
93
+
94
+ # Grab the last numeric footnote that was specified and, assuming
95
+ # there is one, increment the count. Otherwise, start the count
96
+ # off at one.
97
+ last_instance = ctx.footnotes.select(&:numeric?).last
98
+ instance.symbol = last_instance.nil? ? 1 : last_instance.symbol.to_i + 1
99
+
100
+ end
101
+
102
+ # Make sure the instance is marked as having been used so it will
103
+ # appear in the {footnotes} rendering.
104
+ instance.active = true
105
+
84
106
  # Allow footnotes to be defined without showing a symbol
85
107
  hidden = opt[:hidden].to_i == 1
86
108
  "#{instance.symbol}" unless hidden
@@ -94,6 +116,10 @@ module Inkcite
94
116
  # Nothing to do if footnotes are blank.
95
117
  return if ctx.footnotes.blank?
96
118
 
119
+ # Grab the active footnotes.
120
+ active_footnotes = ctx.footnotes.select(&:active)
121
+ return if active_footnotes.blank?
122
+
97
123
  # Check to see if a template has been provided. Otherwise use a default one based
98
124
  # on the format of the email.
99
125
  tmpl = opt[:tmpl] || opt[:template]
@@ -114,11 +140,11 @@ module Inkcite
114
140
 
115
141
  # First, collect all symbols in the natural order they are defined
116
142
  # in the email.
117
- footnotes = ctx.footnotes.select(&:symbol?)
143
+ footnotes = active_footnotes.select(&:symbol?)
118
144
 
119
145
  # Now add to the list all numeric footnotes ordered naturally
120
146
  # regardless of how they were ordered in the email.
121
- footnotes += ctx.footnotes.select(&:numeric?).sort { |f1, f2| f1.number <=> f2.number }
147
+ footnotes += active_footnotes.select(&:numeric?).sort { |f1, f2| f1.number <=> f2.number }
122
148
 
123
149
  html = ''
124
150
 
@@ -0,0 +1,79 @@
1
+ require 'litmus'
2
+
3
+ module Inkcite
4
+ module Renderer
5
+ class LitmusAnalytics < Base
6
+
7
+ def render tag, opt, ctx
8
+
9
+ # Litmus tracking is enabled only for production emails.
10
+ return nil unless ctx.production? && ctx.email?
11
+
12
+ # Deprecated code/id parameters. They shouldn't be passed anymore.
13
+ report_id = opt[:code] || opt[:id]
14
+ merge_tag = opt[MERGE_TAG] || ctx[MERGE_TAG]
15
+
16
+ # Initialize the Litmus API.
17
+ config = ctx.config[:litmus]
18
+ Litmus::Base.new(config[:subdomain], config[:username], config[:password], true)
19
+
20
+ # Will hold the Litmus Report object from which we'll retrieve the
21
+ # bug HTML to inject into the email.
22
+ report = nil
23
+
24
+ # If no code has been provided by the designer, check to see
25
+ # if one has been previously recorded for this version. If
26
+ # so, use it - otherwise, require one from litmus automatically.
27
+ if report_id.blank?
28
+
29
+ # Check to see if a campaign has been previously created for this
30
+ # version so the ID can be reused.
31
+ report_id = ctx.meta(:litmus_report_id)
32
+ if report_id.blank?
33
+
34
+ # Create a new report object using the title of the email specified
35
+ # in the helpers file.
36
+ report = Litmus::Report.create(ctx.title)
37
+
38
+ # Retrieve the unique ID assigned by Litmus and then stuff it
39
+ # into the meta data so we don't create a new one on future
40
+ # builds.
41
+ report_id = report['id']
42
+ ctx.set_meta :litmus_report_id, report_id
43
+
44
+ end
45
+
46
+ end
47
+
48
+ if report.nil?
49
+
50
+ report = Litmus::Report.show(report_id)
51
+ if report.nil?
52
+ ctx.error 'Invalid Litmus Analytics code or id', :code => report_id
53
+ return nil
54
+ end
55
+
56
+ end
57
+
58
+ # Grab the HTML from Litmus that needs to be injected into the source
59
+ # of the email.
60
+ bug_html = report[BUG_HTML]
61
+
62
+ # Replace the merge tag, if one was provided.
63
+ bug_html.gsub!('[UNIQUE]', merge_tag) unless merge_tag.nil?
64
+
65
+ # Inject HTML into the footer of the email where it won't be subject
66
+ # to inline'n or compression.
67
+ ctx.footer << bug_html
68
+
69
+ nil
70
+ end
71
+
72
+ private
73
+
74
+ BUG_HTML = 'bug_html'
75
+ MERGE_TAG = :'merge-tag'
76
+
77
+ end
78
+ end
79
+ end
@@ -21,34 +21,43 @@ module Inkcite
21
21
  # css isn't supported.
22
22
  element[:bgcolor] = hex(bgcolor) unless bgcolor.blank?
23
23
 
24
- # Assisted background image handling for maximum compatibility.
25
24
  bgimage = opt[:background]
26
25
  bgposition = opt[BACKGROUND_POSITION]
27
26
  bgrepeat = opt[BACKGROUND_REPEAT]
27
+ bgsize = opt[BACKGROUND_SIZE]
28
+
29
+ # Sets the background image attributes in the element's style
30
+ # attribute. These values take precedence on the desktop
31
+ # version of the email.
32
+ desktop_background = mix_background_shorthand(
33
+ bgcolor,
34
+ bgimage,
35
+ bgposition,
36
+ bgrepeat,
37
+ bgsize,
38
+ ctx
39
+ )
28
40
 
29
- # No need to set any CSS if there is no background image present on this
30
- # element. Previously, it would also set the background-color attribute
31
- # for unnecessary duplication.
32
- background_css(element.style, bgcolor, bgimage, bgposition, bgrepeat, nil, false, ctx) unless bgimage.blank?
33
-
34
- m_bgcolor = detect(opt[MOBILE_BACKGROUND_COLOR], opt[MOBILE_BGCOLOR])
35
- m_bgimage = detect(opt[MOBILE_BACKGROUND_IMAGE], opt[MOBILE_BACKGROUND])
41
+ element.style[:background] = desktop_background unless bgimage.blank?
36
42
 
37
- mobile_background = background_css(
38
- {},
39
- m_bgcolor,
40
- m_bgimage,
43
+ # Set the mobile background image attributes. These values take
44
+ # precedence on the mobile version of the email. If unset the
45
+ # mobile version inherits from the desktop version.
46
+ mobile_background = mix_background_shorthand(
47
+ detect(opt[MOBILE_BACKGROUND_COLOR], opt[MOBILE_BGCOLOR], bgcolor),
48
+ detect(opt[MOBILE_BACKGROUND_IMAGE], opt[MOBILE_BACKGROUND], bgimage),
41
49
  detect(opt[MOBILE_BACKGROUND_POSITION], bgposition),
42
50
  detect(opt[MOBILE_BACKGROUND_REPEAT], bgrepeat),
43
- detect(opt[MOBILE_BACKGROUND_SIZE]),
44
- (m_bgcolor && bgcolor) || (m_bgimage && bgimage),
51
+ detect(opt[MOBILE_BACKGROUND_SIZE], bgsize),
45
52
  ctx
46
53
  )
47
54
 
48
- unless mobile_background.blank?
55
+ unless mobile_background.blank? || mobile_background == desktop_background
56
+
57
+ mobile_background << ' !important' unless desktop_background.blank?
49
58
 
50
59
  # Add the responsive rule that applies to this element.
51
- rule = Rule.new(element.tag, unique_klass(ctx), mobile_background)
60
+ rule = Rule.new(element.tag, unique_klass(ctx), { :background => mobile_background })
52
61
 
53
62
  # Add the rule to the view and the element
54
63
  ctx.media_query << rule
@@ -87,61 +96,43 @@ module Inkcite
87
96
 
88
97
  private
89
98
 
90
- def background_css into, bgcolor, img, position, repeat, size, important, ctx
99
+ def mix_background_shorthand bgcolor, img, position, repeat, size, ctx
91
100
 
92
- unless bgcolor.blank? && img.blank?
101
+ values = []
93
102
 
94
- bgcolor = hex(bgcolor) unless bgcolor.blank?
103
+ values << hex(bgcolor) unless none?(bgcolor)
104
+
105
+ unless img.blank?
95
106
 
96
107
  # If no image has been provided or if the image provided is equal
97
108
  # to "none" then we'll set the values independently. Otherwise
98
109
  # we'll use a composite background declaration.
99
110
  if none?(img)
111
+ values << 'none'
100
112
 
101
- unless bgcolor.blank?
102
- bgcolor << ' !important' if important
103
- into[BACKGROUND_COLOR] = bgcolor
104
- end
113
+ else
105
114
 
106
- # Check specifically for a value of "none" which allows the email
107
- # designer to the background that is otherwise present on the
108
- # desktop version of the email.
109
- if img == NONE
110
- img = 'none'
111
- img << ' !important' if important
112
- into[BACKGROUND_IMAGE] = img
113
- end
115
+ values << "url(#{ctx.image_url(img)})"
114
116
 
115
- else
117
+ position = '0% 0%' if position.blank? && !size.blank?
118
+ unless position.blank?
119
+ values << position
120
+ unless size.blank?
121
+ values << '/'
122
+ values << (size == 'fill' ? '100% auto' : size)
123
+ end
124
+ end
116
125
 
117
126
  # Default to no-repeat if a position has been supplied or replace
118
127
  # 'none' as a convenience (cause none is easier to type than no-repeat).
119
128
  repeat = 'no-repeat' if (repeat.blank? && !position.blank?) || repeat == NONE
129
+ values << repeat unless repeat.blank?
120
130
 
121
- sty = []
122
- sty << bgcolor unless bgcolor.blank?
123
-
124
- ctx.assert_image_exists(img)
125
-
126
- sty << "url(#{ctx.image_url(img)})"
127
- sty << position unless position.blank?
128
- sty << repeat unless repeat.blank?
129
- sty << '!important' if important
130
-
131
- into[:background] = sty.join(' ')
132
-
133
- end
134
-
135
- # Background size needs to be set independently. Perhaps it can be
136
- # mixed into background: but I couldn't make it work.
137
- unless size.blank?
138
- into[BACKGROUND_SIZE] = size
139
- into[BACKGROUND_SIZE] << ' !important' if important
140
131
  end
141
132
 
142
133
  end
143
134
 
144
- into
135
+ values.blank?? nil : values.join(' ')
145
136
  end
146
137
 
147
138
  end
@@ -1,3 +1,3 @@
1
1
  module Inkcite
2
- VERSION = "1.2.0"
2
+ VERSION = "1.3.0"
3
3
  end
data/lib/inkcite/view.rb CHANGED
@@ -151,7 +151,32 @@ module Inkcite
151
151
  end
152
152
 
153
153
  def footnotes
154
- @footnotes ||= []
154
+
155
+ if @footnotes.nil?
156
+ @footnotes = []
157
+
158
+ # Preload the array of footnotes if they exist
159
+ footnotes_tsv_file = @email.project_file(FOOTNOTES_TSV_FILE)
160
+ if File.exists?(footnotes_tsv_file)
161
+ CSV.foreach(footnotes_tsv_file, { :col_sep => "\t" }) do |fn|
162
+
163
+ id = fn[0]
164
+ next if id.blank?
165
+
166
+ text = fn[2]
167
+ next if text.blank?
168
+
169
+ # Read the symbol and replace it with nil (so that one will be auto-generated)
170
+ symbol = fn[1]
171
+ symbol = nil if symbol.blank?
172
+
173
+ @footnotes << Renderer::Footnote::Instance.new(id, symbol, text, false)
174
+
175
+ end
176
+ end
177
+ end
178
+
179
+ @footnotes
155
180
  end
156
181
 
157
182
  def file_name ext=nil
@@ -347,10 +372,10 @@ module Inkcite
347
372
  # Render the body statement and apply the email's background color to it.
348
373
  bgcolor = Renderer.hex(self[BACKGROUND])
349
374
 
350
- # Intentially not setting the link colors because those should be entirely
375
+ # Intentionally not setting the link colors because those should be entirely
351
376
  # controlled by the styles and attributes of the links themselves. By not
352
377
  # setting it, links created sans-helper should be visually distinct.
353
- html << Renderer.render("<body bgcolor=\"#{bgcolor}\" style=\"background-color: #{bgcolor}; width: 100% !important; min-width: 100% !important; margin: 0; padding: 0; -webkit-text-size-adjust: none; -ms-text-size-adjust: none;\">", self)
378
+ html << Renderer.render("<body bgcolor=\"#{bgcolor}\" style=\"background-color: #{bgcolor}; width: 100% !important; min-width: 100% !important; margin: 0 !important; padding: 0; -webkit-text-size-adjust: none; -ms-text-size-adjust: none;\">", self)
354
379
 
355
380
  html << minified
356
381
 
@@ -522,6 +547,9 @@ module Inkcite
522
547
  # Tab-separated file containing links declarations.
523
548
  LINKS_TSV_FILE = 'links.tsv'
524
549
 
550
+ # Tab-separated file containing footnote declarations.
551
+ FOOTNOTES_TSV_FILE = 'footnotes.tsv'
552
+
525
553
  def assert_in_browser msg
526
554
  raise msg if email? && !development?
527
555
  end
@@ -716,6 +744,10 @@ module Inkcite
716
744
  # Ensure that telephone numbers are displayed using the same style as links.
717
745
  reset << "a[href^=tel] { color: #{self[Renderer::Base::LINK_COLOR]}; text-decoration:none;}"
718
746
 
747
+ # Remove extraneous left-margins on Android 4.4
748
+ # https://litmus.com/community/code/4194-why-is-email-not-centered-on-android-4-4#comment-5727
749
+ reset << 'div[style*="margin: 16px 0"] { margin:0 !important; }'
750
+
719
751
  end
720
752
 
721
753
  # Reset the font on every cell to the default family.
@@ -91,12 +91,12 @@ describe Inkcite::Renderer::Td do
91
91
 
92
92
  it 'can have a custom background color on mobile' do
93
93
  Inkcite::Renderer.render('{td mobile-bgcolor=#f09}', @view).must_equal('<td class="m1">')
94
- @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background-color:#ff0099 }')
94
+ @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background:#ff0099 }')
95
95
  end
96
96
 
97
97
  it 'can override background color on mobile' do
98
98
  Inkcite::Renderer.render('{td bgcolor=#f00 mobile-bgcolor=#00f}', @view).must_equal('<td bgcolor=#ff0000 class="m1">')
99
- @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background-color:#0000ff !important }')
99
+ @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background:#0000ff !important }')
100
100
  end
101
101
 
102
102
  it 'can have a background image' do
@@ -109,18 +109,18 @@ describe Inkcite::Renderer::Td do
109
109
  end
110
110
 
111
111
  it 'can override background image on mobile' do
112
- Inkcite::Renderer.render('{td background=floor.jpg background-position=bottom mobile-background-image=sky.jpg mobile-background-position=top}', @view).must_equal('<td class="m1" style="background:url(images/floor.jpg) bottom no-repeat">')
113
- @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background:url(images/sky.jpg) top no-repeat !important }')
112
+ Inkcite::Renderer.render('{td background=floor.jpg mobile-background-image=sky.jpg }', @view).must_equal('<td class="m1" style="background:url(images/floor.jpg)">')
113
+ @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background:url(images/sky.jpg) !important }')
114
114
  end
115
115
 
116
- it 'can disable background image on mobile' do
117
- Inkcite::Renderer.render('{td bgcolor=#f00 background=floor.jpg background-position=bottom mobile-bgcolor=#0f0 mobile-background-image=none}', @view).must_equal('<td bgcolor=#ff0000 class="m1" style="background:#ff0000 url(images/floor.jpg) bottom no-repeat">')
118
- @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background-color:#00ff00 !important;background-image:none !important }')
116
+ it 'can override background position on mobile' do
117
+ Inkcite::Renderer.render('{td background=floor.jpg background-position=bottom mobile-background-position=top}', @view).must_equal('<td class="m1" style="background:url(images/floor.jpg) bottom no-repeat">')
118
+ @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background:url(images/floor.jpg) top no-repeat !important }')
119
119
  end
120
120
 
121
- it 'inherits background position and repeat on mobile' do
122
- Inkcite::Renderer.render('{td background=floor.jpg background-position=bottom mobile-background-image=sky.jpg}', @view).must_equal('<td class="m1" style="background:url(images/floor.jpg) bottom no-repeat">')
123
- @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background:url(images/sky.jpg) bottom no-repeat !important }')
121
+ it 'can disable background image on mobile' do
122
+ Inkcite::Renderer.render('{td background=floor.jpg mobile-background-image=none}', @view).must_equal('<td class="m1" style="background:url(images/floor.jpg)">')
123
+ @view.media_query.find_by_klass('m1').to_css.must_equal('td[class~="m1"] { background:none !important }')
124
124
  end
125
125
 
126
126
  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.2.0
4
+ version: 1.3.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: 2015-09-15 00:00:00.000000000 Z
11
+ date: 2015-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -267,7 +267,7 @@ files:
267
267
  - lib/inkcite/renderer/increment.rb
268
268
  - lib/inkcite/renderer/like.rb
269
269
  - lib/inkcite/renderer/link.rb
270
- - lib/inkcite/renderer/litmus.rb
270
+ - lib/inkcite/renderer/litmus_analytics.rb
271
271
  - lib/inkcite/renderer/lorem.rb
272
272
  - lib/inkcite/renderer/mobile_image.rb
273
273
  - lib/inkcite/renderer/mobile_style.rb
@@ -1,33 +0,0 @@
1
- module Inkcite
2
- module Renderer
3
- class Litmus < Base
4
-
5
- def render tag, opt, ctx
6
-
7
- # Litmus tracking is enabled only for production emails.
8
- return nil unless ctx.production? && ctx.email?
9
-
10
- code = opt[:code] || opt[:id]
11
- return nil if code.blank?
12
-
13
- merge_tag = opt[MERGE_TAG] || ctx[MERGE_TAG]
14
-
15
- ctx.styles << "@media print{#_t { background-image: url('https://#{code}.emltrk.com/#{code}?p&d=#{merge_tag}');}}"
16
- ctx.styles << "div.OutlookMessageHeader {background-image:url('https://#{code}.emltrk.com/#{code}?f&d=#{merge_tag}')}"
17
- ctx.styles << "table.moz-email-headers-table {background-image:url('https://#{code}.emltrk.com/#{code}?f&d=#{merge_tag}')}"
18
- ctx.styles << "blockquote #_t {background-image:url('https://#{code}.emltrk.com/#{code}?f&d=#{merge_tag}')}"
19
- ctx.styles << "#MailContainerBody #_t {background-image:url('https://#{code}.emltrk.com/#{code}?f&d=#{merge_tag}')}"
20
-
21
- ctx.footer << '<div id="_t"></div>'
22
- ctx.footer << "<img src=\"https://#{code}.emltrk.com/#{code}?d=#{merge_tag}\" width=1 height=1 border=0 />"
23
-
24
- nil
25
- end
26
-
27
- private
28
-
29
- MERGE_TAG = :'merge-tag'
30
-
31
- end
32
- end
33
- end