tailwindcss 3.0.23 → 3.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/CHANGELOG.md +29 -3
  2. package/lib/cli-peer-dependencies.js +3 -3
  3. package/lib/cli.js +183 -161
  4. package/lib/constants.js +8 -8
  5. package/lib/corePlugins.js +1572 -1523
  6. package/lib/featureFlags.js +9 -9
  7. package/lib/index.js +19 -6
  8. package/lib/lib/cacheInvalidation.js +69 -0
  9. package/lib/lib/collapseAdjacentRules.js +26 -13
  10. package/lib/lib/collapseDuplicateDeclarations.js +1 -1
  11. package/lib/lib/defaultExtractor.js +6 -6
  12. package/lib/lib/detectNesting.js +9 -9
  13. package/lib/lib/evaluateTailwindFunctions.js +16 -16
  14. package/lib/lib/expandApplyAtRules.js +180 -27
  15. package/lib/lib/expandTailwindAtRules.js +132 -122
  16. package/lib/lib/generateRules.js +90 -72
  17. package/lib/lib/getModuleDependencies.js +14 -14
  18. package/lib/lib/normalizeTailwindDirectives.js +35 -35
  19. package/lib/lib/partitionApplyAtRules.js +7 -7
  20. package/lib/lib/resolveDefaultsAtRules.js +81 -77
  21. package/lib/lib/setupContextUtils.js +78 -87
  22. package/lib/lib/setupTrackingContext.js +57 -57
  23. package/lib/lib/sharedState.js +10 -8
  24. package/lib/lib/substituteScreenAtRules.js +2 -2
  25. package/lib/postcss-plugins/nesting/README.md +2 -2
  26. package/lib/postcss-plugins/nesting/index.js +1 -1
  27. package/lib/postcss-plugins/nesting/plugin.js +41 -9
  28. package/lib/processTailwindFeatures.js +7 -7
  29. package/lib/public/colors.js +241 -241
  30. package/lib/public/resolve-config.js +5 -5
  31. package/lib/util/buildMediaQuery.js +2 -2
  32. package/lib/util/cloneDeep.js +1 -1
  33. package/lib/util/cloneNodes.js +12 -1
  34. package/lib/util/color.js +21 -20
  35. package/lib/util/createUtilityPlugin.js +6 -6
  36. package/lib/util/dataTypes.js +77 -75
  37. package/lib/util/escapeClassName.js +5 -5
  38. package/lib/util/escapeCommas.js +1 -1
  39. package/lib/util/flattenColorPalette.js +2 -2
  40. package/lib/util/formatVariantSelector.js +19 -19
  41. package/lib/util/getAllConfigs.js +5 -5
  42. package/lib/util/hashConfig.js +5 -5
  43. package/lib/util/isKeyframeRule.js +1 -1
  44. package/lib/util/isPlainObject.js +1 -1
  45. package/lib/util/isValidArbitraryValue.js +27 -27
  46. package/lib/util/log.js +8 -8
  47. package/lib/util/nameClass.js +7 -7
  48. package/lib/util/negateValue.js +4 -4
  49. package/lib/util/normalizeConfig.js +39 -39
  50. package/lib/util/normalizeScreens.js +4 -4
  51. package/lib/util/parseAnimationValue.js +56 -56
  52. package/lib/util/parseBoxShadowValue.js +60 -20
  53. package/lib/util/parseDependency.js +32 -32
  54. package/lib/util/parseObjectStyles.js +6 -6
  55. package/lib/util/pluginUtils.js +9 -9
  56. package/lib/util/prefixSelector.js +1 -1
  57. package/lib/util/resolveConfig.js +28 -28
  58. package/lib/util/resolveConfigPath.js +16 -16
  59. package/lib/util/responsive.js +6 -6
  60. package/lib/util/toColorValue.js +1 -1
  61. package/lib/util/toPath.js +2 -2
  62. package/lib/util/transformThemeValue.js +27 -27
  63. package/lib/util/withAlphaVariable.js +19 -19
  64. package/package.json +24 -23
  65. package/peers/index.js +4777 -4831
  66. package/scripts/generate-types.js +52 -0
  67. package/src/cli.js +41 -11
  68. package/src/corePlugins.js +67 -5
  69. package/src/featureFlags.js +2 -2
  70. package/src/index.js +17 -1
  71. package/src/lib/cacheInvalidation.js +52 -0
  72. package/src/lib/collapseAdjacentRules.js +16 -1
  73. package/src/lib/defaultExtractor.js +4 -4
  74. package/src/lib/expandApplyAtRules.js +179 -6
  75. package/src/lib/expandTailwindAtRules.js +25 -5
  76. package/src/lib/generateRules.js +68 -46
  77. package/src/lib/resolveDefaultsAtRules.js +6 -2
  78. package/src/lib/setupContextUtils.js +25 -26
  79. package/src/lib/setupTrackingContext.js +3 -3
  80. package/src/lib/sharedState.js +1 -0
  81. package/src/postcss-plugins/nesting/README.md +2 -2
  82. package/src/postcss-plugins/nesting/plugin.js +36 -0
  83. package/src/util/cloneNodes.js +14 -1
  84. package/src/util/color.js +7 -5
  85. package/src/util/dataTypes.js +3 -1
  86. package/src/util/log.js +7 -7
  87. package/src/util/parseBoxShadowValue.js +50 -2
  88. package/src/util/resolveConfig.js +32 -0
  89. package/stubs/defaultConfig.stub.js +5 -0
@@ -0,0 +1,52 @@
1
+ import prettier from 'prettier'
2
+ import { corePlugins } from '../src/corePlugins'
3
+ import colors from '../src/public/colors'
4
+ import fs from 'fs'
5
+ import path from 'path'
6
+
7
+ fs.writeFileSync(
8
+ path.join(process.cwd(), 'types', 'generated', 'corePluginList.d.ts'),
9
+ `export type CorePluginList = ${Object.keys(corePlugins)
10
+ .map((p) => `'${p}'`)
11
+ .join(' | ')}`
12
+ )
13
+
14
+ let colorsWithoutDeprecatedColors = Object.fromEntries(
15
+ Object.entries(Object.getOwnPropertyDescriptors(colors))
16
+ .filter(([_, { value }]) => {
17
+ return typeof value !== 'undefined'
18
+ })
19
+ .map(([name, definition]) => [name, definition.value])
20
+ )
21
+
22
+ let deprecatedColors = Object.entries(Object.getOwnPropertyDescriptors(colors))
23
+ .filter(([_, { value }]) => {
24
+ return typeof value === 'undefined'
25
+ })
26
+ .map(([name, definition]) => {
27
+ let warn = console.warn
28
+ let messages = []
29
+ console.warn = (...args) => messages.push(args.pop())
30
+ definition.get()
31
+ console.warn = warn
32
+ let message = messages.join(' ').trim()
33
+ let newColor = message.match(/renamed to `(.*)`/)[1]
34
+ return `/** @deprecated ${message} */${name}: DefaultColors['${newColor}'],`
35
+ })
36
+ .join('\n')
37
+
38
+ fs.writeFileSync(
39
+ path.join(process.cwd(), 'types', 'generated', 'colors.d.ts'),
40
+ prettier.format(
41
+ `export interface DefaultColors { ${JSON.stringify(colorsWithoutDeprecatedColors).slice(
42
+ 1,
43
+ -1
44
+ )}\n${deprecatedColors}\n}`,
45
+ {
46
+ semi: false,
47
+ singleQuote: true,
48
+ printWidth: 100,
49
+ parser: 'typescript',
50
+ }
51
+ )
52
+ )
package/src/cli.js CHANGED
@@ -7,7 +7,7 @@ import path from 'path'
7
7
  import arg from 'arg'
8
8
  import fs from 'fs'
9
9
  import postcssrc from 'postcss-load-config'
10
- import { cosmiconfig } from 'cosmiconfig'
10
+ import { lilconfig } from 'lilconfig'
11
11
  import loadPlugins from 'postcss-load-config/src/plugins' // Little bit scary, looking at private/internal API
12
12
  import tailwind from './processTailwindFeatures'
13
13
  import resolveConfigInternal from '../resolveConfig'
@@ -151,6 +151,10 @@ let commands = {
151
151
  args: {
152
152
  '--full': { type: Boolean, description: 'Initialize a full `tailwind.config.js` file' },
153
153
  '--postcss': { type: Boolean, description: 'Initialize a `postcss.config.js` file' },
154
+ '--types': {
155
+ type: Boolean,
156
+ description: 'Add TypeScript types for the `tailwind.config.js` file',
157
+ },
154
158
  '-f': '--full',
155
159
  '-p': '--postcss',
156
160
  },
@@ -161,6 +165,12 @@ let commands = {
161
165
  '--input': { type: String, description: 'Input file' },
162
166
  '--output': { type: String, description: 'Output file' },
163
167
  '--watch': { type: Boolean, description: 'Watch for changes and rebuild as needed' },
168
+ /*
169
+ '--poll': {
170
+ type: Boolean,
171
+ description: 'Use polling instead of filesystem events when watching',
172
+ },
173
+ */
164
174
  '--content': {
165
175
  type: String,
166
176
  description: 'Content paths to use for removing unused classes',
@@ -187,6 +197,9 @@ let commands = {
187
197
  '-o': '--output',
188
198
  '-m': '--minify',
189
199
  '-w': '--watch',
200
+ /*
201
+ '-p': '--poll',
202
+ */
190
203
  },
191
204
  },
192
205
  }
@@ -204,7 +217,7 @@ if (
204
217
  help({
205
218
  usage: [
206
219
  'tailwindcss [--input input.css] [--output output.css] [--watch] [options...]',
207
- 'tailwindcss init [--full] [--postcss] [options...]',
220
+ 'tailwindcss init [--full] [--postcss] [--types] [options...]',
208
221
  ],
209
222
  commands: Object.keys(commands)
210
223
  .filter((command) => command !== 'build')
@@ -331,6 +344,13 @@ function init() {
331
344
  'utf8'
332
345
  )
333
346
 
347
+ if (args['--types']) {
348
+ let typesHeading = "/** @type {import('tailwindcss/types').Config} */"
349
+ stubFile =
350
+ stubFile.replace(`module.exports = `, `${typesHeading}\nconst config = `) +
351
+ '\nmodule.exports = config'
352
+ }
353
+
334
354
  // Change colors import
335
355
  stubFile = stubFile.replace('../colors', 'tailwindcss/colors')
336
356
 
@@ -367,8 +387,17 @@ async function build() {
367
387
  let input = args['--input']
368
388
  let output = args['--output']
369
389
  let shouldWatch = args['--watch']
390
+ let shouldPoll = false
391
+ /*
392
+ let shouldPoll = args['--poll']
393
+ */
394
+ let shouldCoalesceWriteEvents = shouldPoll || process.platform === 'win32'
370
395
  let includePostCss = args['--postcss']
371
396
 
397
+ // Polling interval in milliseconds
398
+ // Used only when polling or coalescing add/change events on Windows
399
+ let pollInterval = 10
400
+
372
401
  // TODO: Deprecate this in future versions
373
402
  if (!input && args['_'][1]) {
374
403
  console.error('[deprecation] Running tailwindcss without -i, please provide an input file.')
@@ -397,8 +426,8 @@ async function build() {
397
426
  ? await (async () => {
398
427
  let file = path.resolve(customPostCssPath)
399
428
 
400
- // Implementation, see: https://unpkg.com/browse/postcss-load-config@3.0.1/src/index.js
401
- let { config = {} } = await cosmiconfig('postcss').load(file)
429
+ // Implementation, see: https://unpkg.com/browse/postcss-load-config@3.1.0/src/index.js
430
+ let { config = {} } = await lilconfig('postcss').load(file)
402
431
  if (typeof config === 'function') {
403
432
  config = config()
404
433
  } else {
@@ -746,14 +775,15 @@ async function build() {
746
775
  }
747
776
 
748
777
  watcher = chokidar.watch([...contextDependencies, ...extractFileGlobs(config)], {
778
+ usePolling: shouldPoll,
779
+ interval: shouldPoll ? pollInterval : undefined,
749
780
  ignoreInitial: true,
750
- awaitWriteFinish:
751
- process.platform === 'win32'
752
- ? {
753
- stabilityThreshold: 50,
754
- pollInterval: 10,
755
- }
756
- : false,
781
+ awaitWriteFinish: shouldCoalesceWriteEvents
782
+ ? {
783
+ stabilityThreshold: 50,
784
+ pollInterval: pollInterval,
785
+ }
786
+ : false,
757
787
  })
758
788
 
759
789
  let chain = Promise.resolve()
@@ -3,6 +3,7 @@ import * as path from 'path'
3
3
  import postcss from 'postcss'
4
4
  import createUtilityPlugin from './util/createUtilityPlugin'
5
5
  import buildMediaQuery from './util/buildMediaQuery'
6
+ import escapeClassName from './util/escapeClassName'
6
7
  import parseAnimationValue from './util/parseAnimationValue'
7
8
  import flattenColorPalette from './util/flattenColorPalette'
8
9
  import withAlphaVariable, { withAlphaValue } from './util/withAlphaVariable'
@@ -26,6 +27,10 @@ export let variantPlugins = {
26
27
 
27
28
  addVariant('placeholder', '&::placeholder')
28
29
 
30
+ /*
31
+ addVariant('backdrop', '&::backdrop')
32
+ */
33
+
29
34
  addVariant('before', ({ container }) => {
30
35
  container.walkRules((rule) => {
31
36
  let foundContent = false
@@ -117,6 +122,9 @@ export let variantPlugins = {
117
122
  'focus',
118
123
  'focus-visible',
119
124
  'active',
125
+ /*
126
+ 'enabled',
127
+ */
120
128
  'disabled',
121
129
  ].map((variant) => (Array.isArray(variant) ? variant : [variant, `:${variant}`]))
122
130
 
@@ -171,7 +179,8 @@ export let variantPlugins = {
171
179
  },
172
180
 
173
181
  darkVariants: ({ config, addVariant }) => {
174
- let mode = config('darkMode', 'media')
182
+ let [mode] = [].concat(config('darkMode', 'media'))
183
+
175
184
  if (mode === false) {
176
185
  mode = 'media'
177
186
  log.warn('darkmode-false', [
@@ -182,7 +191,10 @@ export let variantPlugins = {
182
191
  }
183
192
 
184
193
  if (mode === 'class') {
185
- addVariant('dark', '.dark &')
194
+ addVariant('dark', `.dark &`)
195
+ /*
196
+ addVariant('dark', `${className} &`)
197
+ */
186
198
  } else if (mode === 'media') {
187
199
  addVariant('dark', '@media (prefers-color-scheme: dark)')
188
200
  }
@@ -527,6 +539,43 @@ export let corePlugins = {
527
539
  })
528
540
  },
529
541
 
542
+ /*
543
+ borderSpacing: ({ addDefaults, matchUtilities, theme }) => {
544
+ addDefaults('border-spacing', {
545
+ '--tw-border-spacing-x': 0,
546
+ '--tw-border-spacing-y': 0,
547
+ })
548
+
549
+ matchUtilities(
550
+ {
551
+ 'border-spacing': (value) => {
552
+ return {
553
+ '--tw-border-spacing-x': value,
554
+ '--tw-border-spacing-y': value,
555
+ '@defaults border-spacing': {},
556
+ 'border-spacing': 'var(--tw-border-spacing-x) var(--tw-border-spacing-y)',
557
+ }
558
+ },
559
+ 'border-spacing-x': (value) => {
560
+ return {
561
+ '--tw-border-spacing-x': value,
562
+ '@defaults border-spacing': {},
563
+ 'border-spacing': 'var(--tw-border-spacing-x) var(--tw-border-spacing-y)',
564
+ }
565
+ },
566
+ 'border-spacing-y': (value) => {
567
+ return {
568
+ '--tw-border-spacing-y': value,
569
+ '@defaults border-spacing': {},
570
+ 'border-spacing': 'var(--tw-border-spacing-x) var(--tw-border-spacing-y)',
571
+ }
572
+ },
573
+ },
574
+ { values: theme('borderSpacing') }
575
+ )
576
+ },
577
+ */
578
+
530
579
  transformOrigin: createUtilityPlugin('transformOrigin', [['origin', ['transformOrigin']]]),
531
580
  translate: createUtilityPlugin(
532
581
  'translate',
@@ -611,8 +660,8 @@ export let corePlugins = {
611
660
  })
612
661
  },
613
662
 
614
- animation: ({ matchUtilities, theme, prefix }) => {
615
- let prefixName = (name) => prefix(`.${name}`).slice(1)
663
+ animation: ({ matchUtilities, theme, config }) => {
664
+ let prefixName = (name) => `${config('prefix')}${escapeClassName(name)}`
616
665
  let keyframes = Object.fromEntries(
617
666
  Object.entries(theme('keyframes') ?? {}).map(([key, value]) => {
618
667
  return [key, { [`@keyframes ${prefixName(key)}`]: value }]
@@ -1522,6 +1571,10 @@ export let corePlugins = {
1522
1571
  '.text-center': { 'text-align': 'center' },
1523
1572
  '.text-right': { 'text-align': 'right' },
1524
1573
  '.text-justify': { 'text-align': 'justify' },
1574
+ /*
1575
+ '.text-start': { 'text-align': 'start' },
1576
+ '.text-end': { 'text-align': 'end' },
1577
+ */
1525
1578
  })
1526
1579
  },
1527
1580
 
@@ -1925,6 +1978,9 @@ export let corePlugins = {
1925
1978
  ringWidth: ({ matchUtilities, addDefaults, addUtilities, theme }) => {
1926
1979
  let ringOpacityDefault = theme('ringOpacity.DEFAULT', '0.5')
1927
1980
  let ringColorDefault = withAlphaValue(
1981
+ /*
1982
+ theme('ringColor')?.DEFAULT,
1983
+ */
1928
1984
  theme('ringColor.DEFAULT'),
1929
1985
  ringOpacityDefault,
1930
1986
  `rgb(147 197 253 / ${ringOpacityDefault})`
@@ -1964,10 +2020,16 @@ export let corePlugins = {
1964
2020
  })
1965
2021
  },
1966
2022
 
1967
- ringColor: ({ matchUtilities, theme }) => {
2023
+ ringColor: ({ matchUtilities, theme, corePlugins }) => {
1968
2024
  matchUtilities(
1969
2025
  {
1970
2026
  ring: (value) => {
2027
+ if (!corePlugins('ringOpacity')) {
2028
+ return {
2029
+ '--tw-ring-color': toColorValue(value),
2030
+ }
2031
+ }
2032
+
1971
2033
  return withAlphaVariable({
1972
2034
  color: value,
1973
2035
  property: '--tw-ring-color',
@@ -1,4 +1,4 @@
1
- import chalk from 'chalk'
1
+ import colors from 'picocolors'
2
2
  import log from './util/log'
3
3
 
4
4
  let defaults = {
@@ -41,7 +41,7 @@ export function issueFlagNotices(config) {
41
41
 
42
42
  if (experimentalFlagsEnabled(config).length > 0) {
43
43
  let changes = experimentalFlagsEnabled(config)
44
- .map((s) => chalk.yellow(s))
44
+ .map((s) => colors.yellow(s))
45
45
  .join(', ')
46
46
 
47
47
  log.warn('experimental-flags-enabled', [
package/src/index.js CHANGED
@@ -13,7 +13,23 @@ module.exports = function tailwindcss(configOrPath) {
13
13
  return root
14
14
  },
15
15
  function (root, result) {
16
- processTailwindFeatures(setupTrackingContext(configOrPath))(root, result)
16
+ let context = setupTrackingContext(configOrPath)
17
+
18
+ /*
19
+ if (root.type === 'document') {
20
+ let roots = root.nodes.filter((node) => node.type === 'root')
21
+
22
+ for (const root of roots) {
23
+ if (root.type === 'root') {
24
+ processTailwindFeatures(context)(root, result)
25
+ }
26
+ }
27
+
28
+ return
29
+ }
30
+ */
31
+
32
+ processTailwindFeatures(context)(root, result)
17
33
  },
18
34
  env.DEBUG &&
19
35
  function (root) {
@@ -0,0 +1,52 @@
1
+ import crypto from 'crypto'
2
+ import * as sharedState from './sharedState'
3
+
4
+ /**
5
+ * Calculate the hash of a string.
6
+ *
7
+ * This doesn't need to be cryptographically secure or
8
+ * anything like that since it's used only to detect
9
+ * when the CSS changes to invalidate the context.
10
+ *
11
+ * This is wrapped in a try/catch because it's really dependent
12
+ * on how Node itself is build and the environment and OpenSSL
13
+ * version / build that is installed on the user's machine.
14
+ *
15
+ * Based on the environment this can just outright fail.
16
+ *
17
+ * See https://github.com/nodejs/node/issues/40455
18
+ *
19
+ * @param {string} str
20
+ */
21
+ function getHash(str) {
22
+ try {
23
+ return crypto.createHash('md5').update(str, 'utf-8').digest('binary')
24
+ } catch (err) {
25
+ return ''
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Determine if the CSS tree is different from the
31
+ * previous version for the given `sourcePath`.
32
+ *
33
+ * @param {string} sourcePath
34
+ * @param {import('postcss').Node} root
35
+ */
36
+ export function hasContentChanged(sourcePath, root) {
37
+ let css = root.toString()
38
+
39
+ // We only care about files with @tailwind directives
40
+ // Other files use an existing context
41
+ if (!css.includes('@tailwind')) {
42
+ return false
43
+ }
44
+
45
+ let existingHash = sharedState.sourceHashMap.get(sourcePath)
46
+ let rootHash = getHash(css)
47
+ let didChange = existingHash !== rootHash
48
+
49
+ sharedState.sourceHashMap.set(sourcePath, rootHash)
50
+
51
+ return didChange
52
+ }
@@ -5,7 +5,7 @@ let comparisonMap = {
5
5
  let types = new Set(Object.keys(comparisonMap))
6
6
 
7
7
  export default function collapseAdjacentRules() {
8
- return (root) => {
8
+ function collapseRulesIn(root) {
9
9
  let currentRule = null
10
10
  root.each((node) => {
11
11
  if (!types.has(node.type)) {
@@ -35,5 +35,20 @@ export default function collapseAdjacentRules() {
35
35
  currentRule = node
36
36
  }
37
37
  })
38
+
39
+ // After we've collapsed adjacent rules & at-rules, we need to collapse
40
+ // adjacent rules & at-rules that are children of at-rules.
41
+ // We do not care about nesting rules because Tailwind CSS
42
+ // explicitly does not handle rule nesting on its own as
43
+ // the user is expected to use a nesting plugin
44
+ root.each((node) => {
45
+ if (node.type === 'atrule') {
46
+ collapseRulesIn(node)
47
+ }
48
+ })
49
+ }
50
+
51
+ return (root) => {
52
+ collapseRulesIn(root)
38
53
  }
39
54
  }
@@ -2,16 +2,16 @@ const PATTERNS = [
2
2
  /(?:\['([^'\s]+[^<>"'`\s:\\])')/.source, // ['text-lg' -> text-lg
3
3
  /(?:\["([^"\s]+[^<>"'`\s:\\])")/.source, // ["text-lg" -> text-lg
4
4
  /(?:\[`([^`\s]+[^<>"'`\s:\\])`)/.source, // [`text-lg` -> text-lg
5
- /([^<>"'`\s]*\[\w*'[^"`\s]*'?\])/.source, // font-['some_font',sans-serif]
6
- /([^<>"'`\s]*\[\w*"[^'`\s]*"?\])/.source, // font-["some_font",sans-serif]
5
+ /([^${(<>"'`\s]*\[\w*'[^"`\s]*'?\])/.source, // font-['some_font',sans-serif]
6
+ /([^${(<>"'`\s]*\[\w*"[^'`\s]*"?\])/.source, // font-["some_font",sans-serif]
7
7
  /([^<>"'`\s]*\[\w*\('[^"'`\s]*'\)\])/.source, // bg-[url('...')]
8
8
  /([^<>"'`\s]*\[\w*\("[^"'`\s]*"\)\])/.source, // bg-[url("...")]
9
9
  /([^<>"'`\s]*\[\w*\('[^"`\s]*'\)\])/.source, // bg-[url('...'),url('...')]
10
10
  /([^<>"'`\s]*\[\w*\("[^'`\s]*"\)\])/.source, // bg-[url("..."),url("...")]
11
11
  /([^<>"'`\s]*\[[^<>"'`\s]*\('[^"`\s]*'\)+\])/.source, // h-[calc(100%-theme('spacing.1'))]
12
12
  /([^<>"'`\s]*\[[^<>"'`\s]*\("[^'`\s]*"\)+\])/.source, // h-[calc(100%-theme("spacing.1"))]
13
- /([^<>"'`\s]*\['[^"'`\s]*'\])/.source, // `content-['hello']` but not `content-['hello']']`
14
- /([^<>"'`\s]*\["[^"'`\s]*"\])/.source, // `content-["hello"]` but not `content-["hello"]"]`
13
+ /([^${(<>"'`\s]*\['[^"'`\s]*'\])/.source, // `content-['hello']` but not `content-['hello']']`
14
+ /([^${(<>"'`\s]*\["[^"'`\s]*"\])/.source, // `content-["hello"]` but not `content-["hello"]"]`
15
15
  /([^<>"'`\s]*\[[^<>"'`\s]*:[^\]\s]*\])/.source, // `[attr:value]`
16
16
  /([^<>"'`\s]*\[[^<>"'`\s]*:'[^"'`\s]*'\])/.source, // `[content:'hello']` but not `[content:"hello"]`
17
17
  /([^<>"'`\s]*\[[^<>"'`\s]*:"[^"'`\s]*"\])/.source, // `[content:"hello"]` but not `[content:'hello']`