Skip to content

Commit b921e38

Browse files
committed
refactor: to esm syntax
1 parent 1abaa1f commit b921e38

File tree

4 files changed

+315
-313
lines changed

4 files changed

+315
-313
lines changed

lib/index.js

Lines changed: 164 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -1,162 +1,164 @@
1-
const srcset = require('srcset')
2-
const postcss = require('postcss')
3-
const merge = require('lodash.merge')
4-
const isUrl = require('is-url-superb')
5-
const {walk} = require('posthtml/lib/api')
6-
const postcssBaseUrl = require('./plugins/postcss-baseurl.js')
7-
8-
const defaultTags = {
9-
a: {
10-
href: true,
11-
},
12-
area: {
13-
href: true,
14-
},
15-
audio: {
16-
src: true,
17-
},
18-
base: {
19-
href: true,
20-
},
21-
body: {
22-
background: true,
23-
},
24-
embed: {
25-
src: true,
26-
},
27-
iframe: {
28-
src: true,
29-
},
30-
img: {
31-
src: true,
32-
srcset: true,
33-
},
34-
input: {
35-
src: true,
36-
},
37-
link: {
38-
href: true,
39-
},
40-
script: {
41-
src: true,
42-
},
43-
source: {
44-
src: true,
45-
srcset: true,
46-
},
47-
table: {
48-
background: true,
49-
},
50-
td: {
51-
background: true,
52-
},
53-
th: {
54-
background: true,
55-
},
56-
track: {
57-
src: true,
58-
},
59-
video: {
60-
poster: true,
61-
},
62-
}
63-
64-
module.exports = (options = {}) => tree => {
65-
options.url = options.url || ''
66-
options.attributes = options.attributes || {}
67-
options.allTags = options.allTags || false
68-
options.styleTag = options.styleTag || false
69-
options.inlineCss = options.inlineCss || false
70-
options.tags = options.allTags ? merge(defaultTags, options.tags) : options.tags || {}
71-
72-
tree.walk = tree.walk || walk
73-
74-
const process = node => {
75-
// Skip if `url` was not provided
76-
if (options.url && (typeof options.url !== 'string' || options.url === '')) {
77-
return node
78-
}
79-
80-
// Skip if `options.tags` is not an array or object
81-
if (!['array', 'object'].includes(typeof options.tags)) {
82-
return node
83-
}
84-
85-
// Handle embedded stylesheets
86-
if (node.tag === 'style' && node.content && options.styleTag) {
87-
node.content = postcss([
88-
postcssBaseUrl({
89-
base: options.url,
90-
})
91-
])
92-
.process(node.content.join('').trim())
93-
.css
94-
}
95-
96-
// Handle style attribute
97-
if (node.attrs && node.attrs.style && options.inlineCss) {
98-
node.attrs.style = prependUrl(node.attrs.style, options.url)
99-
}
100-
101-
// Handle defined HTML attributes
102-
Object.entries(options.attributes).forEach(([attribute, value]) => {
103-
if (node.attrs && node.attrs[attribute]) {
104-
handleSingleValueAttributes(node, attribute, value)
105-
}
106-
})
107-
108-
// Handle defined HTML tags
109-
const tags = Array.isArray(options.tags) ?
110-
Object.entries(defaultTags).filter(([tag]) => options.tags.includes(tag)) :
111-
Object.entries(options.tags)
112-
113-
tags.forEach(([tag, attributes]) => {
114-
if (node.tag !== tag) {
115-
return node
116-
}
117-
118-
// Handle tag attributes
119-
Object.entries(attributes).forEach(([attribute, value]) => {
120-
if (node.attrs && node.attrs[attribute]) {
121-
// Handle "single-value" attributes
122-
if (['href', 'src', 'poster', 'background'].includes(attribute)) {
123-
handleSingleValueAttributes(node, attribute, value)
124-
}
125-
126-
// Handle `srcset` attribute
127-
if (attribute === 'srcset') {
128-
const parsed = srcset.parse(node.attrs[attribute])
129-
130-
parsed.map(p => {
131-
if (!isUrl(p.url)) {
132-
p.url = typeof value === 'boolean' ? options.url + p.url : value + p.url
133-
}
134-
135-
return p
136-
})
137-
138-
node.attrs[attribute] = srcset.stringify(parsed)
139-
}
140-
}
141-
})
142-
})
143-
144-
// Return the node
145-
return node
146-
}
147-
148-
const handleSingleValueAttributes = (node, attribute, value) => {
149-
if (isUrl(node.attrs[attribute])) {
150-
return node
151-
}
152-
153-
node.attrs[attribute] = typeof value === 'boolean' ? options.url + node.attrs[attribute] : value + node.attrs[attribute]
154-
}
155-
156-
const prependUrl = (value, url) => {
157-
const {css} = postcss([postcssBaseUrl({base: url})]).process(`div { ${value} }`)
158-
return css.replace(/div {\s|\s}$/gm, '')
159-
}
160-
161-
return tree.walk(process)
162-
}
1+
import srcset from 'srcset'
2+
import postcss from 'postcss'
3+
import merge from 'lodash.merge'
4+
import isUrl from 'is-url-superb'
5+
import { walk } from 'posthtml/lib/api.js'
6+
import postcssBaseUrl from './plugins/postcss-baseurl.js'
7+
8+
const defaultTags = {
9+
a: {
10+
href: true,
11+
},
12+
area: {
13+
href: true,
14+
},
15+
audio: {
16+
src: true,
17+
},
18+
base: {
19+
href: true,
20+
},
21+
body: {
22+
background: true,
23+
},
24+
embed: {
25+
src: true,
26+
},
27+
iframe: {
28+
src: true,
29+
},
30+
img: {
31+
src: true,
32+
srcset: true,
33+
},
34+
input: {
35+
src: true,
36+
},
37+
link: {
38+
href: true,
39+
},
40+
script: {
41+
src: true,
42+
},
43+
source: {
44+
src: true,
45+
srcset: true,
46+
},
47+
table: {
48+
background: true,
49+
},
50+
td: {
51+
background: true,
52+
},
53+
th: {
54+
background: true,
55+
},
56+
track: {
57+
src: true,
58+
},
59+
video: {
60+
poster: true,
61+
},
62+
}
63+
64+
const plugin = (options = {}) => tree => {
65+
options.url = options.url || ''
66+
options.attributes = options.attributes || {}
67+
options.allTags = options.allTags || false
68+
options.styleTag = options.styleTag || false
69+
options.inlineCss = options.inlineCss || false
70+
options.tags = options.allTags ? merge(defaultTags, options.tags) : options.tags || {}
71+
72+
tree.walk = tree.walk || walk
73+
74+
const process = node => {
75+
// Skip if `url` was not provided
76+
if (options.url && (typeof options.url !== 'string' || options.url === '')) {
77+
return node
78+
}
79+
80+
// Skip if `options.tags` is not an array or object
81+
if (!['array', 'object'].includes(typeof options.tags)) {
82+
return node
83+
}
84+
85+
// Handle embedded stylesheets
86+
if (node.tag === 'style' && node.content && options.styleTag) {
87+
node.content = postcss([
88+
postcssBaseUrl({
89+
base: options.url,
90+
})
91+
])
92+
.process(node.content.join('').trim())
93+
.css
94+
}
95+
96+
// Handle style attribute
97+
if (node.attrs && node.attrs.style && options.inlineCss) {
98+
node.attrs.style = prependUrl(node.attrs.style, options.url)
99+
}
100+
101+
// Handle defined HTML attributes
102+
Object.entries(options.attributes).forEach(([attribute, value]) => {
103+
if (node.attrs && node.attrs[attribute]) {
104+
handleSingleValueAttributes(node, attribute, value)
105+
}
106+
})
107+
108+
// Handle defined HTML tags
109+
const tags = Array.isArray(options.tags) ?
110+
Object.entries(defaultTags).filter(([tag]) => options.tags.includes(tag)) :
111+
Object.entries(options.tags)
112+
113+
tags.forEach(([tag, attributes]) => {
114+
if (node.tag !== tag) {
115+
return node
116+
}
117+
118+
// Handle tag attributes
119+
Object.entries(attributes).forEach(([attribute, value]) => {
120+
if (node.attrs && node.attrs[attribute]) {
121+
// Handle "single-value" attributes
122+
if (['href', 'src', 'poster', 'background'].includes(attribute)) {
123+
handleSingleValueAttributes(node, attribute, value)
124+
}
125+
126+
// Handle `srcset` attribute
127+
if (attribute === 'srcset') {
128+
const parsed = srcset.parse(node.attrs[attribute])
129+
130+
parsed.map(p => {
131+
if (!isUrl(p.url)) {
132+
p.url = typeof value === 'boolean' ? options.url + p.url : value + p.url
133+
}
134+
135+
return p
136+
})
137+
138+
node.attrs[attribute] = srcset.stringify(parsed)
139+
}
140+
}
141+
})
142+
})
143+
144+
// Return the node
145+
return node
146+
}
147+
148+
const handleSingleValueAttributes = (node, attribute, value) => {
149+
if (isUrl(node.attrs[attribute])) {
150+
return node
151+
}
152+
153+
node.attrs[attribute] = typeof value === 'boolean' ? options.url + node.attrs[attribute] : value + node.attrs[attribute]
154+
}
155+
156+
const prependUrl = (value, url) => {
157+
const {css} = postcss([postcssBaseUrl({base: url})]).process(`div { ${value} }`)
158+
return css.replace(/div {\s|\s}$/gm, '')
159+
}
160+
161+
return tree.walk(process)
162+
}
163+
164+
export default plugin

lib/plugins/postcss-baseurl.js

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,34 @@
1-
const isUrl = require('is-url-superb')
2-
3-
const urlPattern = /(url\(["']?)(.*?)(["']?\))/g
4-
5-
module.exports = (options = {}) => {
6-
const {base} = options
7-
8-
return {
9-
postcssPlugin: 'postcss-baseurl',
10-
Once(root) {
11-
root.walkAtRules(rule => {
12-
if (rule.name === 'font-face') {
13-
rule.walkDecls(decl => {
14-
const {value} = decl
15-
16-
decl.value = value.replace(urlPattern, ($0, $1, $2, $3) => {
17-
return isUrl($2) ? $1 + $2 + $3 : $1 + base + $2 + $3
18-
})
19-
})
20-
}
21-
})
22-
23-
root.walkRules(rule => {
24-
rule.walkDecls(decl => {
25-
const {value} = decl
26-
27-
decl.value = value.replace(urlPattern, ($0, $1, $2, $3) => {
28-
return isUrl($2) ? $1 + $2 + $3 : $1 + base + $2 + $3
29-
})
30-
})
31-
})
32-
}
33-
}
34-
}
35-
36-
module.exports.postcss = true
1+
import isUrl from 'is-url-superb'
2+
3+
const urlPattern = /(url\(["']?)(.*?)(["']?\))/g
4+
5+
export default function postcssBaseurl(options = {}) {
6+
const { base } = options
7+
8+
return {
9+
postcssPlugin: 'postcss-baseurl',
10+
Once(root) {
11+
root.walkAtRules(rule => {
12+
if (rule.name === 'font-face') {
13+
rule.walkDecls(decl => {
14+
const { value } = decl
15+
decl.value = value.replace(urlPattern, ($0, $1, $2, $3) => {
16+
return isUrl($2) ? $1 + $2 + $3 : $1 + base + $2 + $3
17+
})
18+
})
19+
}
20+
})
21+
22+
root.walkRules(rule => {
23+
rule.walkDecls(decl => {
24+
const { value } = decl
25+
decl.value = value.replace(urlPattern, ($0, $1, $2, $3) => {
26+
return isUrl($2) ? $1 + $2 + $3 : $1 + base + $2 + $3
27+
})
28+
})
29+
})
30+
}
31+
}
32+
}
33+
34+
postcssBaseurl.postcss = true

0 commit comments

Comments
 (0)