mjml-rb 0.3.0 → 0.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: cfa6cc54a797f8b4323003dbcfd92fa4ef02b1e0b118e58acd14bb8e901e502d
4
- data.tar.gz: 12d0fb1d71e03a23811caac5b0417b7f32823b95870e47296ea51fd8bd713018
3
+ metadata.gz: a5afc17046611848190458b50e1b7d0670011e8f1e32a6723b63c7e7ff76029c
4
+ data.tar.gz: ff832c4861cd1c28d76f47e0f66f257e8fa1c956dd6e0836826df83be3e4782d
5
5
  SHA512:
6
- metadata.gz: 689a1974e1c6e7477e202c3fb070c63eadf3b66617e2ea177feb6b45ae9d58cf9c1472dd7ddbe4e141d6583e67f83c93f76ca91c5f787d4a706241523c313361
7
- data.tar.gz: ad73e16bd469bdfd98ccff031aca1796f99c460c87ab6435ba272492ffeb4ffff2b1e77f1019c368324286942cc561239e20b4219e6010efcac7d2066a945bb6
6
+ metadata.gz: e43bae28df235a80ad028bc43e37401c45c59c8e0d486f09e8d22faa786c1e18e62e696bde4cce668fcee4ea1c7d3d037cec3ec93d890b0e8e33404f98b776fe
7
+ data.tar.gz: c35f403ee71148fa10f6e9d794a61695f35f74201e561fba1afecb4686c71388c01f13bf69c19b799214102ad142a6f86281d922b3ed5eed2ed1e348b446f737
@@ -39,6 +39,7 @@ module MjmlRb
39
39
 
40
40
  def render(tag_name:, node:, context:, attrs:, parent:)
41
41
  width_pct = context.delete(:_column_width_pct) || 100.0
42
+ mobile_width = context.delete(:_column_mobile_width)
42
43
  css_class = attrs["css-class"]
43
44
  a = self.class.default_attributes.merge(attrs)
44
45
 
@@ -63,7 +64,7 @@ module MjmlRb
63
64
  "direction" => a["direction"],
64
65
  "display" => "inline-block",
65
66
  "vertical-align" => vertical_align,
66
- "width" => "100%"
67
+ "width" => (mobile_width ? mobile_width_value(a, width_pct, context[:container_width]) : "100%")
67
68
  )
68
69
 
69
70
  column_markup =
@@ -168,6 +169,22 @@ module MjmlRb
168
169
  value && !value.empty?
169
170
  end
170
171
 
172
+ def mobile_width_value(attrs, width_pct, parent_width)
173
+ width = attrs["width"]
174
+
175
+ if present_attr?(width) && width.end_with?("%")
176
+ width
177
+ elsif present_attr?(width) && width.end_with?("px")
178
+ parent_width_px = parse_pixel_value(parent_width || "600px")
179
+ return "100%" if parent_width_px.zero?
180
+
181
+ percentage = (parse_pixel_value(width) / parent_width_px) * 100
182
+ "#{percentage.to_s.sub(/\.?0+$/, "")}%"
183
+ else
184
+ "#{width_pct.to_f.to_s.sub(/\.?0+$/, "")}%"
185
+ end
186
+ end
187
+
171
188
  def with_child_container_width(context, attrs, width_pct)
172
189
  previous_container_width = context[:container_width]
173
190
  context[:container_width] = child_container_width(context, attrs, width_pct)
@@ -77,6 +77,7 @@ module MjmlRb
77
77
  width_pct = widths[column_index] || 100.0
78
78
  column_index += 1
79
79
  context[:_column_width_pct] = width_pct
80
+ context[:_column_mobile_width] = true
80
81
  td_style = style_join(
81
82
  "vertical-align" => resolved_attributes(child, context)["vertical-align"] || "top",
82
83
  "width" => "#{(group_width_px * width_pct / 100.0).round}px"
@@ -238,11 +238,11 @@ module MjmlRb
238
238
  def hero_container_width(attrs, container_width)
239
239
  width = parse_unit_value(container_width)
240
240
  content_width = width - padding_side(attrs, "left") - padding_side(attrs, "right")
241
- "#{[content_width, 0].max}px"
241
+ px_length([content_width, 0].max)
242
242
  end
243
243
 
244
244
  def normalize_container_width(value)
245
- "#{parse_unit_value(value)}px"
245
+ px_length(parse_unit_value(value))
246
246
  end
247
247
 
248
248
  def padding_side(attrs, side)
@@ -280,6 +280,17 @@ module MjmlRb
280
280
  def blank?(value)
281
281
  value.nil? || value.to_s.empty?
282
282
  end
283
+
284
+ def px_length(value)
285
+ "#{format_number(value)}px"
286
+ end
287
+
288
+ def format_number(value)
289
+ number = value.to_f
290
+ return number.to_i.to_s if number == number.to_i
291
+
292
+ number.to_s.sub(/\.?0+$/, "")
293
+ end
283
294
  end
284
295
  end
285
296
  end
@@ -64,7 +64,7 @@ module MjmlRb
64
64
  render_wrapper(node, context, attrs)
65
65
  else
66
66
  a = self.class.default_attributes.merge(attrs)
67
- if a["full-width"] == "full-width"
67
+ if a["full-width"] == "full-width" && !context[:_inside_full_width_wrapper]
68
68
  render_full_width_section(node, context, a)
69
69
  else
70
70
  render_section(node, context, a)
@@ -254,8 +254,8 @@ module MjmlRb
254
254
 
255
255
  # Build v:fill attributes
256
256
  fill_pairs = [
257
- ["origin", "#{v_origin_x}, #{v_origin_y}"],
258
- ["position", "#{v_pos_x}, #{v_pos_y}"],
257
+ ["origin", "#{format_vml_number(v_origin_x)}, #{format_vml_number(v_origin_y)}"],
258
+ ["position", "#{format_vml_number(v_pos_x)}, #{format_vml_number(v_pos_y)}"],
259
259
  ["src", bg_url],
260
260
  ["color", bg_color],
261
261
  ["type", vml_type]
@@ -287,6 +287,13 @@ module MjmlRb
287
287
  end
288
288
  end
289
289
 
290
+ def format_vml_number(value)
291
+ number = value.to_f
292
+ return number.to_i.to_s if number == number.to_i
293
+
294
+ number.to_s.sub(/\.?0+$/, "")
295
+ end
296
+
290
297
  def vml_size_attributes(bg_size)
291
298
  case bg_size
292
299
  when "cover"
@@ -639,7 +646,9 @@ module MjmlRb
639
646
  box_width = container_px - pad_left - pad_right - border_left - border_right
640
647
 
641
648
  previous_container_width = context[:container_width]
649
+ previous_full_width_wrapper = context[:_inside_full_width_wrapper]
642
650
  context[:container_width] = "#{box_width}px"
651
+ context[:_inside_full_width_wrapper] = full_width
643
652
 
644
653
  div_attrs = {"class" => (full_width ? nil : css_class), "style" => div_style}
645
654
  inner = merge_outlook_conditionals(render_wrapped_children_wrapper(node, context, container_px, a["gap"]))
@@ -686,6 +695,7 @@ module MjmlRb
686
695
  end
687
696
  ensure
688
697
  context[:container_width] = previous_container_width if previous_container_width
698
+ context[:_inside_full_width_wrapper] = previous_full_width_wrapper
689
699
  end
690
700
 
691
701
  # Wrap each child mj-section/mj-wrapper in an Outlook conditional <tr><td>.
@@ -703,7 +713,7 @@ module MjmlRb
703
713
  child_attrs = resolved_attributes(child, context)
704
714
  child_css = child_attrs["css-class"]
705
715
  outlook_class = suffix_css_classes(child_css)
706
- td_open = %(<!--[if mso | IE]><tr><td class="#{escape_attr(outlook_class)}" width="#{container_px}px" ><![endif]-->)
716
+ td_open = %(<!--[if mso | IE]><tr><td class="#{escape_attr(outlook_class)}" width="#{container_px}" ><![endif]-->)
707
717
  td_close = %(<!--[if mso | IE]></td></tr><![endif]-->)
708
718
  child_html = with_wrapper_child_gap(context, index.zero? ? nil : gap) do
709
719
  render_node(child, context, parent: "mj-wrapper")
@@ -113,6 +113,7 @@ module MjmlRb
113
113
 
114
114
  def build_html_document(content, context)
115
115
  content = minify_outlook_conditionals(content)
116
+ content = apply_html_attributes_to_content(content, context)
116
117
  title = context[:title].to_s
117
118
  preview = context[:preview]
118
119
  head_raw = Array(context[:head_raw]).join("\n")
@@ -165,7 +166,6 @@ module MjmlRb
165
166
  </html>
166
167
  HTML
167
168
 
168
- html = apply_html_attributes(html, context)
169
169
  html = apply_inline_styles(html, context)
170
170
  html = merge_outlook_conditionals(html)
171
171
  before_doctype.empty? ? html : "#{before_doctype}\n#{html}"
@@ -307,23 +307,33 @@ module MjmlRb
307
307
  end
308
308
  end
309
309
 
310
- def apply_html_attributes(html, context)
310
+ def apply_html_attributes_to_content(content, context)
311
311
  rules = context[:html_attributes] || {}
312
- return html if rules.empty?
312
+ return content if rules.empty?
313
313
 
314
- document = Nokogiri::HTML(html)
314
+ root = html_attributes_fragment_root(content, context)
315
315
 
316
316
  rules.each do |selector, attrs|
317
317
  next if selector.empty? || attrs.empty?
318
318
 
319
- select_nodes(document, selector).each do |node|
319
+ select_nodes(root, selector).each do |node|
320
320
  attrs.each do |name, value|
321
321
  node[name] = value.to_s
322
322
  end
323
323
  end
324
324
  end
325
325
 
326
- document.to_html
326
+ root.inner_html
327
+ end
328
+
329
+ def html_attributes_fragment_root(content, context)
330
+ wrapper_attrs = {
331
+ "data-mjml-body-root" => "true",
332
+ "lang" => context[:lang],
333
+ "dir" => context[:dir]
334
+ }
335
+ fragment = Nokogiri::HTML::DocumentFragment.parse("<div#{html_attrs(wrapper_attrs)}>#{content}</div>")
336
+ fragment.at_css("div[data-mjml-body-root='true']")
327
337
  end
328
338
 
329
339
  def apply_inline_styles(html, context)
@@ -1,3 +1,3 @@
1
1
  module MjmlRb
2
- VERSION = "0.3.0".freeze
2
+ VERSION = "0.3.1".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mjml-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Andriichuk