Skip to content

Commit 437dc7a

Browse files
authored
Merge pull request #109 from posthtml/feat/attributes
2 parents a628fc8 + 96956fd commit 437dc7a

File tree

3 files changed

+218
-146
lines changed

3 files changed

+218
-146
lines changed

lib/index.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,22 @@ module.exports = (config = {}) => tree => {
1010
return node
1111
}
1212

13-
const tags = config && config.tags ? config.tags : ['a']
13+
const tags = Array.isArray(config.tags) ? config.tags : ['a']
14+
15+
const knownAttributes = new Set(config.attributes || ['href', 'src', 'poster', 'srcset', 'background'])
1416

1517
tree.match(matchHelper(tags.join(',')), node => {
16-
const url = node.attrs.href
18+
if (!node.attrs) {
19+
return node
20+
}
21+
22+
const matchingAttribute = Object.keys(node.attrs).find(key => knownAttributes.has(key))
23+
24+
if (!matchingAttribute) {
25+
return node
26+
}
27+
28+
const url = node.attrs[matchingAttribute]
1729
const parsed = qs.parseUrl(url, config.qs)
1830

1931
if (config.strict && !isUrl(parsed.url.trim())) {
@@ -24,7 +36,7 @@ module.exports = (config = {}) => tree => {
2436
parsed.query[item] = config.parameters[item]
2537
})
2638

27-
node.attrs.href = qs.stringifyUrl(parsed, config.qs)
39+
node.attrs[matchingAttribute] = qs.stringifyUrl(parsed, config.qs)
2840

2941
return node
3042
})

readme.md

+165-143
Original file line numberDiff line numberDiff line change
@@ -1,143 +1,165 @@
1-
<div align="center">
2-
<img width="150" height="150" title="PostHTML" src="https://posthtml.github.io/posthtml/logo.svg">
3-
<h1>URL Parameters</h1>
4-
<p>Add parameters to URLs</p>
5-
6-
[![Version][npm-version-shield]][npm]
7-
[![Build][github-ci-shield]][github-ci]
8-
[![License][license-shield]][license]
9-
[![Downloads][npm-stats-shield]][npm-stats]
10-
</div>
11-
12-
## About
13-
14-
This is a PostHTML plugin that allows you to add parameters to URLs.
15-
16-
## Install
17-
18-
```
19-
$ npm i posthtml posthtml-url-parameters
20-
```
21-
22-
## Usage
23-
24-
```js
25-
const posthtml = require('posthtml')
26-
const urlParams = require('posthtml-url-parameters')
27-
28-
posthtml([
29-
urlParams({
30-
parameters: { foo: 'bar', baz: 'qux' }
31-
})
32-
])
33-
.process('<a href="https://example.com">Test</div>')
34-
.then(result => console.log(result.html)))
35-
36-
// <a href="https://example.com?baz=qux&foo=bar">Test</div>
37-
```
38-
39-
## Configuration
40-
41-
### `parameters`
42-
43-
Default: `undefined`
44-
45-
Object containing parameter name (key) and its value.
46-
47-
Example:
48-
49-
```js
50-
require('posthtml-url-parameters')({
51-
parameters: {
52-
utm_source: 'Campaign',
53-
'1stDraft': true
54-
}
55-
})
56-
```
57-
58-
### `tags`
59-
60-
Default: `[a]`
61-
62-
Array of tag names to process.
63-
64-
By default, only URLs inside `href=""` attributes of tags in this array will be processed.
65-
66-
Example:
67-
68-
```js
69-
require('posthtml-url-parameters')({
70-
tags: ['a', 'link'],
71-
// ...
72-
})
73-
```
74-
75-
You may use some CSS selectors when specifying tags:
76-
77-
```js
78-
require('posthtml-url-parameters')({
79-
tags: ['a.button', 'a[href*="example.com"]' 'link'],
80-
// ...
81-
})
82-
```
83-
84-
All [`posthtml-match-helper` selectors](https://github.com/posthtml/posthtml-match-helper) are supported.
85-
86-
### `strict`
87-
88-
Default: `false`
89-
90-
By default, the plugin will append query parameters only to valid URLs.
91-
92-
You may disable `strict` mode to append parameters to any string:
93-
94-
```js
95-
const posthtml = require('posthtml')
96-
const urlParams = require('posthtml-url-parameters')
97-
98-
posthtml([
99-
urlParams({
100-
parameters: { foo: 'bar' },
101-
strict: false,
102-
})
103-
])
104-
.process('<a href="https://example.com/campaigns/{{ id }}">Details</div>')
105-
.then(result => console.log(result.html)))
106-
107-
// <a href="https://example.com/campaigns/{{ id }}?foo=bar">Details</div>
108-
```
109-
110-
### `qs`
111-
112-
Default: `undefined`
113-
114-
Options to pass to `query-string` - see available options [here](https://github.com/sindresorhus/query-string#stringifyobject-options).
115-
116-
For example, you may disable encoding:
117-
118-
```js
119-
const posthtml = require('posthtml')
120-
const urlParams = require('posthtml-url-parameters')
121-
122-
posthtml([
123-
urlParams({
124-
parameters: { foo: '@Bar@' },
125-
qs: {
126-
encode: false
127-
}
128-
})
129-
])
130-
.process('<a href="https://example.com">Test</div>')
131-
.then(result => console.log(result.html)))
132-
133-
// <a href="https://example.com?foo=@Bar@">Test</div>
134-
```
135-
136-
[npm]: https://www.npmjs.com/package/posthtml-url-parameters
137-
[npm-version-shield]: https://img.shields.io/npm/v/posthtml-url-parameters.svg
138-
[npm-stats]: http://npm-stat.com/charts.html?package=posthtml-url-parameters
139-
[npm-stats-shield]: https://img.shields.io/npm/dt/posthtml-url-parameters.svg
140-
[github-ci]: https://github.com/posthtml/posthtml-url-parameters/actions
141-
[github-ci-shield]: https://github.com/posthtml/posthtml-url-parameters/actions/workflows/nodejs.yml/badge.svg
142-
[license]: ./license
143-
[license-shield]: https://img.shields.io/npm/l/posthtml-url-parameters.svg
1+
<div align="center">
2+
<img width="150" height="150" title="PostHTML" src="https://posthtml.github.io/posthtml/logo.svg">
3+
<h1>URL Parameters</h1>
4+
<p>Add parameters to URLs</p>
5+
6+
[![Version][npm-version-shield]][npm]
7+
[![Build][github-ci-shield]][github-ci]
8+
[![License][license-shield]][license]
9+
[![Downloads][npm-stats-shield]][npm-stats]
10+
</div>
11+
12+
## About
13+
14+
This is a PostHTML plugin that allows you to add parameters to URLs.
15+
16+
## Install
17+
18+
```
19+
npm i posthtml posthtml-url-parameters
20+
```
21+
22+
## Usage
23+
24+
```js
25+
const posthtml = require('posthtml')
26+
const urlParams = require('posthtml-url-parameters')
27+
28+
posthtml([
29+
urlParams({
30+
parameters: { foo: 'bar', baz: 'qux' }
31+
})
32+
])
33+
.process('<a href="https://example.com">Test</div>')
34+
.then(result => console.log(result.html)))
35+
36+
// <a href="https://example.com?baz=qux&foo=bar">Test</div>
37+
```
38+
39+
## Configuration
40+
41+
### `parameters`
42+
43+
Default: `undefined`
44+
45+
Object containing parameter name (key) and its value.
46+
47+
Example:
48+
49+
```js
50+
require('posthtml-url-parameters')({
51+
parameters: {
52+
utm_source: 'Campaign',
53+
'1stDraft': true
54+
}
55+
})
56+
```
57+
58+
### `tags`
59+
60+
Default: `[a]`
61+
62+
Array of tag names to process.
63+
64+
By default, only URLs inside [known attributes](#attributes) of tags in this array will be processed.
65+
66+
Example:
67+
68+
```js
69+
require('posthtml-url-parameters')({
70+
tags: ['a', 'link'],
71+
// ...
72+
})
73+
```
74+
75+
You may use some CSS selectors when specifying tags:
76+
77+
```js
78+
require('posthtml-url-parameters')({
79+
tags: ['a.button', 'a[href*="example.com"]' 'link'],
80+
// ...
81+
})
82+
```
83+
84+
All [`posthtml-match-helper` selectors](https://github.com/posthtml/posthtml-match-helper) are supported.
85+
86+
### attributes
87+
88+
Type: `Array`\
89+
Default: `['src', 'href', 'poster', 'srcset', 'background']`
90+
91+
Array of attributes to process for the given tags.
92+
93+
You may override this with your own list of attributes - the plugin will only process URLs in _these_ attributes.
94+
95+
```js
96+
posthtml([
97+
urlParams({
98+
parameters: {foo: 'bar'},
99+
attributes: ['data-href']
100+
})
101+
])
102+
.process('<a href="foo.html" data-href="https://example.com">Test</a>')
103+
.then(result => console.log(result.html)))
104+
105+
// <a href="foo.html" data-href="https://example.com?foo=bar">Test</a>
106+
```
107+
108+
### `strict`
109+
110+
Default: `false`
111+
112+
By default, the plugin will append query parameters only to valid URLs.
113+
114+
You may disable `strict` mode to append parameters to any string:
115+
116+
```js
117+
const posthtml = require('posthtml')
118+
const urlParams = require('posthtml-url-parameters')
119+
120+
posthtml([
121+
urlParams({
122+
parameters: { foo: 'bar' },
123+
strict: false,
124+
})
125+
])
126+
.process('<a href="https://example.com/campaigns/{{ id }}">Details</a>')
127+
.then(result => console.log(result.html)))
128+
129+
// <a href="https://example.com/campaigns/{{ id }}?foo=bar">Details</a>
130+
```
131+
132+
### `qs`
133+
134+
Default: `undefined`
135+
136+
Options to pass to `query-string` - see available options [here](https://github.com/sindresorhus/query-string#stringifyobject-options).
137+
138+
For example, you may disable encoding:
139+
140+
```js
141+
const posthtml = require('posthtml')
142+
const urlParams = require('posthtml-url-parameters')
143+
144+
posthtml([
145+
urlParams({
146+
parameters: { foo: '@Bar@' },
147+
qs: {
148+
encode: false
149+
}
150+
})
151+
])
152+
.process('<a href="https://example.com">Test</a>')
153+
.then(result => console.log(result.html)))
154+
155+
// <a href="https://example.com?foo=@Bar@">Test</a>
156+
```
157+
158+
[npm]: https://www.npmjs.com/package/posthtml-url-parameters
159+
[npm-version-shield]: https://img.shields.io/npm/v/posthtml-url-parameters.svg
160+
[npm-stats]: http://npm-stat.com/charts.html?package=posthtml-url-parameters
161+
[npm-stats-shield]: https://img.shields.io/npm/dt/posthtml-url-parameters.svg
162+
[github-ci]: https://github.com/posthtml/posthtml-url-parameters/actions
163+
[github-ci-shield]: https://github.com/posthtml/posthtml-url-parameters/actions/workflows/nodejs.yml/badge.svg
164+
[license]: ./license
165+
[license-shield]: https://img.shields.io/npm/l/posthtml-url-parameters.svg

test/test.js

+38
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,41 @@ test('Processes only tags provided in the `tags` option', async t => {
9393
<link rel="stylesheet" href="https://example.com/style.css?foo=bar">
9494
<module href="https://example.com/header.html"></module>`)
9595
})
96+
97+
test('Adds parameters to known attribute values', async t => {
98+
const html = await process(`
99+
<img src="https://example.com/image.jpg">
100+
<video poster="https://example.com/poster.jpg"></video>
101+
<table><td background="https://example.com/image.jpg"></td></table>
102+
`, {
103+
parameters: {foo: 'bar', baz: 'qux'},
104+
tags: ['img[src]', 'video[poster]', 'td[background]']
105+
})
106+
107+
t.is(html, `<img src="https://example.com/image.jpg?baz=qux&foo=bar">
108+
<video poster="https://example.com/poster.jpg?baz=qux&foo=bar"></video>
109+
<table><td background="https://example.com/image.jpg?baz=qux&foo=bar"></td></table>`)
110+
})
111+
112+
test('Adds parameters to specified attribute values only', async t => {
113+
const html = await process(`
114+
<a href="foo.html" data-href="https://example.com">Test</a>
115+
<img src="image.jpg">
116+
`, {
117+
parameters: {foo: 'bar'},
118+
tags: ['a', 'img'],
119+
attributes: ['data-href']
120+
})
121+
122+
t.is(html, `<a href="foo.html" data-href="https://example.com?foo=bar">Test</a>
123+
<img src="image.jpg">`)
124+
})
125+
126+
test('Skip if node has no attributes', async t => {
127+
const html = await process('<a>Test</a>', {
128+
parameters: {foo: 'bar'},
129+
tags: ['a']
130+
})
131+
132+
t.is(html, '<a>Test</a>')
133+
})

0 commit comments

Comments
 (0)