inky-rb 1.3.7.0 → 1.3.7.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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile.lock +119 -8
  4. data/README.md +27 -2
  5. data/inky.gemspec +6 -2
  6. data/lib/generators/inky/install_generator.rb +3 -2
  7. data/lib/generators/inky/templates/mailer_layout.html.erb +2 -2
  8. data/lib/generators/inky/templates/mailer_layout.html.haml +13 -0
  9. data/lib/generators/inky/templates/mailer_layout.html.slim +15 -0
  10. data/lib/inky.rb +9 -8
  11. data/lib/inky/component_factory.rb +139 -0
  12. data/lib/inky/configuration.rb +31 -0
  13. data/lib/inky/rails/engine.rb +1 -1
  14. data/lib/inky/rails/template_handler.rb +24 -8
  15. data/lib/inky/rails/version.rb +1 -1
  16. data/spec/configuration_spec.rb +38 -0
  17. data/spec/inky_spec.rb +19 -0
  18. data/spec/spec_helper.rb +5 -5
  19. data/spec/test_app/Rakefile +6 -0
  20. data/spec/test_app/app/controllers/application_controller.rb +3 -0
  21. data/spec/test_app/app/controllers/inky_controller.rb +9 -0
  22. data/spec/test_app/app/helpers/application_helper.rb +2 -0
  23. data/spec/test_app/app/mailers/application_mailer.rb +4 -0
  24. data/spec/test_app/app/views/inky/_inky_partial.html.inky +1 -0
  25. data/spec/test_app/app/views/inky/explicit_builder.html.inky-builder +1 -0
  26. data/spec/test_app/app/views/inky/explicit_slim.html.inky-slim +2 -0
  27. data/spec/test_app/app/views/inky/layout.html.erb +1 -0
  28. data/spec/test_app/app/views/inky/non_inky.html.erb +3 -0
  29. data/spec/test_app/app/views/inky/simple.html.inky +1 -0
  30. data/spec/test_app/app/views/inky/slim.html.inky +2 -0
  31. data/spec/test_app/app/views/layouts/application.html.erb +4 -0
  32. data/spec/test_app/app/views/layouts/inky_layout.html.inky +11 -0
  33. data/spec/test_app/config.ru +5 -0
  34. data/spec/test_app/config/application.rb +22 -0
  35. data/spec/test_app/config/boot.rb +5 -0
  36. data/spec/test_app/config/cable.yml +9 -0
  37. data/spec/test_app/config/database.yml +25 -0
  38. data/spec/test_app/config/environment.rb +5 -0
  39. data/spec/test_app/config/environments/development.rb +54 -0
  40. data/spec/test_app/config/environments/production.rb +86 -0
  41. data/spec/test_app/config/environments/test.rb +44 -0
  42. data/spec/test_app/config/initializers/application_controller_renderer.rb +6 -0
  43. data/spec/test_app/config/initializers/assets.rb +11 -0
  44. data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
  45. data/spec/test_app/config/initializers/cookies_serializer.rb +5 -0
  46. data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
  47. data/spec/test_app/config/initializers/inflections.rb +16 -0
  48. data/spec/test_app/config/initializers/mime_types.rb +4 -0
  49. data/spec/test_app/config/initializers/new_framework_defaults.rb +24 -0
  50. data/spec/test_app/config/initializers/secret_token.rb +1 -0
  51. data/spec/test_app/config/initializers/session_store.rb +3 -0
  52. data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
  53. data/spec/test_app/config/locales/en.yml +23 -0
  54. data/spec/test_app/config/puma.rb +47 -0
  55. data/spec/test_app/config/routes.rb +3 -0
  56. data/spec/test_app/config/secrets.yml +22 -0
  57. data/spec/test_app/config/spring.rb +6 -0
  58. data/spec/test_app/log/.keep +0 -0
  59. data/spec/test_app/spec/features/inky_spec.rb +100 -0
  60. data/spec/test_app/spec/helper.rb +14 -0
  61. metadata +197 -5
  62. data/lib/component_factory.rb +0 -138
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a4008c29bb92a467214a676eb6dfa34286f7333
4
- data.tar.gz: 2a5e4bf73fe574f8d952aed07ad6324c7aecfdad
3
+ metadata.gz: 77c176107d789eb48bb01a6d4f6d75713f67d062
4
+ data.tar.gz: 3caf4fac84fadda5c06c8bce1a77b01a6cd443aa
5
5
  SHA512:
6
- metadata.gz: 0c67e33eb5035b4e02333642e3781eb70292bb7b1b2dcdf3fc3af6d54c8802f7085f232cbef1bb9198f3a0f048b2b926b510631aa72f8c841d95d594c14a5bef
7
- data.tar.gz: 6f1d96ad26149214322c00e279f8ffbea12c531f9d30848c1d43af5b5beec3d08187580c82e9b90f34dcd8269c945d6090d7a47f66664aa9d01b311639def83b
6
+ metadata.gz: c9d7938d47cbe1cfe38b36a04d27839a4f8af211a3657814d5f71cfd805de0402bd51c13d3a097a4d908b691ec5482da8cf26cd8432daf972243187d3885d7d2
7
+ data.tar.gz: 8cadd7b1c791284697612b8a87e2cb7b88a270f3e407c1cca6273d73c826824e33d9006ae10167438f6a113da79b2c832803ed047940a51da472d1154fb4b258
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
1
  *.swp
2
2
  pkg
3
3
  spec/_cases_output
4
+ spec/test_app/log/*.log
5
+ spec/test_app/tmp/
@@ -1,28 +1,110 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- inky-rb (1.3.7.0)
4
+ inky-rb (1.3.7.1)
5
5
  foundation_emails (~> 2)
6
6
  nokogiri
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
+ actionmailer (4.2.7.1)
12
+ actionpack (= 4.2.7.1)
13
+ actionview (= 4.2.7.1)
14
+ activejob (= 4.2.7.1)
15
+ mail (~> 2.5, >= 2.5.4)
16
+ rails-dom-testing (~> 1.0, >= 1.0.5)
17
+ actionpack (4.2.7.1)
18
+ actionview (= 4.2.7.1)
19
+ activesupport (= 4.2.7.1)
20
+ rack (~> 1.6)
21
+ rack-test (~> 0.6.2)
22
+ rails-dom-testing (~> 1.0, >= 1.0.5)
23
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
24
+ actionview (4.2.7.1)
25
+ activesupport (= 4.2.7.1)
26
+ builder (~> 3.1)
27
+ erubis (~> 2.7.0)
28
+ rails-dom-testing (~> 1.0, >= 1.0.5)
29
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
30
+ activejob (4.2.7.1)
31
+ activesupport (= 4.2.7.1)
32
+ globalid (>= 0.3.0)
33
+ activemodel (4.2.7.1)
34
+ activesupport (= 4.2.7.1)
35
+ builder (~> 3.1)
36
+ activerecord (4.2.7.1)
37
+ activemodel (= 4.2.7.1)
38
+ activesupport (= 4.2.7.1)
39
+ arel (~> 6.0)
40
+ activesupport (4.2.7.1)
41
+ i18n (~> 0.7)
42
+ json (~> 1.7, >= 1.7.7)
43
+ minitest (~> 5.1)
44
+ thread_safe (~> 0.3, >= 0.3.4)
45
+ tzinfo (~> 1.1)
46
+ addressable (2.3.8)
47
+ arel (6.0.3)
11
48
  ast (2.3.0)
49
+ builder (3.2.2)
50
+ capybara (2.7.0)
51
+ addressable
52
+ mime-types (>= 1.16)
53
+ nokogiri (>= 1.3.3)
54
+ rack (>= 1.0.0)
55
+ rack-test (>= 0.5.4)
56
+ xpath (~> 2.0)
57
+ concurrent-ruby (1.0.2)
12
58
  diff-lcs (1.2.5)
59
+ erubis (2.7.0)
13
60
  foundation_emails (2.2.1.0)
61
+ globalid (0.3.7)
62
+ activesupport (>= 4.1.0)
63
+ i18n (0.7.0)
64
+ json (1.8.3)
65
+ loofah (2.0.3)
66
+ nokogiri (>= 1.5.9)
67
+ mail (2.6.4)
68
+ mime-types (>= 1.16, < 4)
69
+ mime-types (3.1)
70
+ mime-types-data (~> 3.2015)
71
+ mime-types-data (3.2016.0521)
14
72
  mini_portile2 (2.1.0)
73
+ minitest (5.9.1)
15
74
  nokogiri (1.6.8.1)
16
75
  mini_portile2 (~> 2.1.0)
17
76
  parser (2.3.1.4)
18
77
  ast (~> 2.2)
19
78
  powerpack (0.1.1)
79
+ rack (1.6.4)
80
+ rack-test (0.6.3)
81
+ rack (>= 1.0)
82
+ rails (4.2.7.1)
83
+ actionmailer (= 4.2.7.1)
84
+ actionpack (= 4.2.7.1)
85
+ actionview (= 4.2.7.1)
86
+ activejob (= 4.2.7.1)
87
+ activemodel (= 4.2.7.1)
88
+ activerecord (= 4.2.7.1)
89
+ activesupport (= 4.2.7.1)
90
+ bundler (>= 1.3.0, < 2.0)
91
+ railties (= 4.2.7.1)
92
+ sprockets-rails
93
+ rails-deprecated_sanitizer (1.0.3)
94
+ activesupport (>= 4.2.0.alpha)
95
+ rails-dom-testing (1.0.7)
96
+ activesupport (>= 4.2.0.beta, < 5.0)
97
+ nokogiri (~> 1.6.0)
98
+ rails-deprecated_sanitizer (>= 1.0.1)
99
+ rails-html-sanitizer (1.0.3)
100
+ loofah (~> 2.0)
101
+ railties (4.2.7.1)
102
+ actionpack (= 4.2.7.1)
103
+ activesupport (= 4.2.7.1)
104
+ rake (>= 0.8.7)
105
+ thor (>= 0.18.1, < 2.0)
20
106
  rainbow (2.1.0)
21
- rake (11.2.2)
22
- rspec (3.5.0)
23
- rspec-core (~> 3.5.0)
24
- rspec-expectations (~> 3.5.0)
25
- rspec-mocks (~> 3.5.0)
107
+ rake (11.3.0)
26
108
  rspec-core (3.5.0)
27
109
  rspec-support (~> 3.5.0)
28
110
  rspec-expectations (3.5.0)
@@ -31,6 +113,14 @@ GEM
31
113
  rspec-mocks (3.5.0)
32
114
  diff-lcs (>= 1.2.0, < 2.0)
33
115
  rspec-support (~> 3.5.0)
116
+ rspec-rails (3.5.2)
117
+ actionpack (>= 3.0)
118
+ activesupport (>= 3.0)
119
+ railties (>= 3.0)
120
+ rspec-core (~> 3.5.0)
121
+ rspec-expectations (~> 3.5.0)
122
+ rspec-mocks (~> 3.5.0)
123
+ rspec-support (~> 3.5.0)
34
124
  rspec-support (3.5.0)
35
125
  rubocop (0.43.0)
36
126
  parser (>= 2.3.1.1, < 3.0)
@@ -39,19 +129,40 @@ GEM
39
129
  ruby-progressbar (~> 1.7)
40
130
  unicode-display_width (~> 1.0, >= 1.0.1)
41
131
  ruby-progressbar (1.7.5)
132
+ slim (3.0.6)
133
+ temple (~> 0.7.3)
134
+ tilt (>= 1.3.3, < 2.1)
135
+ sprockets (3.7.0)
136
+ concurrent-ruby (~> 1.0)
137
+ rack (> 1, < 3)
138
+ sprockets-rails (3.2.0)
139
+ actionpack (>= 4.0)
140
+ activesupport (>= 4.0)
141
+ sprockets (>= 3.0.0)
142
+ temple (0.7.6)
143
+ thor (0.19.1)
144
+ thread_safe (0.3.5)
145
+ tilt (1.4.1)
146
+ tzinfo (1.2.2)
147
+ thread_safe (~> 0.1)
42
148
  unicode-display_width (1.1.1)
149
+ xpath (2.0.0)
150
+ nokogiri (~> 1.3)
43
151
 
44
152
  PLATFORMS
45
153
  ruby
46
154
 
47
155
  DEPENDENCIES
48
156
  bundler (~> 1.6)
157
+ capybara
49
158
  inky-rb!
159
+ rails
50
160
  rake
51
- rspec
52
161
  rspec-core
53
162
  rspec-expectations
163
+ rspec-rails
54
164
  rubocop
165
+ slim
55
166
 
56
167
  BUNDLED WITH
57
- 1.12.5
168
+ 1.13.6
data/README.md CHANGED
@@ -62,19 +62,44 @@ Run the following command to set up the required styles and mailer layout:
62
62
  rails g inky:install
63
63
  ```
64
64
 
65
- (You can specify the generated mailer layout filename like so: `rails g inky:install some_name`)
65
+ (You can specify the generated mailer layout filename like so: `rails g inky:install some_name` and also your prefered
66
+ markup language like: `rails g inky:install mailer_layout slim`)
66
67
 
67
- Rename your email templates to use the `.inky` file extension. Note that you'll still be able to use ERB within the `.inky` templates:
68
+ Rename your email templates to use the `.inky` file extension. Note that you'll still be able to use your default
69
+ template engine within the `.inky` templates:
68
70
 
69
71
  ```
70
72
  welcome.html => welcome.html.inky
71
73
  pw_reset.html.erb => pw_reset.html.inky
72
74
  ```
73
75
 
76
+
74
77
  You're all set!
75
78
 
76
79
  ** The majority of email clients ignore linked stylesheets. By using a CSS inliner like `premailer-rails` or `roadie`, you're able to leave your stylesheets in a separate file, keeping your markup lean.
77
80
 
81
+ ## Alternative template engine
82
+
83
+ If you do not use ERB for your views and layouts but some other markup like Haml or Slim, you can configure Inky to
84
+ use these languages. To do so, just set an initializer:
85
+
86
+ ```ruby
87
+ # config/initializers/inky.rb
88
+ Inky.configure do |config|
89
+ config.template_engine = :slim
90
+ end
91
+ ```
92
+
93
+ Check [lib/generators/inky/templates/mailer_layout.html.slim](lib/generators/inky/templates/mailer_layout.html.slim)
94
+ for a Slim example.
95
+
96
+ You may prefer to specify which template engine to use before inky:
97
+
98
+ ```
99
+ welcome.html.haml => welcome.html.inky-haml
100
+ pw_reset.html.erb => pw_reset.html.inky-erb
101
+ ```
102
+
78
103
  ## Custom Elements
79
104
 
80
105
  Inky simplifies the process of creating HTML emails by expanding out simple tags like `<row>` and `<column>` into full table syntax. The names of the tags can be changed with the `components` setting.
@@ -13,12 +13,16 @@ Gem::Specification.new do |s|
13
13
 
14
14
  s.files = `git ls-files -z`.split("\x0")
15
15
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+ s.test_files = Dir['spec/**/*']
17
17
 
18
18
  s.add_dependency "foundation_emails", "~> 2"
19
19
  s.add_dependency "nokogiri"
20
20
  s.add_development_dependency "bundler", "~> 1.6"
21
21
  s.add_development_dependency "rake"
22
- s.add_development_dependency "rspec"
23
22
  s.add_development_dependency "rubocop"
23
+ s.add_development_dependency "rspec-rails"
24
+ s.add_development_dependency "capybara"
25
+ s.add_development_dependency "rails"
26
+ s.add_development_dependency "slim"
27
+ # s.add_development_dependency "pry-byebug"
24
28
  end
@@ -6,11 +6,12 @@ module Inky
6
6
  desc 'Install Foundation for Emails'
7
7
  source_root File.join(File.dirname(__FILE__), 'templates')
8
8
  argument :layout_name, type: :string, default: 'mailer', banner: 'layout_name'
9
+ argument :extension, type: :string, default: 'erb', banner: 'extension'
9
10
 
10
11
  def preserve_original_mailer_layout
11
12
  return unless layout_name == 'mailer'
12
13
 
13
- original_mailer = File.join(layouts_base_dir, 'mailer.html.erb')
14
+ original_mailer = File.join(layouts_base_dir, "mailer.html.#{extension}")
14
15
  rename_filename = File.join(layouts_base_dir, "old_mailer_#{Time.now.to_i}.html.erb")
15
16
  File.rename(original_mailer, rename_filename) if File.exist? original_mailer
16
17
  end
@@ -20,7 +21,7 @@ module Inky
20
21
  end
21
22
 
22
23
  def create_mailer_layout
23
- template 'mailer_layout.html.erb', File.join(layouts_base_dir, "#{layout_name.underscore}.html.erb")
24
+ template "mailer_layout.html.#{extension}", File.join(layouts_base_dir, "#{layout_name.underscore}.html.#{extension}")
24
25
  end
25
26
 
26
27
  private
@@ -4,7 +4,7 @@
4
4
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
5
  <meta name="viewport" content="width=device-width" />
6
6
 
7
- <%%= stylesheet_link_tag "foundation_emails" %>
7
+ <%= stylesheet_link_tag "foundation_emails" %>
8
8
  </head>
9
9
 
10
10
  <body>
@@ -12,7 +12,7 @@
12
12
  <tr>
13
13
  <td class="center" align="center" valign="top">
14
14
  <center>
15
- <%%= yield %>
15
+ <%= yield %>
16
16
  </center>
17
17
  </td>
18
18
  </tr>
@@ -0,0 +1,13 @@
1
+ !!! Strict
2
+ %html{:xmlns => "http://www.w3.org/1999/xhtml"}
3
+ %head
4
+ %meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/
5
+ %meta{:content => "width=device-width", :name => "viewport"}/
6
+ = stylesheet_link_tag "foundation_emails"
7
+ %body
8
+ %table.body{"data-made-with-foundation" => ""}
9
+ %tr
10
+ %td.center{:align => "center", :valign => "top"}
11
+ %center
12
+ %container
13
+ = yield
@@ -0,0 +1,15 @@
1
+ doctype strict
2
+ html[xmlns='http://www.w3.org/1999/xhtml']
3
+ head
4
+ meta http-equiv="Content-Type" content="text/html; charset=utf-8"
5
+ meta name="viewport" content="width=device-width"
6
+
7
+ = stylesheet_link_tag "foundation_emails"
8
+
9
+ body
10
+ table.body data-made-with-foundation=""
11
+ tr
12
+ td.center align="center" valign="top"
13
+ center
14
+ container
15
+ = yield
@@ -1,7 +1,9 @@
1
+ require 'nokogiri'
2
+ require_relative 'inky/configuration'
3
+ require_relative 'inky/component_factory'
4
+
1
5
  module Inky
2
6
  class Core
3
- require 'nokogiri'
4
- require_relative 'component_factory'
5
7
  attr_accessor :components, :column_count, :component_lookup, :component_tags
6
8
 
7
9
  include ComponentFactory
@@ -28,14 +30,13 @@ module Inky
28
30
  self.component_tags = components.values
29
31
  end
30
32
 
31
- def release_the_kraken(xml_string)
32
- xml_string = xml_string.gsub(/doctype/i, 'DOCTYPE')
33
- raws, str = Inky::Core.extract_raws(xml_string)
33
+ def release_the_kraken(html_string)
34
+ html_string.force_encoding('utf-8') # transform_doc barfs if encoding is ASCII-8bit
35
+ html_string = html_string.gsub(/doctype/i, 'DOCTYPE')
36
+ raws, str = Inky::Core.extract_raws(html_string)
34
37
  parse_cmd = str =~ /<html/i ? :parse : :fragment
35
38
  html = Nokogiri::HTML.public_send(parse_cmd, str)
36
- html.elements.each do |elem|
37
- transform_doc(elem)
38
- end
39
+ transform_doc(html)
39
40
  string = html.to_html(encoding: 'US-ASCII')
40
41
  Inky::Core.re_inject_raws(string, raws)
41
42
  end
@@ -0,0 +1,139 @@
1
+ module Inky
2
+ module ComponentFactory
3
+ def component_factory(elem)
4
+ transform_method = :"_transform_#{component_lookup[elem.name]}"
5
+ return unless respond_to?(transform_method)
6
+ inner = elem.children.map(&:to_s).join
7
+ send(transform_method, elem, inner)
8
+ end
9
+
10
+ tags = %w[class id href size large no-expander small target]
11
+ tags = tags.to_set if tags.respond_to? :to_set
12
+ IGNORED_ON_PASSTHROUGH = tags.freeze
13
+
14
+ def _pass_through_attributes(elem)
15
+ elem.attributes.reject { |e| IGNORED_ON_PASSTHROUGH.include?(e.downcase) }.map do |name, value|
16
+ %{#{name}="#{value}" }
17
+ end.join
18
+ end
19
+
20
+ def _has_class(elem, klass)
21
+ elem.attr('class') =~ /(^|\s)#{klass}($|\s)/
22
+ end
23
+
24
+ def _combine_classes(elem, extra_classes)
25
+ [elem['class'], extra_classes].join(' ')
26
+ end
27
+
28
+ def _combine_attributes(elem, extra_classes = nil)
29
+ classes = _combine_classes(elem, extra_classes)
30
+ [_pass_through_attributes(elem), classes && %{class="#{classes}"}].join
31
+ end
32
+
33
+ def _target_attribute(elem)
34
+ elem.attributes['target'] ? %{ target="#{elem.attributes['target']}"} : ''
35
+ end
36
+
37
+ def _transform_button(component, inner)
38
+ expand = _has_class(component, 'expand')
39
+ if component.attr('href')
40
+ target = _target_attribute(component)
41
+ extra = ' align="center" class="float-center"' if expand
42
+ inner = %{<a href="#{component.attr('href')}"#{target}#{extra}>#{inner}</a>}
43
+ end
44
+ inner = "<center>#{inner}</center>" if expand
45
+
46
+ classes = _combine_classes(component, 'button')
47
+ expander = '<td class="expander"></td>' if expand
48
+ %{<table class="#{classes}"><tr><td><table><tr><td>#{inner}</td></tr></table></td>#{expander}</tr></table>}
49
+ end
50
+
51
+ def _transform_menu(component, inner)
52
+ attributes = _combine_attributes(component, 'menu')
53
+ %{<table #{attributes}><tr><td><table><tr>#{inner}</tr></table></td></tr></table>}
54
+ end
55
+
56
+ def _transform_menu_item(component, inner)
57
+ target = _target_attribute(component)
58
+ attributes = _combine_attributes(component, 'menu-item')
59
+ %{<th #{attributes}><a href="#{component.attr('href')}"#{target}>#{inner}</a></th>}
60
+ end
61
+
62
+ def _transform_container(component, inner)
63
+ attributes = _combine_attributes(component, 'container')
64
+ %{<table #{attributes} align="center"><tbody><tr><td>#{inner}</td></tr></tbody></table>}
65
+ end
66
+
67
+ def _transform_row(component, inner)
68
+ attributes = _combine_attributes(component, 'row')
69
+ %{<table #{attributes}><tbody><tr>#{inner}</tr></tbody></table>}
70
+ end
71
+
72
+ # in inky.js this is factored out into makeClumn. TBD if we need that here.
73
+ def _transform_columns(component, inner)
74
+ col_count = component.parent.elements.size
75
+
76
+ small_val = component.attr('small')
77
+ large_val = component.attr('large')
78
+
79
+ small_size = small_val || column_count
80
+ large_size = large_val || small_val || (column_count / col_count).to_i
81
+
82
+ classes = _combine_classes(component, "small-#{small_size} large-#{large_size} columns")
83
+
84
+ classes << ' first' unless component.previous_element
85
+ classes << ' last' unless component.next_element
86
+
87
+ subrows = component.elements.css(".row").to_a.concat(component.elements.css("row").to_a)
88
+ expander = %{<th class="expander"></th>} if large_size.to_i == column_count && subrows.empty?
89
+
90
+ %{<th class="#{classes}" #{_pass_through_attributes(component)}><table><tr><th>#{inner}</th>#{expander}</tr></table></th>}
91
+ end
92
+
93
+ def _transform_block_grid(component, inner)
94
+ classes = _combine_classes(component, "block-grid up-#{component.attr('up')}")
95
+ %{<table class="#{classes}"><tr>#{inner}</tr></table>}
96
+ end
97
+
98
+ def _transform_center(component, _inner)
99
+ # NOTE: Using children instead of elements because elements.to_a
100
+ # sometimes appears to miss elements that show up in size
101
+ component.elements.each do |child|
102
+ child['align'] = 'center'
103
+ child['class'] = _combine_classes(child, 'float-center')
104
+ items = component.elements.css(".menu-item").to_a.concat(component.elements.css("item").to_a)
105
+ items.each do |item|
106
+ item['class'] = _combine_classes(item, 'float-center')
107
+ end
108
+ end
109
+ component.to_s
110
+ end
111
+
112
+ def _transform_callout(component, inner)
113
+ classes = _combine_classes(component, 'callout-inner')
114
+ attributes = _pass_through_attributes(component)
115
+ %{<table #{attributes}class="callout"><tr><th class="#{classes}">#{inner}</th><th class="expander"></th></tr></table>}
116
+ end
117
+
118
+ def _transform_spacer(component, _inner)
119
+ classes = _combine_classes(component, 'spacer')
120
+ build_table = ->(size, extra) { %{<table class="#{classes} #{extra}"><tbody><tr><td height="#{size}px" style="font-size:#{size}px;line-height:#{size}px;">&#xA0;</td></tr></tbody></table>} }
121
+ size = component.attr('size')
122
+ size_sm = component.attr('size-sm')
123
+ size_lg = component.attr('size-lg')
124
+ if size_sm || size_lg
125
+ html = ''
126
+ html << build_table[size_sm, 'hide-for-large'] if size_sm
127
+ html << build_table[size_lg, 'show-for-large'] if size_lg
128
+ html
129
+ else
130
+ build_table[size || 16, nil]
131
+ end
132
+ end
133
+
134
+ def _transform_wrapper(component, inner)
135
+ attributes = _combine_attributes(component, 'wrapper')
136
+ %{<table #{attributes} align="center"><tr><td class="wrapper-inner">#{inner}</td></tr></table>}
137
+ end
138
+ end
139
+ end