Skip to content

Commit e9abec5

Browse files
authored
Merge pull request #25 from posthtml/refactor-tags
2 parents 480a83c + a2aea0f commit e9abec5

File tree

5 files changed

+135
-67
lines changed

5 files changed

+135
-67
lines changed

lib/index.js

Lines changed: 66 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,75 +3,81 @@ const postcss = require('postcss')
33
const merge = require('lodash.merge')
44
const isUrl = require('is-url-superb')
55
const postcssBaseUrl = require('./plugins/postcss-baseurl.js')
6+
const defaultTags = {
7+
a: {
8+
href: true,
9+
},
10+
area: {
11+
href: true,
12+
},
13+
audio: {
14+
src: true,
15+
},
16+
base: {
17+
href: true,
18+
},
19+
body: {
20+
background: true,
21+
},
22+
embed: {
23+
src: true,
24+
},
25+
iframe: {
26+
src: true,
27+
},
28+
img: {
29+
src: true,
30+
srcset: true,
31+
},
32+
input: {
33+
src: true,
34+
},
35+
link: {
36+
href: true,
37+
},
38+
script: {
39+
src: true,
40+
},
41+
source: {
42+
src: true,
43+
srcset: true,
44+
},
45+
table: {
46+
background: true,
47+
},
48+
td: {
49+
background: true,
50+
},
51+
th: {
52+
background: true,
53+
},
54+
track: {
55+
src: true,
56+
},
57+
video: {
58+
poster: true,
59+
},
60+
}
661

762
module.exports = (options = {}) => tree => {
863
options.url = options.url || ''
964
options.attributes = options.attributes || {}
1065
options.allTags = options.allTags || false
1166
options.styleTag = options.styleTag || false
1267
options.inlineCss = options.inlineCss || false
13-
options.tags = options.allTags ? merge({
14-
a: {
15-
href: true,
16-
},
17-
area: {
18-
href: true,
19-
},
20-
audio: {
21-
src: true,
22-
},
23-
base: {
24-
href: true,
25-
},
26-
body: {
27-
background: true,
28-
},
29-
embed: {
30-
src: true,
31-
},
32-
iframe: {
33-
src: true,
34-
},
35-
img: {
36-
src: true,
37-
srcset: true,
38-
},
39-
input: {
40-
src: true,
41-
},
42-
link: {
43-
href: true,
44-
},
45-
script: {
46-
src: true,
47-
},
48-
source: {
49-
src: true,
50-
srcset: true,
51-
},
52-
table: {
53-
background: true,
54-
},
55-
td: {
56-
background: true,
57-
},
58-
th: {
59-
background: true,
60-
},
61-
track: {
62-
src: true,
63-
},
64-
video: {
65-
poster: true,
66-
},
67-
}, options.tags) : options.tags || {}
68+
options.tags = options.allTags ? merge(defaultTags, options.tags) : options.tags || {}
6869

6970
const process = node => {
7071
// Skip if `url` was not provided
7172
if (options.url && (typeof options.url !== 'string' || options.url === '')) {
7273
return node
7374
}
7475

76+
// Skip if `options.tags` is not an array or object
77+
if (!['array', 'object'].includes(typeof options.tags)) {
78+
return node
79+
}
80+
7581
// Handle embedded stylesheets
7682
if (node.tag === 'style' && node.content && options.styleTag) {
7783
node.content = postcss([
@@ -96,7 +102,11 @@ module.exports = (options = {}) => tree => {
96102
})
97103

98104
// Handle defined HTML tags
99-
Object.entries(options.tags).forEach(([tag, attributes]) => {
105+
const tags = Array.isArray(options.tags) ?
106+
Object.entries(defaultTags).filter(([tag]) => options.tags.includes(tag)) :
107+
Object.entries(options.tags)
108+
109+
tags.forEach(([tag, attributes]) => {
100110
if (node.tag !== tag) {
101111
return node
102112
}

readme.md

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,16 @@ When set to `true`, the plugin will prepend your `url` to all `url()` sources in
108108

109109
### `tags`
110110

111-
Type: `object`\
112-
Default: `{/*object with select tags to handle*/}`
111+
Type: `array|object`\
112+
Default: [defaultTags](./lib/index.js) (object)
113+
114+
Define a list of tags and their attributes to handle.
113115

114-
An object that defines tags and their attributes to handle.
116+
When using the `tags` option, the plugin will _only handle those tags_.
115117

116-
When you define tags to handle with the `tags` option, the plugin will _only handle those tags_.
118+
#### Array `tags`
117119

118-
For example, the `<a>` tag here is not prepended to:
120+
To replace all known attributes for a list of tags, use the array format:
119121

120122
```js
121123
posthtml([
@@ -124,11 +126,43 @@ posthtml([
124126
.process(
125127
`<a href="foo/bar.html">
126128
<img src="img.jpg" srcset="img-HD.jpg 2x,img-xs.jpg 100w">
129+
</a>
130+
131+
<script src="javascript.js"></script>`,
132+
{
133+
tags: ['img', 'script'],
134+
}
135+
)
136+
.then(result => console.log(result.html))
137+
```
138+
139+
Result:
140+
141+
```html
142+
<a href="foo/bar.html">
143+
<img src="https://example.com/image1.jpg" srcset="https://example.com/image1-HD.jpg 2x, https://example.com/image1-phone.jpg 100w">
144+
</a>
145+
146+
<script src="https://example.com/javascript.js"></script>
147+
```
148+
149+
#### Object `tags`
150+
151+
You may use an object for granular control over how specific attributes should be handled:
152+
153+
```js
154+
posthtml([
155+
baseUrl()
156+
])
157+
.process(
158+
`<a href="foo/bar.html">
159+
<img src="img.jpg" srcset="img-HD.jpg 2x, img-xs.jpg 100w">
127160
</a>`,
128161
{
162+
url: 'https://foo.com/',
129163
tags: {
130164
img: {
131-
src: 'https://foo.com/',
165+
src: true,
132166
srcset: 'https://bar.com/',
133167
},
134168
},
@@ -145,6 +179,8 @@ Result:
145179
</a>
146180
```
147181

182+
You may set the value of an attribute to `true` and the plugin will use the `url` option value - we did that above for the `src` attribute.
183+
148184
### `attributes`
149185

150186
Type: `object`\

test/expected/user-tags.html

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
<a href="foo/bar.html">
2-
<img src="https://example.com/image1.jpg" srcset="https://example2.com/image1-HD.jpg 2x, https://example2.com/image1-phone.jpg 100w">
2+
<img src="https://example.com/image1.jpg" srcset="https://example.com/image1-HD.jpg 2x, https://example.com/image1-phone.jpg 100w">
33
</a>
4+
5+
<script src="https://example.com/javascript.js"></script>

test/fixtures/user-tags.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
<a href="foo/bar.html">
22
<img src="image1.jpg" srcset="image1-HD.jpg 2x,image1-phone.jpg 100w">
33
</a>
4+
5+
<script src="javascript.js"></script>

test/test.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,21 @@ const process = (t, name, options, log = false) => {
2121
.then(html => t.is(html, expected(name).trim()))
2222
}
2323

24-
test('does nothing if `url` was not provided', t => {
24+
test('skip if `url` was not provided', t => {
2525
return process(t, 'no-url', {})
2626
})
2727

28-
test('does nothing if `url` is not a string', t => {
28+
test('skip if `url` is not a string', t => {
2929
return process(t, 'no-url', {url: true})
3030
})
3131

32+
test('skip if `options.tags` is invalid', t => {
33+
return process(t, 'no-url', {
34+
url: 'https://example.com',
35+
tags: true,
36+
})
37+
})
38+
3239
test('skips absolute urls', t => {
3340
return process(t, 'absolute-urls')
3441
})
@@ -84,13 +91,24 @@ test('css urls', t => {
8491
})
8592
})
8693

87-
test('applies only to user-defined tags', t => {
94+
test('user-defined tags (object)', t => {
8895
return process(t, 'user-tags', {
96+
url: 'https://example.com/',
8997
tags: {
9098
img: {
99+
src: true,
100+
srcset: 'https://example.com/',
101+
},
102+
script: {
91103
src: 'https://example.com/',
92-
srcset: 'https://example2.com/',
93104
},
94105
},
95106
})
96107
})
108+
109+
test('user-defined tags (array)', t => {
110+
return process(t, 'user-tags', {
111+
url: 'https://example.com/',
112+
tags: ['img', 'script'],
113+
})
114+
})

0 commit comments

Comments
 (0)