|
|
|
|
@@ -1058,13 +1058,19 @@ function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = f
|
|
|
|
|
* @param string $context The context. Default 'wp_get_attachment_image'.
|
|
|
|
|
*/
|
|
|
|
|
$context = apply_filters( 'wp_get_attachment_image_context', 'wp_get_attachment_image' );
|
|
|
|
|
$attr = wp_parse_args( $attr, $default_attr );
|
|
|
|
|
|
|
|
|
|
// Add `loading` attribute.
|
|
|
|
|
if ( wp_lazy_loading_enabled( 'img', $context ) ) {
|
|
|
|
|
$default_attr['loading'] = wp_get_loading_attr_default( $context );
|
|
|
|
|
}
|
|
|
|
|
$loading_attr = $attr;
|
|
|
|
|
$loading_attr['width'] = $width;
|
|
|
|
|
$loading_attr['height'] = $height;
|
|
|
|
|
$loading_optimization_attr = wp_get_loading_optimization_attributes(
|
|
|
|
|
'img',
|
|
|
|
|
$loading_attr,
|
|
|
|
|
$context
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$attr = wp_parse_args( $attr, $default_attr );
|
|
|
|
|
// Add loading optimization attributes if not available.
|
|
|
|
|
$attr = array_merge( $attr, $loading_optimization_attr );
|
|
|
|
|
|
|
|
|
|
// Omit the `decoding` attribute if the value is invalid according to the spec.
|
|
|
|
|
if ( empty( $attr['decoding'] ) || ! in_array( $attr['decoding'], array( 'async', 'sync', 'auto' ), true ) ) {
|
|
|
|
|
@@ -1073,10 +1079,15 @@ function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = f
|
|
|
|
|
|
|
|
|
|
// If the default value of `lazy` for the `loading` attribute is overridden
|
|
|
|
|
// to omit the attribute for this image, ensure it is not included.
|
|
|
|
|
if ( array_key_exists( 'loading', $attr ) && ! $attr['loading'] ) {
|
|
|
|
|
if ( isset( $attr['loading'] ) && ! $attr['loading'] ) {
|
|
|
|
|
unset( $attr['loading'] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the `fetchpriority` attribute is overridden and set to false or an empty string.
|
|
|
|
|
if ( isset( $attr['fetchpriority'] ) && ! $attr['fetchpriority'] ) {
|
|
|
|
|
unset( $attr['fetchpriority'] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generate 'srcset' and 'sizes' if not already present.
|
|
|
|
|
if ( empty( $attr['srcset'] ) ) {
|
|
|
|
|
$image_meta = wp_get_attachment_metadata( $attachment_id );
|
|
|
|
|
@@ -1780,7 +1791,7 @@ function wp_lazy_loading_enabled( $tag_name, $context ) {
|
|
|
|
|
*
|
|
|
|
|
* @see wp_img_tag_add_width_and_height_attr()
|
|
|
|
|
* @see wp_img_tag_add_srcset_and_sizes_attr()
|
|
|
|
|
* @see wp_img_tag_add_loading_attr()
|
|
|
|
|
* @see wp_img_tag_add_loading_optimization_attrs()
|
|
|
|
|
* @see wp_iframe_tag_add_loading_attr()
|
|
|
|
|
*
|
|
|
|
|
* @param string $content The HTML content to be filtered.
|
|
|
|
|
@@ -1793,7 +1804,6 @@ function wp_filter_content_tags( $content, $context = null ) {
|
|
|
|
|
$context = current_filter();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$add_img_loading_attr = wp_lazy_loading_enabled( 'img', $context );
|
|
|
|
|
$add_iframe_loading_attr = wp_lazy_loading_enabled( 'iframe', $context );
|
|
|
|
|
|
|
|
|
|
if ( ! preg_match_all( '/<(img|iframe)\s[^>]+>/', $content, $matches, PREG_SET_ORDER ) ) {
|
|
|
|
|
@@ -1857,10 +1867,8 @@ function wp_filter_content_tags( $content, $context = null ) {
|
|
|
|
|
$filtered_image = wp_img_tag_add_srcset_and_sizes_attr( $filtered_image, $context, $attachment_id );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add 'loading' attribute if applicable.
|
|
|
|
|
if ( $add_img_loading_attr && ! str_contains( $filtered_image, ' loading=' ) ) {
|
|
|
|
|
$filtered_image = wp_img_tag_add_loading_attr( $filtered_image, $context );
|
|
|
|
|
}
|
|
|
|
|
// Add loading optimization attributes if applicable.
|
|
|
|
|
$filtered_image = wp_img_tag_add_loading_optimization_attrs( $filtered_image, $context );
|
|
|
|
|
|
|
|
|
|
// Add 'decoding=async' attribute unless a 'decoding' attribute is already present.
|
|
|
|
|
if ( ! str_contains( $filtered_image, ' decoding=' ) ) {
|
|
|
|
|
@@ -1914,45 +1922,101 @@ function wp_filter_content_tags( $content, $context = null ) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Adds `loading` attribute to an `img` HTML tag.
|
|
|
|
|
* Adds optimization attributes to an `img` HTML tag.
|
|
|
|
|
*
|
|
|
|
|
* @since 5.5.0
|
|
|
|
|
* @since 6.3.0
|
|
|
|
|
*
|
|
|
|
|
* @param string $image The HTML `img` tag where the attribute should be added.
|
|
|
|
|
* @param string $context Additional context to pass to the filters.
|
|
|
|
|
* @return string Converted `img` tag with `loading` attribute added.
|
|
|
|
|
* @return string Converted `img` tag with optimization attributes added.
|
|
|
|
|
*/
|
|
|
|
|
function wp_img_tag_add_loading_attr( $image, $context ) {
|
|
|
|
|
// Get loading attribute value to use. This must occur before the conditional check below so that even images that
|
|
|
|
|
// are ineligible for being lazy-loaded are considered.
|
|
|
|
|
$value = wp_get_loading_attr_default( $context );
|
|
|
|
|
function wp_img_tag_add_loading_optimization_attrs( $image, $context ) {
|
|
|
|
|
$width = preg_match( '/ width=["\']([0-9]+)["\']/', $image, $match_width ) ? (int) $match_width[1] : null;
|
|
|
|
|
$height = preg_match( '/ height=["\']([0-9]+)["\']/', $image, $match_height ) ? (int) $match_height[1] : null;
|
|
|
|
|
$loading_val = preg_match( '/ loading=["\']([A-Za-z]+)["\']/', $image, $match_loading ) ? $match_loading[1] : null;
|
|
|
|
|
$fetchpriority_val = preg_match( '/ fetchpriority=["\']([A-Za-z]+)["\']/', $image, $match_fetchpriority ) ? $match_fetchpriority[1] : null;
|
|
|
|
|
|
|
|
|
|
// Images should have source and dimension attributes for the `loading` attribute to be added.
|
|
|
|
|
/*
|
|
|
|
|
* Get loading optimization attributes to use.
|
|
|
|
|
* This must occur before the conditional check below so that even images
|
|
|
|
|
* that are ineligible for being lazy-loaded are considered.
|
|
|
|
|
*/
|
|
|
|
|
$optimization_attrs = wp_get_loading_optimization_attributes(
|
|
|
|
|
'img',
|
|
|
|
|
array(
|
|
|
|
|
'width' => $width,
|
|
|
|
|
'height' => $height,
|
|
|
|
|
'loading' => $loading_val,
|
|
|
|
|
'fetchpriority' => $fetchpriority_val,
|
|
|
|
|
),
|
|
|
|
|
$context
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Images should have source and dimension attributes for the loading optimization attributes to be added.
|
|
|
|
|
if ( ! str_contains( $image, ' src="' ) || ! str_contains( $image, ' width="' ) || ! str_contains( $image, ' height="' ) ) {
|
|
|
|
|
return $image;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Filters the `loading` attribute value to add to an image. Default `lazy`.
|
|
|
|
|
*
|
|
|
|
|
* Returning `false` or an empty string will not add the attribute.
|
|
|
|
|
* Returning `true` will add the default value.
|
|
|
|
|
*
|
|
|
|
|
* @since 5.5.0
|
|
|
|
|
*
|
|
|
|
|
* @param string|bool $value The `loading` attribute value. Returning a falsey value will result in
|
|
|
|
|
* the attribute being omitted for the image.
|
|
|
|
|
* @param string $image The HTML `img` tag to be filtered.
|
|
|
|
|
* @param string $context Additional context about how the function was called or where the img tag is.
|
|
|
|
|
*/
|
|
|
|
|
$value = apply_filters( 'wp_img_tag_add_loading_attr', $value, $image, $context );
|
|
|
|
|
// Retained for backward compatibility.
|
|
|
|
|
$loading_attrs_enabled = wp_lazy_loading_enabled( 'img', $context );
|
|
|
|
|
|
|
|
|
|
if ( $value ) {
|
|
|
|
|
if ( ! in_array( $value, array( 'lazy', 'eager' ), true ) ) {
|
|
|
|
|
$value = 'lazy';
|
|
|
|
|
if ( empty( $loading_val ) && $loading_attrs_enabled ) {
|
|
|
|
|
/**
|
|
|
|
|
* Filters the `loading` attribute value to add to an image. Default `lazy`.
|
|
|
|
|
* This filter is added in for backward compatibility.
|
|
|
|
|
*
|
|
|
|
|
* Returning `false` or an empty string will not add the attribute.
|
|
|
|
|
* Returning `true` will add the default value.
|
|
|
|
|
* `true` and `false` usage supported for backward compatibility.
|
|
|
|
|
*
|
|
|
|
|
* @since 5.5.0
|
|
|
|
|
*
|
|
|
|
|
* @param string|bool $loading Current value for `loading` attribute for the image.
|
|
|
|
|
* @param string $image The HTML `img` tag to be filtered.
|
|
|
|
|
* @param string $context Additional context about how the function was called or where the img tag is.
|
|
|
|
|
*/
|
|
|
|
|
$filtered_loading_attr = apply_filters(
|
|
|
|
|
'wp_img_tag_add_loading_attr',
|
|
|
|
|
isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false,
|
|
|
|
|
$image,
|
|
|
|
|
$context
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Validate the values after filtering.
|
|
|
|
|
if ( isset( $optimization_attrs['loading'] ) && ! $filtered_loading_attr ) {
|
|
|
|
|
// Unset `loading` attributes if `$filtered_loading_attr` is set to `false`.
|
|
|
|
|
unset( $optimization_attrs['loading'] );
|
|
|
|
|
} elseif ( in_array( $filtered_loading_attr, array( 'lazy', 'eager' ), true ) ) {
|
|
|
|
|
/*
|
|
|
|
|
* If the filter changed the loading attribute to "lazy" when a fetchpriority attribute
|
|
|
|
|
* with value "high" is already present, trigger a warning since those two attribute
|
|
|
|
|
* values should be mutually exclusive.
|
|
|
|
|
*
|
|
|
|
|
* The same warning is present in `wp_get_loading_optimization_attributes()`, and here it
|
|
|
|
|
* is only intended for the specific scenario where the above filtered caused the problem.
|
|
|
|
|
*/
|
|
|
|
|
if ( isset( $optimization_attrs['fetchpriority'] ) && 'high' === $optimization_attrs['fetchpriority'] &&
|
|
|
|
|
( isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false ) !== $filtered_loading_attr &&
|
|
|
|
|
'lazy' === $filtered_loading_attr
|
|
|
|
|
) {
|
|
|
|
|
_doing_it_wrong(
|
|
|
|
|
__FUNCTION__,
|
|
|
|
|
__( 'An image should not be lazy-loaded and marked as high priority at the same time.' ),
|
|
|
|
|
'6.3.0'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The filtered value will still be respected.
|
|
|
|
|
$optimization_attrs['loading'] = $filtered_loading_attr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return str_replace( '<img', '<img loading="' . esc_attr( $value ) . '"', $image );
|
|
|
|
|
if ( ! empty( $optimization_attrs['loading'] ) ) {
|
|
|
|
|
$image = str_replace( '<img', '<img loading="' . esc_attr( $optimization_attrs['loading'] ) . '"', $image );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( empty( $fetchpriority_val ) && ! empty( $optimization_attrs['fetchpriority'] ) ) {
|
|
|
|
|
$image = str_replace( '<img', '<img fetchpriority="' . esc_attr( $optimization_attrs['fetchpriority'] ) . '"', $image );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $image;
|
|
|
|
|
@@ -2103,13 +2167,30 @@ function wp_iframe_tag_add_loading_attr( $iframe, $context ) {
|
|
|
|
|
|
|
|
|
|
// Get loading attribute value to use. This must occur before the conditional check below so that even iframes that
|
|
|
|
|
// are ineligible for being lazy-loaded are considered.
|
|
|
|
|
$value = wp_get_loading_attr_default( $context );
|
|
|
|
|
$optimization_attrs = wp_get_loading_optimization_attributes(
|
|
|
|
|
'iframe',
|
|
|
|
|
array(
|
|
|
|
|
/*
|
|
|
|
|
* The concrete values for width and height are not important here for now
|
|
|
|
|
* since fetchpriority is not yet supported for iframes.
|
|
|
|
|
* TODO: Use WP_HTML_Tag_Processor to extract actual values once support is
|
|
|
|
|
* added.
|
|
|
|
|
*/
|
|
|
|
|
'width' => str_contains( $iframe, ' width="' ) ? 100 : null,
|
|
|
|
|
'height' => str_contains( $iframe, ' height="' ) ? 100 : null,
|
|
|
|
|
// This function is never called when a 'loading' attribute is already present.
|
|
|
|
|
'loading' => null,
|
|
|
|
|
),
|
|
|
|
|
$context
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Iframes should have source and dimension attributes for the `loading` attribute to be added.
|
|
|
|
|
if ( ! str_contains( $iframe, ' src="' ) || ! str_contains( $iframe, ' width="' ) || ! str_contains( $iframe, ' height="' ) ) {
|
|
|
|
|
return $iframe;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$value = isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Filters the `loading` attribute value to add to an iframe. Default `lazy`.
|
|
|
|
|
*
|
|
|
|
|
@@ -5469,45 +5550,102 @@ function wp_get_webp_info( $filename ) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gets the default value to use for a `loading` attribute on an element.
|
|
|
|
|
* Gets loading optimization attributes.
|
|
|
|
|
*
|
|
|
|
|
* This function should only be called for a tag and context if lazy-loading is generally enabled.
|
|
|
|
|
* This function returns an array of attributes that should be merged into the given attributes array to optimize
|
|
|
|
|
* loading performance. Potential attributes returned by this function are:
|
|
|
|
|
* - `loading` attribute with a value of "lazy"
|
|
|
|
|
* - `fetchpriority` attribute with a value of "high"
|
|
|
|
|
*
|
|
|
|
|
* The function usually returns 'lazy', but uses certain heuristics to guess whether the current element is likely to
|
|
|
|
|
* appear above the fold, in which case it returns a boolean `false`, which will lead to the `loading` attribute being
|
|
|
|
|
* omitted on the element. The purpose of this refinement is to avoid lazy-loading elements that are within the initial
|
|
|
|
|
* viewport, which can have a negative performance impact.
|
|
|
|
|
* If any of these attributes are already present in the given attributes, they will not be modified. Note that no
|
|
|
|
|
* element should have both `loading="lazy"` and `fetchpriority="high"`, so the function will trigger a warning in case
|
|
|
|
|
* both attributes are present with those values.
|
|
|
|
|
*
|
|
|
|
|
* Under the hood, the function uses {@see wp_increase_content_media_count()} every time it is called for an element
|
|
|
|
|
* within the main content. If the element is the very first content element, the `loading` attribute will be omitted.
|
|
|
|
|
* This default threshold of 3 content elements to omit the `loading` attribute for can be customized using the
|
|
|
|
|
* {@see 'wp_omit_loading_attr_threshold'} filter.
|
|
|
|
|
*
|
|
|
|
|
* @since 5.9.0
|
|
|
|
|
* @since 6.3.0
|
|
|
|
|
*
|
|
|
|
|
* @global WP_Query $wp_query WordPress Query object.
|
|
|
|
|
*
|
|
|
|
|
* @param string $context Context for the element for which the `loading` attribute value is requested.
|
|
|
|
|
* @return string|bool The default `loading` attribute value. Either 'lazy', 'eager', or a boolean `false`, to indicate
|
|
|
|
|
* that the `loading` attribute should be skipped.
|
|
|
|
|
* @param string $tag_name The tag name.
|
|
|
|
|
* @param array $attr Array of the attributes for the tag.
|
|
|
|
|
* @param string $context Context for the element for which the loading optimization attribute is requested.
|
|
|
|
|
* @return array Loading optimization attributes.
|
|
|
|
|
*/
|
|
|
|
|
function wp_get_loading_attr_default( $context ) {
|
|
|
|
|
function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) {
|
|
|
|
|
global $wp_query;
|
|
|
|
|
|
|
|
|
|
// Skip lazy-loading for the overall block template, as it is handled more granularly.
|
|
|
|
|
/*
|
|
|
|
|
* Closure for postprocessing logic.
|
|
|
|
|
* It is here to avoid duplicate logic in many places below, without having
|
|
|
|
|
* to introduce a very specific private global function.
|
|
|
|
|
*/
|
|
|
|
|
$postprocess = static function( $loading_attributes, $with_fetchpriority = false ) use ( $tag_name, $attr, $context ) {
|
|
|
|
|
// Potentially add `fetchpriority="high"`.
|
|
|
|
|
if ( $with_fetchpriority ) {
|
|
|
|
|
$loading_attributes = wp_maybe_add_fetchpriority_high_attr( $loading_attributes, $tag_name, $attr );
|
|
|
|
|
}
|
|
|
|
|
// Potentially strip `loading="lazy"` if the feature is disabled.
|
|
|
|
|
if ( isset( $loading_attributes['loading'] ) && ! wp_lazy_loading_enabled( $tag_name, $context ) ) {
|
|
|
|
|
unset( $loading_attributes['loading'] );
|
|
|
|
|
}
|
|
|
|
|
return $loading_attributes;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$loading_attrs = array();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Skip lazy-loading for the overall block template, as it is handled more granularly.
|
|
|
|
|
* The skip is also applicable for `fetchpriority`.
|
|
|
|
|
*/
|
|
|
|
|
if ( 'template' === $context ) {
|
|
|
|
|
return false;
|
|
|
|
|
return $loading_attrs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do not lazy-load images in the header block template part, as they are likely above the fold.
|
|
|
|
|
// For classic themes, this is handled in the condition below using the 'get_header' action.
|
|
|
|
|
// For now this function only supports images and iframes.
|
|
|
|
|
if ( 'img' !== $tag_name && 'iframe' !== $tag_name ) {
|
|
|
|
|
return $loading_attrs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For any resources, width and height must be provided, to avoid layout shifts.
|
|
|
|
|
if ( ! isset( $attr['width'], $attr['height'] ) ) {
|
|
|
|
|
return $loading_attrs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( isset( $attr['loading'] ) ) {
|
|
|
|
|
/*
|
|
|
|
|
* While any `loading` value could be set in `$loading_attrs`, for
|
|
|
|
|
* consistency we only do it for `loading="lazy"` since that is the
|
|
|
|
|
* only possible value that WordPress core would apply on its own.
|
|
|
|
|
*/
|
|
|
|
|
if ( 'lazy' === $attr['loading'] ) {
|
|
|
|
|
$loading_attrs['loading'] = 'lazy';
|
|
|
|
|
if ( isset( $attr['fetchpriority'] ) && 'high' === $attr['fetchpriority'] ) {
|
|
|
|
|
_doing_it_wrong(
|
|
|
|
|
__FUNCTION__,
|
|
|
|
|
__( 'An image should not be lazy-loaded and marked as high priority at the same time.' ),
|
|
|
|
|
'6.3.0'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $postprocess( $loading_attrs, true );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// An image with `fetchpriority="high"` cannot be assigned `loading="lazy"` at the same time.
|
|
|
|
|
if ( isset( $attr['fetchpriority'] ) && 'high' === $attr['fetchpriority'] ) {
|
|
|
|
|
return $postprocess( $loading_attrs, true );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Do not lazy-load images in the header block template part, as they are likely above the fold.
|
|
|
|
|
* For classic themes, this is handled in the condition below using the 'get_header' action.
|
|
|
|
|
*/
|
|
|
|
|
$header_area = WP_TEMPLATE_PART_AREA_HEADER;
|
|
|
|
|
if ( "template_part_{$header_area}" === $context ) {
|
|
|
|
|
return false;
|
|
|
|
|
return $postprocess( $loading_attrs, true );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Special handling for programmatically created image tags.
|
|
|
|
|
if ( ( 'the_post_thumbnail' === $context || 'wp_get_attachment_image' === $context ) ) {
|
|
|
|
|
if ( 'the_post_thumbnail' === $context || 'wp_get_attachment_image' === $context ) {
|
|
|
|
|
/*
|
|
|
|
|
* Skip programmatically created images within post content as they need to be handled together with the other
|
|
|
|
|
* images within the post content.
|
|
|
|
|
@@ -5515,7 +5653,7 @@ function wp_get_loading_attr_default( $context ) {
|
|
|
|
|
* post content image being lazy-loaded only because there are images elsewhere in the post content.
|
|
|
|
|
*/
|
|
|
|
|
if ( doing_filter( 'the_content' ) ) {
|
|
|
|
|
return false;
|
|
|
|
|
return $postprocess( $loading_attrs, true );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Conditionally skip lazy-loading on images before the loop.
|
|
|
|
|
@@ -5529,7 +5667,7 @@ function wp_get_loading_attr_default( $context ) {
|
|
|
|
|
*/
|
|
|
|
|
&& did_action( 'get_header' ) && ! did_action( 'get_footer' )
|
|
|
|
|
) {
|
|
|
|
|
return false;
|
|
|
|
|
return $postprocess( $loading_attrs, true );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -5540,23 +5678,23 @@ function wp_get_loading_attr_default( $context ) {
|
|
|
|
|
if ( 'the_content' === $context || 'the_post_thumbnail' === $context ) {
|
|
|
|
|
// Only elements within the main query loop have special handling.
|
|
|
|
|
if ( is_admin() || ! in_the_loop() || ! is_main_query() ) {
|
|
|
|
|
return 'lazy';
|
|
|
|
|
$loading_attrs['loading'] = 'lazy';
|
|
|
|
|
return $postprocess( $loading_attrs, false );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Increase the counter since this is a main query content element.
|
|
|
|
|
$content_media_count = wp_increase_content_media_count();
|
|
|
|
|
|
|
|
|
|
// If the count so far is below the threshold, return `false` so that the `loading` attribute is omitted.
|
|
|
|
|
// If the count so far is below the threshold, `loading` attribute is omitted.
|
|
|
|
|
if ( $content_media_count <= wp_omit_loading_attr_threshold() ) {
|
|
|
|
|
return false;
|
|
|
|
|
// The first largest image will still get `fetchpriority='high'`.
|
|
|
|
|
return $postprocess( $loading_attrs, true );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// For elements after the threshold, lazy-load them as usual.
|
|
|
|
|
return 'lazy';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Lazy-load by default for any unknown context.
|
|
|
|
|
return 'lazy';
|
|
|
|
|
$loading_attrs['loading'] = 'lazy';
|
|
|
|
|
return $postprocess( $loading_attrs, false );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@@ -5609,3 +5747,76 @@ function wp_increase_content_media_count( $amount = 1 ) {
|
|
|
|
|
|
|
|
|
|
return $content_media_count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Determines whether to add `fetchpriority='high'` to loading attributes.
|
|
|
|
|
*
|
|
|
|
|
* @since 6.3.0
|
|
|
|
|
* @access private
|
|
|
|
|
*
|
|
|
|
|
* @param array $loading_attrs Array of the loading optimization attributes for the element.
|
|
|
|
|
* @param string $tag_name The tag name.
|
|
|
|
|
* @param array $attr Array of the attributes for the element.
|
|
|
|
|
* @return array Updated loading optimization attributes for the element.
|
|
|
|
|
*/
|
|
|
|
|
function wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr ) {
|
|
|
|
|
// For now, adding `fetchpriority="high"` is only supported for images.
|
|
|
|
|
if ( 'img' !== $tag_name ) {
|
|
|
|
|
return $loading_attrs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( isset( $attr['fetchpriority'] ) ) {
|
|
|
|
|
/*
|
|
|
|
|
* While any `fetchpriority` value could be set in `$loading_attrs`,
|
|
|
|
|
* for consistency we only do it for `fetchpriority="high"` since that
|
|
|
|
|
* is the only possible value that WordPress core would apply on its
|
|
|
|
|
* own.
|
|
|
|
|
*/
|
|
|
|
|
if ( 'high' === $attr['fetchpriority'] ) {
|
|
|
|
|
$loading_attrs['fetchpriority'] = 'high';
|
|
|
|
|
wp_high_priority_element_flag( false );
|
|
|
|
|
}
|
|
|
|
|
return $loading_attrs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Lazy-loading and `fetchpriority="high"` are mutually exclusive.
|
|
|
|
|
if ( isset( $loading_attrs['loading'] ) && 'lazy' === $loading_attrs['loading'] ) {
|
|
|
|
|
return $loading_attrs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( ! wp_high_priority_element_flag() ) {
|
|
|
|
|
return $loading_attrs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Filters the minimum square-pixels threshold for an image to be eligible as the high-priority image.
|
|
|
|
|
*
|
|
|
|
|
* @since 6.3.0
|
|
|
|
|
*
|
|
|
|
|
* @param int $threshold Minimum square-pixels threshold. Default 50000.
|
|
|
|
|
*/
|
|
|
|
|
$wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 );
|
|
|
|
|
if ( $wp_min_priority_img_pixels <= $attr['width'] * $attr['height'] ) {
|
|
|
|
|
$loading_attrs['fetchpriority'] = 'high';
|
|
|
|
|
wp_high_priority_element_flag( false );
|
|
|
|
|
}
|
|
|
|
|
return $loading_attrs;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Accesses a flag that indicates if an element is a possible candidate for `fetchpriority='high'`.
|
|
|
|
|
*
|
|
|
|
|
* @since 6.3.0
|
|
|
|
|
* @access private
|
|
|
|
|
*
|
|
|
|
|
* @param bool $value Optional. Used to change the static variable. Default null.
|
|
|
|
|
* @return bool Returns true if high-priority element was marked already, otherwise false.
|
|
|
|
|
*/
|
|
|
|
|
function wp_high_priority_element_flag( $value = null ) {
|
|
|
|
|
static $high_priority_element = true;
|
|
|
|
|
|
|
|
|
|
if ( is_bool( $value ) ) {
|
|
|
|
|
$high_priority_element = $value;
|
|
|
|
|
}
|
|
|
|
|
return $high_priority_element;
|
|
|
|
|
}
|
|
|
|
|
|