Skip to content

Commit 0ab39c3

Browse files
authored
Allow _ inside url() when using arbitrary values (#5853)
* allow for underscores in url() * update changelog
1 parent ae0e83d commit 0ab39c3

6 files changed

+66
-7
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3030
- Fix CLI `--content` option ([#5775](https://github.com/tailwindlabs/tailwindcss/pull/5775))
3131
- Fix before/after utilities overriding custom content values at larger breakpoints ([#5820](https://github.com/tailwindlabs/tailwindcss/pull/5820))
3232
- Cleanup duplicate properties ([#5830](https://github.com/tailwindlabs/tailwindcss/pull/5830))
33+
- Allow `_` inside `url()` when using arbitrary values ([#5853](https://github.com/tailwindlabs/tailwindcss/pull/5853))
3334

3435
## [3.0.0-alpha.1] - 2021-10-01
3536

src/lib/expandTailwindAtRules.js

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ const PATTERNS = [
1111
/([^<>"'`\s]*\[\w*"[^"`\s]*"?\])/.source, // font-["some_font",sans-serif]
1212
/([^<>"'`\s]*\[\w*\('[^"'`\s]*'\)\])/.source, // bg-[url('...')]
1313
/([^<>"'`\s]*\[\w*\("[^"'`\s]*"\)\])/.source, // bg-[url("...")]
14+
/([^<>"'`\s]*\[\w*\('[^"`\s]*'\)\])/.source, // bg-[url('...'),url('...')]
15+
/([^<>"'`\s]*\[\w*\("[^'`\s]*"\)\])/.source, // bg-[url("..."),url("...")]
1416
/([^<>"'`\s]*\['[^"'`\s]*'\])/.source, // `content-['hello']` but not `content-['hello']']`
1517
/([^<>"'`\s]*\["[^"'`\s]*"\])/.source, // `content-["hello"]` but not `content-["hello"]"]`
1618
/([^<>"'`\s]*\[[^"'`\s]+\][^<>"'`\s]*)/.source, // `fill-[#bada55]`, `fill-[#bada55]/50`

src/util/dataTypes.js

+19-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,22 @@ let UNDERSCORE = /_(?![^(]*\))/g // Underscore separator that is not located bet
77

88
// This is not a data type, but rather a function that can normalize the
99
// correct values.
10-
export function normalize(value) {
10+
export function normalize(value, isRoot = true) {
11+
// Keep raw strings if it starts with `url(`
12+
if (value.includes('url(')) {
13+
return value
14+
.split(/(url\(.*?\))/g)
15+
.filter(Boolean)
16+
.map((part) => {
17+
if (/^url\(.*?\)$/.test(part)) {
18+
return part
19+
}
20+
21+
return normalize(part, false)
22+
})
23+
.join('')
24+
}
25+
1126
// Convert `_` to ` `, except for escaped underscores `\_`
1227
value = value
1328
.replace(
@@ -18,10 +33,9 @@ export function normalize(value) {
1833
.replace(/\\_/g, '_')
1934

2035
// Remove leftover whitespace
21-
value = value.trim()
22-
23-
// Keep raw strings if it starts with `url(`
24-
if (value.startsWith('url(')) return value
36+
if (isRoot) {
37+
value = value.trim()
38+
}
2539

2640
// Add spaces around operators inside calc() that do not follow an operator
2741
// or '('.

src/util/pluginUtils.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,18 @@ function splitAtFirst(input, delim) {
160160

161161
export function coerceValue(types, modifier, options, tailwindConfig) {
162162
if (isArbitraryValue(modifier)) {
163-
let [explicitType, value] = splitAtFirst(modifier.slice(1, -1), ':')
163+
let arbitraryValue = modifier.slice(1, -1)
164+
let [explicitType, value] = splitAtFirst(arbitraryValue, ':')
165+
166+
// It could be that this resolves to `url(https` which is not a valid
167+
// identifier. We currently only support "simple" words with dashes or
168+
// underscores. E.g.: family-name
169+
if (!/^[\w-_]+$/g.test(explicitType)) {
170+
value = arbitraryValue
171+
}
164172

165-
if (explicitType !== undefined && !supportedTypes.includes(explicitType)) {
173+
//
174+
else if (explicitType !== undefined && !supportedTypes.includes(explicitType)) {
166175
return []
167176
}
168177

tests/arbitrary-values.test.html

+1
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126

127127
<div class="cursor-[pointer]"></div>
128128
<div class="cursor-[url(hand.cur)_2_2,pointer]"></div>
129+
<div class="cursor-[url('./path_to_hand.cur')_2_2,pointer]"></div>
129130
<div class="cursor-[var(--value)]"></div>
130131

131132
<div class="list-['\1F44D']"></div>

tests/arbitrary-values.test.js

+32
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,35 @@ it('should warn and not generate if arbitrary values are ambiguous', () => {
220220
return expect(result.css).toMatchFormattedCss(css``)
221221
})
222222
})
223+
224+
it('should support colons in URLs', () => {
225+
let config = {
226+
content: [
227+
{ raw: html`<div class="bg-[url('https://www.spacejam.com/1996/img/bg_stars.gif')]"></div>` },
228+
],
229+
}
230+
231+
return run('@tailwind utilities', config).then((result) => {
232+
return expect(result.css).toMatchFormattedCss(css`
233+
.bg-\[url\(\'https\:\/\/www\.spacejam\.com\/1996\/img\/bg_stars\.gif\'\)\] {
234+
background-image: url('https://www.spacejam.com/1996/img/bg_stars.gif');
235+
}
236+
`)
237+
})
238+
})
239+
240+
it('should support unescaped underscores in URLs', () => {
241+
let config = {
242+
content: [
243+
{ raw: html`<div class="bg-[url('brown_potato.jpg'),_url('red_tomato.png')]"></div>` },
244+
],
245+
}
246+
247+
return run('@tailwind utilities', config).then((result) => {
248+
return expect(result.css).toMatchFormattedCss(`
249+
.bg-\\[url\\(\\'brown_potato\\.jpg\\'\\)\\2c _url\\(\\'red_tomato\\.png\\'\\)\\] {
250+
background-image: url('brown_potato.jpg'), url('red_tomato.png');
251+
}
252+
`)
253+
})
254+
})

0 commit comments

Comments
 (0)