Skip to content

Commit bf28bf6

Browse files
ttkomaRobinMalfait
andauthored
Fix cannot read properties of undefined (reading 'modifier') (#9656)
* 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 <[email protected]>
1 parent 0a4ae77 commit bf28bf6

File tree

3 files changed

+67
-8
lines changed

3 files changed

+67
-8
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- Ensure configured `font-feature-settings` are included in Preflight ([#9707](https://github.com/tailwindlabs/tailwindcss/pull/9707))
1717
- Fix fractional values not being parsed properly inside arbitrary properties ([#9705](https://github.com/tailwindlabs/tailwindcss/pull/9705))
1818
- Fix incorrect selectors when using `@apply` in selectors with combinators and pseudos ([#9722](https://github.com/tailwindlabs/tailwindcss/pull/9722))
19+
- Fix cannot read properties of undefined (reading 'modifier') ([#9656](https://github.com/tailwindlabs/tailwindcss/pull/9656))
1920

2021
## [3.2.1] - 2022-10-21
2122

src/lib/setupContextUtils.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
528528
variantFunctions = [].concat(variantFunctions).map((variantFunction) => {
529529
if (typeof variantFunction !== 'string') {
530530
// Safelist public API functions
531-
return (api) => {
531+
return (api = {}) => {
532532
let { args, modifySelectors, container, separator, wrap, format } = api
533533
let result = variantFunction(
534534
Object.assign(
@@ -581,11 +581,13 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
581581

582582
api.addVariant(
583583
isSpecial ? `${variant}${key}` : `${variant}-${key}`,
584-
({ args, container }) =>
585-
variantFn(
584+
({ args, container }) => {
585+
return variantFn(
586586
value,
587-
modifiersEnabled ? { modifier: args.modifier, container } : { container }
588-
),
587+
modifiersEnabled ? { modifier: args?.modifier, container } : { container }
588+
)
589+
},
590+
589591
{
590592
...options,
591593
value,
@@ -601,13 +603,13 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
601603
api.addVariant(
602604
variant,
603605
({ args, container }) => {
604-
if (args.value === sharedState.NONE && !hasDefault) {
606+
if (args?.value === sharedState.NONE && !hasDefault) {
605607
return null
606608
}
607609

608610
return variantFn(
609-
args.value === sharedState.NONE ? options.values.DEFAULT : args.value,
610-
modifiersEnabled ? { modifier: args.modifier, container } : { container }
611+
args?.value === sharedState.NONE ? options.values.DEFAULT : args?.value,
612+
modifiersEnabled ? { modifier: args?.modifier, container } : { container }
611613
)
612614
},
613615
{

tests/match-variants.test.js

+56
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import resolveConfig from '../src/public/resolve-config'
2+
import { createContext } from '../src/lib/setupContextUtils'
3+
14
import { run, html, css } from './util/run'
25

36
test('partial arbitrary variants', () => {
@@ -788,3 +791,56 @@ it('should be possible to use `undefined` as a DEFAULT value', () => {
788791
`)
789792
})
790793
})
794+
795+
it('should be possible to use `undefined` as a DEFAULT value', () => {
796+
let config = {
797+
content: [
798+
{
799+
raw: html`
800+
<div>
801+
<div class="foo:underline"></div>
802+
</div>
803+
`,
804+
},
805+
],
806+
corePlugins: { preflight: false },
807+
plugins: [
808+
({ matchVariant }) => {
809+
matchVariant('foo', (value) => `.foo${value === undefined ? '-good' : '-bad'} &`, {
810+
values: { DEFAULT: undefined },
811+
})
812+
},
813+
],
814+
}
815+
816+
let input = css`
817+
@tailwind utilities;
818+
`
819+
820+
return run(input, config).then((result) => {
821+
expect(result.css).toMatchFormattedCss(css`
822+
.foo-good .foo\:underline {
823+
text-decoration-line: underline;
824+
}
825+
`)
826+
})
827+
})
828+
829+
it('should not break things', () => {
830+
let config = {}
831+
832+
let context = createContext(resolveConfig(config))
833+
let [[, fn]] = context.variantMap.get('group')
834+
835+
let format
836+
837+
expect(
838+
fn({
839+
format(input) {
840+
format = input
841+
},
842+
})
843+
).toBe(undefined)
844+
845+
expect(format).toBe(':merge(.group) &')
846+
})

0 commit comments

Comments
 (0)