@maizzle/framework 5.3.1 → 5.4.0-0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maizzle/framework",
3
- "version": "5.3.1",
3
+ "version": "5.4.0-0",
4
4
  "description": "Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -63,7 +63,7 @@
63
63
  "html-crush": "^6.0.19",
64
64
  "is-url-superb": "^6.1.0",
65
65
  "istextorbinary": "^9.5.0",
66
- "juice": "^10.0.1",
66
+ "juice": "next",
67
67
  "lodash-es": "^4.17.21",
68
68
  "morphdom": "^2.7.4",
69
69
  "ora": "^8.1.0",
@@ -1,9 +1,7 @@
1
1
  import juice from 'juice'
2
2
  import postcss from 'postcss'
3
3
  import get from 'lodash-es/get.js'
4
- import has from 'lodash-es/has.js'
5
4
  import * as cheerio from 'cheerio/slim'
6
- import remove from 'lodash-es/remove.js'
7
5
  import { render } from 'posthtml-render'
8
6
  import isEmpty from 'lodash-es/isEmpty.js'
9
7
  import safeParser from 'postcss-safe-parser'
@@ -29,26 +27,7 @@ export async function inline(html = '', options = {}) {
29
27
 
30
28
  options.removeInlinedSelectors = get(options, 'removeInlinedSelectors', true)
31
29
  options.preferUnitlessValues = get(options, 'preferUnitlessValues', true)
32
- options.safelist = new Set([
33
- ...get(options, 'safelist', []),
34
- ...[
35
- '.body', // Gmail
36
- '.gmail', // Gmail
37
- '.apple', // Apple Mail
38
- '.ios', // Mail on iOS
39
- '.ox-', // Open-Xchange
40
- '.outlook', // Outlook.com
41
- '[data-ogs', // Outlook.com
42
- '.bloop_container', // Airmail
43
- '.Singleton', // Apple Mail 10
44
- '.unused', // Notes 8
45
- '.moz-text-html', // Thunderbird
46
- '.mail-detail-content', // Comcast, Libero webmail
47
- 'edo', // Edison (all)
48
- '#msgBody', // Freenet uses #msgBody
49
- '.lang' // Fenced code blocks
50
- ],
51
- ])
30
+ options.preservedSelectors = get(options, 'safelist', [])
52
31
 
53
32
  juice.styleToAttribute = get(options, 'styleToAttribute', {})
54
33
  juice.applyWidthAttributes = get(options, 'applyWidthAttributes', true)
@@ -86,7 +65,7 @@ export async function inline(html = '', options = {}) {
86
65
  */
87
66
  $.root().html(
88
67
  css
89
- ? juice.inlineContent($.html(), css, { removeStyleTags, ...options })
68
+ ? juice($.html(), { extraCss: css, removeStyleTags, ...options })
90
69
  : juice($.html(), { removeStyleTags, ...options })
91
70
  )
92
71
 
@@ -110,9 +89,7 @@ export async function inline(html = '', options = {}) {
110
89
  /**
111
90
  * Remove inlined selectors from the HTML
112
91
  */
113
- // For each style tag
114
92
  $('style:not([embed])').each((_i, el) => {
115
- // Parse the CSS
116
93
  const { root } = postcss()
117
94
  .process(
118
95
  $(el).html(),
@@ -122,27 +99,9 @@ export async function inline(html = '', options = {}) {
122
99
  }
123
100
  )
124
101
 
125
- // Precompile a single regex to match any substring from the preservedClasses set
126
- const combinedPattern = Array.from(options.safelist)
127
- .map(pattern => pattern.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')) // Escape special regex chars
128
- .join('|') // Combine all patterns into a single regex pattern with 'OR' (|)
129
-
130
- const combinedRegex = new RegExp(combinedPattern)
131
-
132
102
  const selectors = new Set()
133
103
 
134
- // Preserve selectors in at rules
135
- root.walkAtRules(rule => {
136
- if (['media', 'supports'].includes(rule.name)) {
137
- rule.walkRules(rule => {
138
- options.safelist.add(rule.selector)
139
- })
140
- }
141
- })
142
-
143
- // For each rule in the CSS block we're parsing
144
104
  root.walkRules(rule => {
145
- // Create a set of selectors
146
105
  const { selector } = rule
147
106
 
148
107
  // Add the selector to the set as long as it's not a pseudo selector
@@ -152,30 +111,11 @@ export async function inline(html = '', options = {}) {
152
111
  prop: get(rule.nodes[0], 'prop')
153
112
  })
154
113
  }
155
- // Preserve pseudo selectors
156
- else {
157
- options.safelist.add(selector)
158
- }
159
-
160
- if (options.removeInlinedSelectors) {
161
- // Remove the rule in the <style> tag as long as it's not a preserved class
162
- if (!options.safelist.has(selector) && !combinedRegex.test(selector)) {
163
- rule.remove()
164
- }
165
-
166
- // Update the <style> tag contents
167
- $(el).html(root.toString())
168
- }
169
114
  })
170
115
 
171
116
  /**
172
- * CSS optimizations
173
- *
174
- * 1. `preferUnitlessValues` - Replace unit values with `0` where possible
175
- * 2. `removeInlinedSelectors` - Remove inlined selectors from the HTML
117
+ * `preferUnitlessValues` - replace unit values with `0` where possible
176
118
  */
177
-
178
- // Loop over selectors that we found in the <style> tags
179
119
  selectors.forEach(({ name, prop }) => {
180
120
  const elements = $(name).get()
181
121
 
@@ -187,7 +127,6 @@ export async function inline(html = '', options = {}) {
187
127
  const styleAttr = $(el).attr('style')
188
128
  const inlineStyles = {}
189
129
 
190
- // 1. `preferUnitlessValues`
191
130
  if (styleAttr) {
192
131
  try {
193
132
  const root = postcss.parse(`* { ${styleAttr} }`)
@@ -215,29 +154,6 @@ export async function inline(html = '', options = {}) {
215
154
  )
216
155
  } catch {}
217
156
  }
218
-
219
- // Get the classes from the element's class attribute
220
- const classes = $(el).attr('class')
221
-
222
- // 2. `removeInlinedSelectors`
223
- if (options.removeInlinedSelectors && classes) {
224
- const classList = classes.split(' ')
225
-
226
- // If the class has been inlined in the style attribute...
227
- if (has(inlineStyles, prop)) {
228
- // Try to remove the classes that have been inlined
229
- if (![...options.safelist].some(item => item.includes(name))) {
230
- remove(classList, classToRemove => name.includes(classToRemove))
231
- }
232
-
233
- // Update the class list on the element with the new classes
234
- if (classList.length > 0) {
235
- $(el).attr('class', classList.join(' '))
236
- } else {
237
- $(el).removeAttr('class')
238
- }
239
- }
240
- }
241
157
  })
242
158
  }
243
159
  })