mjml-rb 0.2.4 → 0.2.6
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 +4 -4
- data/README.md +7 -7
- data/lib/mjml-rb/components/breakpoint.rb +5 -0
- data/lib/mjml-rb/components/head.rb +59 -0
- data/lib/mjml-rb/components/html_attributes.rb +23 -1
- data/lib/mjml-rb/components/raw.rb +4 -0
- data/lib/mjml-rb/renderer.rb +5 -65
- data/lib/mjml-rb/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f213ff60765d24bebf6bd96742274aa2eed792452c0176b8de29bfbdbc8506cb
|
|
4
|
+
data.tar.gz: 7859582b4ecf32f4f5018cbea4929169ebf96089fc3ae2c973672c015e190ed3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 28114bad8d00b9260fb49945b9383b18be09b588ba6474458d20b2b1b4f0986ca44cc8a20487e230931e4985e21f135878cbd938aff5f95fb156cd8af623558c
|
|
7
|
+
data.tar.gz: 6992e280ea3c63a02b3715ffaf53e0944d123a1a17be5e3237fedc6a4a66baf44863ba14a822a1d931e0beddba8ded6d14d02271957b8afcdee4ab78df9dbda0
|
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` |
|
|
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
|
-
| `mj-all` |
|
|
66
|
+
| `mj-all` | migrated | Implemented through `attributes.rb` with npm-style global default attribute precedence. |
|
|
67
67
|
| `mj-class` | migrated | Supported through `attributes.rb`, including nested per-tag descendant defaults. |
|
|
68
|
-
| `mj-title` |
|
|
69
|
-
| `mj-preview` |
|
|
70
|
-
| `mj-style` |
|
|
71
|
-
| `mj-font` |
|
|
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. |
|
|
@@ -76,6 +76,6 @@ The table below tracks current JS-to-Ruby migration status for MJML components i
|
|
|
76
76
|
| `mj-selector` | migrated | Supported as the selector container for `mj-html-attribute` rules. |
|
|
77
77
|
| `mj-html-attribute` | migrated | Supported for injecting custom HTML attributes into matched rendered nodes. |
|
|
78
78
|
|
|
79
|
-
Remaining top-level migration work is mainly `mj-carousel` and `mj-carousel-image
|
|
79
|
+
Remaining top-level migration work is mainly `mj-carousel` and `mj-carousel-image`.
|
|
80
80
|
|
|
81
81
|
TODO: `mj-html-attributes` currently uses `Nokogiri` to parse rendered HTML and apply CSS-selector-based attribute injections. Rewrite this path to avoid `Nokogiri` if we want to keep the runtime dependency surface minimal.
|
|
@@ -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
|
data/lib/mjml-rb/renderer.rb
CHANGED
|
@@ -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
|
-
|
|
75
|
-
|
|
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))
|
data/lib/mjml-rb/version.rb
CHANGED
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
|
+
version: 0.2.6
|
|
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
|