bootstrap-email 1.0.0.alpha1 → 1.0.0.alpha3

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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/core/bootstrap-email.scss +2 -0
  4. data/core/bootstrap-head.scss +1 -1
  5. data/core/scss/_selectors_for_utils.scss +24 -0
  6. data/core/scss/_utilities.scss +24 -4
  7. data/core/scss/components/_grid.scss +12 -9
  8. data/core/scss/components/_stack.scss +33 -0
  9. data/core/scss/utilities/_sizing.scss +21 -2
  10. data/core/scss/utilities/_typography.scss +4 -10
  11. data/core/scss/utilities/_valign.scss +5 -0
  12. data/core/templates/body.html +9 -0
  13. data/core/templates/{container.html.erb → container.html} +4 -4
  14. data/core/templates/div.html +3 -0
  15. data/core/templates/table-left.html +9 -0
  16. data/core/templates/table-to-tbody.html +5 -0
  17. data/core/templates/table-to-tr.html +7 -0
  18. data/core/templates/table.html +9 -0
  19. data/core/templates/td.html +3 -0
  20. data/core/templates/tr.html +5 -0
  21. data/lib/{bootstrap_email.rb → bootstrap-email.rb} +6 -1
  22. data/lib/bootstrap-email/bootstrap_email_cli.rb +9 -9
  23. data/lib/bootstrap-email/compiler.rb +49 -65
  24. data/lib/bootstrap-email/config.rb +50 -0
  25. data/lib/bootstrap-email/{components → converters}/alert.rb +1 -1
  26. data/lib/bootstrap-email/converters/align.rb +22 -0
  27. data/lib/bootstrap-email/{components → converters}/badge.rb +1 -1
  28. data/lib/bootstrap-email/converters/base.rb +62 -0
  29. data/lib/bootstrap-email/converters/block.rb +13 -0
  30. data/lib/bootstrap-email/converters/body.rb +10 -0
  31. data/lib/bootstrap-email/{components → converters}/button.rb +1 -1
  32. data/lib/bootstrap-email/{components → converters}/card.rb +3 -3
  33. data/lib/bootstrap-email/{components → converters}/color.rb +1 -1
  34. data/lib/bootstrap-email/{components → converters}/container.rb +1 -1
  35. data/lib/bootstrap-email/converters/force_encoding.rb +16 -0
  36. data/lib/bootstrap-email/converters/grid.rb +14 -0
  37. data/lib/bootstrap-email/converters/head_style.rb +33 -0
  38. data/lib/bootstrap-email/{components → converters}/hr.rb +2 -2
  39. data/lib/bootstrap-email/{components → converters}/margin.rb +1 -1
  40. data/lib/bootstrap-email/{components → converters}/padding.rb +1 -1
  41. data/lib/bootstrap-email/converters/paragraph.rb +13 -0
  42. data/lib/bootstrap-email/converters/preview_text.rb +18 -0
  43. data/lib/bootstrap-email/{components → converters}/spacer.rb +1 -1
  44. data/lib/bootstrap-email/{components → converters}/spacing.rb +5 -6
  45. data/lib/bootstrap-email/converters/stack.rb +30 -0
  46. data/lib/bootstrap-email/{components → converters}/table.rb +1 -1
  47. data/lib/bootstrap-email/converters/version_comment.rb +15 -0
  48. data/lib/bootstrap-email/erb.rb +9 -0
  49. data/lib/bootstrap-email/rails/action_mailer.rb +7 -2
  50. data/lib/bootstrap-email/sass_cache.rb +43 -26
  51. data/lib/bootstrap-email/setup.rb +27 -0
  52. metadata +44 -31
  53. data/core/templates/body.html.erb +0 -9
  54. data/core/templates/col.html.erb +0 -3
  55. data/core/templates/div.html.erb +0 -3
  56. data/core/templates/row.html.erb +0 -7
  57. data/core/templates/table-left.html.erb +0 -9
  58. data/core/templates/table.html.erb +0 -9
  59. data/lib/bootstrap-email/components/align.rb +0 -21
  60. data/lib/bootstrap-email/components/base.rb +0 -26
  61. data/lib/bootstrap-email/components/body.rb +0 -22
  62. data/lib/bootstrap-email/components/grid.rb +0 -14
  63. data/lib/bootstrap-email/components/paragraph.rb +0 -24
@@ -0,0 +1,9 @@
1
+ module BootstrapEmail
2
+ class Erb
3
+ def self.template(path, locals_hash = {})
4
+ namespace = OpenStruct.new(locals_hash)
5
+ template_html = File.read(path)
6
+ ERB.new(template_html).result(namespace.instance_eval { binding })
7
+ end
8
+ end
9
+ end
@@ -2,9 +2,14 @@ ActiveSupport.on_load(:action_mailer, {yield: true}) do |action_mailer|
2
2
  action_mailer.class_eval do # To support Rails less than 6
3
3
  # sit in the middle and compile the html
4
4
  def bootstrap_mail(*args, &block)
5
- bootstrap = BootstrapEmail::Compiler.new(mail(*args, &block), type: :rails)
6
- bootstrap.perform_full_compile
5
+ mail_message = mail(*args, &block)
6
+ # if you override the #mail method in you ApplicationMailer you may intentionally return something other than a mail message
7
+ if mail_message
8
+ bootstrap = BootstrapEmail::Compiler.new(mail_message, type: :rails)
9
+ bootstrap.perform_full_compile
10
+ end
7
11
  end
12
+ alias bootstrap_email bootstrap_mail
8
13
  alias make_bootstrap_mail bootstrap_mail
9
14
  end
10
15
  end
@@ -1,38 +1,45 @@
1
1
  module BootstrapEmail
2
2
  class SassCache
3
- CACHE_DIR = File.expand_path('../../.sass-cache', __dir__)
4
3
  SASS_DIR = File.expand_path('../../core', __dir__)
5
4
 
6
- def self.compile(name, config_path: nil, style: :compressed)
7
- path = "#{SASS_DIR}/#{name}"
8
- config_file = nil
5
+ def self.compile(type, style: :compressed)
6
+ new(type, style).compile
7
+ end
9
8
 
10
- lookup_locations = ["#{name}.config.scss", "app/assets/stylesheets/#{name}.config.scss"]
11
- locations = lookup_locations.select { |location| File.exist?(File.expand_path(location, Dir.pwd)) }
9
+ attr_accessor :type, :style, :file_path, :config_file, :checksum
12
10
 
13
- if config_path && File.exist?(config_path)
14
- # check if custom config was passed in
15
- config_file = File.read(config_path)
16
- elsif locations.any?
17
- config_file = File.read(File.expand_path(locations.first, Dir.pwd))
18
- end
11
+ def initialize(type, style)
12
+ self.type = type
13
+ self.style = style
14
+ self.file_path = "#{SASS_DIR}/#{type}"
15
+ self.config_file = load_config
16
+ self.checksum = checksum_files
17
+ end
19
18
 
20
- check = checksum(config_file&.gsub("//= @import #{name};", "@import '#{path}';"))
21
- cache_path = "#{CACHE_DIR}/#{check}/#{name}.css"
22
- if cached?(cache_path)
23
- File.read(cache_path)
24
- else
25
- file = config_file.nil? ? File.read("#{path}.scss") : config_file
26
- SassC::Engine.new(file, style: style).render.tap do |css|
27
- Dir.mkdir(CACHE_DIR) unless File.directory?(CACHE_DIR)
28
- Dir.mkdir("#{CACHE_DIR}/#{check}") unless File.directory?("#{CACHE_DIR}/#{check}")
29
- File.write(cache_path, css)
30
- puts "New css file cached for #{name}"
31
- end
19
+ def cache_dir
20
+ BootstrapEmail.config.sass_cache_location
21
+ end
22
+
23
+ def compile
24
+ cache_path = "#{cache_dir}/#{checksum}/#{type}.css"
25
+ unless cached?(cache_path)
26
+ compile_and_cache_scss(cache_path)
32
27
  end
28
+ File.read(cache_path)
33
29
  end
34
30
 
35
- def self.checksum(config_file)
31
+ private
32
+
33
+ def load_config
34
+ path = BootstrapEmail.config.sass_location_for(type: type)
35
+ replace_config(File.read(path)) if path
36
+ end
37
+
38
+ def replace_config(config_file)
39
+ config_file.gsub("//= @import #{type};", "@import '#{file_path}';")
40
+ end
41
+
42
+ def checksum_files
36
43
  checksums = config_file.nil? ? [] : [Digest::SHA1.hexdigest(config_file)]
37
44
  Dir.glob('../../core/**/*.scss', base: __dir__).each do |path|
38
45
  checksums << Digest::SHA1.file(File.expand_path(path, __dir__)).hexdigest
@@ -40,8 +47,18 @@ module BootstrapEmail
40
47
  Digest::SHA1.hexdigest(checksums.join)
41
48
  end
42
49
 
43
- def self.cached?(cache_path)
50
+ def cached?(cache_path)
44
51
  File.file?(cache_path)
45
52
  end
53
+
54
+ def compile_and_cache_scss(cache_path)
55
+ file = config_file || File.read("#{file_path}.scss")
56
+ css = SassC::Engine.new(file, style: style).render
57
+ FileUtils.mkdir_p("#{cache_dir}/#{checksum}") unless File.directory?("#{cache_dir}/#{checksum}")
58
+ File.write(cache_path, css)
59
+ if BootstrapEmail.config.sass_log_enabled?
60
+ puts "New css file cached for #{type}"
61
+ end
62
+ end
46
63
  end
47
64
  end
@@ -0,0 +1,27 @@
1
+ module BootstrapEmail
2
+ class << self
3
+ def config
4
+ @config ||= BootstrapEmail::Config.new
5
+ @config
6
+ end
7
+
8
+ def load_options(options)
9
+ @config ||= BootstrapEmail::Config.new
10
+ @config.load_options(options)
11
+ @config
12
+ end
13
+
14
+ def configure(&proc)
15
+ @config ||= BootstrapEmail::Config.new
16
+ yield @config
17
+ end
18
+
19
+ def reset_config!
20
+ remove_instance_variable :@config if defined?(@config)
21
+ end
22
+
23
+ def clear_sass_cache!
24
+ FileUtils.rm_rf(BootstrapEmail.config.sass_cache_location)
25
+ end
26
+ end
27
+ 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.0.0.alpha1
4
+ version: 1.0.0.alpha3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stuart Yamartino
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-25 00:00:00.000000000 Z
11
+ date: 2021-05-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -30,28 +30,28 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.14'
33
+ version: '1.7'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.14'
40
+ version: '1.7'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sassc
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '2.4'
47
+ version: '2.0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '2.4'
54
+ version: '2.0'
55
55
  description:
56
56
  email: stu@stuyam.com
57
57
  executables:
@@ -80,6 +80,7 @@ files:
80
80
  - core/scss/components/_hr.scss
81
81
  - core/scss/components/_image.scss
82
82
  - core/scss/components/_preview.scss
83
+ - core/scss/components/_stack.scss
83
84
  - core/scss/components/_table.scss
84
85
  - core/scss/utilities/_background.scss
85
86
  - core/scss/utilities/_border-radius.scss
@@ -90,38 +91,50 @@ files:
90
91
  - core/scss/utilities/_spacing.scss
91
92
  - core/scss/utilities/_text-decoration.scss
92
93
  - core/scss/utilities/_typography.scss
93
- - core/templates/body.html.erb
94
- - core/templates/col.html.erb
95
- - core/templates/container.html.erb
96
- - core/templates/div.html.erb
97
- - core/templates/row.html.erb
98
- - core/templates/table-left.html.erb
99
- - core/templates/table.html.erb
94
+ - core/scss/utilities/_valign.scss
95
+ - core/templates/body.html
96
+ - core/templates/container.html
97
+ - core/templates/div.html
98
+ - core/templates/table-left.html
99
+ - core/templates/table-to-tbody.html
100
+ - core/templates/table-to-tr.html
101
+ - core/templates/table.html
102
+ - core/templates/td.html
103
+ - core/templates/tr.html
104
+ - lib/bootstrap-email.rb
100
105
  - lib/bootstrap-email/bootstrap_email_cli.rb
101
106
  - lib/bootstrap-email/compiler.rb
102
- - lib/bootstrap-email/components/alert.rb
103
- - lib/bootstrap-email/components/align.rb
104
- - lib/bootstrap-email/components/badge.rb
105
- - lib/bootstrap-email/components/base.rb
106
- - lib/bootstrap-email/components/body.rb
107
- - lib/bootstrap-email/components/button.rb
108
- - lib/bootstrap-email/components/card.rb
109
- - lib/bootstrap-email/components/color.rb
110
- - lib/bootstrap-email/components/container.rb
111
- - lib/bootstrap-email/components/grid.rb
112
- - lib/bootstrap-email/components/hr.rb
113
- - lib/bootstrap-email/components/margin.rb
114
- - lib/bootstrap-email/components/padding.rb
115
- - lib/bootstrap-email/components/paragraph.rb
116
- - lib/bootstrap-email/components/spacer.rb
117
- - lib/bootstrap-email/components/spacing.rb
118
- - lib/bootstrap-email/components/table.rb
107
+ - lib/bootstrap-email/config.rb
108
+ - lib/bootstrap-email/converters/alert.rb
109
+ - lib/bootstrap-email/converters/align.rb
110
+ - lib/bootstrap-email/converters/badge.rb
111
+ - lib/bootstrap-email/converters/base.rb
112
+ - lib/bootstrap-email/converters/block.rb
113
+ - lib/bootstrap-email/converters/body.rb
114
+ - lib/bootstrap-email/converters/button.rb
115
+ - lib/bootstrap-email/converters/card.rb
116
+ - lib/bootstrap-email/converters/color.rb
117
+ - lib/bootstrap-email/converters/container.rb
118
+ - lib/bootstrap-email/converters/force_encoding.rb
119
+ - lib/bootstrap-email/converters/grid.rb
120
+ - lib/bootstrap-email/converters/head_style.rb
121
+ - lib/bootstrap-email/converters/hr.rb
122
+ - lib/bootstrap-email/converters/margin.rb
123
+ - lib/bootstrap-email/converters/padding.rb
124
+ - lib/bootstrap-email/converters/paragraph.rb
125
+ - lib/bootstrap-email/converters/preview_text.rb
126
+ - lib/bootstrap-email/converters/spacer.rb
127
+ - lib/bootstrap-email/converters/spacing.rb
128
+ - lib/bootstrap-email/converters/stack.rb
129
+ - lib/bootstrap-email/converters/table.rb
130
+ - lib/bootstrap-email/converters/version_comment.rb
131
+ - lib/bootstrap-email/erb.rb
119
132
  - lib/bootstrap-email/initialize.rb
120
133
  - lib/bootstrap-email/rails/action_mailer.rb
121
134
  - lib/bootstrap-email/rails/engine.rb
122
135
  - lib/bootstrap-email/sass_cache.rb
136
+ - lib/bootstrap-email/setup.rb
123
137
  - lib/bootstrap-email/version.rb
124
- - lib/bootstrap_email.rb
125
138
  homepage: https://bootstrapemail.com
126
139
  licenses:
127
140
  - MIT
@@ -1,9 +0,0 @@
1
- <table valign="top" class="<%= classes %>">
2
- <tbody>
3
- <tr>
4
- <td valign="top">
5
- <%= contents %>
6
- </td>
7
- </tr>
8
- </tbody>
9
- </table>
@@ -1,3 +0,0 @@
1
- <td class="<%= classes %>" align="left" valign="top">
2
- <%= contents %>
3
- </td>
@@ -1,3 +0,0 @@
1
- <div class="<%= classes %>">
2
- <%= contents %>
3
- </div>
@@ -1,7 +0,0 @@
1
- <table class="<%= classes %>">
2
- <tbody>
3
- <tr>
4
- <%= contents %>
5
- </tr>
6
- </tbody>
7
- </table>
@@ -1,9 +0,0 @@
1
- <table class="<%= classes %>" align="left">
2
- <tbody>
3
- <tr>
4
- <td>
5
- <%= contents %>
6
- </td>
7
- </tr>
8
- </tbody>
9
- </table>
@@ -1,9 +0,0 @@
1
- <table class="<%= classes %>">
2
- <tbody>
3
- <tr>
4
- <td>
5
- <%= contents %>
6
- </td>
7
- </tr>
8
- </tbody>
9
- </table>
@@ -1,21 +0,0 @@
1
- module BootstrapEmail
2
- module Component
3
- class Align < Base
4
- def build
5
- ['left', 'center', 'right'].each do |type|
6
- each_node(".align-#{type}") do |node|
7
- align_helper(node, type)
8
- end
9
- end
10
- end
11
-
12
- def align_helper(node, type)
13
- if node.name != 'table'
14
- node['class'] = node['class'].sub("align-#{type}", '')
15
- node = node.replace(template('table', classes: "align-#{type}", contents: node.to_html))[0]
16
- end
17
- node['align'] = type
18
- end
19
- end
20
- end
21
- end
@@ -1,26 +0,0 @@
1
- module BootstrapEmail
2
- module Component
3
- class Base
4
- attr_reader :doc
5
- def initialize(doc)
6
- @doc = doc
7
- end
8
-
9
- def self.build(doc)
10
- new(doc).build
11
- end
12
-
13
- def template(file, locals_hash = {})
14
- locals_hash[:classes] = locals_hash[:classes].split.join(' ') if locals_hash[:classes]
15
- namespace = OpenStruct.new(locals_hash)
16
- template_html = File.read(File.expand_path("../../../core/templates/#{file}.html.erb", __dir__))
17
- ERB.new(template_html).result(namespace.instance_eval { binding })
18
- end
19
-
20
- def each_node(css_lookup, &blk)
21
- # sort by youngest child and traverse backwards up the tree
22
- doc.css(css_lookup).sort_by { |n| n.ancestors.size }.reverse!.each(&blk)
23
- end
24
- end
25
- end
26
- end
@@ -1,22 +0,0 @@
1
- module BootstrapEmail
2
- module Component
3
- class Body < Base
4
- def build
5
- each_node('body') do |node|
6
- node.replace('<body>' + preview_text.to_s + template('body', classes: "#{node['class']} body", contents: node.inner_html) + '</body>')
7
- end
8
- end
9
-
10
- def preview_text
11
- preview_node = doc.at_css('preview')
12
- return if preview_node.nil?
13
-
14
- # apply spacing after the text max of 100 characters so it doesn't show body text
15
- preview_node.content += '&nbsp;' * [(100 - preview_node.content.length.to_i), 0].max
16
- node = template('div', classes: 'preview', contents: preview_node.content)
17
- preview_node.remove
18
- node
19
- end
20
- end
21
- end
22
- end
@@ -1,14 +0,0 @@
1
- module BootstrapEmail
2
- module Component
3
- class Grid < Base
4
- def build
5
- each_node('.row') do |node|
6
- node.replace(template('row', classes: node['class'], contents: node.inner_html))
7
- end
8
- each_node('*[class*=col]') do |node|
9
- node.replace(template('col', classes: node['class'], contents: node.inner_html))
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,24 +0,0 @@
1
- module BootstrapEmail
2
- module Component
3
- class Paragraph < Base
4
- def build
5
- each_node('p') do |node|
6
- next if margin?(node) || space_y?(node)
7
-
8
- node['class'] ||= ''
9
- node['class'] += 'mb-4'
10
- end
11
- end
12
-
13
- private
14
-
15
- def margin?(node)
16
- node['class'].to_s.match?(/m[tby]{1}-(lg-)?\d+/)
17
- end
18
-
19
- def space_y?(node)
20
- node.parent['class'].to_s.match?(/space-y-(lg-)?\d+/)
21
- end
22
- end
23
- end
24
- end