@maizzle/framework 5.0.2 → 5.0.4

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.0.2",
3
+ "version": "5.0.4",
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",
@@ -9,7 +9,6 @@ import isEmpty from 'lodash-es/isEmpty.js'
9
9
  import safeParser from 'postcss-safe-parser'
10
10
  import isObject from 'lodash-es/isObject.js'
11
11
  import { parser as parse } from 'posthtml-parser'
12
- import { parseCSSRule } from '../utils/string.js'
13
12
  import { useAttributeSizes } from './useAttributeSizes.js'
14
13
  import { getPosthtmlOptions } from '../posthtml/defaultConfig.js'
15
14
 
@@ -143,15 +142,18 @@ export async function inline(html = '', options = {}) {
143
142
 
144
143
  // For each rule in the CSS block we're parsing
145
144
  root.walkRules(rule => {
145
+ // Create a set of selectors
146
146
  const { selector } = rule
147
147
 
148
- selectors.add({
149
- name: selector,
150
- prop: get(rule.nodes[0], 'prop')
151
- })
152
-
148
+ // Add the selector to the set as long as it's not a pseudo selector
149
+ if (!/(^|[^\\])::?[\w-]+/.test(selector)) {
150
+ selectors.add({
151
+ name: selector,
152
+ prop: get(rule.nodes[0], 'prop')
153
+ })
154
+ }
153
155
  // Preserve pseudo selectors
154
- if ([':hover', ':active', ':focus', ':visited', ':link', ':before', ':after'].some(i => selector.includes(i))) {
156
+ else {
155
157
  options.safelist.add(selector)
156
158
  }
157
159
 
@@ -166,6 +168,13 @@ export async function inline(html = '', options = {}) {
166
168
  }
167
169
  })
168
170
 
171
+ /**
172
+ * CSS optimizations
173
+ *
174
+ * 1. `preferUnitlessValues` - Replace unit values with `0` where possible
175
+ * 2. `removeInlinedSelectors` - Remove inlined selectors from the HTML
176
+ */
177
+
169
178
  // Loop over selectors that we found in the <style> tags
170
179
  selectors.forEach(({ name, prop }) => {
171
180
  const elements = $(name).get()
@@ -176,11 +185,16 @@ export async function inline(html = '', options = {}) {
176
185
  elements.forEach((el) => {
177
186
  // Get a `property|value` list from the inline style attribute
178
187
  const styleAttr = $(el).attr('style')
179
- let inlineStyles = {}
188
+ const inlineStyles = {}
180
189
 
190
+ // 1. `preferUnitlessValues`
181
191
  if (styleAttr) {
182
- inlineStyles = styleAttr.split(';').reduce((acc, i) => {
183
- let { property, value } = parseCSSRule(i)
192
+ // Parse the inline styles using postcss
193
+ const root = postcss.parse(`* { ${styleAttr} }`)
194
+
195
+ root.first.each((decl) => {
196
+ const property = decl.prop
197
+ let value = decl.value
184
198
 
185
199
  if (value && options.preferUnitlessValues) {
186
200
  value = value.replace(
@@ -190,11 +204,9 @@ export async function inline(html = '', options = {}) {
190
204
  }
191
205
 
192
206
  if (property) {
193
- acc[property] = value
207
+ inlineStyles[property] = value
194
208
  }
195
-
196
- return acc
197
- }, {})
209
+ })
198
210
 
199
211
  // Update the element's style attribute with the new value
200
212
  $(el).attr(
@@ -206,6 +218,7 @@ export async function inline(html = '', options = {}) {
206
218
  // Get the classes from the element's class attribute
207
219
  const classes = $(el).attr('class')
208
220
 
221
+ // 2. `removeInlinedSelectors`
209
222
  if (options.removeInlinedSelectors && classes) {
210
223
  const classList = classes.split(' ')
211
224
 
@@ -174,27 +174,6 @@ export function getFileExtensionsFromPattern(pattern) {
174
174
  return ['html'] // No recognizable extension pattern, default to 'html'
175
175
  }
176
176
 
177
- export function parseCSSRule(rule) {
178
- // Step 1: Trim the input string
179
- rule = rule.trim()
180
-
181
- // Step 2: Find the index of the first colon
182
- const colonIndex = rule.indexOf(':')
183
-
184
- // Step 3: Extract property and value parts
185
- if (colonIndex === -1) {
186
- return {
187
- property: '',
188
- value: ''
189
- }
190
- }
191
-
192
- const property = rule.slice(0, colonIndex).trim()
193
- const value = rule.slice(colonIndex + 1).trim()
194
-
195
- return { property, value }
196
- }
197
-
198
177
  /**
199
178
  * Normalize a string by removing extra whitespace.
200
179
  *