@maizzle/framework 4.8.7 → 5.0.0-beta.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/bin/maizzle +3 -1
- package/package.json +65 -58
- package/src/commands/build.js +244 -19
- package/src/commands/serve.js +2 -197
- package/src/generators/plaintext.js +192 -91
- package/src/generators/render.js +128 -0
- package/src/index.js +46 -14
- package/src/{generators/posthtml → posthtml}/defaultComponentsConfig.js +6 -4
- package/src/{generators/posthtml → posthtml}/defaultConfig.js +1 -1
- package/src/posthtml/index.js +74 -0
- package/src/posthtml/plugins/expandLinkTag.js +36 -0
- package/src/server/client.js +181 -0
- package/src/server/index.js +383 -0
- package/src/server/routes/hmr.js +24 -0
- package/src/server/routes/index.js +38 -0
- package/src/server/views/error.html +83 -0
- package/src/server/views/index.html +24 -0
- package/src/server/websockets.js +27 -0
- package/src/transformers/addAttributes.js +30 -0
- package/src/transformers/attributeToStyle.js +30 -36
- package/src/transformers/baseUrl.js +52 -23
- package/src/transformers/comb.js +51 -0
- package/src/transformers/core.js +20 -0
- package/src/transformers/filters/defaultFilters.js +90 -70
- package/src/transformers/filters/index.js +14 -78
- package/src/transformers/index.js +268 -63
- package/src/transformers/inline.js +240 -0
- package/src/transformers/markdown.js +13 -14
- package/src/transformers/minify.js +21 -16
- package/src/transformers/posthtmlMso.js +13 -8
- package/src/transformers/prettify.js +16 -15
- package/src/transformers/preventWidows.js +32 -26
- package/src/transformers/removeAttributes.js +17 -17
- package/src/transformers/replaceStrings.js +30 -9
- package/src/transformers/safeClassNames.js +24 -24
- package/src/transformers/shorthandCss.js +22 -0
- package/src/transformers/sixHex.js +15 -15
- package/src/transformers/urlParameters.js +18 -16
- package/src/transformers/useAttributeSizes.js +65 -0
- package/src/utils/getConfigByFilePath.js +124 -0
- package/src/utils/node.js +68 -0
- package/src/utils/string.js +117 -0
- package/types/build.d.ts +117 -57
- package/types/components.d.ts +130 -112
- package/types/config.d.ts +454 -242
- package/types/css/inline.d.ts +234 -0
- package/types/css/purge.d.ts +125 -0
- package/types/events.d.ts +5 -105
- package/types/index.d.ts +148 -116
- package/types/markdown.d.ts +20 -18
- package/types/minify.d.ts +122 -120
- package/types/plaintext.d.ts +46 -52
- package/types/posthtml.d.ts +103 -136
- package/types/render.d.ts +0 -117
- package/types/urlParameters.d.ts +21 -20
- package/types/widowWords.d.ts +9 -7
- package/src/functions/plaintext.js +0 -5
- package/src/functions/render.js +0 -5
- package/src/generators/config.js +0 -52
- package/src/generators/output/index.js +0 -4
- package/src/generators/output/to-disk.js +0 -254
- package/src/generators/output/to-string.js +0 -73
- package/src/generators/postcss.js +0 -23
- package/src/generators/posthtml/index.js +0 -75
- package/src/generators/tailwindcss.js +0 -157
- package/src/transformers/extraAttributes.js +0 -33
- package/src/transformers/inlineCss.js +0 -42
- package/src/transformers/removeInlineBackgroundColor.js +0 -56
- package/src/transformers/removeInlineSizes.js +0 -43
- package/src/transformers/removeInlinedSelectors.js +0 -100
- package/src/transformers/removeUnusedCss.js +0 -48
- package/src/transformers/shorthandInlineCSS.js +0 -26
- package/src/utils/helpers.js +0 -13
- package/types/baseUrl.d.ts +0 -79
- package/types/fetch.d.ts +0 -143
- package/types/inlineCss.d.ts +0 -207
- package/types/layouts.d.ts +0 -39
- package/types/removeUnusedCss.d.ts +0 -115
- package/types/tailwind.d.ts +0 -22
- package/types/templates.d.ts +0 -181
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Maizzle | Templates</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<each loop="items, index in templates">
|
|
10
|
+
<div>
|
|
11
|
+
<h2>{{ index }}</h2>
|
|
12
|
+
<ul>
|
|
13
|
+
<each loop="item in items">
|
|
14
|
+
<li>
|
|
15
|
+
<a href="{{ item.href }}">
|
|
16
|
+
{{ item.base }}
|
|
17
|
+
</a>
|
|
18
|
+
</li>
|
|
19
|
+
</each>
|
|
20
|
+
</ul>
|
|
21
|
+
</div>
|
|
22
|
+
</each>
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import WebSocket from 'ws'
|
|
2
|
+
|
|
3
|
+
export function initWebSockets(wss, options = {}) {
|
|
4
|
+
options.shouldScroll = options.shouldScroll || false
|
|
5
|
+
options.useHmr = options.useHmr || true
|
|
6
|
+
|
|
7
|
+
wss.on('connection', ws => {
|
|
8
|
+
// Handle incoming messages from the client
|
|
9
|
+
ws.on('message', message => {
|
|
10
|
+
const parsedMessage = JSON.parse(message)
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Broadcast message back to all connected clients
|
|
14
|
+
* We use it to send the scroll position back so other clients can follow
|
|
15
|
+
*/
|
|
16
|
+
wss.clients.forEach(client => {
|
|
17
|
+
if (client.readyState === WebSocket.OPEN) {
|
|
18
|
+
client.send(JSON.stringify({
|
|
19
|
+
...parsedMessage,
|
|
20
|
+
scrollSync: options.shouldScroll,
|
|
21
|
+
hmr: options.useHmr
|
|
22
|
+
}))
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import posthtml from 'posthtml'
|
|
2
|
+
import { defu as merge } from 'defu'
|
|
3
|
+
import posthtmlConfig from '../posthtml/defaultConfig.js'
|
|
4
|
+
import addAttributesPlugin from 'posthtml-extra-attributes'
|
|
5
|
+
|
|
6
|
+
export default function posthtmlPlugin(attributes = {}) {
|
|
7
|
+
const defaultAttributes = {
|
|
8
|
+
table: {
|
|
9
|
+
cellpadding: 0,
|
|
10
|
+
cellspacing: 0,
|
|
11
|
+
role: 'none'
|
|
12
|
+
},
|
|
13
|
+
img: {
|
|
14
|
+
alt: ''
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// User-defined attributes take precedence
|
|
19
|
+
attributes = merge(attributes, defaultAttributes)
|
|
20
|
+
|
|
21
|
+
return addAttributesPlugin({ attributes })
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function addAttributes(html = '', attributes = {}, posthtmlOptions = {}) {
|
|
25
|
+
return posthtml([
|
|
26
|
+
posthtmlPlugin(attributes)
|
|
27
|
+
])
|
|
28
|
+
.process(html, merge(posthtmlOptions, posthtmlConfig))
|
|
29
|
+
.then(result => result.html)
|
|
30
|
+
}
|
|
@@ -1,44 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
module.exports = async (html, config = {}, direct = false) => {
|
|
14
|
-
const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
|
|
15
|
-
const attributes = get(config, 'inlineCSS.attributeToStyle', false)
|
|
16
|
-
|
|
17
|
-
if (typeof attributes === 'boolean' && attributes) {
|
|
18
|
-
return posthtml([attributesToStyle()]).process(html, posthtmlOptions).then(result => result.html)
|
|
1
|
+
import posthtml from 'posthtml'
|
|
2
|
+
import get from 'lodash-es/get.js'
|
|
3
|
+
import { defu as merge } from 'defu'
|
|
4
|
+
import keys from 'lodash-es/keys.js'
|
|
5
|
+
import forEach from 'lodash-es/forEach.js'
|
|
6
|
+
import parseAttrs from 'posthtml-attrs-parser'
|
|
7
|
+
import intersection from 'lodash-es/intersection.js'
|
|
8
|
+
import posthtmlConfig from '../posthtml/defaultConfig.js'
|
|
9
|
+
|
|
10
|
+
const posthtmlPlugin = (attributes = []) => tree => {
|
|
11
|
+
if (!Array.isArray(attributes)) {
|
|
12
|
+
return tree
|
|
19
13
|
}
|
|
20
14
|
|
|
21
|
-
if (
|
|
22
|
-
return
|
|
15
|
+
if (attributes.length === 0) {
|
|
16
|
+
return tree
|
|
23
17
|
}
|
|
24
18
|
|
|
25
|
-
if (direct) {
|
|
26
|
-
return posthtml([
|
|
27
|
-
attributesToStyle({
|
|
28
|
-
attributes: Array.isArray(config) ? config : []
|
|
29
|
-
})
|
|
30
|
-
]).process(html, posthtmlOptions).then(result => result.html)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return html
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const attributesToStyle = (options = {}) => tree => {
|
|
37
|
-
options.attributes = options.attributes || ['width', 'height', 'bgcolor', 'background', 'align', 'valign']
|
|
38
|
-
|
|
39
19
|
const process = node => {
|
|
20
|
+
if (!node.attrs) {
|
|
21
|
+
return node
|
|
22
|
+
}
|
|
23
|
+
|
|
40
24
|
const nodeAttributes = parseAttrs(node.attrs)
|
|
41
|
-
const matches = intersection(keys(nodeAttributes),
|
|
25
|
+
const matches = intersection(keys(nodeAttributes), attributes)
|
|
42
26
|
const nodeStyle = get(node.attrs, 'style')
|
|
43
27
|
const cssToInline = []
|
|
44
28
|
|
|
@@ -87,7 +71,7 @@ const attributesToStyle = (options = {}) => tree => {
|
|
|
87
71
|
}
|
|
88
72
|
})
|
|
89
73
|
|
|
90
|
-
nodeAttributes.style = nodeStyle ? `${nodeStyle} ${cssToInline.join('; ')}` : `${cssToInline.join('; ')}`
|
|
74
|
+
nodeAttributes.style = nodeStyle ? `${nodeStyle.split(';').join(';')} ${cssToInline.join('; ')}` : `${cssToInline.join('; ')}`
|
|
91
75
|
|
|
92
76
|
node.attrs = nodeAttributes.compose()
|
|
93
77
|
|
|
@@ -96,3 +80,13 @@ const attributesToStyle = (options = {}) => tree => {
|
|
|
96
80
|
|
|
97
81
|
return tree.walk(process)
|
|
98
82
|
}
|
|
83
|
+
|
|
84
|
+
export default posthtmlPlugin
|
|
85
|
+
|
|
86
|
+
export async function attributeToStyle(html = '', attributes = [], posthtmlOptions = {}) {
|
|
87
|
+
return posthtml([
|
|
88
|
+
posthtmlPlugin(attributes)
|
|
89
|
+
])
|
|
90
|
+
.process(html, merge(posthtmlOptions, posthtmlConfig))
|
|
91
|
+
.then(result => result.html)
|
|
92
|
+
}
|
|
@@ -1,41 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import posthtml from 'posthtml'
|
|
2
|
+
import isUrl from 'is-url-superb'
|
|
3
|
+
import get from 'lodash-es/get.js'
|
|
4
|
+
import { defu as merge } from 'defu'
|
|
5
|
+
import baseUrl from 'posthtml-base-url'
|
|
6
|
+
import { render } from 'posthtml-render'
|
|
7
|
+
import isEmpty from 'lodash-es/isEmpty.js'
|
|
8
|
+
import isObject from 'lodash-es/isObject.js'
|
|
9
|
+
import { parser as parse } from 'posthtml-parser'
|
|
10
|
+
import posthtmlConfig from '../posthtml/defaultConfig.js'
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
|
|
10
|
-
|
|
11
|
-
// Handle `baseUrl` as a string
|
|
12
|
+
const posthtmlPlugin = url => tree => {
|
|
13
|
+
// Handle `baseURL` as a string
|
|
12
14
|
if (typeof url === 'string' && url.length > 0) {
|
|
13
|
-
html = rewriteVMLs(
|
|
15
|
+
const html = rewriteVMLs(render(tree), url)
|
|
14
16
|
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
return baseUrl({
|
|
18
|
+
url,
|
|
19
|
+
allTags: true,
|
|
20
|
+
styleTag: true,
|
|
21
|
+
inlineCss: true
|
|
22
|
+
})(parse(html, posthtmlConfig))
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
// Handle `baseURL` as an object
|
|
23
26
|
if (isObject(url) && !isEmpty(url)) {
|
|
24
|
-
html = rewriteVMLs(
|
|
27
|
+
const html = rewriteVMLs(render(tree), get(url, 'url', ''))
|
|
28
|
+
const {
|
|
29
|
+
styleTag = true,
|
|
30
|
+
inlineCss = true,
|
|
31
|
+
allTags,
|
|
32
|
+
tags,
|
|
33
|
+
url: baseURL,
|
|
34
|
+
...posthtmlOptions
|
|
35
|
+
} = url
|
|
25
36
|
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
return baseUrl({
|
|
38
|
+
styleTag,
|
|
39
|
+
inlineCss,
|
|
40
|
+
allTags,
|
|
41
|
+
tags,
|
|
42
|
+
url: baseURL,
|
|
43
|
+
})(parse(html, merge(posthtmlConfig, posthtmlOptions)))
|
|
31
44
|
}
|
|
32
45
|
|
|
33
|
-
return
|
|
46
|
+
return tree
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default posthtmlPlugin
|
|
50
|
+
|
|
51
|
+
export async function addBaseUrl(html = '', options = {}, posthtmlOptions = {}) {
|
|
52
|
+
return posthtml([
|
|
53
|
+
posthtmlPlugin(options)
|
|
54
|
+
])
|
|
55
|
+
.process(html, merge(posthtmlOptions, posthtmlConfig))
|
|
56
|
+
.then(result => result.html)
|
|
34
57
|
}
|
|
35
58
|
|
|
36
59
|
/**
|
|
60
|
+
* Handle VML
|
|
61
|
+
*
|
|
37
62
|
* VML backgrounds must be handled with regex because
|
|
38
63
|
* they're inside HTML comments.
|
|
64
|
+
*
|
|
65
|
+
* @param {string} html The HTML content
|
|
66
|
+
* @param {string} url The base URL to prepend
|
|
67
|
+
* @returns {string} The modified HTML
|
|
39
68
|
*/
|
|
40
69
|
const rewriteVMLs = (html, url) => {
|
|
41
70
|
// Handle <v:image>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import posthtml from 'posthtml'
|
|
2
|
+
import get from 'lodash-es/get.js'
|
|
3
|
+
import { defu as merge } from 'defu'
|
|
4
|
+
import { render } from 'posthtml-render'
|
|
5
|
+
import { comb as emailComb } from 'email-comb'
|
|
6
|
+
import { parser as parse } from 'posthtml-parser'
|
|
7
|
+
import posthtmlConfig from '../posthtml/defaultConfig.js'
|
|
8
|
+
|
|
9
|
+
const posthtmlPlugin = options => tree => {
|
|
10
|
+
const defaultSafelist = [
|
|
11
|
+
'*body*', // Gmail
|
|
12
|
+
'.gmail*', // Gmail
|
|
13
|
+
'.apple*', // Apple Mail
|
|
14
|
+
'.ios*', // Mail on iOS
|
|
15
|
+
'.ox-*', // Open-Xchange
|
|
16
|
+
'.outlook*', // Outlook.com
|
|
17
|
+
'[data-ogs*', // Outlook.com
|
|
18
|
+
'.bloop_container', // Airmail
|
|
19
|
+
'.Singleton', // Apple Mail 10
|
|
20
|
+
'.unused', // Notes 8
|
|
21
|
+
'.moz-text-html', // Thunderbird
|
|
22
|
+
'.mail-detail-content', // Comcast, Libero webmail
|
|
23
|
+
'*edo*', // Edison (all)
|
|
24
|
+
'#*', // Freenet uses #msgBody
|
|
25
|
+
'.lang*' // Fenced code blocks
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
const defaultOptions = {
|
|
29
|
+
backend: [
|
|
30
|
+
{ heads: '{{', tails: '}}' },
|
|
31
|
+
{ heads: '{%', tails: '%}' },
|
|
32
|
+
],
|
|
33
|
+
whitelist: [...defaultSafelist, ...get(options, 'whitelist', [])]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
options = merge(options, defaultOptions)
|
|
37
|
+
|
|
38
|
+
const { result: html } = emailComb(render(tree), options)
|
|
39
|
+
|
|
40
|
+
return parse(html)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default posthtmlPlugin
|
|
44
|
+
|
|
45
|
+
export async function comb(html = '', options = {}, posthtmlOptions = {}) {
|
|
46
|
+
return posthtml([
|
|
47
|
+
posthtmlPlugin(options)
|
|
48
|
+
])
|
|
49
|
+
.process(html, merge(posthtmlOptions, posthtmlConfig))
|
|
50
|
+
.then(result => result.html)
|
|
51
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const posthtmlPlugin = (config = {}) => tree => {
|
|
2
|
+
const process = node => {
|
|
3
|
+
/**
|
|
4
|
+
* Remove plaintext tags when developing locally
|
|
5
|
+
*/
|
|
6
|
+
if (
|
|
7
|
+
config._dev
|
|
8
|
+
&& node.tag === 'plaintext'
|
|
9
|
+
) {
|
|
10
|
+
node.tag = false
|
|
11
|
+
node.content = ['']
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return node
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return tree.walk(process)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default posthtmlPlugin
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
const append = (content, attribute) => content + attribute
|
|
2
|
+
|
|
3
|
+
const capitalize = content => content.charAt(0).toUpperCase() + content.slice(1)
|
|
4
|
+
|
|
5
|
+
const ceil = content => Math.ceil(Number.parseFloat(content))
|
|
6
|
+
|
|
7
|
+
const divide = (content, attribute) => Number.parseFloat(content) / Number.parseFloat(attribute)
|
|
8
|
+
|
|
1
9
|
const escapeMap = {
|
|
2
10
|
'&': '&',
|
|
3
11
|
'<': '<',
|
|
@@ -5,31 +13,27 @@ const escapeMap = {
|
|
|
5
13
|
'"': '"',
|
|
6
14
|
'\'': '''
|
|
7
15
|
}
|
|
8
|
-
|
|
9
|
-
const unescapeMap = {
|
|
10
|
-
'&': '&',
|
|
11
|
-
'<': '<',
|
|
12
|
-
'>': '>',
|
|
13
|
-
'"': '"',
|
|
14
|
-
''': '\''
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const unescape = string => string.replace(/&(amp|lt|gt|#34|#39);/g, m => unescapeMap[m])
|
|
18
|
-
|
|
19
|
-
const append = (content, attribute) => content + attribute
|
|
20
|
-
const capitalize = content => content.charAt(0).toUpperCase() + content.slice(1)
|
|
21
|
-
const ceil = content => Math.ceil(Number.parseFloat(content))
|
|
22
|
-
const divide = (content, attribute) => Number.parseFloat(content) / Number.parseFloat(attribute)
|
|
16
|
+
// biome-ignore lint: not confusing
|
|
23
17
|
const escape = content => content.replace(/["&'<>]/g, m => escapeMap[m])
|
|
18
|
+
|
|
24
19
|
const escapeOnce = content => escape(unescape(content))
|
|
20
|
+
|
|
25
21
|
const floor = content => Math.floor(Number.parseFloat(content))
|
|
22
|
+
|
|
26
23
|
const lowercase = content => content.toLowerCase()
|
|
24
|
+
|
|
27
25
|
const lstrip = content => content.replace(/^\s+/, '')
|
|
26
|
+
|
|
28
27
|
const minus = (content, attribute) => Number.parseFloat(content) - Number.parseFloat(attribute)
|
|
28
|
+
|
|
29
29
|
const modulo = (content, attribute) => Number.parseFloat(content) % Number.parseFloat(attribute)
|
|
30
|
+
|
|
30
31
|
const multiply = (content, attribute) => Number.parseFloat(content) * Number.parseFloat(attribute)
|
|
32
|
+
|
|
31
33
|
const newlineToBr = content => content.replace(/\n/g, '<br>')
|
|
34
|
+
|
|
32
35
|
const plus = (content, attribute) => Number.parseFloat(content) + Number.parseFloat(attribute)
|
|
36
|
+
|
|
33
37
|
const prepend = (content, attribute) => attribute + content
|
|
34
38
|
|
|
35
39
|
const remove = (content, attribute) => {
|
|
@@ -38,6 +42,7 @@ const remove = (content, attribute) => {
|
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
const removeFirst = (content, attribute) => content.replace(attribute, '')
|
|
45
|
+
|
|
41
46
|
const replace = (content, attribute) => {
|
|
42
47
|
const [search, replace] = attribute.split('|')
|
|
43
48
|
const regex = new RegExp(search, 'g')
|
|
@@ -50,77 +55,92 @@ const replaceFirst = (content, attribute) => {
|
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
const round = content => Math.round(Number.parseFloat(content))
|
|
58
|
+
|
|
53
59
|
const rstrip = content => content.replace(/\s+$/, '')
|
|
60
|
+
|
|
54
61
|
const uppercase = content => content.toUpperCase()
|
|
62
|
+
|
|
55
63
|
const size = content => content.length
|
|
64
|
+
|
|
56
65
|
const slice = (content, attribute) => {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
const [start, end] = attribute.split(',')
|
|
67
|
+
|
|
68
|
+
if (!end && !start) {
|
|
69
|
+
return content
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!end) {
|
|
61
73
|
return content.slice(attribute)
|
|
62
74
|
}
|
|
75
|
+
|
|
76
|
+
return content.slice(start, end)
|
|
63
77
|
}
|
|
64
78
|
|
|
65
79
|
const stripNewlines = content => content.replace(/\n/g, '')
|
|
80
|
+
|
|
66
81
|
const trim = content => content.trim()
|
|
82
|
+
|
|
67
83
|
const truncate = (content, attribute) => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} catch {
|
|
74
|
-
const length = Number.parseInt(attribute, 10)
|
|
75
|
-
return content.length > length ? content.slice(0, length) + '...' : content
|
|
76
|
-
}
|
|
84
|
+
const [length, omission] = attribute.split(',')
|
|
85
|
+
|
|
86
|
+
return content && content.length > Number.parseInt(length, 10)
|
|
87
|
+
? content.slice(0, length) + (omission || '...')
|
|
88
|
+
: content // content is shorter than length required to truncate
|
|
77
89
|
}
|
|
78
90
|
|
|
79
91
|
const truncateWords = (content, attribute) => {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
const [length, omission] = attribute.split(',')
|
|
93
|
+
|
|
94
|
+
return content.split(' ')
|
|
95
|
+
.slice(0, Number.parseInt(length, 10))
|
|
96
|
+
.join(' ') + (omission || '...')
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const unescapeMap = {
|
|
100
|
+
'&': '&',
|
|
101
|
+
'<': '<',
|
|
102
|
+
'>': '>',
|
|
103
|
+
'"': '"',
|
|
104
|
+
''': '\''
|
|
87
105
|
}
|
|
106
|
+
// biome-ignore lint: not confusing
|
|
107
|
+
const unescape = string => string.replace(/&(amp|lt|gt|#34|#39);/g, m => unescapeMap[m])
|
|
88
108
|
|
|
89
|
-
// eslint-disable-next-line
|
|
90
109
|
const urlDecode = content => content.split('+').map(decodeURIComponent).join(' ')
|
|
91
|
-
|
|
110
|
+
|
|
92
111
|
const urlEncode = content => content.split(' ').map(encodeURIComponent).join('+')
|
|
93
112
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
113
|
+
export const filters = {
|
|
114
|
+
append,
|
|
115
|
+
capitalize,
|
|
116
|
+
ceil,
|
|
117
|
+
'divide-by': divide,
|
|
118
|
+
escape,
|
|
119
|
+
'escape-once': escapeOnce,
|
|
120
|
+
floor,
|
|
121
|
+
lowercase,
|
|
122
|
+
lstrip,
|
|
123
|
+
minus,
|
|
124
|
+
modulo,
|
|
125
|
+
multiply,
|
|
126
|
+
'newline-to-br': newlineToBr,
|
|
127
|
+
plus,
|
|
128
|
+
prepend,
|
|
129
|
+
remove,
|
|
130
|
+
'remove-first': removeFirst,
|
|
131
|
+
replace,
|
|
132
|
+
'replace-first': replaceFirst,
|
|
133
|
+
round,
|
|
134
|
+
rstrip,
|
|
135
|
+
uppercase,
|
|
136
|
+
size,
|
|
137
|
+
slice,
|
|
138
|
+
'strip-newlines': stripNewlines,
|
|
139
|
+
times: multiply,
|
|
140
|
+
trim,
|
|
141
|
+
truncate,
|
|
142
|
+
'truncate-words': truncateWords,
|
|
143
|
+
'url-decode': urlDecode,
|
|
144
|
+
'url-encode': urlEncode,
|
|
145
|
+
unescape
|
|
146
|
+
}
|
|
@@ -1,83 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const Tailwind = require('../../generators/tailwindcss')
|
|
7
|
-
const safeClassNames = require('posthtml-safe-class-names')
|
|
8
|
-
const defaultConfig = require('../../generators/posthtml/defaultConfig')
|
|
1
|
+
import posthtml from 'posthtml'
|
|
2
|
+
import { defu as merge } from 'defu'
|
|
3
|
+
import posthtmlContent from 'posthtml-content'
|
|
4
|
+
import posthtmlConfig from '../../posthtml/defaultConfig.js'
|
|
5
|
+
import { filters as defaultFilters } from './defaultFilters.js'
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return html
|
|
13
|
-
}
|
|
7
|
+
export default function posthtmlPlugin(filters = {}) {
|
|
8
|
+
filters = merge(defaultFilters, filters)
|
|
14
9
|
|
|
15
|
-
|
|
16
|
-
merge(defaultFilters, config) :
|
|
17
|
-
merge(defaultFilters, get(config, 'filters', {}))
|
|
18
|
-
|
|
19
|
-
const posthtmlOptions = merge(defaultConfig, get(config, 'build.posthtml.options', {}))
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Compile CSS in <style {post|tailwind}css> tags
|
|
23
|
-
*/
|
|
24
|
-
const maizzleConfig = omit(config, ['build.tailwind.css', 'css'])
|
|
25
|
-
|
|
26
|
-
filters.postcss = css => PostCSS.process(css, maizzleConfig)
|
|
27
|
-
filters.tailwindcss = css => Tailwind.compile({
|
|
28
|
-
css,
|
|
29
|
-
html,
|
|
30
|
-
config: merge({
|
|
31
|
-
build: {
|
|
32
|
-
tailwind: {
|
|
33
|
-
config: get(config, 'build.tailwind.config', 'tailwind.config.js')
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}, maizzleConfig)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
const posthtmlPlugins = [
|
|
40
|
-
styleDataEmbed(),
|
|
41
|
-
posthtmlContent(filters)
|
|
42
|
-
]
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Run `safeClassNames` in filters only when not when developing locally and
|
|
46
|
-
* `safeClassNames` is not explicitly disabled (set to `false`).
|
|
47
|
-
*/
|
|
48
|
-
if (get(config, 'env') !== 'local' && get(config, 'safeClassNames') !== false) {
|
|
49
|
-
posthtmlPlugins.push(safeClassNames({
|
|
50
|
-
replacements: {
|
|
51
|
-
'{': '{',
|
|
52
|
-
'}': '}'
|
|
53
|
-
}
|
|
54
|
-
}))
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return posthtml(posthtmlPlugins)
|
|
58
|
-
.process(html, posthtmlOptions)
|
|
59
|
-
.then(result => result.html)
|
|
10
|
+
return posthtmlContent(filters)
|
|
60
11
|
}
|
|
61
12
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const styleDataEmbed = () => tree => {
|
|
69
|
-
const process = node => {
|
|
70
|
-
if (
|
|
71
|
-
node.tag === 'style'
|
|
72
|
-
&& node.attrs
|
|
73
|
-
&& (has(node.attrs, 'preserve') || has(node.attrs, 'embed'))) {
|
|
74
|
-
node.attrs = {...node.attrs, 'data-embed': true}
|
|
75
|
-
node.attrs.preserve = false
|
|
76
|
-
node.attrs.embed = false
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return node
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return tree.walk(process)
|
|
13
|
+
export async function filters(html = '', filters = {}, posthtmlOptions = {}) {
|
|
14
|
+
return posthtml([
|
|
15
|
+
posthtmlPlugin(filters)
|
|
16
|
+
])
|
|
17
|
+
.process(html, merge(posthtmlOptions, posthtmlConfig))
|
|
18
|
+
.then(result => result.html)
|
|
83
19
|
}
|