mjml-rb 0.2.4 → 0.2.5

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: 4bb6667d87d9376e60199a47e987e10cfb496be78c4bd549f71fa049c2618aff
4
- data.tar.gz: 98f63a171ea6a2d5b1dd6212c86a13cdd2eabf71c1ab9f12d15f8c83a04e30d2
3
+ metadata.gz: 288347d54c01e4a6c60ed76c71ed988cb74f8a88eed9de7d7fb06cf740bd79e5
4
+ data.tar.gz: 369dc21e8dd16555318abfd6bc4cfa28649e4bbcce10a8a9b9b6f0613c87fb90
5
5
  SHA512:
6
- metadata.gz: 33c9d050ef8ebd560b92a513391957c9fd2ebea43023d3977c5c06fe154bc7eef1bf6646abbf555dcbf6f53d4900461cceb89daaf0e3b2be36d3e08cec445b38
7
- data.tar.gz: 839a5ddbe4448b2c86b9b015d59468e8f2553a78432cf6371bdb6d061c850568850bde0316fd9be6ac548a0bc17715900d233cd1538cff03785383f29d960240
6
+ metadata.gz: 3bf2de79918958b9d4cd9b66191e6b2b52c5494d97d961a129d2d9db7193690a8616063c1168245ced32c736a24caca07aeda5945747d44a972568894b79fd01
7
+ data.tar.gz: e4e56ca10989e917fb5b4d14b4d090099b1003c97599d0dd57330a35c09981dee2424568e00a1b144050d5c564da86e5bf713cbf098065585a985b78a48a2039
data/README.md CHANGED
@@ -61,14 +61,14 @@ The table below tracks current JS-to-Ruby migration status for MJML components i
61
61
  | `mj-navbar` | migrated | Implemented in `navbar.rb`, including `base-url` propagation and breakpoint-aware hamburger CSS. |
62
62
  | `mj-navbar-link` | migrated | Implemented in `navbar.rb` as an ending-tag navbar child component. |
63
63
  | `mj-raw` | migrated | Implemented in `raw.rb`, including head insertion and top-level `position="file-start"` output before the doctype. |
64
- | `mj-head` | partial | Core tags such as `mj-title`, `mj-preview`, `mj-style`, `mj-font`, and `mj-attributes` are supported. |
64
+ | `mj-head` | migrated | Implemented in `head.rb` and dispatches supported head children through component handlers. |
65
65
  | `mj-attributes` | migrated | Implemented in `attributes.rb`, including npm-style `mj-class` descendant defaults. |
66
66
  | `mj-all` | partial | Supported through `mj-attributes`. |
67
67
  | `mj-class` | migrated | Supported through `attributes.rb`, including nested per-tag descendant defaults. |
68
- | `mj-title` | partial | Supported through head context. |
69
- | `mj-preview` | partial | Supported through head context. |
70
- | `mj-style` | partial | Supported, including inline CSS application. |
71
- | `mj-font` | partial | Supported for font link injection. |
68
+ | `mj-title` | migrated | Implemented in `head.rb`. |
69
+ | `mj-preview` | migrated | Implemented in `head.rb`. |
70
+ | `mj-style` | migrated | Implemented in `head.rb`, including inline-style registration. |
71
+ | `mj-font` | migrated | Implemented in `head.rb`. |
72
72
  | `mj-carousel` | not migrated | Declared in dependency rules but no renderer implementation yet. |
73
73
  | `mj-carousel-image` | not migrated | Declared in dependency rules but no renderer implementation yet. |
74
74
  | `mj-breakpoint` | migrated | Supported in `mj-head` and used to control desktop column media-query widths. |
@@ -20,6 +20,11 @@ module MjmlRb
20
20
  def render(tag_name:, node:, context:, attrs:, parent:)
21
21
  ""
22
22
  end
23
+
24
+ def handle_head(node, context)
25
+ width = node.attributes["width"].to_s.strip
26
+ context[:breakpoint] = width unless width.empty?
27
+ end
23
28
  end
24
29
  end
25
30
  end
@@ -0,0 +1,59 @@
1
+ require_relative "base"
2
+
3
+ module MjmlRb
4
+ module Components
5
+ class Head < Base
6
+ TAGS = %w[mj-head mj-title mj-preview mj-style mj-font].freeze
7
+
8
+ ALLOWED_ATTRIBUTES = {
9
+ "mj-style" => {
10
+ "inline" => "string"
11
+ },
12
+ "mj-font" => {
13
+ "name" => "string",
14
+ "href" => "string"
15
+ }
16
+ }.freeze
17
+
18
+ class << self
19
+ def allowed_attributes_for(tag_name)
20
+ ALLOWED_ATTRIBUTES[tag_name] || {}
21
+ end
22
+
23
+ def allowed_attributes
24
+ {}
25
+ end
26
+ end
27
+
28
+ def tags
29
+ TAGS
30
+ end
31
+
32
+ def render(tag_name:, node:, context:, attrs:, parent:)
33
+ ""
34
+ end
35
+
36
+ def handle_head(node, context)
37
+ case node.tag_name
38
+ when "mj-head"
39
+ node.element_children.each do |child|
40
+ component = renderer.send(:component_for, child.tag_name)
41
+ component.handle_head(child, context) if component&.respond_to?(:handle_head)
42
+ end
43
+ when "mj-title"
44
+ context[:title] = raw_inner(node).strip
45
+ when "mj-preview"
46
+ context[:preview] = raw_inner(node).strip
47
+ when "mj-style"
48
+ css = raw_inner(node)
49
+ context[:head_styles] << css
50
+ context[:inline_styles] << css if node.attributes["inline"] == "inline"
51
+ when "mj-font"
52
+ name = node.attributes["name"]
53
+ href = node.attributes["href"]
54
+ context[:fonts][name] = href if name && href
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -3,7 +3,7 @@ require_relative "base"
3
3
  module MjmlRb
4
4
  module Components
5
5
  class HtmlAttributes < Base
6
- TAGS = %w[mj-selector mj-html-attribute].freeze
6
+ TAGS = %w[mj-html-attributes mj-selector mj-html-attribute].freeze
7
7
 
8
8
  ALLOWED_ATTRIBUTES = {
9
9
  "mj-selector" => {
@@ -27,6 +27,28 @@ module MjmlRb
27
27
  def render(tag_name:, node:, context:, attrs:, parent:)
28
28
  render_children(node, context, parent: parent)
29
29
  end
30
+
31
+ def handle_head(node, context)
32
+ node.element_children.each do |selector|
33
+ next unless selector.tag_name == "mj-selector"
34
+
35
+ path = selector.attributes["path"].to_s.strip
36
+ next if path.empty?
37
+
38
+ custom_attrs = selector.element_children.each_with_object({}) do |child, memo|
39
+ next unless child.tag_name == "mj-html-attribute"
40
+
41
+ name = child.attributes["name"].to_s.strip
42
+ next if name.empty?
43
+
44
+ memo[name] = child.text_content
45
+ end
46
+ next if custom_attrs.empty?
47
+
48
+ context[:html_attributes][path] ||= {}
49
+ context[:html_attributes][path].merge!(custom_attrs)
50
+ end
51
+ end
30
52
  end
31
53
  end
32
54
  end
@@ -16,6 +16,10 @@ module MjmlRb
16
16
  def render(tag_name:, node:, context:, attrs:, parent:)
17
17
  raw_inner(node)
18
18
  end
19
+
20
+ def handle_head(node, context)
21
+ context[:head_raw] << raw_inner(node)
22
+ end
19
23
  end
20
24
  end
21
25
  end
@@ -5,6 +5,7 @@ require_relative "components/attributes"
5
5
  require_relative "components/body"
6
6
  require_relative "components/breakpoint"
7
7
  require_relative "components/button"
8
+ require_relative "components/head"
8
9
  require_relative "components/hero"
9
10
  require_relative "components/image"
10
11
  require_relative "components/navbar"
@@ -71,76 +72,13 @@ module MjmlRb
71
72
  return context unless head
72
73
 
73
74
  head.element_children.each do |node|
74
- case node.tag_name
75
- when "mj-title"
76
- context[:title] = node.text_content.strip
77
- when "mj-preview"
78
- context[:preview] = node.text_content.strip
79
- when "mj-style"
80
- context[:head_styles] << node.text_content
81
- context[:inline_styles] << node.text_content if node.attributes["inline"] == "inline"
82
- when "mj-font"
83
- name = node.attributes["name"]
84
- href = node.attributes["href"]
85
- context[:fonts][name] = href if name && href
86
- when "mj-breakpoint"
87
- width = node.attributes["width"].to_s.strip
88
- context[:breakpoint] = width unless width.empty?
89
- when "mj-attributes"
90
- if (component = component_for(node.tag_name)) && component.respond_to?(:handle_head)
91
- component.handle_head(node, context)
92
- else
93
- absorb_attribute_node(node, context)
94
- end
95
- when "mj-html-attributes"
96
- absorb_html_attributes_node(node, context)
97
- when "mj-raw"
98
- context[:head_raw] << raw_inner(node)
99
- end
75
+ component = component_for(node.tag_name)
76
+ component.handle_head(node, context) if component&.respond_to?(:handle_head)
100
77
  end
101
78
 
102
79
  context
103
80
  end
104
81
 
105
- def absorb_attribute_node(attributes_node, context)
106
- attributes_node.element_children.each do |child|
107
- case child.tag_name
108
- when "mj-all"
109
- context[:global_defaults].merge!(child.attributes)
110
- when "mj-class"
111
- name = child.attributes["name"]
112
- next unless name
113
-
114
- context[:classes][name] = child.attributes.reject { |k, _| k == "name" }
115
- else
116
- context[:tag_defaults][child.tag_name] ||= {}
117
- context[:tag_defaults][child.tag_name].merge!(child.attributes)
118
- end
119
- end
120
- end
121
-
122
- def absorb_html_attributes_node(html_attributes_node, context)
123
- html_attributes_node.element_children.each do |selector|
124
- next unless selector.tag_name == "mj-selector"
125
-
126
- path = selector.attributes["path"].to_s.strip
127
- next if path.empty?
128
-
129
- custom_attrs = selector.element_children.each_with_object({}) do |child, memo|
130
- next unless child.tag_name == "mj-html-attribute"
131
-
132
- name = child.attributes["name"].to_s.strip
133
- next if name.empty?
134
-
135
- memo[name] = child.text_content
136
- end
137
- next if custom_attrs.empty?
138
-
139
- context[:html_attributes][path] ||= {}
140
- context[:html_attributes][path].merge!(custom_attrs)
141
- end
142
- end
143
-
144
82
  def build_html_document(content, context)
145
83
  title = context[:title].to_s
146
84
  preview = context[:preview]
@@ -433,6 +371,7 @@ module MjmlRb
433
371
  registry = {}
434
372
  # Register component classes here as they are implemented.
435
373
  register_component(registry, Components::Body.new(self))
374
+ register_component(registry, Components::Head.new(self))
436
375
  register_component(registry, Components::Attributes.new(self))
437
376
  register_component(registry, Components::Breakpoint.new(self))
438
377
  register_component(registry, Components::Accordion.new(self))
@@ -443,6 +382,7 @@ module MjmlRb
443
382
  register_component(registry, Components::Raw.new(self))
444
383
  register_component(registry, Components::Text.new(self))
445
384
  register_component(registry, Components::Divider.new(self))
385
+ register_component(registry, Components::HtmlAttributes.new(self))
446
386
  register_component(registry, Components::Table.new(self))
447
387
  register_component(registry, Components::Social.new(self))
448
388
  register_component(registry, Components::Section.new(self))
@@ -1,3 +1,3 @@
1
1
  module MjmlRb
2
- VERSION = "0.2.4".freeze
2
+ VERSION = "0.2.5".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.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrei Andriichuk
@@ -61,6 +61,7 @@ files:
61
61
  - lib/mjml-rb/components/button.rb
62
62
  - lib/mjml-rb/components/column.rb
63
63
  - lib/mjml-rb/components/divider.rb
64
+ - lib/mjml-rb/components/head.rb
64
65
  - lib/mjml-rb/components/hero.rb
65
66
  - lib/mjml-rb/components/html_attributes.rb
66
67
  - lib/mjml-rb/components/image.rb