Remove text opacity CSS variables from ::marker (#8622)

* Refactor

* Allow parallel variant fns to mutate the container

* Remove text color variable from marker pseudo class

wip

* Update changelog
This commit is contained in:
Jordan Pittman 2022-06-14 10:09:09 -04:00 • committed by GitHub
parent 22eaad17c3
commit 15dc5a3da9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 115 additions and 32 deletions

View file

@ -14,6 +14,7 @@ import { version as tailwindVersion } from '../package.json'
import log from './util/log'
import { normalizeScreens } from './util/normalizeScreens'
import { formatBoxShadowValue, parseBoxShadowValue } from './util/parseBoxShadowValue'
import { removeAlphaVariables } from './util/removeAlphaVariables'
import { flagEnabled } from './featureFlags'
export let variantPlugins = {
@ -21,7 +22,19 @@ export let variantPlugins = {
addVariant('first-letter', '&::first-letter')
addVariant('first-line', '&::first-line')
addVariant('marker', ['& *::marker', '&::marker'])
addVariant('marker', [
({ container }) => {
removeAlphaVariables(container, ['--tw-text-opacity'])
return '& *::marker'
},
({ container }) => {
removeAlphaVariables(container, ['--tw-text-opacity'])
return '&::marker'
},
])
addVariant('selection', ['& *::selection', '&::selection'])
addVariant('file', '&::file-selector-button')
@ -77,21 +90,11 @@ export let variantPlugins = {
[
'visited',
({ container }) => {
let toRemove = ['--tw-text-opacity', '--tw-border-opacity', '--tw-bg-opacity']
container.walkDecls((decl) => {
if (toRemove.includes(decl.prop)) {
decl.remove()
return
}
for (const varName of toRemove) {
if (decl.value.includes(`/ var(${varName})`)) {
decl.value = decl.value.replace(`/ var(${varName})`, '')
}
}
})
removeAlphaVariables(container, [
'--tw-text-opacity',
'--tw-border-opacity',
'--tw-bg-opacity',
])
return '&:visited'
},

View file

@ -163,15 +163,17 @@ function applyVariant(variant, matches, context) {
let container = postcss.root({ nodes: [rule.clone()] })
for (let [variantSort, variantFunction] of variantFunctionTuples) {
let clone = container.clone()
for (let [variantSort, variantFunction, containerFromArray] of variantFunctionTuples) {
let clone = containerFromArray ?? container.clone()
let collectedFormats = []
let originals = new Map()
function prepareBackup() {
if (originals.size > 0) return // Already prepared, chicken out
clone.walkRules((rule) => originals.set(rule, rule.selector))
// Already prepared, chicken out
if (clone.raws.neededBackup) {
return
}
clone.raws.neededBackup = true
clone.walkRules((rule) => (rule.raws.originalSelector = rule.selector))
}
function modifySelectors(modifierFunction) {
@ -231,6 +233,10 @@ function applyVariant(variant, matches, context) {
// reserving additional X places for these 'unknown' variants in between.
variantSort | BigInt(idx << ruleWithVariant.length),
variantFunction,
// If the clone has been modified we have to pass that back
// though so each rule can use the modified container
clone.clone(),
])
}
continue
@ -244,13 +250,15 @@ function applyVariant(variant, matches, context) {
continue
}
// We filled the `originals`, therefore we assume that somebody touched
// We had to backup selectors, therefore we assume that somebody touched
// `container` or `modifySelectors`. Let's see if they did, so that we
// can restore the selectors, and collect the format strings.
if (originals.size > 0) {
if (clone.raws.neededBackup) {
delete clone.raws.neededBackup
clone.walkRules((rule) => {
if (!originals.has(rule)) return
let before = originals.get(rule)
let before = rule.raws.originalSelector
if (!before) return
delete rule.raws.originalSelector
if (before === rule.selector) return // No mutation happened
let modified = rule.selector

View file

@ -0,0 +1,24 @@
/**
* This function removes any uses of CSS variables used as an alpha channel
*
* This is required for selectors like `:visited` which do not allow
* changes in opacity or external control using CSS variables.
*
* @param {import('postcss').Container} container
* @param {string[]} toRemove
*/
export function removeAlphaVariables(container, toRemove) {
container.walkDecls((decl) => {
if (toRemove.includes(decl.prop)) {
decl.remove()
return
}
for (let varName of toRemove) {
if (decl.value.includes(`/ var(${varName})`)) {
decl.value = decl.value.replace(`/ var(${varName})`, '')
}
}
})
}