Changeset 64597 for trunk/src/wp-includes/class-wp-theme-json.php
- Timestamp:
- 10/20/2026 11:50:22 AM (17 hours ago)
- File:
-
- 1 edited
-
trunk/src/wp-includes/class-wp-theme-json.php (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-theme-json.php
r64590 r64597 658 658 * Defines which pseudo selectors are enabled for which elements. 659 659 * 660 * The order of the selectors should be: link, any-link, visited, hover, focus, focus-visible, active.661 * This is to ensure the user action (hover, focus and active) styles have a higher662 * specificity than the visited styles, which in turn have a higher specificity than663 * the unvisited styles.660 * The selector order controls the cascade when multiple states match. Link and button 661 * selectors follow the LVHA order, with focus-visible immediately after focus. Text input 662 * validation states come before the focus states because an edited field can match both 663 * at once, so user action styles must be output last to win. 664 664 * 665 665 * See https://core.trac.wordpress.org/ticket/56928. … … 670 670 * @since 6.8.0 Added support for ':focus-visible'. 671 671 * @since 6.9.0 Added `textInput` and `select` elements. 672 * @since 7.2.0 Added ':required', ':user-valid', ':user-invalid', ':focus', ':focus-visible', 673 * and '::placeholder' support for the text input element. 672 674 * @var array 673 675 */ 674 676 const VALID_ELEMENT_PSEUDO_SELECTORS = array( 675 'link' => array( ':link', ':any-link', ':visited', ':hover', ':focus', ':focus-visible', ':active' ), 676 'button' => array( ':link', ':any-link', ':visited', ':hover', ':focus', ':focus-visible', ':active' ), 677 'link' => array( ':link', ':any-link', ':visited', ':hover', ':focus', ':focus-visible', ':active' ), 678 'button' => array( ':link', ':any-link', ':visited', ':hover', ':focus', ':focus-visible', ':active' ), 679 'textInput' => array( ':required', ':user-valid', ':user-invalid', ':focus', ':focus-visible', '::placeholder' ), 677 680 ); 678 681 … … 1587 1590 1588 1591 return $output; 1592 } 1593 1594 /** 1595 * Determines whether a pseudo selector is a pseudo-element, e.g. '::placeholder'. 1596 * 1597 * Pseudo-elements are not valid inside `:where()`, so rules that target them 1598 * cannot use the `:root :where()` specificity wrapper. 1599 * 1600 * @since 7.2.0 1601 * 1602 * @param string|null $pseudo_selector Pseudo selector to check, e.g. ':hover' or '::placeholder'. 1603 * @return bool True if the pseudo selector is a pseudo-element. 1604 */ 1605 protected static function is_pseudo_element( $pseudo_selector ) { 1606 return is_string( $pseudo_selector ) && str_starts_with( $pseudo_selector, '::' ); 1607 } 1608 1609 /** 1610 * Builds the specificity-capped selector for a pseudo selector rule. 1611 * 1612 * Pseudo-classes are appended to each part of the base selector inside the 1613 * `:root :where()` wrapper, e.g. `:root :where(a:hover)`. Pseudo-elements are 1614 * not valid inside `:where()`, so they are appended after the wrapper instead, 1615 * e.g. `:root :where(textarea, input)::placeholder`, which keeps the same 1616 * specificity regardless of where the element styles are defined. 1617 * 1618 * @since 7.2.0 1619 * 1620 * @param string $base_selector Selector without the pseudo selector, e.g. 'textarea, input'. 1621 * @param string $pseudo_selector Pseudo selector to apply, e.g. ':hover' or '::placeholder'. 1622 * @return string The selector to use for the rule. 1623 */ 1624 protected static function get_pseudo_rule_selector( $base_selector, $pseudo_selector ) { 1625 if ( static::is_pseudo_element( $pseudo_selector ) ) { 1626 return ':root :where(' . $base_selector . ')' . $pseudo_selector; 1627 } 1628 1629 return ':root :where(' . static::append_to_selector( $base_selector, $pseudo_selector ) . ')'; 1589 1630 } 1590 1631 … … 4276 4317 } 4277 4318 4278 $pseudo_selector_ruleset = static::to_ruleset( ':root :where(' . static::append_to_selector( $variation_element_selector, $pseudo_selector ) . ')', $pseudo_declarations );4319 $pseudo_selector_ruleset = static::to_ruleset( static::get_pseudo_rule_selector( $variation_element_selector, $pseudo_selector ), $pseudo_declarations ); 4279 4320 $variation_responsive_pseudo_css .= $breakpoint_media . '{' . $pseudo_selector_ruleset . '}'; 4280 4321 } … … 4421 4462 * still need to be wrapped in `:root :where` to cap specificity for nested 4422 4463 * variations etc. Pseudo selectors won't match the ELEMENTS selector exactly. 4464 * 4465 * Pseudo-elements, e.g. ::placeholder, are not valid inside `:where()`, so 4466 * they are appended after the wrapper instead. 4423 4467 */ 4424 4468 $element_only_selector = $is_root_selector || ( … … 4431 4475 4432 4476 // 2. Generate and append the rules that use the general selector. 4433 $general_selector = $element_only_selector ? $selector : ":root :where($selector)"; 4434 $block_rules .= static::to_ruleset( $general_selector, $declarations ); 4477 if ( static::is_pseudo_element( $pseudo_selector ) ) { 4478 // The node selector already carries the pseudo-element on each part, so strip it to get the base selector. 4479 $general_selector = static::get_pseudo_rule_selector( str_replace( $pseudo_selector, '', $selector ), $pseudo_selector ); 4480 } else { 4481 $general_selector = $element_only_selector ? $selector : ":root :where($selector)"; 4482 } 4483 $block_rules .= static::to_ruleset( $general_selector, $declarations ); 4435 4484 4436 4485 // 3. Generate and append the rules that use the duotone selector.
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)