ProShell v2.0
Dashboard
Server Info
Server: 158.106.128.192
PHP: 8.2.33
home
planet5
public_html
bansibaba.com
wp-includes
2026-09-15 18:24:05
Editing: DetermineHeroImages.php
Cancel
Save Changes
<?php /** * Class DetermineHeroImages. * * @package AmpProject\AmpWP */ namespace AmpProject\AmpWP\Optimizer\Transformer; use AmpProject\Dom\Document; use AmpProject\Dom\Element; use AmpProject\Html\Attribute; use AmpProject\Optimizer\ErrorCollection; use AmpProject\Optimizer\ImageDimensions; use AmpProject\Optimizer\Transformer; /** * Determine the images to flag with data-hero-candidate so the Optimizer can prerender them. * * This transformer checks for the following images in the given order: * 1. Header images (including Custom Logo and Custom Header) * 2. Image which is descendant of first child of first entry content * * @package AmpProject\AmpWP * @since 2.1 * @internal */ final class DetermineHeroImages implements Transformer { /** * XPath query to find preceding images which are not lazy-loaded. * * @var string */ const PRECEDING_NON_LAZY_IMAGE_XPATH_QUERY = "preceding::amp-img[ not( @data-hero ) ][ not( noscript/img/@loading ) or noscript/img/@loading != 'lazy' ]"; /** * XPath query to find the first entry-content. * * Note that the 'entry-content' class name is the classic form for what the h-entry spec now has as 'e-content'. * The 'amp-wp-article-content' class name is used in legacy Reader templates. Note that 'entry-content' isn't * simply just added to templates/single.php and templates/page.php because these templates are frequently forked. * * @link https://microformats.org/wiki/h-entry * @var string */ const FIRST_ENTRY_CONTENT_XPATH_QUERY = " .//*[ @class ][ contains( concat( ' ', normalize-space( @class ), ' ' ), ' entry-content ' ) or contains( concat( ' ', normalize-space( @class ), ' ' ), ' e-content ' ) or contains( concat( ' ', normalize-space( @class ), ' ' ), ' amp-wp-article-content ' ) ] "; /** * XPath query to find an image at the beginning of entry content (including nested inside of another block). * * @var string */ const INITIAL_CONTENT_IMAGE_XPATH_QUERY = './*[1]//amp-img[ not( @data-hero ) ]'; /** * Apply transformations to the provided DOM document. * * @param Document $document DOM document to apply the * transformations to. * @param ErrorCollection $errors Collection of errors that are collected * during transformation. * @return void */ public function transform( Document $document, ErrorCollection $errors ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable $hero_image_elements = []; foreach ( [ 'header_images', 'initial_content_image' ] as $hero_image_source ) { $candidate = null; switch ( $hero_image_source ) { case 'header_images': $candidate = $this->get_header_images( $document ); break; case 'initial_content_image': $candidate = $this->get_initial_content_image( $document ); break; } if ( $candidate instanceof Element ) { $hero_image_elements[ spl_object_hash( $candidate ) ] = $candidate; } elseif ( is_array( $candidate ) ) { foreach ( $candidate as $hero_image_element ) { $hero_image_elements[ spl_object_hash( $hero_image_element ) ] = $hero_image_element; } } } $this->add_data_hero_candidate_attribute( array_values( $hero_image_elements ) ); } /** * Retrieve the images in the header. * * This returns all non-tiny images which occur before the main content, or else a tiny image that has `logo` in the * class name. * * Note that the `HeroCandidateFiltering` service will have already identified the Header Image and Custom Logo for * any theme using the standard `the_header_image_tag()` and `the_custom_logo()` template tags, respectively. This * remains for here as a fallback to identify Header Images and Custom Logos being rendered via non-standard * template tags. * * @see \AmpProject\AmpWP\Optimizer\HeroCandidateFiltering::add_custom_logo_data_hero_candidate_attribute() * @see \AmpProject\AmpWP\Optimizer\HeroCandidateFiltering::filter_header_image_tag() * * @param Document $document Document to retrieve the header images from. * @return Element[] Header images. */ private function get_header_images( Document $document ) { // Note that 3,508 out of 3,923 themes on WP.org (89%) use the <main> element. $after_header_element = $document->getElementsByTagName( 'main' )->item( 0 ); // If a theme happens to not use the <main> element, then fall back to using the first entry-content. if ( ! $after_header_element instanceof Element ) { $after_header_element = $this->get_first_entry_content( $document ); } if ( ! $after_header_element instanceof Element ) { return []; } $query = $document->xpath->query( self::PRECEDING_NON_LAZY_IMAGE_XPATH_QUERY, $after_header_element ); return array_filter( iterator_to_array( $query ), static function ( Element $element ) { // A custom logo may in fact be tiny and yet since it is in the header it should be prerendered. // Note that a theme may not be using `the_custom_logo()` template tag and that is why the `custom-logo` // class is not being checked for specifically. if ( $element->hasAttribute( Attribute::CLASS_ ) && false !== strpos( $element->getAttribute( Attribute::CLASS_ ), 'logo' ) ) { return true; } return ! ( new ImageDimensions( $element ) )->isTiny(); } ); } /** * Retrieve the first entry content. * * @param Document $document Document to retrieve the first entry content from. * @return Element|null First entry content element. */ private function get_first_entry_content( Document $document ) { $query = $document->xpath->query( self::FIRST_ENTRY_CONTENT_XPATH_QUERY, $document->body ); $entry_content = $query->item( 0 ); return $entry_content instanceof Element ? $entry_content : null; } /** * Retrieve the first image that is in the first position in content. * * @param Document $document Document to retrieve the image from. * @return Element|null Image at the beginning of the first entry content. */ private function get_initial_content_image( Document $document ) { $entry_content = $this->get_first_entry_content( $document ); if ( ! $entry_content instanceof Element ) { return null; } $query = $document->xpath->query( self::INITIAL_CONTENT_IMAGE_XPATH_QUERY, $entry_content ); $image = $query->item( 0 ); if ( $image instanceof Element && ! ( new ImageDimensions( $image ) )->isTiny() ) { return $image; } return null; } /** * Add the data-hero attribute to viable hero images. * * @param Element[] $hero_image_elements Elements that are viable hero images. */ private function add_data_hero_candidate_attribute( $hero_image_elements ) { foreach ( $hero_image_elements as $hero_image_element ) { $hero_image_element->setAttribute( Attribute::DATA_HERO_CANDIDATE, null ); } } }
Upload Files
Cancel
Upload
Create New
Cancel
Create
Change Permissions
Cancel
Save
Change Date
Cancel
Save
Rename Item
Cancel
Save
Confirm Delete
Are you sure you want to delete the selected items?
Cancel
Delete