[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> class-wp-styles.php (source)

   1  <?php
   2  /**
   3   * Dependencies API: WP_Styles class
   4   *
   5   * @since 2.6.0
   6   *
   7   * @package WordPress
   8   * @subpackage Dependencies
   9   */
  10  
  11  /**
  12   * Core class used to register styles.
  13   *
  14   * @since 2.6.0
  15   *
  16   * @see WP_Dependencies
  17   */
  18  class WP_Styles extends WP_Dependencies {
  19      /**
  20       * Base URL for styles.
  21       *
  22       * Full URL with trailing slash.
  23       *
  24       * @since 2.6.0
  25       * @see wp_default_styles()
  26       * @var string|null
  27       */
  28      public $base_url;
  29  
  30      /**
  31       * URL of the content directory.
  32       *
  33       * @since 2.8.0
  34       * @see wp_default_styles()
  35       * @var string|null
  36       */
  37      public $content_url;
  38  
  39      /**
  40       * Default version string for stylesheets.
  41       *
  42       * @since 2.6.0
  43       * @see wp_default_styles()
  44       * @var string|null
  45       */
  46      public $default_version;
  47  
  48      /**
  49       * The current text direction.
  50       *
  51       * @since 2.6.0
  52       * @see wp_default_styles()
  53       * @var string
  54       */
  55      public $text_direction = 'ltr';
  56  
  57      /**
  58       * Holds a list of style handles which will be concatenated.
  59       *
  60       * @since 2.8.0
  61       * @var string
  62       */
  63      public $concat = '';
  64  
  65      /**
  66       * Holds a string which contains style handles and their version.
  67       *
  68       * @since 2.8.0
  69       * @deprecated 3.4.0
  70       * @var string
  71       */
  72      public $concat_version = '';
  73  
  74      /**
  75       * Whether to perform concatenation.
  76       *
  77       * @since 2.8.0
  78       * @var bool
  79       */
  80      public $do_concat = false;
  81  
  82      /**
  83       * Holds HTML markup of styles and additional data if concatenation
  84       * is enabled.
  85       *
  86       * @since 2.8.0
  87       * @var string
  88       */
  89      public $print_html = '';
  90  
  91      /**
  92       * Holds inline styles if concatenation is enabled.
  93       *
  94       * @since 3.3.0
  95       * @var string
  96       */
  97      public $print_code = '';
  98  
  99      /**
 100       * List of default directories.
 101       *
 102       * @since 2.8.0
 103       * @see wp_default_styles()
 104       * @var string[]|null
 105       */
 106      public $default_dirs;
 107  
 108      /**
 109       * Constructor.
 110       *
 111       * @since 2.6.0
 112       */
 113  	public function __construct() {
 114          /**
 115           * Fires when the WP_Styles instance is initialized.
 116           *
 117           * @since 2.6.0
 118           *
 119           * @param WP_Styles $wp_styles WP_Styles instance (passed by reference).
 120           */
 121          do_action_ref_array( 'wp_default_styles', array( &$this ) );
 122      }
 123  
 124      /**
 125       * Processes a style dependency.
 126       *
 127       * @since 2.6.0
 128       * @since 5.5.0 Added the `$group` parameter.
 129       *
 130       * @see WP_Dependencies::do_item()
 131       *
 132       * @param string    $handle The style's registered handle.
 133       * @param int|false $group  Optional. Group level: level (int), no groups (false).
 134       *                          Default false.
 135       * @return bool True on success, false on failure.
 136       */
 137  	public function do_item( $handle, $group = false ) {
 138          if ( ! parent::do_item( $handle ) ) {
 139              return false;
 140          }
 141  
 142          $obj = $this->registered[ $handle ];
 143          if ( $obj->extra['conditional'] ?? false ) {
 144  
 145              return false;
 146          }
 147          if ( null === $obj->ver ) {
 148              $ver = '';
 149          } else {
 150              $ver = $obj->ver ? $obj->ver : $this->default_version;
 151          }
 152  
 153          if ( isset( $this->args[ $handle ] ) ) {
 154              $ver = $ver ? $ver . '&amp;' . $this->args[ $handle ] : $this->args[ $handle ];
 155          }
 156  
 157          $src          = $obj->src;
 158          $inline_style = $this->print_inline_style( $handle, false );
 159  
 160          if ( $inline_style ) {
 161              $processor = new WP_HTML_Tag_Processor( '<style></style>' );
 162              $processor->next_tag();
 163              $processor->set_attribute( 'id', "{$handle}-inline-css" );
 164              $processor->set_modifiable_text( "\n{$inline_style}\n" );
 165              $inline_style_tag = "{$processor->get_updated_html()}\n";
 166          } else {
 167              $inline_style_tag = '';
 168          }
 169  
 170          if ( $this->do_concat ) {
 171              if ( is_string( $src ) && $this->in_default_dir( $src ) && ! isset( $obj->extra['alt'] ) ) {
 172                  $this->concat         .= "$handle,";
 173                  $this->concat_version .= "$handle$ver";
 174  
 175                  $this->print_code .= $inline_style;
 176  
 177                  return true;
 178              }
 179          }
 180  
 181          $media = $obj->args ?? 'all';
 182  
 183          // A single item may alias a set of items, by having dependencies, but no source.
 184          if ( ! $src ) {
 185              if ( $inline_style_tag ) {
 186                  if ( $this->do_concat ) {
 187                      $this->print_html .= $inline_style_tag;
 188                  } else {
 189                      echo $inline_style_tag;
 190                  }
 191              }
 192  
 193              return true;
 194          }
 195  
 196          $href = $this->_css_href( $src, $obj->ver, $handle );
 197          if ( ! $href ) {
 198              return true;
 199          }
 200  
 201          $rel   = isset( $obj->extra['alt'] ) && $obj->extra['alt'] ? 'alternate stylesheet' : 'stylesheet';
 202          $title = $obj->extra['title'] ?? '';
 203  
 204          $tag = sprintf(
 205              "<link rel='%s' id='%s-css'%s href='%s' media='%s' />\n",
 206              $rel,
 207              esc_attr( $handle ),
 208              $title ? sprintf( " title='%s'", esc_attr( $title ) ) : '',
 209              $href,
 210              esc_attr( $media )
 211          );
 212  
 213          /**
 214           * Filters the HTML link tag of an enqueued style.
 215           *
 216           * @since 2.6.0
 217           * @since 4.3.0 Introduced the `$href` parameter.
 218           * @since 4.5.0 Introduced the `$media` parameter.
 219           *
 220           * @param string $tag    The link tag for the enqueued style.
 221           * @param string $handle The style's registered handle.
 222           * @param string $href   The stylesheet's source URL.
 223           * @param string $media  The stylesheet's media attribute.
 224           */
 225          $tag = apply_filters( 'style_loader_tag', $tag, $handle, $href, $media );
 226  
 227          if ( 'rtl' === $this->text_direction && isset( $obj->extra['rtl'] ) && $obj->extra['rtl'] ) {
 228              if ( is_bool( $obj->extra['rtl'] ) || 'replace' === $obj->extra['rtl'] ) {
 229                  $suffix   = $obj->extra['suffix'] ?? '';
 230                  $rtl_href = str_replace( "{$suffix}.css", "-rtl{$suffix}.css", $this->_css_href( $src, $ver, "$handle-rtl" ) );
 231              } else {
 232                  $rtl_href = $this->_css_href( $obj->extra['rtl'], $ver, "$handle-rtl" );
 233              }
 234  
 235              $rtl_tag = sprintf(
 236                  "<link rel='%s' id='%s-rtl-css'%s href='%s' media='%s' />\n",
 237                  $rel,
 238                  esc_attr( $handle ),
 239                  $title ? sprintf( " title='%s'", esc_attr( $title ) ) : '',
 240                  $rtl_href,
 241                  esc_attr( $media )
 242              );
 243  
 244              /** This filter is documented in wp-includes/class-wp-styles.php */
 245              $rtl_tag = apply_filters( 'style_loader_tag', $rtl_tag, $handle, $rtl_href, $media );
 246  
 247              if ( 'replace' === $obj->extra['rtl'] ) {
 248                  $tag = $rtl_tag;
 249              } else {
 250                  $tag .= $rtl_tag;
 251              }
 252          }
 253  
 254          if ( $this->do_concat ) {
 255              $this->print_html .= $tag;
 256              if ( $inline_style_tag ) {
 257                  $this->print_html .= $inline_style_tag;
 258              }
 259          } else {
 260              echo $tag;
 261              $this->print_inline_style( $handle );
 262          }
 263  
 264          return true;
 265      }
 266  
 267      /**
 268       * Adds extra CSS styles to a registered stylesheet.
 269       *
 270       * @since 3.3.0
 271       *
 272       * @param string $handle The style's registered handle.
 273       * @param string $code   String containing the CSS styles to be added.
 274       * @return bool True on success, false on failure.
 275       */
 276  	public function add_inline_style( $handle, $code ) {
 277          if ( ! $code ) {
 278              return false;
 279          }
 280  
 281          $after = $this->get_data( $handle, 'after' );
 282          if ( ! $after ) {
 283              $after = array();
 284          }
 285  
 286          $after[] = $code;
 287  
 288          return $this->add_data( $handle, 'after', $after );
 289      }
 290  
 291      /**
 292       * Prints extra CSS styles of a registered stylesheet.
 293       *
 294       * @since 3.3.0
 295       *
 296       * @param string $handle  The style's registered handle.
 297       * @param bool   $display Optional. Whether to print the inline style
 298       *                        instead of just returning it. Default true.
 299       * @return string|bool False if no data exists, inline styles if `$display` is true,
 300       *                     true otherwise.
 301       */
 302  	public function print_inline_style( $handle, $display = true ) {
 303          $output = $this->get_data( $handle, 'after' );
 304  
 305          if ( empty( $output ) || ! is_array( $output ) ) {
 306              return false;
 307          }
 308  
 309          if ( ! $this->do_concat ) {
 310  
 311              // Obtain the original `src` for a stylesheet possibly inlined by wp_maybe_inline_styles().
 312              $inlined_src = $this->get_data( $handle, 'inlined_src' );
 313  
 314              // If there's only one `after` inline style, and that inline style had been inlined, then use the $inlined_src
 315              // as the sourceURL. Otherwise, if there is more than one inline `after` style associated with the handle,
 316              // then resort to using the handle to construct the sourceURL since there isn't a single source.
 317              if ( count( $output ) === 1 && is_string( $inlined_src ) && strlen( $inlined_src ) > 0 ) {
 318                  $source_url = esc_url_raw( $inlined_src );
 319              } else {
 320                  $source_url = rawurlencode( "{$handle}-inline-css" );
 321              }
 322  
 323              $output[] = sprintf(
 324                  '/*# sourceURL=%s */',
 325                  $source_url
 326              );
 327          }
 328  
 329          $output = implode( "\n", $output );
 330  
 331          if ( ! $display ) {
 332              return $output;
 333          }
 334  
 335          $processor = new WP_HTML_Tag_Processor( '<style></style>' );
 336          $processor->next_tag();
 337          $processor->set_attribute( 'id', "{$handle}-inline-css" );
 338          $processor->set_modifiable_text( "\n{$output}\n" );
 339          echo "{$processor->get_updated_html()}\n";
 340  
 341          return true;
 342      }
 343  
 344      /**
 345       * Overrides the add_data method from WP_Dependencies, to allow unsetting dependencies for conditional styles.
 346       *
 347       * @since 6.9.0
 348       *
 349       * @param string $handle Name of the item. Should be unique.
 350       * @param string $key    The data key.
 351       * @param mixed  $value  The data value.
 352       * @return bool True on success, false on failure.
 353       */
 354  	public function add_data( $handle, $key, $value ) {
 355          if ( ! isset( $this->registered[ $handle ] ) ) {
 356              return false;
 357          }
 358  
 359          if ( 'conditional' === $key ) {
 360              $this->registered[ $handle ]->deps = array();
 361          }
 362  
 363          return parent::add_data( $handle, $key, $value );
 364      }
 365  
 366      /**
 367       * Determines style dependencies.
 368       *
 369       * @since 2.6.0
 370       *
 371       * @see WP_Dependencies::all_deps()
 372       *
 373       * @param string|string[] $handles   Item handle (string) or item handles (array of strings).
 374       * @param bool            $recursion Optional. Internal flag that function is calling itself.
 375       *                                   Default false.
 376       * @param int|false       $group     Optional. Group level: level (int), no groups (false).
 377       *                                   Default false.
 378       * @return bool True on success, false on failure.
 379       */
 380  	public function all_deps( $handles, $recursion = false, $group = false ) {
 381          $result = parent::all_deps( $handles, $recursion, $group );
 382          if ( ! $recursion ) {
 383              /**
 384               * Filters the array of enqueued styles before processing for output.
 385               *
 386               * @since 2.6.0
 387               *
 388               * @param string[] $to_do The list of enqueued style handles about to be processed.
 389               */
 390              $this->to_do = apply_filters( 'print_styles_array', $this->to_do );
 391          }
 392          return $result;
 393      }
 394  
 395      /**
 396       * Generates an enqueued style's fully-qualified URL.
 397       *
 398       * @since 2.6.0
 399       *
 400       * @param string            $src    The source of the enqueued style.
 401       * @param string|false|null $ver    The version of the enqueued style.
 402       * @param string            $handle The style's registered handle.
 403       * @return string Style's fully-qualified URL.
 404       */
 405  	public function _css_href( $src, $ver, $handle ) {
 406          if ( ! is_bool( $src ) && ! preg_match( '|^(https?:)?//|', $src ) && ! ( $this->content_url && str_starts_with( $src, $this->content_url ) ) ) {
 407              $src = $this->base_url . $src;
 408          }
 409  
 410          $query_args = array();
 411          if ( empty( $ver ) && null !== $ver && is_string( $this->default_version ) ) {
 412              $query_args['ver'] = $this->default_version;
 413          } elseif ( is_scalar( $ver ) ) {
 414              $query_args['ver'] = (string) $ver;
 415          }
 416          if ( isset( $this->args[ $handle ] ) ) {
 417              parse_str( $this->args[ $handle ], $parsed_args );
 418              if ( $parsed_args ) {
 419                  $query_args = array_merge( $query_args, $parsed_args );
 420              }
 421          }
 422          $src = add_query_arg( rawurlencode_deep( $query_args ), $src );
 423  
 424          /**
 425           * Filters an enqueued style's fully-qualified URL.
 426           *
 427           * @since 2.6.0
 428           *
 429           * @param string $src    The source URL of the enqueued style.
 430           * @param string $handle The style's registered handle.
 431           */
 432          $src = apply_filters( 'style_loader_src', $src, $handle );
 433          return esc_url( $src );
 434      }
 435  
 436      /**
 437       * Whether a handle's source is in a default directory.
 438       *
 439       * @since 2.8.0
 440       *
 441       * @param string $src The source of the enqueued style.
 442       * @return bool True if found, false if not.
 443       */
 444  	public function in_default_dir( $src ) {
 445          if ( ! $this->default_dirs ) {
 446              return true;
 447          }
 448  
 449          foreach ( (array) $this->default_dirs as $test ) {
 450              if ( str_starts_with( $src, $test ) ) {
 451                  return true;
 452              }
 453          }
 454          return false;
 455      }
 456  
 457      /**
 458       * Processes items and dependencies for the footer group.
 459       *
 460       * HTML 5 allows styles in the body, grab late enqueued items and output them in the footer.
 461       *
 462       * @since 3.3.0
 463       *
 464       * @see WP_Dependencies::do_items()
 465       *
 466       * @return string[] Handles of items that have been processed.
 467       */
 468  	public function do_footer_items() {
 469          $this->do_items( false, 1 );
 470          return $this->done;
 471      }
 472  
 473      /**
 474       * Resets class properties.
 475       *
 476       * @since 3.3.0
 477       */
 478  	public function reset() {
 479          $this->do_concat      = false;
 480          $this->concat         = '';
 481          $this->concat_version = '';
 482          $this->print_html     = '';
 483      }
 484  
 485      /**
 486       * Gets a style-specific dependency warning message.
 487       *
 488       * @since 6.9.1
 489       *
 490       * @param string   $handle                     Style handle with missing dependencies.
 491       * @param string[] $missing_dependency_handles Missing dependency handles.
 492       * @return string Formatted, localized warning message.
 493       */
 494  	protected function get_dependency_warning_message( $handle, $missing_dependency_handles ) {
 495          return sprintf(
 496              /* translators: 1: Style handle, 2: Comma-separated list of missing dependency handles. */
 497              __( 'The style with the handle "%1$s" was enqueued with dependencies that are not registered: %2$s.' ),
 498              $handle,
 499              implode( ', ', $missing_dependency_handles )
 500          );
 501      }
 502  }


Generated : Sat Mar 7 08:20:03 2026 Cross-referenced by PHPXref