From a0c4aa9575f5388cc78be6c2d181c6c677e9585b Mon Sep 17 00:00:00 2001 From: Konstantin Lapeev <1864455+ttkoma@users.noreply.github.com> Date: Tue, 25 Oct 2022 03:47:10 +0300 Subject: [PATCH 1/4] fix #9655 --- src/lib/setupContextUtils.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index 4e6cc96e9038..4d514b9bac9f 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -584,7 +584,7 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs ({ args, container }) => variantFn( value, - modifiersEnabled ? { modifier: args.modifier, container } : { container } + modifiersEnabled ? { modifier: (args ?? {}).modifier, container } : { container } ), { ...options, @@ -601,6 +601,10 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs api.addVariant( variant, ({ args, container }) => { + if (!args) { + return null + } + if (args.value === sharedState.NONE && !hasDefault) { return null } From 229f32df18fa4762f5bc9f776d71f4a4f7e962ba Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 3 Nov 2022 12:52:54 +0100 Subject: [PATCH 2/4] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49ce94a4ac41..48e6aa38beb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 From 5fd1ad1b8d286dd008769c914be2f5ed2d571667 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 3 Nov 2022 13:39:43 +0100 Subject: [PATCH 3/4] add test for making sure calling variantFn doesn't crash --- src/lib/setupContextUtils.js | 22 ++++++++---- tests/match-variants.test.js | 66 ++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index 4d514b9bac9f..4afdeca5a4bd 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -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( @@ -581,11 +581,19 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs api.addVariant( isSpecial ? `${variant}${key}` : `${variant}-${key}`, - ({ args, container }) => - variantFn( + ({ args, container }) => { + // For backwards compatibility reasons for older versions of the vscode intellisense + // plugin and the JetBrains plugin. + if (!args) { + return null + } + + return variantFn( value, - modifiersEnabled ? { modifier: (args ?? {}).modifier, container } : { container } - ), + modifiersEnabled ? { modifier: args.modifier, container } : { container } + ) + }, + { ...options, value, @@ -601,10 +609,12 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs api.addVariant( variant, ({ args, container }) => { + // For backwards compatibility reasons for older versions of the vscode intellisense + // plugin and the JetBrains plugin. if (!args) { return null } - + if (args.value === sharedState.NONE && !hasDefault) { return null } diff --git a/tests/match-variants.test.js b/tests/match-variants.test.js index dd839151fe55..8bd237b46605 100644 --- a/tests/match-variants.test.js +++ b/tests/match-variants.test.js @@ -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', () => { @@ -788,3 +791,66 @@ 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` +
+
+
+ `, + }, + ], + 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 = { + plugins: [ + ({ matchVariant }) => { + matchVariant( + 'foo', + (_value, { modifier: _modifier }) => { + expect(true).toBe(true) // Should not be called + return `.foo &` + }, + { + modifiers: { + bar: 'bar', + }, + } + ) + }, + ], + } + + let context = createContext(resolveConfig(config)) + let [[, fn]] = context.variantMap.get('foo') + expect(fn()).toBe(null) + expect(fn({})).toBe(null) + expect(fn({ format() {} })).toBe(null) + + expect.assertions(3) +}) From 5626fe60a780d5565d3d981e2e3526d1e91f6d46 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Thu, 3 Nov 2022 15:07:06 +0100 Subject: [PATCH 4/4] make it behave as-if modifiers didn't exist --- src/lib/setupContextUtils.js | 20 ++++---------------- tests/match-variants.test.js | 36 +++++++++++++----------------------- 2 files changed, 17 insertions(+), 39 deletions(-) diff --git a/src/lib/setupContextUtils.js b/src/lib/setupContextUtils.js index 4afdeca5a4bd..78df6486a575 100644 --- a/src/lib/setupContextUtils.js +++ b/src/lib/setupContextUtils.js @@ -582,15 +582,9 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs api.addVariant( isSpecial ? `${variant}${key}` : `${variant}-${key}`, ({ args, container }) => { - // For backwards compatibility reasons for older versions of the vscode intellisense - // plugin and the JetBrains plugin. - if (!args) { - return null - } - return variantFn( value, - modifiersEnabled ? { modifier: args.modifier, container } : { container } + modifiersEnabled ? { modifier: args?.modifier, container } : { container } ) }, @@ -609,19 +603,13 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs api.addVariant( variant, ({ args, container }) => { - // For backwards compatibility reasons for older versions of the vscode intellisense - // plugin and the JetBrains plugin. - if (!args) { - return null - } - - 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 } ) }, { diff --git a/tests/match-variants.test.js b/tests/match-variants.test.js index 8bd237b46605..ad08042af2b4 100644 --- a/tests/match-variants.test.js +++ b/tests/match-variants.test.js @@ -827,30 +827,20 @@ it('should be possible to use `undefined` as a DEFAULT value', () => { }) it('should not break things', () => { - let config = { - plugins: [ - ({ matchVariant }) => { - matchVariant( - 'foo', - (_value, { modifier: _modifier }) => { - expect(true).toBe(true) // Should not be called - return `.foo &` - }, - { - modifiers: { - bar: 'bar', - }, - } - ) - }, - ], - } + let config = {} let context = createContext(resolveConfig(config)) - let [[, fn]] = context.variantMap.get('foo') - expect(fn()).toBe(null) - expect(fn({})).toBe(null) - expect(fn({ format() {} })).toBe(null) + let [[, fn]] = context.variantMap.get('group') + + let format + + expect( + fn({ + format(input) { + format = input + }, + }) + ).toBe(undefined) - expect.assertions(3) + expect(format).toBe(':merge(.group) &') })