@maizzle/framework 4.2.4 → 4.3.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/README.md +5 -5
- package/package.json +8 -4
- package/src/generators/tailwindcss.js +1 -1
- package/src/transformers/filters/index.js +4 -0
- package/src/transformers/index.js +1 -1
- package/src/transformers/inlineCss.js +8 -3
- package/src/transformers/removeInlineSizes.js +2 -3
- package/src/transformers/removeUnusedCss.js +6 -2
- package/.editorconfig +0 -9
- package/.github/CONTRIBUTING.md +0 -33
- package/.github/ISSUE_TEMPLATE.md +0 -2
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -9
- package/.github/dependabot.yml +0 -11
- package/.github/media/logo-dark.svg +0 -1
- package/.github/media/logo-light.svg +0 -1
- package/.github/workflows/nodejs.yml +0 -28
- package/test/expected/posthtml/component.html +0 -13
- package/test/expected/transformers/base-url.html +0 -99
- package/test/expected/transformers/filters.html +0 -81
- package/test/fixtures/basic.html +0 -9
- package/test/fixtures/posthtml/component.html +0 -19
- package/test/fixtures/transformers/base-url.html +0 -101
- package/test/fixtures/transformers/filters.html +0 -87
- package/test/stubs/assets/foo.bar +0 -1
- package/test/stubs/breaking/bad.html +0 -5
- package/test/stubs/components/component.html +0 -5
- package/test/stubs/config/config.js +0 -10
- package/test/stubs/config/config.maizzle-ci.js +0 -10
- package/test/stubs/data.json +0 -14
- package/test/stubs/empty/empty.html +0 -0
- package/test/stubs/events/before-create.html +0 -1
- package/test/stubs/layouts/basic.html +0 -1
- package/test/stubs/layouts/full.html +0 -12
- package/test/stubs/layouts/template.html +0 -5
- package/test/stubs/main.css +0 -5
- package/test/stubs/plaintext/front-matter.html +0 -9
- package/test/stubs/plaintext/plaintext.html +0 -5
- package/test/stubs/post.css +0 -6
- package/test/stubs/tailwind/content-source.html +0 -1
- package/test/stubs/tailwind/tailwind.css +0 -3
- package/test/stubs/template.html +0 -10
- package/test/stubs/templates/1.html +0 -1
- package/test/stubs/templates/2.html +0 -1
- package/test/stubs/templates/2.test +0 -1
- package/test/test-config.js +0 -19
- package/test/test-misc.js +0 -8
- package/test/test-postcss.js +0 -8
- package/test/test-posthtml.js +0 -112
- package/test/test-tailwindcss.js +0 -115
- package/test/test-todisk.js +0 -493
- package/test/test-tostring.js +0 -164
- package/test/test-transformers.js +0 -626
- package/xo.config.js +0 -22
|
@@ -1,626 +0,0 @@
|
|
|
1
|
-
const test = require('ava')
|
|
2
|
-
const Maizzle = require('../src')
|
|
3
|
-
|
|
4
|
-
const path = require('path')
|
|
5
|
-
const fs = require('fs')
|
|
6
|
-
|
|
7
|
-
const readFile = (dir, filename) => fs.promises
|
|
8
|
-
.readFile(path.join(__dirname, dir, `${filename}.html`), 'utf8')
|
|
9
|
-
.then(html => html.trim())
|
|
10
|
-
|
|
11
|
-
const fixture = file => readFile('fixtures/transformers', file)
|
|
12
|
-
const expected = file => readFile('expected/transformers', file)
|
|
13
|
-
|
|
14
|
-
test('remove inline sizes', async t => {
|
|
15
|
-
const options = {
|
|
16
|
-
width: ['TD'],
|
|
17
|
-
height: ['TD']
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const html = await Maizzle.removeInlineSizes('<td style="width:100%;height:10px;">test</td>', options)
|
|
21
|
-
|
|
22
|
-
t.is(html, '<td style="">test</td>')
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
test('remove inline background-color', async t => {
|
|
26
|
-
const html = await Maizzle.removeInlineBgColor(`<td style="background-color: red" bgcolor="red">test</td>`)
|
|
27
|
-
const html2 = await Maizzle.removeInlineBgColor(
|
|
28
|
-
`<td style="background-color: red" bgcolor="red">test</td>`,
|
|
29
|
-
{
|
|
30
|
-
inlineCSS: {
|
|
31
|
-
preferBgColorAttribute: true
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
t.is(html, '<td style="" bgcolor="red">test</td>')
|
|
37
|
-
t.is(html2, '<td style="" bgcolor="red">test</td>')
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
test('remove inline background-color (with tags)', async t => {
|
|
41
|
-
const html = await Maizzle.removeInlineBgColor(
|
|
42
|
-
`<table style="background-color: red"><tr><td style="background-color: red">test</td></tr></table>`,
|
|
43
|
-
['table']
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
t.is(html, '<table style="" bgcolor="red"><tr><td style="background-color: red">test</td></tr></table>')
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
test('inline CSS', async t => {
|
|
50
|
-
const html = `<div class="foo bar">test</div>`
|
|
51
|
-
const css = `
|
|
52
|
-
.foo {color: red}
|
|
53
|
-
.bar {cursor: pointer}
|
|
54
|
-
`
|
|
55
|
-
|
|
56
|
-
const result = await Maizzle.inlineCSS(html, {
|
|
57
|
-
customCSS: css,
|
|
58
|
-
removeStyleTags: false,
|
|
59
|
-
styleToAttribute: {
|
|
60
|
-
'text-align': 'align'
|
|
61
|
-
},
|
|
62
|
-
applyWidthAttributes: ['TABLE'],
|
|
63
|
-
applyHeightAttributes: ['TD'],
|
|
64
|
-
mergeLonghand: ['div'],
|
|
65
|
-
excludedProperties: ['cursor'],
|
|
66
|
-
codeBlocks: {
|
|
67
|
-
RB: {
|
|
68
|
-
start: '<%',
|
|
69
|
-
end: '%>'
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
t.is(result, '<div class="foo bar" style="color: red;">test</div>')
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
test('inline CSS (disabled)', async t => {
|
|
78
|
-
const html = `<div class="foo">test</div>`
|
|
79
|
-
const css = `.foo {color: red}`
|
|
80
|
-
|
|
81
|
-
const result = await Maizzle.inlineCSS(html, {inlineCSS: false, customCSS: css})
|
|
82
|
-
|
|
83
|
-
t.is(result, '<div class="foo">test</div>')
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
test('remove unused CSS', async t => {
|
|
87
|
-
const html = `<!DOCTYPE html>
|
|
88
|
-
<html>
|
|
89
|
-
<head>
|
|
90
|
-
<style>
|
|
91
|
-
.foo {color: red}
|
|
92
|
-
.bar-baz {color: blue}
|
|
93
|
-
.baz {color: white}
|
|
94
|
-
</style>
|
|
95
|
-
</head>
|
|
96
|
-
<body>
|
|
97
|
-
<div class="foo {{ test }}">test div with some text</div>
|
|
98
|
-
</body>
|
|
99
|
-
</html>`
|
|
100
|
-
|
|
101
|
-
const result1 = `<!DOCTYPE html>
|
|
102
|
-
<html>
|
|
103
|
-
<head>
|
|
104
|
-
<style>
|
|
105
|
-
.foo {color: red}
|
|
106
|
-
.bar-baz {color: blue}
|
|
107
|
-
</style>
|
|
108
|
-
</head>
|
|
109
|
-
<body>
|
|
110
|
-
<div class="foo {{ test }}">test div with some text</div>
|
|
111
|
-
</body>
|
|
112
|
-
</html>`
|
|
113
|
-
|
|
114
|
-
const result2 = `<!DOCTYPE html>
|
|
115
|
-
<html>
|
|
116
|
-
<head>
|
|
117
|
-
<style>
|
|
118
|
-
.foo {color: red}
|
|
119
|
-
</style>
|
|
120
|
-
</head>
|
|
121
|
-
<body>
|
|
122
|
-
<div class="foo {{ test }}">test div with some text</div>
|
|
123
|
-
</body>
|
|
124
|
-
</html>`
|
|
125
|
-
|
|
126
|
-
const enabled = await Maizzle.removeUnusedCSS(html, true)
|
|
127
|
-
const disabled = await Maizzle.removeUnusedCSS(html, {removeUnusedCSS: false})
|
|
128
|
-
const withOptions = await Maizzle.removeUnusedCSS(html, {whitelist: ['.bar*']})
|
|
129
|
-
|
|
130
|
-
t.is(enabled, result2)
|
|
131
|
-
t.is(disabled, html)
|
|
132
|
-
t.is(withOptions, result1)
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
test('remove unused CSS (disabled)', async t => {
|
|
136
|
-
const html = `<!DOCTYPE html>
|
|
137
|
-
<html>
|
|
138
|
-
<head>
|
|
139
|
-
<style>
|
|
140
|
-
.foo {color: red}
|
|
141
|
-
</style>
|
|
142
|
-
</head>
|
|
143
|
-
<body>
|
|
144
|
-
<div class="foo">test div with some text</div>
|
|
145
|
-
</body>
|
|
146
|
-
</html>`
|
|
147
|
-
|
|
148
|
-
const result = `<!DOCTYPE html>
|
|
149
|
-
<html>
|
|
150
|
-
<head>
|
|
151
|
-
<style>
|
|
152
|
-
.foo {color: red}
|
|
153
|
-
</style>
|
|
154
|
-
</head>
|
|
155
|
-
<body>
|
|
156
|
-
<div class="foo">test div with some text</div>
|
|
157
|
-
</body>
|
|
158
|
-
</html>`
|
|
159
|
-
|
|
160
|
-
const disabled = await Maizzle.removeUnusedCSS(html, {removeUnusedCSS: false})
|
|
161
|
-
const unset = await Maizzle.removeUnusedCSS(html)
|
|
162
|
-
|
|
163
|
-
t.is(disabled, result)
|
|
164
|
-
t.is(unset, result)
|
|
165
|
-
})
|
|
166
|
-
|
|
167
|
-
test('remove attributes', async t => {
|
|
168
|
-
const html = await Maizzle.removeAttributes(
|
|
169
|
-
`<div style="" remove keep role="article" delete-me="with-regex"></div>`,
|
|
170
|
-
[
|
|
171
|
-
{name: 'role', value: 'article'},
|
|
172
|
-
'remove',
|
|
173
|
-
{name: 'delete-me', value: /^with/}
|
|
174
|
-
]
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
t.is(html, '<div keep></div>')
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
test('extra attributes', async t => {
|
|
181
|
-
const html = await Maizzle.applyExtraAttributes('<div />', {div: {role: 'article'}})
|
|
182
|
-
|
|
183
|
-
t.is(html, '<div role="article"></div>')
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
test('extra attributes (disabled)', async t => {
|
|
187
|
-
const html = await Maizzle.applyExtraAttributes('<img src="example.jpg">', {extraAttributes: false})
|
|
188
|
-
|
|
189
|
-
t.is(html, '<img src="example.jpg">')
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
test('base URL (string)', async t => {
|
|
193
|
-
const source = await fixture('base-url')
|
|
194
|
-
const html = await Maizzle.applyBaseUrl(source, 'https://example.com/')
|
|
195
|
-
|
|
196
|
-
t.is(html, await expected('base-url'))
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
test('base URL (object)', async t => {
|
|
200
|
-
const source = await fixture('base-url')
|
|
201
|
-
const html = await Maizzle.applyBaseUrl(source, {
|
|
202
|
-
url: 'https://example.com/',
|
|
203
|
-
allTags: true,
|
|
204
|
-
styleTag: true,
|
|
205
|
-
inlineCss: true
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
t.is(html, await expected('base-url'))
|
|
209
|
-
})
|
|
210
|
-
|
|
211
|
-
test('prettify', async t => {
|
|
212
|
-
// `prettify: true`
|
|
213
|
-
const html2 = await Maizzle.prettify('<div><p>test</p></div>', true)
|
|
214
|
-
|
|
215
|
-
// With custom object config
|
|
216
|
-
// eslint-disable-next-line
|
|
217
|
-
const html = await Maizzle.prettify('<div><p>test</p></div>', {indent_inner_result: true})
|
|
218
|
-
|
|
219
|
-
// No config
|
|
220
|
-
const html3 = await Maizzle.prettify('<div><p>test</p></div>')
|
|
221
|
-
|
|
222
|
-
// Empty object config
|
|
223
|
-
const html4 = await Maizzle.prettify('<div><p>test</p></div>', {})
|
|
224
|
-
|
|
225
|
-
t.is(html, '<div>\n <p>test</p>\n</div>')
|
|
226
|
-
t.is(html2, '<div>\n <p>test</p>\n</div>')
|
|
227
|
-
t.is(html3, '<div><p>test</p></div>')
|
|
228
|
-
t.is(html4, '<div><p>test</p></div>')
|
|
229
|
-
})
|
|
230
|
-
|
|
231
|
-
test('minify', async t => {
|
|
232
|
-
const html = await Maizzle.minify('<div>\n\n<p>\n\ntest</p></div>', {lineLengthLimit: 10})
|
|
233
|
-
|
|
234
|
-
t.is(html, '<div><p>\ntest</p>\n</div>')
|
|
235
|
-
})
|
|
236
|
-
|
|
237
|
-
test('minify (disabled)', async t => {
|
|
238
|
-
const html = await Maizzle.minify('<div>\n\n<p>\n\ntest</p></div>', {minify: false})
|
|
239
|
-
|
|
240
|
-
t.is(html, '<div>\n\n<p>\n\ntest</p></div>')
|
|
241
|
-
})
|
|
242
|
-
|
|
243
|
-
test('replace strings', async t => {
|
|
244
|
-
const html = await Maizzle.replaceStrings('initial text', {initial: 'updated'})
|
|
245
|
-
|
|
246
|
-
t.is(html, 'updated text')
|
|
247
|
-
})
|
|
248
|
-
|
|
249
|
-
test('safe class names', async t => {
|
|
250
|
-
const html = await Maizzle.safeClassNames('<div class="sm:text-left w-1.5">foo</div>', {'.': '_dot_'})
|
|
251
|
-
|
|
252
|
-
t.is(html, '<div class="sm-text-left w-1_dot_5">foo</div>')
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
test('safe class names (disabled)', async t => {
|
|
256
|
-
const html = await Maizzle.safeClassNames('<div class="sm:text-left">foo</div>', {safeClassNames: false})
|
|
257
|
-
|
|
258
|
-
t.is(html, '<div class="sm:text-left">foo</div>')
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
test('six digit hex', async t => {
|
|
262
|
-
const html = await Maizzle.ensureSixHEX(
|
|
263
|
-
`
|
|
264
|
-
<div bgcolor="#000" style="color: #fff; background-color: #000">This should not change: #ffc</div>
|
|
265
|
-
<font color="#fff">Text</font>
|
|
266
|
-
`)
|
|
267
|
-
|
|
268
|
-
t.is(
|
|
269
|
-
html.trim(),
|
|
270
|
-
`
|
|
271
|
-
<div bgcolor="#000000" style="color: #fff; background-color: #000">This should not change: #ffc</div>
|
|
272
|
-
<font color="#ffffff">Text</font>
|
|
273
|
-
`.trim()
|
|
274
|
-
)
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
test('six digit hex (disabled)', async t => {
|
|
278
|
-
const html = await Maizzle.ensureSixHEX('<td style="color: #ffc" bgcolor="#000"></td>', {sixHex: false})
|
|
279
|
-
|
|
280
|
-
t.is(html, '<td style="color: #ffc" bgcolor="#000"></td>')
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
test('filters (default)', async t => {
|
|
284
|
-
const source = await fixture('filters')
|
|
285
|
-
const html = await Maizzle.withFilters(source)
|
|
286
|
-
|
|
287
|
-
t.is(html, await expected('filters'))
|
|
288
|
-
})
|
|
289
|
-
|
|
290
|
-
test('filters (tailwindcss)', async t => {
|
|
291
|
-
const html = await Maizzle.withFilters(
|
|
292
|
-
`<style tailwindcss>
|
|
293
|
-
div {
|
|
294
|
-
@apply hidden;
|
|
295
|
-
}
|
|
296
|
-
</style>`
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
t.true(html.replace(/\s/g, '').includes(`div{display:none}`))
|
|
300
|
-
})
|
|
301
|
-
|
|
302
|
-
test('filters (postcss)', async t => {
|
|
303
|
-
const html = await Maizzle.withFilters(
|
|
304
|
-
`<style postcss>
|
|
305
|
-
div {
|
|
306
|
-
margin-top: 1px;
|
|
307
|
-
margin-right: 2px;
|
|
308
|
-
margin-bottom: 3px;
|
|
309
|
-
margin-left: 4px;
|
|
310
|
-
}
|
|
311
|
-
</style>`
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
t.is(html.replace(/\n {2,}/g, ''), '<style>div {margin: 1px 2px 3px 4px;}</style>')
|
|
315
|
-
})
|
|
316
|
-
|
|
317
|
-
test('url parameters', async t => {
|
|
318
|
-
const simple = await Maizzle.addURLParams(
|
|
319
|
-
`<a href="https://example.com">test</a>
|
|
320
|
-
<link href="https://foo.bar">`,
|
|
321
|
-
{
|
|
322
|
-
bar: 'baz',
|
|
323
|
-
qix: 'qux'
|
|
324
|
-
}
|
|
325
|
-
)
|
|
326
|
-
|
|
327
|
-
const withOptions = await Maizzle.addURLParams(
|
|
328
|
-
`<a href="example.com">test</a>
|
|
329
|
-
<link href="https://foo.bar">`,
|
|
330
|
-
{
|
|
331
|
-
_options: {
|
|
332
|
-
tags: ['a[href*="example"]'],
|
|
333
|
-
strict: false,
|
|
334
|
-
qs: {
|
|
335
|
-
encode: true
|
|
336
|
-
}
|
|
337
|
-
},
|
|
338
|
-
foo: '@Bar@',
|
|
339
|
-
bar: 'baz'
|
|
340
|
-
}
|
|
341
|
-
)
|
|
342
|
-
|
|
343
|
-
t.is(simple, `<a href="https://example.com?bar=baz&qix=qux">test</a>
|
|
344
|
-
<link href="https://foo.bar">`)
|
|
345
|
-
|
|
346
|
-
t.is(withOptions, `<a href="example.com?bar=baz&foo=%40Bar%40">test</a>
|
|
347
|
-
<link href="https://foo.bar">`)
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
test('attribute to style', async t => {
|
|
351
|
-
const html = `<table width="100%" height="600" align="left" bgcolor="#FFFFFF" background="https://example.com/image.jpg">
|
|
352
|
-
<tr>
|
|
353
|
-
<td align="center" valign="top"></td>
|
|
354
|
-
</tr>
|
|
355
|
-
</table>`
|
|
356
|
-
|
|
357
|
-
const expected = `<table width="100%" height="600" align="left" bgcolor="#FFFFFF" background="https://example.com/image.jpg" style="width: 100%; height: 600px; float: left; background-color: #FFFFFF; background-image: url('https://example.com/image.jpg')">
|
|
358
|
-
<tr style="">
|
|
359
|
-
<td align="center" valign="top" style="text-align: center; vertical-align: top"></td>
|
|
360
|
-
</tr>
|
|
361
|
-
</table>`
|
|
362
|
-
|
|
363
|
-
const html2 = `<table align="center">
|
|
364
|
-
<tr>
|
|
365
|
-
<td></td>
|
|
366
|
-
</tr>
|
|
367
|
-
</table>`
|
|
368
|
-
|
|
369
|
-
const expected2 = `<table align="center" style="margin-left: auto; margin-right: auto">
|
|
370
|
-
<tr style="">
|
|
371
|
-
<td style=""></td>
|
|
372
|
-
</tr>
|
|
373
|
-
</table>`
|
|
374
|
-
|
|
375
|
-
const withArray = await Maizzle.attributeToStyle(html, ['width', 'height', 'bgcolor', 'background', 'align', 'valign'])
|
|
376
|
-
const withOptionBoolean = await Maizzle.attributeToStyle(html2, {inlineCSS: {attributeToStyle: true}})
|
|
377
|
-
const withOptionArray = await Maizzle.attributeToStyle(html2, {inlineCSS: {attributeToStyle: ['align']}})
|
|
378
|
-
|
|
379
|
-
t.is(withArray, expected)
|
|
380
|
-
t.is(withOptionBoolean, expected2)
|
|
381
|
-
t.is(withOptionArray, expected2)
|
|
382
|
-
})
|
|
383
|
-
|
|
384
|
-
test('prevent widows', async t => {
|
|
385
|
-
const html = await Maizzle.preventWidows(`
|
|
386
|
-
<!--[if mso]>
|
|
387
|
-
<p>A paragraph inside an Outlook MSO comment</p>
|
|
388
|
-
<![endif]-->
|
|
389
|
-
<div>Text following an MSO comment</div>
|
|
390
|
-
`)
|
|
391
|
-
|
|
392
|
-
t.is(html, `
|
|
393
|
-
<!--[if mso]>
|
|
394
|
-
<p>A paragraph inside an Outlook MSO comment</p>
|
|
395
|
-
<![endif]-->
|
|
396
|
-
<div>Text following an MSO comment</div>
|
|
397
|
-
`)
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
test('prevent widows (with options)', async t => {
|
|
401
|
-
const html = await Maizzle.preventWidows(`
|
|
402
|
-
<div no-widows>
|
|
403
|
-
<p>Text following an MSO comment</p>
|
|
404
|
-
<!--[if mso 15]>
|
|
405
|
-
<p>A paragraph inside an Outlook MSO comment</p>
|
|
406
|
-
<p>unescaped {{{ foo }}}</p>
|
|
407
|
-
<![endif]-->
|
|
408
|
-
<p>expression {{ foo }}</p>
|
|
409
|
-
<!--[if !mso]><!-->
|
|
410
|
-
<div>All Outlooks will ignore this</div>
|
|
411
|
-
<!--<![endif]-->
|
|
412
|
-
<p>unescaped {{{ foo }}}</p>
|
|
413
|
-
</div>
|
|
414
|
-
<p>Should not remove widows here</p>
|
|
415
|
-
`, {
|
|
416
|
-
attrName: 'no-widows',
|
|
417
|
-
minWordCount: 3,
|
|
418
|
-
ignore: [
|
|
419
|
-
{
|
|
420
|
-
heads: 'foo',
|
|
421
|
-
tails: 'bar'
|
|
422
|
-
}
|
|
423
|
-
]
|
|
424
|
-
})
|
|
425
|
-
|
|
426
|
-
t.is(html, `
|
|
427
|
-
<div>
|
|
428
|
-
<p>Text following an MSO comment</p>
|
|
429
|
-
<!--[if mso 15]>
|
|
430
|
-
<p>A paragraph inside an Outlook MSO comment</p>
|
|
431
|
-
<p>unescaped {{{ foo }}}</p>
|
|
432
|
-
<![endif]-->
|
|
433
|
-
<p>expression {{ foo }}</p>
|
|
434
|
-
<!--[if !mso]><!-->
|
|
435
|
-
<div>All Outlooks will ignore this</div>
|
|
436
|
-
<!--<![endif]-->
|
|
437
|
-
<p>unescaped {{{ foo }}}</p>
|
|
438
|
-
</div>
|
|
439
|
-
<p>Should not remove widows here</p>
|
|
440
|
-
`)
|
|
441
|
-
})
|
|
442
|
-
|
|
443
|
-
test('markdown (disabled)', async t => {
|
|
444
|
-
const html = await Maizzle.markdown('> a quote', {markdown: false})
|
|
445
|
-
|
|
446
|
-
t.is(html, '> a quote')
|
|
447
|
-
})
|
|
448
|
-
|
|
449
|
-
test('remove inlined selectors', async t => {
|
|
450
|
-
const html = `<!DOCTYPE html>
|
|
451
|
-
<html>
|
|
452
|
-
<head>
|
|
453
|
-
<style>
|
|
454
|
-
img {
|
|
455
|
-
border: 0;
|
|
456
|
-
vertical-align: middle
|
|
457
|
-
}
|
|
458
|
-
.hover-text-blue:hover {
|
|
459
|
-
color: #00a8ff;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
.m-0 {margin: 0}
|
|
463
|
-
|
|
464
|
-
.mb-4 {margin-bottom: 16px}
|
|
465
|
-
|
|
466
|
-
.mt-0 {margin-top: 0}
|
|
467
|
-
|
|
468
|
-
.remove {color: red}
|
|
469
|
-
|
|
470
|
-
[data-ogsc] .hidden {display: none}
|
|
471
|
-
|
|
472
|
-
#keepId {float:none}
|
|
473
|
-
|
|
474
|
-
.foo-class {
|
|
475
|
-
/* COMMENT */
|
|
476
|
-
color: red;
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
.ignore {
|
|
480
|
-
display: inline-block;
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
@media (max-width: 600px) {
|
|
484
|
-
.ignore {color: blue}
|
|
485
|
-
}
|
|
486
|
-
</style>
|
|
487
|
-
<style>
|
|
488
|
-
.keep {margin: 0}
|
|
489
|
-
</style>
|
|
490
|
-
</head>
|
|
491
|
-
<body>
|
|
492
|
-
<div no-value id="keepId" class="remove keep ignore foo-class" style="color: red; display: inline">
|
|
493
|
-
<h1 class="m-0 mb-4 mt-0 hover-text-blue" style="margin: 0 0 16px;">Title</h1>
|
|
494
|
-
<img src="https://example.com/image.jpg" style="border: 0; vertical-align: middle">
|
|
495
|
-
<div id="keepId" class="remove keep ignore" style="color: red; display: inline">text</div>
|
|
496
|
-
</div>
|
|
497
|
-
</body>
|
|
498
|
-
</html>`
|
|
499
|
-
|
|
500
|
-
const expectedHTML = `<!DOCTYPE html>
|
|
501
|
-
<html>
|
|
502
|
-
<head>
|
|
503
|
-
<style>.hover-text-blue:hover {
|
|
504
|
-
color: #00a8ff;
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
[data-ogsc] .hidden {display: none}
|
|
508
|
-
|
|
509
|
-
#keepId {float:none}
|
|
510
|
-
|
|
511
|
-
.foo-class {
|
|
512
|
-
/* COMMENT */
|
|
513
|
-
color: red;
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
@media (max-width: 600px) {
|
|
517
|
-
.ignore {color: blue}
|
|
518
|
-
}</style>
|
|
519
|
-
<style>.keep {margin: 0}</style>
|
|
520
|
-
</head>
|
|
521
|
-
<body>
|
|
522
|
-
<div no-value id="keepId" class="keep foo-class" style="color: red; display: inline">
|
|
523
|
-
<h1 class="hover-text-blue" style="margin: 0 0 16px">Title</h1>
|
|
524
|
-
<img src="https://example.com/image.jpg" style="border: 0; vertical-align: middle">
|
|
525
|
-
<div id="keepId" class="keep" style="color: red; display: inline">text</div>
|
|
526
|
-
</div>
|
|
527
|
-
</body>
|
|
528
|
-
</html>`
|
|
529
|
-
|
|
530
|
-
const html2 = `<!DOCTYPE html>
|
|
531
|
-
<html>
|
|
532
|
-
<head><style>
|
|
533
|
-
img {
|
|
534
|
-
border: 0;
|
|
535
|
-
vertical-align: middle
|
|
536
|
-
}
|
|
537
|
-
</style></head>
|
|
538
|
-
<body>
|
|
539
|
-
<img src="https://example.com/image.jpg" style="border: 0; vertical-align: middle">
|
|
540
|
-
</body>
|
|
541
|
-
</html>`
|
|
542
|
-
|
|
543
|
-
const expectedNoEmptyStyleTags = `<!DOCTYPE html>
|
|
544
|
-
<html>
|
|
545
|
-
<head></head>
|
|
546
|
-
<body>
|
|
547
|
-
<img src="https://example.com/image.jpg" style="border: 0; vertical-align: middle">
|
|
548
|
-
</body>
|
|
549
|
-
</html>`
|
|
550
|
-
|
|
551
|
-
const basic = await Maizzle.removeInlinedClasses(html)
|
|
552
|
-
const noEmptyStyle = await Maizzle.removeInlinedClasses(html2)
|
|
553
|
-
|
|
554
|
-
const withPostHTMLOptions = await Maizzle.removeInlinedClasses(html, {
|
|
555
|
-
build: {
|
|
556
|
-
posthtml: {
|
|
557
|
-
options: {
|
|
558
|
-
recognizeNoValueAttribute: true
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
})
|
|
563
|
-
|
|
564
|
-
t.is(basic, expectedHTML)
|
|
565
|
-
t.is(withPostHTMLOptions, expectedHTML)
|
|
566
|
-
t.is(noEmptyStyle, expectedNoEmptyStyleTags)
|
|
567
|
-
})
|
|
568
|
-
|
|
569
|
-
test('remove inlined selectors (disabled)', async t => {
|
|
570
|
-
const html = `<!DOCTYPE html>
|
|
571
|
-
<html>
|
|
572
|
-
<head>
|
|
573
|
-
<style>
|
|
574
|
-
.remove {color: red}
|
|
575
|
-
</style>
|
|
576
|
-
</head>
|
|
577
|
-
<body>
|
|
578
|
-
<div class="remove" style="color: red"></div>
|
|
579
|
-
</body>
|
|
580
|
-
</html>`
|
|
581
|
-
|
|
582
|
-
const expected = `<!DOCTYPE html>
|
|
583
|
-
<html>
|
|
584
|
-
<head>
|
|
585
|
-
<style>
|
|
586
|
-
.remove {color: red}
|
|
587
|
-
</style>
|
|
588
|
-
</head>
|
|
589
|
-
<body>
|
|
590
|
-
<div class="remove" style="color: red"></div>
|
|
591
|
-
</body>
|
|
592
|
-
</html>`
|
|
593
|
-
|
|
594
|
-
const result = await Maizzle.removeInlinedClasses(html, {removeInlinedClasses: false})
|
|
595
|
-
|
|
596
|
-
t.is(result, expected)
|
|
597
|
-
})
|
|
598
|
-
|
|
599
|
-
test('shorthand inline css', async t => {
|
|
600
|
-
const html = `
|
|
601
|
-
<div style="padding-left: 2px; padding-right: 2px; padding-top: 2px; padding-bottom: 2px;">padding</div>
|
|
602
|
-
<div style="margin-left: 2px; margin-right: 2px; margin-top: 2px; margin-bottom: 2px;">margin</div>
|
|
603
|
-
<div style="border-width: 1px; border-style: solid; border-color: #000;">border</div>
|
|
604
|
-
<p style="border-width: 1px; border-style: solid; border-color: #000;">border</p>
|
|
605
|
-
`
|
|
606
|
-
|
|
607
|
-
const expect = `
|
|
608
|
-
<div style="padding: 2px;">padding</div>
|
|
609
|
-
<div style="margin: 2px;">margin</div>
|
|
610
|
-
<div style="border: 1px solid #000;">border</div>
|
|
611
|
-
<p style="border: 1px solid #000;">border</p>
|
|
612
|
-
`
|
|
613
|
-
|
|
614
|
-
const expect2 = `
|
|
615
|
-
<div style="padding: 2px;">padding</div>
|
|
616
|
-
<div style="margin: 2px;">margin</div>
|
|
617
|
-
<div style="border: 1px solid #000;">border</div>
|
|
618
|
-
<p style="border-width: 1px; border-style: solid; border-color: #000;">border</p>
|
|
619
|
-
`
|
|
620
|
-
|
|
621
|
-
const result = await Maizzle.shorthandInlineCSS(html)
|
|
622
|
-
const result2 = await Maizzle.shorthandInlineCSS(html, {tags: ['div']})
|
|
623
|
-
|
|
624
|
-
t.is(result, expect)
|
|
625
|
-
t.is(result2, expect2)
|
|
626
|
-
})
|
package/xo.config.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
space: true,
|
|
3
|
-
rules: {
|
|
4
|
-
semi: 0,
|
|
5
|
-
complexity: 0,
|
|
6
|
-
'max-params': 0,
|
|
7
|
-
'no-lonely-if': 0,
|
|
8
|
-
'unicorn/no-reduce': 0,
|
|
9
|
-
'import/extensions': 0,
|
|
10
|
-
'operator-linebreak': 0,
|
|
11
|
-
'max-nested-callbacks': 0,
|
|
12
|
-
'unicorn/filename-case': 0,
|
|
13
|
-
'unicorn/no-hex-escape': 0,
|
|
14
|
-
'unicorn/prefer-ternary': 0,
|
|
15
|
-
'unicorn/string-content': 0,
|
|
16
|
-
'unicorn/no-array-for-each': 0,
|
|
17
|
-
'unicorn/prefer-array-find': 0,
|
|
18
|
-
'promise/prefer-await-to-then': 0,
|
|
19
|
-
'unicorn/no-abusive-eslint-disable': 0,
|
|
20
|
-
quotes: ['error', 'single', {allowTemplateLiterals: true}]
|
|
21
|
-
}
|
|
22
|
-
}
|