Skip to content

Commit

Permalink
Fix cannot read properties of undefined (reading 'modifier') (#9656)
Browse files Browse the repository at this point in the history
* fix #9655

* update changelog

* add test for making sure calling variantFn doesn't crash

* make it behave as-if modifiers didn't exist

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
  • Loading branch information
ttkoma and RobinMalfait authored Nov 3, 2022
1 parent 0a4ae77 commit bf28bf6
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ensure configured `font-feature-settings` are included in Preflight ([#9707](https://github.com/tailwindlabs/tailwindcss/pull/9707))
- Fix fractional values not being parsed properly inside arbitrary properties ([#9705](https://github.com/tailwindlabs/tailwindcss/pull/9705))
- Fix incorrect selectors when using `@apply` in selectors with combinators and pseudos ([#9722](https://github.com/tailwindlabs/tailwindcss/pull/9722))
- Fix cannot read properties of undefined (reading 'modifier') ([#9656](https://github.com/tailwindlabs/tailwindcss/pull/9656))

## [3.2.1] - 2022-10-21

Expand Down
18 changes: 10 additions & 8 deletions src/lib/setupContextUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
variantFunctions = [].concat(variantFunctions).map((variantFunction) => {
if (typeof variantFunction !== 'string') {
// Safelist public API functions
return (api) => {
return (api = {}) => {
let { args, modifySelectors, container, separator, wrap, format } = api
let result = variantFunction(
Object.assign(
Expand Down Expand Up @@ -581,11 +581,13 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs

api.addVariant(
isSpecial ? `${variant}${key}` : `${variant}-${key}`,
({ args, container }) =>
variantFn(
({ args, container }) => {
return variantFn(
value,
modifiersEnabled ? { modifier: args.modifier, container } : { container }
),
modifiersEnabled ? { modifier: args?.modifier, container } : { container }
)
},

{
...options,
value,
Expand All @@ -601,13 +603,13 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
api.addVariant(
variant,
({ args, container }) => {
if (args.value === sharedState.NONE && !hasDefault) {
if (args?.value === sharedState.NONE && !hasDefault) {
return null
}

return variantFn(
args.value === sharedState.NONE ? options.values.DEFAULT : args.value,
modifiersEnabled ? { modifier: args.modifier, container } : { container }
args?.value === sharedState.NONE ? options.values.DEFAULT : args?.value,
modifiersEnabled ? { modifier: args?.modifier, container } : { container }
)
},
{
Expand Down
56 changes: 56 additions & 0 deletions tests/match-variants.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import resolveConfig from '../src/public/resolve-config'
import { createContext } from '../src/lib/setupContextUtils'

import { run, html, css } from './util/run'

test('partial arbitrary variants', () => {
Expand Down Expand Up @@ -788,3 +791,56 @@ it('should be possible to use `undefined` as a DEFAULT value', () => {
`)
})
})

it('should be possible to use `undefined` as a DEFAULT value', () => {
let config = {
content: [
{
raw: html`
<div>
<div class="foo:underline"></div>
</div>
`,
},
],
corePlugins: { preflight: false },
plugins: [
({ matchVariant }) => {
matchVariant('foo', (value) => `.foo${value === undefined ? '-good' : '-bad'} &`, {
values: { DEFAULT: undefined },
})
},
],
}

let input = css`
@tailwind utilities;
`

return run(input, config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.foo-good .foo\:underline {
text-decoration-line: underline;
}
`)
})
})

it('should not break things', () => {
let config = {}

let context = createContext(resolveConfig(config))
let [[, fn]] = context.variantMap.get('group')

let format

expect(
fn({
format(input) {
format = input
},
})
).toBe(undefined)

expect(format).toBe(':merge(.group) &')
})

0 comments on commit bf28bf6

Please sign in to comment.