bootstrap-email 1.1.7 → 1.3.1

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
  SHA256:
3
- metadata.gz: 1145fbba3e6a8db2d8fe571b8f5a4d05ff78ba0ddd4c40dea9ce317e06e5f1fe
4
- data.tar.gz: f2aa2c03962d575448af829b381f18cfde6bacee0a2caf03b66a9ae0f218824f
3
+ metadata.gz: 0af8d16392d189b851cad1448686b2fda2a322b61c0b98553090394a598d0b32
4
+ data.tar.gz: '009e81f356b5f8519113b32f44b1c82cac62692b1bf035b2449da4dea46e60a0'
5
5
  SHA512:
6
- metadata.gz: 150353d9f8a03a0b8fe0434013c5c814a97dc2eb1b03287517174c95d9df30fa22e1564d3dc8d2fc7cc9bc33734da0d845341cc4d8e07bfee1ca23db84490a9e
7
- data.tar.gz: ce8b05c478d2bda5a46518d90a2bb3c8c6c8a1fe01bf197524b95c2b3182d5ca9f9b24e08bce6022f3af68779d7b087c54605dbe3b861b32bd601a1f551f5e8d
6
+ metadata.gz: 2f2f9702d22b020da0968896dd7e3134a716c450492569fd3597676e4ad8305c340ba7abc26bd93b6d0b78b5f60de70a0d7bca2b0f310ccd15c73763e0bc3ca2
7
+ data.tar.gz: fd7db09c66be97a4082768c8b66025f714932dc356bac007033bb7f7a333d722d45caac63818cfca54344c23cf74bbd882045fc8cfeb11e2fef50217799a34a3
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.7
1
+ 1.3.1
@@ -42,6 +42,10 @@ parser = OptionParser.new do |opts|
42
42
  options[:config] = File.expand_path(v, Dir.pwd)
43
43
  end
44
44
 
45
+ opts.on('-t', '--text', 'Return the plain text version of the email.') do |v|
46
+ options[:plain_text] = true
47
+ end
48
+
45
49
  opts.on('-h', '--help', 'Prints this help') do
46
50
  puts opts
47
51
  exit
@@ -70,22 +74,23 @@ else
70
74
  end
71
75
 
72
76
  if input
77
+ method = options[:plain_text] ? :perform_text_compile : :perform_html_compile
73
78
  case options[:type]
74
79
  when :pattern
75
80
  Dir.glob(input, base: Dir.pwd).each do |path|
76
81
  next unless File.file?(path)
77
82
 
78
83
  puts "Compiling file #{path}"
79
- compiled = BootstrapEmail::Compiler.new(path, type: :file, options: { config_path: options[:config] }).perform_full_compile
84
+ compiled = BootstrapEmail::Compiler.new(path, type: :file, options: { config_path: options[:config] }).public_send(method)
80
85
  destination = options[:destination].chomp('/*')
81
86
  FileUtils.mkdir_p("#{Dir.pwd}/#{destination}")
82
87
  File.write(File.expand_path("#{destination}/#{path.split('/').last}", Dir.pwd), compiled)
83
88
  end
84
89
  when :file
85
90
  path = File.expand_path(input, Dir.pwd)
86
- puts BootstrapEmail::Compiler.new(path, type: :file, options: { config_path: options[:config], sass_log_enabled: false }).perform_full_compile
91
+ puts BootstrapEmail::Compiler.new(path, type: :file, options: { config_path: options[:config], sass_log_enabled: false }).public_send(method)
87
92
  when :string
88
- puts BootstrapEmail::Compiler.new(input, options: { config_path: options[:config], sass_log_enabled: false }).perform_full_compile
93
+ puts BootstrapEmail::Compiler.new(input, options: { config_path: options[:config], sass_log_enabled: false }).public_send(method)
89
94
  end
90
95
  else
91
96
  puts opts
@@ -2,35 +2,46 @@
2
2
 
3
3
  module BootstrapEmail
4
4
  class Compiler
5
- attr_accessor :type, :doc, :premailer
5
+ attr_accessor :type, :config, :doc, :premailer
6
6
 
7
7
  def initialize(input, type: :string, options: {})
8
- BootstrapEmail.load_options(options)
8
+ self.config = BootstrapEmail::Config.new(options)
9
9
  self.type = type
10
10
  case type
11
- when :rails
12
- @mail = input
13
- html = (@mail.html_part || @mail).body.raw_source
14
11
  when :string
15
12
  html = input
16
13
  when :file
17
14
  html = File.read(input)
18
15
  end
19
- html = add_layout!(html)
16
+ html = add_layout(html)
20
17
  sass_load_paths
21
18
  build_premailer_doc(html)
22
19
  end
23
20
 
24
- def perform_full_compile
25
- compile_html!
26
- inline_css!
27
- configure_html!
28
- finalize_document!
21
+ def perform_multipart_compile
22
+ @perform_multipart_compile ||= {
23
+ text: perform_text_compile,
24
+ html: perform_html_compile
25
+ }
29
26
  end
30
27
 
28
+ def perform_text_compile
29
+ @perform_text_compile ||= plain_text
30
+ end
31
+
32
+ def perform_html_compile
33
+ @perform_html_compile ||= begin
34
+ compile_html
35
+ inline_css
36
+ configure_html
37
+ finalize_document
38
+ end
39
+ end
40
+ alias perform_full_compile perform_html_compile
41
+
31
42
  private
32
43
 
33
- def add_layout!(html)
44
+ def add_layout(html)
34
45
  document = Nokogiri::HTML(html)
35
46
  return html unless document.at_css('head').nil?
36
47
 
@@ -41,11 +52,11 @@ module BootstrapEmail
41
52
  end
42
53
 
43
54
  def sass_load_paths
44
- SassC.load_paths << BootstrapEmail.config.sass_load_paths
55
+ SassC.load_paths << config.sass_load_paths
45
56
  end
46
57
 
47
58
  def build_premailer_doc(html)
48
- css_string = BootstrapEmail::SassCache.compile('bootstrap-email', style: :expanded)
59
+ css_string = BootstrapEmail::SassCache.compile('bootstrap-email', config, style: :expanded)
49
60
  self.premailer = Premailer.new(
50
61
  html,
51
62
  with_html_string: true,
@@ -57,7 +68,7 @@ module BootstrapEmail
57
68
  self.doc = premailer.doc
58
69
  end
59
70
 
60
- def compile_html!
71
+ def compile_html
61
72
  BootstrapEmail::Converter::Body.build(doc)
62
73
  BootstrapEmail::Converter::Block.build(doc)
63
74
 
@@ -81,28 +92,26 @@ module BootstrapEmail
81
92
  BootstrapEmail::Converter::Table.build(doc)
82
93
  end
83
94
 
84
- def inline_css!
95
+ def inline_css
85
96
  premailer.to_inline_css
86
97
  end
87
98
 
88
- def configure_html!
89
- BootstrapEmail::Converter::HeadStyle.build(doc)
99
+ def plain_text
100
+ premailer.to_plain_text
101
+ end
102
+
103
+ def configure_html
104
+ BootstrapEmail::Converter::HeadStyle.build(doc, config)
90
105
  BootstrapEmail::Converter::AddMissingMetaTags.build(doc)
91
106
  BootstrapEmail::Converter::VersionComment.build(doc)
92
107
  end
93
108
 
94
- def finalize_document!
95
- html = doc.to_html(encoding: 'US-ASCII')
96
- BootstrapEmail::Converter::SupportUrlTokens.replace(html)
97
- BootstrapEmail::Converter::EnsureDoctype.replace(html)
98
- BootstrapEmail::Converter::ForceEncoding.replace(html)
99
- BootstrapEmail::Converter::BeautifyHTML.replace(html)
100
- case type
101
- when :rails
102
- (@mail.html_part || @mail).body = html
103
- @mail
104
- when :string, :file
105
- html
109
+ def finalize_document
110
+ doc.to_html(encoding: 'US-ASCII').tap do |html|
111
+ BootstrapEmail::Converter::SupportUrlTokens.replace(html)
112
+ BootstrapEmail::Converter::EnsureDoctype.replace(html)
113
+ BootstrapEmail::Converter::ForceEncoding.replace(html)
114
+ BootstrapEmail::Converter::BeautifyHTML.replace(html)
106
115
  end
107
116
  end
108
117
  end
@@ -2,51 +2,64 @@
2
2
 
3
3
  module BootstrapEmail
4
4
  class Config
5
- attr_writer :sass_email_location, # path to main sass file
6
- :sass_head_location, # path to head sass file
7
- :sass_load_paths, # array of directories for loading sass imports
8
- :sass_cache_location, # path to tmp folder for sass cache
9
- :sass_log_enabled # turn on or off sass log when caching new sass
10
-
11
- def load_options(options)
5
+ def initialize(options = {})
6
+ @config_store = BootstrapEmail::ConfigStore.new(options)
12
7
  file = File.expand_path('bootstrap-email.config.rb', Dir.pwd)
13
8
  if options[:config_path]
14
9
  require_relative options[:config_path]
15
10
  elsif File.exist?(file)
16
11
  require_relative file
17
12
  end
18
- options.each { |name, value| instance_variable_set("@#{name}", value) }
19
13
  end
20
14
 
21
- def sass_location_for(type:)
22
- ivar = instance_variable_get("@sass_#{type.sub('bootstrap-', '')}_location")
23
- return ivar if ivar
15
+ def sass_string_for(type:)
16
+ # look for custom sass string
17
+ sub_type = type.sub('bootstrap-', '')
18
+ string = config_for_option("sass_#{sub_type}_string")
19
+ return string unless string.nil?
20
+
21
+ # look for custom sass path
22
+ path = config_for_option("sass_#{sub_type}_location")
23
+ return File.read(path) unless path.nil?
24
24
 
25
+ # look up and return others if found in default locations
25
26
  lookup_locations = ["#{type}.scss", "app/assets/stylesheets/#{type}.scss"]
26
27
  locations = lookup_locations.map { |location| File.expand_path(location, Dir.pwd) }.select { |location| File.exist?(location) }
27
- locations.first if locations.any?
28
+ File.read(locations.first) if locations.any?
28
29
  end
29
30
 
30
31
  def sass_load_paths
31
32
  paths_array = [SassCache::SASS_DIR]
32
- @sass_load_paths ||= []
33
- paths_array.concat(@sass_load_paths)
33
+ custom_load_paths = config_for_option(:sass_load_paths) || []
34
+ paths_array.concat(custom_load_paths)
34
35
  end
35
36
 
36
37
  def sass_cache_location
37
- @sass_cache_location ||= begin
38
- if defined?(::Rails) && ::Rails.root
39
- ::Rails.root.join('tmp', 'cache', 'bootstrap-email', '.sass-cache')
40
- elsif File.writable?(Dir.pwd)
41
- File.join(Dir.pwd, '.sass-cache', 'bootstrap-email')
42
- else
43
- File.join(Dir.tmpdir, '.sass-cache', 'bootstrap-email')
44
- end
38
+ option = config_for_option(:sass_cache_location)
39
+ return option unless option.nil?
40
+
41
+ if defined?(::Rails) && ::Rails.root
42
+ ::Rails.root.join('tmp', 'cache', 'bootstrap-email', '.sass-cache')
43
+ elsif File.writable?(Dir.pwd)
44
+ File.join(Dir.pwd, '.sass-cache', 'bootstrap-email')
45
+ else
46
+ File.join(Dir.tmpdir, '.sass-cache', 'bootstrap-email')
45
47
  end
46
48
  end
47
49
 
48
50
  def sass_log_enabled?
49
- defined?(@sass_log_enabled) ? @sass_log_enabled : true
51
+ option = config_for_option(:sass_log_enabled)
52
+ option.nil? ? true : option
53
+ end
54
+
55
+ private
56
+
57
+ def config_for_option(option)
58
+ if @config_store.did_set?(option)
59
+ @config_store.public_send(option)
60
+ else
61
+ BootstrapEmail.static_config.public_send(option)
62
+ end
50
63
  end
51
64
  end
52
65
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BootstrapEmail
4
+ class ConfigStore
5
+ OPTIONS = [
6
+ :sass_email_location, # path to main sass file
7
+ :sass_head_location, # path to head sass file
8
+ :sass_email_string, # main sass file passed in as a string
9
+ :sass_head_string, # head sass file passed in as a string
10
+ :sass_load_paths, # array of directories for loading sass imports
11
+ :sass_cache_location, # path to tmp folder for sass cache
12
+ :sass_log_enabled, # turn on or off sass log when caching new sass
13
+ :generate_rails_text_part # boolean for whether or not to generate the text part in rails, default: true
14
+ ].freeze
15
+
16
+ attr_accessor(*OPTIONS)
17
+
18
+ def initialize(options = [])
19
+ defaults
20
+ options.each { |name, value| instance_variable_set("@#{name}", value) if OPTIONS.include?(name) }
21
+ end
22
+
23
+ def did_set?(option)
24
+ instance_variable_defined?("@#{option}")
25
+ end
26
+
27
+ private
28
+
29
+ def defaults
30
+ self.generate_rails_text_part = true
31
+ end
32
+ end
33
+ end
@@ -10,8 +10,8 @@ module BootstrapEmail
10
10
  @cached_templates = {}
11
11
  end
12
12
 
13
- def self.build(doc)
14
- new(doc).build
13
+ def self.build(doc, *args)
14
+ new(doc).build(*args)
15
15
  end
16
16
 
17
17
  private
@@ -3,7 +3,8 @@
3
3
  module BootstrapEmail
4
4
  module Converter
5
5
  class HeadStyle < Base
6
- def build
6
+ def build(config)
7
+ @config = config
7
8
  doc.at_css('head').add_child(bootstrap_email_head)
8
9
  end
9
10
 
@@ -18,7 +19,7 @@ module BootstrapEmail
18
19
  end
19
20
 
20
21
  def purged_css_from_head
21
- default, custom = BootstrapEmail::SassCache.compile('bootstrap-head').split('/*! allow_purge_after */')
22
+ default, custom = BootstrapEmail::SassCache.compile('bootstrap-head', @config).split('/*! allow_purge_after */')
22
23
  # get each CSS declaration
23
24
  custom.scan(/\w*\.[\w\-]*[\s\S\n]+?(?=})}{1}/).each do |group|
24
25
  # get the first class for each comma separated CSS declaration
@@ -7,8 +7,9 @@ module BootstrapEmail
7
7
  preview_node = doc.at_css('preview')
8
8
  return if preview_node.nil?
9
9
 
10
- # apply spacing after the text max of 100 characters so it doesn't show body text
11
- preview_node.inner_html += '&nbsp;' * [(100 - preview_node.content.length.to_i), 0].max
10
+ # https://www.litmus.com/blog/the-little-known-preview-text-hack-you-may-want-to-use-in-every-email/
11
+ # apply spacing after the text max of 278 characters so it doesn't show body text
12
+ preview_node.inner_html += '&#847; &zwnj; &nbsp; ' * [(278 - preview_node.content.length.to_i), 0].max
12
13
  node = template('div', classes: 'preview', contents: preview_node.content)
13
14
  preview_node.remove
14
15
 
@@ -2,15 +2,9 @@
2
2
 
3
3
  ActiveSupport.on_load(:action_mailer, { yield: true }) do |action_mailer|
4
4
  action_mailer.class_eval do # To support Rails less than 6
5
- # sit in the middle and compile the html
6
5
  def bootstrap_mail(*args, &block)
7
- mail_message = mail(*args, &block)
8
- # if you override the #mail method in you ApplicationMailer you may intentionally return something other than a mail message
9
- if mail_message
10
- bootstrap = BootstrapEmail::Compiler.new(mail_message, type: :rails)
11
- bootstrap.perform_full_compile
12
- end
13
- mail_message
6
+ message = mail(*args, &block)
7
+ BootstrapEmail::Rails::MailBuilder.perform(message)
14
8
  end
15
9
  alias_method :bootstrap_email, :bootstrap_mail
16
10
  alias_method :make_bootstrap_mail, :bootstrap_mail
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BootstrapEmail
4
+ module Rails
5
+ class MailBuilder
6
+ attr_reader :message, :bootstrap_email
7
+
8
+ def self.perform(mail)
9
+ new(mail).perform if mail
10
+ end
11
+
12
+ def initialize(mail)
13
+ @message = mail
14
+ @bootstrap_email = BootstrapEmail::Compiler.new(html_part.decoded, type: :string)
15
+ end
16
+
17
+ def perform
18
+ replace_html_part(generate_html_part_replacement)
19
+ message
20
+ end
21
+
22
+ private
23
+
24
+ # Much of this files derives from: https://github.com/fphilipe/premailer-rails/blob/2870060f9740de1c3f7a1da0acfc7b88e3181077/lib/premailer/rails/hook.rb
25
+
26
+ def message_contains_html?
27
+ html_part.present?
28
+ end
29
+
30
+ # Returns true if the message itself has a content type of text/html, thus
31
+ # it does not contain other parts such as alternatives and attachments.
32
+ def pure_html_message?
33
+ message.content_type&.include?('text/html')
34
+ end
35
+
36
+ def generate_html_part_replacement
37
+ if generate_text_part?
38
+ generate_alternative_part
39
+ else
40
+ html = bootstrap_email.perform_html_compile
41
+ build_html_part(html)
42
+ end
43
+ end
44
+
45
+ def generate_text_part?
46
+ BootstrapEmail.static_config.generate_rails_text_part && !message.text_part
47
+ end
48
+
49
+ def generate_alternative_part
50
+ compiled = bootstrap_email.perform_multipart_compile
51
+
52
+ part = Mail::Part.new(content_type: 'multipart/alternative')
53
+ part.add_part(build_text_part(compiled[:text]))
54
+ part.add_part(build_html_part(compiled[:html]))
55
+
56
+ part
57
+ end
58
+
59
+ def build_html_part(html)
60
+ Mail::Part.new do
61
+ content_type 'text/html; charset=UTF-8'
62
+ body html
63
+ end
64
+ end
65
+
66
+ def build_text_part(text)
67
+ Mail::Part.new do
68
+ content_type "text/plain; charset=#{text.encoding}"
69
+ body text
70
+ end
71
+ end
72
+
73
+ def html_part
74
+ if pure_html_message?
75
+ message
76
+ else
77
+ message.html_part
78
+ end
79
+ end
80
+
81
+ def replace_html_part(new_part)
82
+ if pure_html_message?
83
+ replace_in_pure_html_message(new_part)
84
+ else
85
+ replace_part_in_list(message.parts, html_part, new_part)
86
+ end
87
+ end
88
+
89
+ # If the new part is a pure text/html part, the body and its content type
90
+ # are used for the message. If the new part is
91
+ def replace_in_pure_html_message(new_part)
92
+ if new_part.content_type.include?('text/html')
93
+ message.body = new_part.decoded
94
+ message.content_type = new_part.content_type
95
+ else
96
+ message.body = nil
97
+ message.content_type = new_part.content_type
98
+ new_part.parts.each do |part|
99
+ message.add_part(part)
100
+ end
101
+ end
102
+ end
103
+
104
+ def replace_part_in_list(parts_list, old_part, new_part)
105
+ if (index = parts_list.index(old_part))
106
+ parts_list[index] = new_part
107
+ else
108
+ parts_list.any? do |part|
109
+ replace_part_in_list(part.parts, old_part, new_part) if part.respond_to?(:parts)
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -4,22 +4,20 @@ module BootstrapEmail
4
4
  class SassCache
5
5
  SASS_DIR = File.expand_path('../../core', __dir__)
6
6
 
7
- def self.compile(type, style: :compressed)
8
- new(type, style).compile
7
+ def self.compile(type, config, style: :compressed)
8
+ new(type, config, style).compile
9
9
  end
10
10
 
11
- attr_accessor :type, :style, :file_path, :config_file, :checksum
11
+ attr_accessor :type, :config, :style, :file_path, :sass_config, :checksum, :cache_dir
12
12
 
13
- def initialize(type, style)
13
+ def initialize(type, config, style)
14
14
  self.type = type
15
+ self.config = config
15
16
  self.style = style
16
17
  self.file_path = "#{SASS_DIR}/#{type}"
17
- self.config_file = load_config
18
+ self.sass_config = load_sass_config
18
19
  self.checksum = checksum_files
19
- end
20
-
21
- def cache_dir
22
- BootstrapEmail.config.sass_cache_location
20
+ self.cache_dir = config.sass_cache_location
23
21
  end
24
22
 
25
23
  def compile
@@ -30,18 +28,18 @@ module BootstrapEmail
30
28
 
31
29
  private
32
30
 
33
- def load_config
34
- path = BootstrapEmail.config.sass_location_for(type: type)
35
- replace_config(File.read(path)) if path
31
+ def load_sass_config
32
+ sass_string = config.sass_string_for(type: type)
33
+ replace_config(sass_string) if sass_string
36
34
  end
37
35
 
38
- def replace_config(config_file)
39
- config_file.gsub("//= @import #{type};", "@import '#{file_path}';")
36
+ def replace_config(sass_config)
37
+ sass_config.gsub("//= @import #{type};", "@import '#{file_path}';")
40
38
  end
41
39
 
42
40
  def checksum_files
43
- checksums = config_file.nil? ? [] : [Digest::SHA1.hexdigest(config_file)]
44
- BootstrapEmail.config.sass_load_paths.each do |load_path|
41
+ checksums = sass_config.nil? ? [] : [Digest::SHA1.hexdigest(sass_config)]
42
+ config.sass_load_paths.each do |load_path|
45
43
  Dir.glob(File.join(load_path, '**', '*.scss'), base: __dir__).each do |path|
46
44
  checksums << Digest::SHA1.file(File.expand_path(path, __dir__)).hexdigest
47
45
  end
@@ -55,11 +53,11 @@ module BootstrapEmail
55
53
  end
56
54
 
57
55
  def compile_and_cache_scss(cache_path)
58
- file = config_file || File.read("#{file_path}.scss")
56
+ file = sass_config || File.read("#{file_path}.scss")
59
57
  css = SassC::Engine.new(file, style: style).render
60
58
  FileUtils.mkdir_p("#{cache_dir}/#{checksum}") unless File.directory?("#{cache_dir}/#{checksum}")
61
59
  File.write(cache_path, css)
62
- puts "New css file cached for #{type}" if BootstrapEmail.config.sass_log_enabled?
60
+ puts "New css file cached for #{type}" if config.sass_log_enabled?
63
61
  end
64
62
  end
65
63
  end
@@ -2,28 +2,20 @@
2
2
 
3
3
  module BootstrapEmail
4
4
  class << self
5
- def config
6
- @config ||= BootstrapEmail::Config.new
7
- @config
8
- end
9
-
10
- def load_options(options)
11
- @config ||= BootstrapEmail::Config.new
12
- @config.load_options(options)
13
- @config
5
+ def static_config
6
+ @static_config ||= BootstrapEmail::ConfigStore.new
14
7
  end
15
8
 
16
9
  def configure
17
- @config ||= BootstrapEmail::Config.new
18
- yield @config
10
+ yield static_config
19
11
  end
20
12
 
21
13
  def reset_config!
22
- remove_instance_variable :@config if defined?(@config)
14
+ remove_instance_variable :@static_config if defined?(@static_config)
23
15
  end
24
16
 
25
17
  def clear_sass_cache!
26
- FileUtils.rm_rf(BootstrapEmail.config.sass_cache_location)
18
+ FileUtils.rm_rf(BootstrapEmail::Config.new.sass_cache_location)
27
19
  end
28
20
  end
29
21
  end
@@ -16,6 +16,7 @@ rescue LoadError; end
16
16
 
17
17
  require 'action_mailer' if defined?(Rails)
18
18
 
19
+ require_relative 'bootstrap-email/config_store'
19
20
  require_relative 'bootstrap-email/config'
20
21
  require_relative 'bootstrap-email/setup'
21
22
  require_relative 'bootstrap-email/erb'
@@ -28,4 +29,5 @@ Dir[File.join(__dir__, 'bootstrap-email/converters', '*.rb')].each { |file| requ
28
29
  if defined?(Rails)
29
30
  require_relative 'bootstrap-email/rails/action_mailer'
30
31
  require_relative 'bootstrap-email/rails/engine'
32
+ require_relative 'bootstrap-email/rails/mail_builder'
31
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootstrap-email
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stuart Yamartino
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-17 00:00:00.000000000 Z
11
+ date: 2022-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: htmlbeautifier
@@ -119,6 +119,7 @@ files:
119
119
  - lib/bootstrap-email/bootstrap_email_cli.rb
120
120
  - lib/bootstrap-email/compiler.rb
121
121
  - lib/bootstrap-email/config.rb
122
+ - lib/bootstrap-email/config_store.rb
122
123
  - lib/bootstrap-email/converters/add_missing_meta_tags.rb
123
124
  - lib/bootstrap-email/converters/alert.rb
124
125
  - lib/bootstrap-email/converters/align.rb
@@ -149,6 +150,7 @@ files:
149
150
  - lib/bootstrap-email/erb.rb
150
151
  - lib/bootstrap-email/rails/action_mailer.rb
151
152
  - lib/bootstrap-email/rails/engine.rb
153
+ - lib/bootstrap-email/rails/mail_builder.rb
152
154
  - lib/bootstrap-email/sass_cache.rb
153
155
  - lib/bootstrap-email/setup.rb
154
156
  - lib/bootstrap-email/version.rb