Merged in feature/81-dev-dev01 (pull request #5)
auto-patch 81-dev-dev01-2023-12-05T22_45_26 * auto-patch 81-dev-dev01-2023-12-05T22_45_26
This commit is contained in:
@@ -283,12 +283,14 @@ function image_downsize( $id, $size = 'medium' ) {
|
||||
* @param string $name Image size identifier.
|
||||
* @param int $width Optional. Image width in pixels. Default 0.
|
||||
* @param int $height Optional. Image height in pixels. Default 0.
|
||||
* @param bool|array $crop Optional. Image cropping behavior. If false, the image will be scaled (default),
|
||||
* If true, image will be cropped to the specified dimensions using center positions.
|
||||
* If an array, the image will be cropped using the array to specify the crop location.
|
||||
* Array values must be in the format: array( x_crop_position, y_crop_position ) where:
|
||||
* - x_crop_position accepts: 'left', 'center', or 'right'.
|
||||
* - y_crop_position accepts: 'top', 'center', or 'bottom'.
|
||||
* @param bool|array $crop {
|
||||
* Optional. Image cropping behavior. If false, the image will be scaled (default).
|
||||
* If true, image will be cropped to the specified dimensions using center positions.
|
||||
* If an array, the image will be cropped using the array to specify the crop location:
|
||||
*
|
||||
* @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
|
||||
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
|
||||
* }
|
||||
*/
|
||||
function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
|
||||
global $_wp_additional_image_sizes;
|
||||
@@ -343,8 +345,14 @@ function remove_image_size( $name ) {
|
||||
*
|
||||
* @param int $width Image width in pixels.
|
||||
* @param int $height Image height in pixels.
|
||||
* @param bool|array $crop Optional. Whether to crop images to specified width and height or resize.
|
||||
* An array can specify positioning of the crop area. Default false.
|
||||
* @param bool|array $crop {
|
||||
* Optional. Image cropping behavior. If false, the image will be scaled (default).
|
||||
* If true, image will be cropped to the specified dimensions using center positions.
|
||||
* If an array, the image will be cropped using the array to specify the crop location:
|
||||
*
|
||||
* @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
|
||||
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
|
||||
* }
|
||||
*/
|
||||
function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) {
|
||||
add_image_size( 'post-thumbnail', $width, $height, $crop );
|
||||
@@ -511,22 +519,20 @@ function wp_constrain_dimensions( $current_width, $current_height, $max_width =
|
||||
* Calculates dimensions and coordinates for a resized image that fits
|
||||
* within a specified width and height.
|
||||
*
|
||||
* Cropping behavior is dependent on the value of $crop:
|
||||
* 1. If false (default), images will not be cropped.
|
||||
* 2. If an array in the form of array( x_crop_position, y_crop_position ):
|
||||
* - x_crop_position accepts 'left' 'center', or 'right'.
|
||||
* - y_crop_position accepts 'top', 'center', or 'bottom'.
|
||||
* Images will be cropped to the specified dimensions within the defined crop area.
|
||||
* 3. If true, images will be cropped to the specified dimensions using center positions.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param int $orig_w Original width in pixels.
|
||||
* @param int $orig_h Original height in pixels.
|
||||
* @param int $dest_w New width in pixels.
|
||||
* @param int $dest_h New height in pixels.
|
||||
* @param bool|array $crop Optional. Whether to crop image to specified width and height or resize.
|
||||
* An array can specify positioning of the crop area. Default false.
|
||||
* @param bool|array $crop {
|
||||
* Optional. Image cropping behavior. If false, the image will be scaled (default).
|
||||
* If true, image will be cropped to the specified dimensions using center positions.
|
||||
* If an array, the image will be cropped using the array to specify the crop location:
|
||||
*
|
||||
* @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
|
||||
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
|
||||
* }
|
||||
* @return array|false Returned array matches parameters for `imagecopyresampled()`. False on failure.
|
||||
*/
|
||||
function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = false ) {
|
||||
@@ -670,11 +676,17 @@ function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = fa
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param string $file File path.
|
||||
* @param int $width Image width.
|
||||
* @param int $height Image height.
|
||||
* @param bool $crop Optional. Whether to crop image to specified width and height or resize.
|
||||
* Default false.
|
||||
* @param string $file File path.
|
||||
* @param int $width Image width.
|
||||
* @param int $height Image height.
|
||||
* @param bool|array $crop {
|
||||
* Optional. Image cropping behavior. If false, the image will be scaled (default).
|
||||
* If true, image will be cropped to the specified dimensions using center positions.
|
||||
* If an array, the image will be cropped using the array to specify the crop location:
|
||||
*
|
||||
* @type string $0 The x crop position. Accepts 'left' 'center', or 'right'.
|
||||
* @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'.
|
||||
* }
|
||||
* @return array|false Metadata array on success. False if no image was created.
|
||||
*/
|
||||
function image_make_intermediate_size( $file, $width, $height, $crop = false ) {
|
||||
@@ -1048,10 +1060,9 @@ function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = f
|
||||
}
|
||||
|
||||
$default_attr = array(
|
||||
'src' => $src,
|
||||
'class' => "attachment-$size_class size-$size_class",
|
||||
'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
|
||||
'decoding' => 'async',
|
||||
'src' => $src,
|
||||
'class' => "attachment-$size_class size-$size_class",
|
||||
'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -1709,9 +1720,9 @@ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) {
|
||||
}
|
||||
|
||||
// Bail early if an image has been inserted and later edited.
|
||||
if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) &&
|
||||
! str_contains( wp_basename( $image_src ), $img_edit_hash[0] ) ) {
|
||||
|
||||
if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash )
|
||||
&& ! str_contains( wp_basename( $image_src ), $img_edit_hash[0] )
|
||||
) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
@@ -1880,11 +1891,6 @@ function wp_filter_content_tags( $content, $context = null ) {
|
||||
// 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=' ) ) {
|
||||
$filtered_image = wp_img_tag_add_decoding_attr( $filtered_image, $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters an img tag within the content for a given context.
|
||||
*
|
||||
@@ -1945,6 +1951,7 @@ function wp_img_tag_add_loading_optimization_attrs( $image, $context ) {
|
||||
$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;
|
||||
$decoding_val = preg_match( '/ decoding=["\']([A-Za-z]+)["\']/', $image, $match_decoding ) ? $match_decoding[1] : null;
|
||||
|
||||
/*
|
||||
* Get loading optimization attributes to use.
|
||||
@@ -1958,12 +1965,53 @@ function wp_img_tag_add_loading_optimization_attrs( $image, $context ) {
|
||||
'height' => $height,
|
||||
'loading' => $loading_val,
|
||||
'fetchpriority' => $fetchpriority_val,
|
||||
'decoding' => $decoding_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="' ) ) {
|
||||
// Images should have source for the loading optimization attributes to be added.
|
||||
if ( ! str_contains( $image, ' src="' ) ) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
if ( empty( $decoding_val ) ) {
|
||||
/**
|
||||
* Filters the `decoding` attribute value to add to an image. Default `async`.
|
||||
*
|
||||
* Returning a falsey value will omit the attribute.
|
||||
*
|
||||
* @since 6.1.0
|
||||
*
|
||||
* @param string|false|null $value The `decoding` attribute value. Returning a falsey value
|
||||
* will result in the attribute being omitted for the image.
|
||||
* Otherwise, it may be: 'async', 'sync', or 'auto'. Defaults to false.
|
||||
* @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_decoding_attr = apply_filters(
|
||||
'wp_img_tag_add_decoding_attr',
|
||||
isset( $optimization_attrs['decoding'] ) ? $optimization_attrs['decoding'] : false,
|
||||
$image,
|
||||
$context
|
||||
);
|
||||
|
||||
// Validate the values after filtering.
|
||||
if ( isset( $optimization_attrs['decoding'] ) && ! $filtered_decoding_attr ) {
|
||||
// Unset `decoding` attribute if `$filtered_decoding_attr` is set to `false`.
|
||||
unset( $optimization_attrs['decoding'] );
|
||||
} elseif ( in_array( $filtered_decoding_attr, array( 'async', 'sync', 'auto' ), true ) ) {
|
||||
$optimization_attrs['decoding'] = $filtered_decoding_attr;
|
||||
}
|
||||
|
||||
if ( ! empty( $optimization_attrs['decoding'] ) ) {
|
||||
$image = str_replace( '<img', '<img decoding="' . esc_attr( $optimization_attrs['decoding'] ) . '"', $image );
|
||||
}
|
||||
}
|
||||
|
||||
// Images should have dimension attributes for the 'loading' and 'fetchpriority' attributes to be added.
|
||||
if ( ! str_contains( $image, ' width="' ) || ! str_contains( $image, ' height="' ) ) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
@@ -2031,56 +2079,6 @@ function wp_img_tag_add_loading_optimization_attrs( $image, $context ) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `decoding` attribute to an `img` HTML tag.
|
||||
*
|
||||
* The `decoding` attribute allows developers to indicate whether the
|
||||
* browser can decode the image off the main thread (`async`), on the
|
||||
* main thread (`sync`) or as determined by the browser (`auto`).
|
||||
*
|
||||
* By default WordPress adds `decoding="async"` to images but developers
|
||||
* can use the {@see 'wp_img_tag_add_decoding_attr'} filter to modify this
|
||||
* to remove the attribute or set it to another accepted value.
|
||||
*
|
||||
* @since 6.1.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 `decoding` attribute added.
|
||||
*/
|
||||
function wp_img_tag_add_decoding_attr( $image, $context ) {
|
||||
/*
|
||||
* Only apply the decoding attribute to images that have a src attribute that
|
||||
* starts with a double quote, ensuring escaped JSON is also excluded.
|
||||
*/
|
||||
if ( ! str_contains( $image, ' src="' ) ) {
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the `decoding` attribute value to add to an image. Default `async`.
|
||||
*
|
||||
* Returning a falsey value will omit the attribute.
|
||||
*
|
||||
* @since 6.1.0
|
||||
*
|
||||
* @param string|false|null $value The `decoding` attribute value. Returning a falsey value
|
||||
* will result in the attribute being omitted for the image.
|
||||
* Otherwise, it may be: 'async' (default), 'sync', or 'auto'.
|
||||
* @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_decoding_attr', 'async', $image, $context );
|
||||
|
||||
if ( in_array( $value, array( 'async', 'sync', 'auto' ), true ) ) {
|
||||
$image = str_replace( '<img ', '<img decoding="' . esc_attr( $value ) . '" ', $image );
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `width` and `height` attributes to an `img` HTML tag.
|
||||
*
|
||||
@@ -2349,6 +2347,10 @@ add_shortcode( 'caption', 'img_caption_shortcode' );
|
||||
* @return string HTML content to display the caption.
|
||||
*/
|
||||
function img_caption_shortcode( $attr, $content = '' ) {
|
||||
if ( ! $attr ) {
|
||||
$attr = array();
|
||||
}
|
||||
|
||||
// New-style shortcode with the caption inside the shortcode with the link and image tags.
|
||||
if ( ! isset( $attr['caption'] ) ) {
|
||||
if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) {
|
||||
@@ -2536,7 +2538,7 @@ function gallery_shortcode( $attr ) {
|
||||
$post = get_post();
|
||||
|
||||
static $instance = 0;
|
||||
$instance++;
|
||||
++$instance;
|
||||
|
||||
if ( ! empty( $attr['ids'] ) ) {
|
||||
// 'ids' is explicitly ordered, unless you specify otherwise.
|
||||
@@ -2605,6 +2607,7 @@ function gallery_shortcode( $attr ) {
|
||||
$attachments[ $val->ID ] = $_attachments[ $key ];
|
||||
}
|
||||
} elseif ( ! empty( $atts['exclude'] ) ) {
|
||||
$post_parent_id = $id;
|
||||
$attachments = get_children(
|
||||
array(
|
||||
'post_parent' => $id,
|
||||
@@ -2617,6 +2620,7 @@ function gallery_shortcode( $attr ) {
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$post_parent_id = $id;
|
||||
$attachments = get_children(
|
||||
array(
|
||||
'post_parent' => $id,
|
||||
@@ -2629,6 +2633,17 @@ function gallery_shortcode( $attr ) {
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $post_parent_id ) ) {
|
||||
$post_parent = get_post( $post_parent_id );
|
||||
|
||||
// terminate the shortcode execution if user cannot read the post or password-protected
|
||||
if (
|
||||
( ! is_post_publicly_viewable( $post_parent->ID ) && ! current_user_can( 'read_post', $post_parent->ID ) )
|
||||
|| post_password_required( $post_parent ) ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $attachments ) ) {
|
||||
return '';
|
||||
}
|
||||
@@ -2883,7 +2898,7 @@ function wp_playlist_shortcode( $attr ) {
|
||||
$post = get_post();
|
||||
|
||||
static $instance = 0;
|
||||
$instance++;
|
||||
++$instance;
|
||||
|
||||
if ( ! empty( $attr['ids'] ) ) {
|
||||
// 'ids' is explicitly ordered, unless you specify otherwise.
|
||||
@@ -2961,6 +2976,15 @@ function wp_playlist_shortcode( $attr ) {
|
||||
$attachments = get_children( $args );
|
||||
}
|
||||
|
||||
if ( ! empty( $args['post_parent'] ) ) {
|
||||
$post_parent = get_post( $id );
|
||||
|
||||
// terminate the shortcode execution if user cannot read the post or password-protected
|
||||
if ( ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $attachments ) ) {
|
||||
return '';
|
||||
}
|
||||
@@ -3197,7 +3221,7 @@ function wp_audio_shortcode( $attr, $content = '' ) {
|
||||
$post_id = get_post() ? get_the_ID() : 0;
|
||||
|
||||
static $instance = 0;
|
||||
$instance++;
|
||||
++$instance;
|
||||
|
||||
/**
|
||||
* Filters the default audio shortcode output.
|
||||
@@ -3207,7 +3231,7 @@ function wp_audio_shortcode( $attr, $content = '' ) {
|
||||
* @since 3.6.0
|
||||
*
|
||||
* @param string $html Empty variable to be replaced with shortcode markup.
|
||||
* @param array $attr Attributes of the shortcode. @see wp_audio_shortcode()
|
||||
* @param array $attr Attributes of the shortcode. See {@see wp_audio_shortcode()}.
|
||||
* @param string $content Shortcode content.
|
||||
* @param int $instance Unique numeric ID of this audio shortcode instance.
|
||||
*/
|
||||
@@ -3416,7 +3440,7 @@ function wp_video_shortcode( $attr, $content = '' ) {
|
||||
$post_id = get_post() ? get_the_ID() : 0;
|
||||
|
||||
static $instance = 0;
|
||||
$instance++;
|
||||
++$instance;
|
||||
|
||||
/**
|
||||
* Filters the default video shortcode output.
|
||||
@@ -3429,7 +3453,7 @@ function wp_video_shortcode( $attr, $content = '' ) {
|
||||
* @see wp_video_shortcode()
|
||||
*
|
||||
* @param string $html Empty variable to be replaced with shortcode markup.
|
||||
* @param array $attr Attributes of the shortcode. @see wp_video_shortcode()
|
||||
* @param array $attr Attributes of the shortcode. See {@see wp_video_shortcode()}.
|
||||
* @param string $content Video shortcode content.
|
||||
* @param int $instance Unique numeric ID of this video shortcode instance.
|
||||
*/
|
||||
@@ -4501,7 +4525,7 @@ function wp_prepare_attachment_for_js( $attachment ) {
|
||||
*
|
||||
* @since 3.5.0
|
||||
*
|
||||
* @param array $response Array of prepared attachment data. @see wp_prepare_attachment_for_js().
|
||||
* @param array $response Array of prepared attachment data. See {@see wp_prepare_attachment_for_js()}.
|
||||
* @param WP_Post $attachment Attachment object.
|
||||
* @param array|false $meta Array of attachment meta data, or false if there is none.
|
||||
*/
|
||||
@@ -5347,8 +5371,13 @@ function wp_register_media_personal_data_exporter( $exporters ) {
|
||||
* @since 4.9.6
|
||||
*
|
||||
* @param string $email_address The attachment owner email address.
|
||||
* @param int $page Attachment page.
|
||||
* @return array An array of personal data.
|
||||
* @param int $page Attachment page number.
|
||||
* @return array {
|
||||
* An array of personal data.
|
||||
*
|
||||
* @type array[] $data An array of personal data arrays.
|
||||
* @type bool $done Whether the exporter is finished.
|
||||
* }
|
||||
*/
|
||||
function wp_media_personal_data_exporter( $email_address, $page = 1 ) {
|
||||
// Limit us to 50 attachments at a time to avoid timing out.
|
||||
@@ -5470,10 +5499,8 @@ function wp_getimagesize( $filename, array &$image_info = null ) {
|
||||
* See https://core.trac.wordpress.org/ticket/42480
|
||||
*/
|
||||
if ( 2 === func_num_args() ) {
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors
|
||||
$info = @getimagesize( $filename, $image_info );
|
||||
} else {
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors
|
||||
$info = @getimagesize( $filename );
|
||||
}
|
||||
}
|
||||
@@ -5587,6 +5614,7 @@ function wp_get_webp_info( $filename ) {
|
||||
* loading performance. Potential attributes returned by this function are:
|
||||
* - `loading` attribute with a value of "lazy"
|
||||
* - `fetchpriority` attribute with a value of "high"
|
||||
* - `decoding` attribute with a value of "async"
|
||||
*
|
||||
* 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
|
||||
@@ -5604,31 +5632,24 @@ function wp_get_webp_info( $filename ) {
|
||||
function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) {
|
||||
global $wp_query;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
/**
|
||||
* Filters whether to short-circuit loading optimization attributes.
|
||||
*
|
||||
* Returning an array from the filter will effectively short-circuit the loading of optimization attributes,
|
||||
* returning that value instead.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param array|false $loading_attrs False by default, or array of loading optimization attributes to short-circuit.
|
||||
* @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.
|
||||
*/
|
||||
$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;
|
||||
};
|
||||
// Closure to increase media count for images with certain minimum threshold, mostly used for header images.
|
||||
$maybe_increase_content_media_count = static function() use ( $attr ) {
|
||||
/** This filter is documented in wp-admin/includes/media.php */
|
||||
$wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 );
|
||||
// Images with a certain minimum size in the header of the page are also counted towards the threshold.
|
||||
if ( $wp_min_priority_img_pixels <= $attr['width'] * $attr['height'] ) {
|
||||
wp_increase_content_media_count();
|
||||
}
|
||||
};
|
||||
$loading_attrs = apply_filters( 'pre_wp_get_loading_optimization_attributes', false, $tag_name, $attr, $context );
|
||||
|
||||
if ( is_array( $loading_attrs ) ) {
|
||||
return $loading_attrs;
|
||||
}
|
||||
|
||||
$loading_attrs = array();
|
||||
|
||||
@@ -5637,77 +5658,138 @@ function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) {
|
||||
* The skip is also applicable for `fetchpriority`.
|
||||
*/
|
||||
if ( 'template' === $context ) {
|
||||
return $loading_attrs;
|
||||
/** This filter is documented in wp-includes/media.php */
|
||||
return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
|
||||
}
|
||||
|
||||
// For now this function only supports images and iframes.
|
||||
if ( 'img' !== $tag_name && 'iframe' !== $tag_name ) {
|
||||
return $loading_attrs;
|
||||
/** This filter is documented in wp-includes/media.php */
|
||||
return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip programmatically created images within content blobs as they need to be handled together with the other
|
||||
* images within the post content or widget content.
|
||||
* Without this clause, they would already be considered within their own context which skews the image count and
|
||||
* can result in the first post content image being lazy-loaded or an image further down the page being marked as a
|
||||
* high priority.
|
||||
*/
|
||||
if (
|
||||
'the_content' !== $context && doing_filter( 'the_content' ) ||
|
||||
'widget_text_content' !== $context && doing_filter( 'widget_text_content' ) ||
|
||||
'widget_block_content' !== $context && doing_filter( 'widget_block_content' )
|
||||
) {
|
||||
/** This filter is documented in wp-includes/media.php */
|
||||
return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Add `decoding` with a value of "async" for every image unless it has a
|
||||
* conflicting `decoding` attribute already present.
|
||||
*/
|
||||
if ( 'img' === $tag_name ) {
|
||||
if ( isset( $attr['decoding'] ) ) {
|
||||
$loading_attrs['decoding'] = $attr['decoding'];
|
||||
} else {
|
||||
$loading_attrs['decoding'] = 'async';
|
||||
}
|
||||
}
|
||||
|
||||
// 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 );
|
||||
/** This filter is documented in wp-includes/media.php */
|
||||
return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* The key function logic starts here.
|
||||
*/
|
||||
$header_area = WP_TEMPLATE_PART_AREA_HEADER;
|
||||
if ( "template_part_{$header_area}" === $context ) {
|
||||
// Increase media count if there are images in header above a certian minimum size threshold.
|
||||
$maybe_increase_content_media_count();
|
||||
return $postprocess( $loading_attrs, true );
|
||||
}
|
||||
$maybe_in_viewport = null;
|
||||
$increase_count = false;
|
||||
$maybe_increase_count = false;
|
||||
|
||||
// The custom header image is always expected to be in the header.
|
||||
if ( 'get_header_image_tag' === $context ) {
|
||||
// Increase media count if there are images in header above a certian minimum size threshold.
|
||||
$maybe_increase_content_media_count();
|
||||
return $postprocess( $loading_attrs, true );
|
||||
}
|
||||
|
||||
// Special handling for programmatically created image tags.
|
||||
if ( 'the_post_thumbnail' === $context || 'wp_get_attachment_image' === $context || 'widget_media_image' === $context ) {
|
||||
// Logic to handle a `loading` attribute that is already provided.
|
||||
if ( isset( $attr['loading'] ) ) {
|
||||
/*
|
||||
* Skip programmatically created images within post content as they need to be handled together with the other
|
||||
* images within the post content.
|
||||
* Without this clause, they would already be considered below which skews the image count and can result in
|
||||
* the first post content image being lazy-loaded or an image further down the page being marked as a high
|
||||
* priority.
|
||||
* Interpret "lazy" as not in viewport. Any other value can be
|
||||
* interpreted as in viewport (realistically only "eager" or `false`
|
||||
* to force-omit the attribute are other potential values).
|
||||
*/
|
||||
if ( doing_filter( 'the_content' ) ) {
|
||||
return $loading_attrs;
|
||||
if ( 'lazy' === $attr['loading'] ) {
|
||||
$maybe_in_viewport = false;
|
||||
} else {
|
||||
$maybe_in_viewport = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Conditionally skip lazy-loading on images before the loop.
|
||||
if (
|
||||
// Logic to handle a `fetchpriority` attribute that is already provided.
|
||||
if ( isset( $attr['fetchpriority'] ) && 'high' === $attr['fetchpriority'] ) {
|
||||
/*
|
||||
* If the image was already determined to not be in the viewport (e.g.
|
||||
* from an already provided `loading` attribute), trigger a warning.
|
||||
* Otherwise, the value can be interpreted as in viewport, since only
|
||||
* the most important in-viewport image should have `fetchpriority` set
|
||||
* to "high".
|
||||
*/
|
||||
if ( false === $maybe_in_viewport ) {
|
||||
_doing_it_wrong(
|
||||
__FUNCTION__,
|
||||
__( 'An image should not be lazy-loaded and marked as high priority at the same time.' ),
|
||||
'6.3.0'
|
||||
);
|
||||
/*
|
||||
* Set `fetchpriority` here for backward-compatibility as we should
|
||||
* not override what a developer decided, even though it seems
|
||||
* incorrect.
|
||||
*/
|
||||
$loading_attrs['fetchpriority'] = 'high';
|
||||
} else {
|
||||
$maybe_in_viewport = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( null === $maybe_in_viewport ) {
|
||||
$header_enforced_contexts = array(
|
||||
'template_part_' . WP_TEMPLATE_PART_AREA_HEADER => true,
|
||||
'get_header_image_tag' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the header-specific contexts.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param array $default_header_enforced_contexts Map of contexts for which elements should be considered
|
||||
* in the header of the page, as $context => $enabled
|
||||
* pairs. The $enabled should always be true.
|
||||
*/
|
||||
$header_enforced_contexts = apply_filters( 'wp_loading_optimization_force_header_contexts', $header_enforced_contexts );
|
||||
|
||||
// Consider elements with these header-specific contexts to be in viewport.
|
||||
if ( isset( $header_enforced_contexts[ $context ] ) ) {
|
||||
$maybe_in_viewport = true;
|
||||
$maybe_increase_count = true;
|
||||
} elseif ( ! is_admin() && in_the_loop() && is_main_query() ) {
|
||||
/*
|
||||
* Get the content media count, since this is a main query
|
||||
* content element. This is accomplished by "increasing"
|
||||
* the count by zero, as the only way to get the count is
|
||||
* to call this function.
|
||||
* The actual count increase happens further below, based
|
||||
* on the `$increase_count` flag set here.
|
||||
*/
|
||||
$content_media_count = wp_increase_content_media_count( 0 );
|
||||
$increase_count = true;
|
||||
|
||||
// If the count so far is below the threshold, `loading` attribute is omitted.
|
||||
if ( $content_media_count < wp_omit_loading_attr_threshold() ) {
|
||||
$maybe_in_viewport = true;
|
||||
} else {
|
||||
$maybe_in_viewport = false;
|
||||
}
|
||||
} elseif (
|
||||
// Only apply for main query but before the loop.
|
||||
$wp_query->before_loop && $wp_query->is_main_query()
|
||||
/*
|
||||
@@ -5716,38 +5798,54 @@ function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) {
|
||||
* does not include any loop.
|
||||
*/
|
||||
&& did_action( 'get_header' ) && ! did_action( 'get_footer' )
|
||||
) {
|
||||
// Increase media count if there are images in header above a certian minimum size threshold.
|
||||
$maybe_increase_content_media_count();
|
||||
return $postprocess( $loading_attrs, true );
|
||||
) {
|
||||
$maybe_in_viewport = true;
|
||||
$maybe_increase_count = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The first elements in 'the_content' or 'the_post_thumbnail' should not be lazy-loaded,
|
||||
* as they are likely above the fold. Shortcodes are processed after content images, so if
|
||||
* thresholds haven't already been met, apply the same logic to those as well.
|
||||
* If the element is in the viewport (`true`), potentially add
|
||||
* `fetchpriority` with a value of "high". Otherwise, i.e. if the element
|
||||
* is not not in the viewport (`false`) or it is unknown (`null`), add
|
||||
* `loading` with a value of "lazy".
|
||||
*/
|
||||
if ( 'the_content' === $context || 'the_post_thumbnail' === $context || 'do_shortcode' === $context ) {
|
||||
// Only elements within the main query loop have special handling.
|
||||
if ( is_admin() || ! in_the_loop() || ! is_main_query() ) {
|
||||
if ( $maybe_in_viewport ) {
|
||||
$loading_attrs = wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr );
|
||||
} else {
|
||||
// Only add `loading="lazy"` if the feature is enabled.
|
||||
if ( wp_lazy_loading_enabled( $tag_name, $context ) ) {
|
||||
$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, `loading` attribute is omitted.
|
||||
if ( $content_media_count <= wp_omit_loading_attr_threshold() ) {
|
||||
// The first largest image will still get `fetchpriority='high'`.
|
||||
return $postprocess( $loading_attrs, true );
|
||||
}
|
||||
}
|
||||
|
||||
// Lazy-load by default for any unknown context.
|
||||
$loading_attrs['loading'] = 'lazy';
|
||||
return $postprocess( $loading_attrs, false );
|
||||
/*
|
||||
* If flag was set based on contextual logic above, increase the content
|
||||
* media count, either unconditionally, or based on whether the image size
|
||||
* is larger than the threshold.
|
||||
*/
|
||||
if ( $increase_count ) {
|
||||
wp_increase_content_media_count();
|
||||
} elseif ( $maybe_increase_count ) {
|
||||
/** This filter is documented in wp-includes/media.php */
|
||||
$wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 );
|
||||
|
||||
if ( $wp_min_priority_img_pixels <= $attr['width'] * $attr['height'] ) {
|
||||
wp_increase_content_media_count();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the loading optimization attributes.
|
||||
*
|
||||
* @since 6.4.0
|
||||
*
|
||||
* @param array $loading_attrs The loading optimization attributes.
|
||||
* @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 apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5829,6 +5927,7 @@ function wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr
|
||||
$loading_attrs['fetchpriority'] = 'high';
|
||||
wp_high_priority_element_flag( false );
|
||||
}
|
||||
|
||||
return $loading_attrs;
|
||||
}
|
||||
|
||||
@@ -5849,10 +5948,12 @@ function wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr
|
||||
* @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;
|
||||
}
|
||||
|
||||
@@ -5871,5 +5972,6 @@ function wp_high_priority_element_flag( $value = null ) {
|
||||
if ( is_bool( $value ) ) {
|
||||
$high_priority_element = $value;
|
||||
}
|
||||
|
||||
return $high_priority_element;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user