<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[35412] trunk: Responsive images:</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/35412">35412</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/35412","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>azaozz</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2015-10-28 05:40:04 +0000 (Wed, 28 Oct 2015)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Responsive images:
- Introduce `wp_calculate_image_srcset()` that replaces `wp_get_attachment_image_srcset_array()` and is used as lower level function for retrieving the srcset data as array.
- Use the new function when generating `srcset` and `sizes` on the front-end. This is faster as no (other) image API functions are used.
- Change the `wp_get_attachment_image_srcset()`. Now it is meant for use in templates and is no longer used in core.
- A few logic fixes and improvements.
- Some names changed to be (hopefully) more descriptive.
- Fixed/updated tests.

Props joemcgill, jaspermdegroot, azaozz.
See <a href="https://core.trac.wordpress.org/ticket/34430">#34430</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesmediaphp">trunk/src/wp-includes/media.php</a></li>
<li><a href="#trunktestsphpunittestsmediaphp">trunk/tests/phpunit/tests/media.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesmediaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/media.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/media.php   2015-10-28 04:53:56 UTC (rev 35411)
+++ trunk/src/wp-includes/media.php     2015-10-28 05:40:04 UTC (rev 35412)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -813,13 +813,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Generate srcset and sizes if not already present.
</span><span class="cx" style="display: block; padding: 0 10px">                if ( empty( $attr['srcset'] ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $srcset = wp_get_attachment_image_srcset( $attachment_id, $size );
-                       $sizes  = wp_get_attachment_image_sizes( $attachment_id, $size, $width );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $image_meta = wp_get_attachment_metadata( $attachment_id );
+                       $size_array = array( absint( $width ), absint( $height ) );
+                       $sources = wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( $srcset && $sizes ) {
-                               $attr['srcset'] = $srcset;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if ( count( $sources ) > 1 ) {
+                               $attr['srcset'] = wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                if ( empty( $attr['sizes'] ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         if ( empty( $attr['sizes'] ) && ( $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id ) ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                         $attr['sizes'] = $sizes;
</span><span class="cx" style="display: block; padding: 0 10px">                                }
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -864,15 +865,118 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Retrieves an array of URLs and pixel widths representing sizes of an image.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Private, do not use
+ */
+function _wp_upload_dir_baseurl() {
+       static $baseurl = null;
+
+       if ( ! $baseurl ) {
+               $uploads_dir = wp_upload_dir();
+               $baseurl = $uploads_dir['baseurl'];
+       }
+
+       return $baseurl;
+}
+
+/**
+ * Private, do not use
+ */
+function _wp_get_image_size_from_meta( $size, $image_meta ) {
+       if ( $size === 'full' ) {
+               return array(
+                       absint( $image_meta['width'] ),
+                       absint( $image_meta['height'] ),
+               );
+       } elseif ( ! empty( $image_meta['sizes'][$size] ) ) {
+               return array(
+                       absint( $image_meta['sizes'][$size]['width'] ),
+                       absint( $image_meta['sizes'][$size]['height'] ),
+               );
+       }
+
+       return false;
+}
+
+/**
+ * Retrieves the value for an image attachment's 'srcset' attribute.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * The purpose is to populate a source set when creating responsive image markup.
- *
</del><span class="cx" style="display: block; padding: 0 10px">  * @since 4.4.0
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param int          $attachment_id Image attachment ID.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ * @param int          $attachment_id Optional. Image attachment ID.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
</span><span class="cx" style="display: block; padding: 0 10px">  *                                    values in pixels (in that order). Default 'medium'.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array        $image_meta    Optional. The image meta data.
+ * @return string|bool A 'srcset' value string or false.
+ */
+function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) {
+       if ( ! $image = wp_get_attachment_image_src( $attachment_id, $size ) ) {
+               return false;
+       }
+
+       if ( ! is_array( $image_meta ) ) {
+               $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
+       }
+
+       $image_url = $image[0];
+       $size_array = array(
+               absint( $image[1] ),
+               absint( $image[2] )
+       );
+
+       // Calculate the sources for the srcset.
+       $sources = wp_calculate_image_srcset( $image_url, $size_array, $image_meta, $attachment_id );
+
+       // Only return a srcset value if there is more than one source.
+       if ( count( $sources ) < 2 ) {
+               return false;
+       }
+
+       return wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id );
+}
+
+
+/**
+ * A helper function to concatenate and filter the srcset attribute value.
+ *
+ * @since 4.4.0
+ *
+ * @param array   $sources       The array containing image sizes data as returned by wp_calculate_image_srcset().
+ * @param array   $size_array    Array of width and height values in pixels (in that order).
+ * @param array   $image_meta    The image meta data.
+ * @param int     $attachment_id The image attachment post id to pass to the filter.
+ * @return string The srcset attribute value.
+ */
+function wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id ) {
+       $srcset = '';
+
+       foreach ( $sources as $source ) {
+               $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', ';
+       }
+
+       /**
+        * Filter the output of wp_get_attachment_image_srcset().
+        *
+        * @since 4.4.0
+        *
+        * @param string       $srcset        A source set formatted for a `srcset` attribute.
+        * @param int          $attachment_id Image attachment ID.
+        * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
+        *                                    values in pixels (in that order). Default 'medium'.
+        * @param array        $image_meta    The image meta data.
+        */
+       return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size_array, $image_meta );
+}
+
+/**
+ * A helper function to caclulate the image sources to include in a srcset attribute.
+ *
+ * @since 4.4.0
+ *
+ * @param string $image_name    The file name, path, URL or partial path or URL of the image being matched.
+ * @param array  $size_array    Array of width and height values in pixels (in that order).
+ * @param array  $image_meta    The image meta data.
+ * @param int    $attachment_id Optional. The image attachment post id to pass to the filter.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return array|bool $sources {
</span><span class="cx" style="display: block; padding: 0 10px">  *     Array image candidate values containing a URL, descriptor type, and
</span><span class="cx" style="display: block; padding: 0 10px">  *     descriptor value. False if none exist.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -886,103 +990,91 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * }
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' ) {
-       // Get the intermediate size.
-       $image = image_get_intermediate_size( $attachment_id, $size );
-
-       // Get the post meta.
-       $img_meta = wp_get_attachment_metadata( $attachment_id );
-       if ( ! is_array( $img_meta ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $attachment_id = 0 ) {
+       if ( empty( $image_meta['sizes'] ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return false;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Extract the height and width from the intermediate or the full size.
-       $img_width  = ( $image ) ? $image['width']  : $img_meta['width'];
-       $img_height = ( $image ) ? $image['height'] : $img_meta['height'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $image_sizes = $image_meta['sizes'];
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Bail early if the width isn't greater than zero.
-       if ( ! $img_width > 0 ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Get the height and width for the image.
+       $image_width = (int) $size_array[0];
+       $image_height = (int) $size_array[1];
+
+       // Bail early if error/no width.
+       if ( $image_width < 1 ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return false;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Use the URL from the intermediate size or build the url from the metadata.
-       if ( ! empty( $image['url'] ) ) {
-               $img_url = $image['url'];
-       } else {
-               $uploads_dir = wp_upload_dir();
-               $img_file = ( $image ) ? path_join( dirname( $img_meta['file'] ) , $image['file'] ) : $img_meta['file'];
-               $img_url = $uploads_dir['baseurl'] . '/' . $img_file;
-       }
-
-       $img_sizes = $img_meta['sizes'];
-
</del><span class="cx" style="display: block; padding: 0 10px">         // Add full size to the img_sizes array.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $img_sizes['full'] = array(
-               'width'  => $img_meta['width'],
-               'height' => $img_meta['height'],
-               'file'   => wp_basename( $img_meta['file'] )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $image_sizes['full'] = array(
+               'width'  => $image_meta['width'],
+               'height' => $image_meta['height'],
+               'file'   => wp_basename( $image_meta['file'] ),
</ins><span class="cx" style="display: block; padding: 0 10px">         );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $image_baseurl = _wp_upload_dir_baseurl();
+       $dirname = dirname( $image_meta['file'] );
+
+       if ( $dirname !== '.' ) {
+               $image_baseurl = path_join( $image_baseurl, $dirname );
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         // Calculate the image aspect ratio.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $img_ratio = $img_height / $img_width;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $image_ratio = $image_height / $image_width;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /*
</span><span class="cx" style="display: block; padding: 0 10px">         * Images that have been edited in WordPress after being uploaded will
</span><span class="cx" style="display: block; padding: 0 10px">         * contain a unique hash. Look for that hash and use it later to filter
</span><span class="cx" style="display: block; padding: 0 10px">         * out images that are leftovers from previous versions.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $img_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $image_edited = preg_match( '/-e[0-9]{13}/', $image_name, $image_edit_hash );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Filter the maximum width included in a srcset attribute.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Filter the maximum width included in a 'srcset' attribute.
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 4.4.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @param array|string $size Size of image, either array or string.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @param int          $max_width  The maximum width to include in the 'srcset'. Default '1600'.
+        * @param array|string $size_array Array of width and height values in pixels (in that order).
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size_array );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        /*
-        * Set up arrays to hold url candidates and matched image sources so
-        * we can avoid duplicates without looping through the full sources array
-        */
-       $candidates = $sources = array();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Array to hold URL candidates.
+       $sources = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /*
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Loop through available images and only use images that are resized
-        * versions of the same rendition.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * Loop through available images. Only use images that are resized
+        * versions of the same edit.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        foreach ( $img_sizes as $img ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ foreach ( $image_sizes as $image ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Filter out images that are leftovers from previous renditions.
-               if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         // Filter out images that are from previous edits.
+               if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         continue;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Filter out images that are wider than $max_srcset_width.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( $max_srcset_width && $img['width'] > $max_srcset_width ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( $max_srcset_width && $image['width'] > $max_srcset_width ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         continue;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $candidate_url = path_join( dirname( $img_url ), $img['file'] );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $candidate_url = $image['file'];
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Calculate the new image ratio.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( $img['width'] ) {
-                       $img_ratio_compare = $img['height'] / $img['width'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( $image['width'] ) {
+                       $image_ratio_compare = $image['height'] / $image['width'];
</ins><span class="cx" style="display: block; padding: 0 10px">                 } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $img_ratio_compare = 0;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $image_ratio_compare = 0;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // If the new ratio differs by less than 0.01, use it.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! in_array( $candidate_url, $candidates ) ) {
-                       // Add the URL to our list of candidates.
-                       $candidates[] = $candidate_url;
-
-                       // Add the url, descriptor, and value to the sources array to be returned.
-                       $sources[] = array(
-                               'url'        => $candidate_url,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) {
+                       // Add the URL, descriptor, and value to the sources array to be returned.
+                       $sources[ $image['width'] ] = array(
+                               'url'        => path_join( $image_baseurl, $candidate_url ),
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'descriptor' => 'w',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'value'      => $img['width'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'value'      => $image['width'],
</ins><span class="cx" style="display: block; padding: 0 10px">                         );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -992,81 +1084,55 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 4.4.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @param array        $sources       An array of image urls and widths.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @param array        $sources       An array of image URLs and widths.
</ins><span class="cx" style="display: block; padding: 0 10px">          * @param int          $attachment_id Attachment ID for image.
</span><span class="cx" style="display: block; padding: 0 10px">         * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
</span><span class="cx" style="display: block; padding: 0 10px">         *                                    values in pixels (in that order). Default 'medium'.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @param array        $image_meta    The image meta data.
+
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return apply_filters( 'wp_get_attachment_image_srcset_array', $sources, $attachment_id, $size );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return apply_filters( 'wp_get_attachment_image_srcset_array', array_values( $sources ), $attachment_id, $size_array, $image_meta );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * Retrieves the value for an image attachment's 'srcset' attribute.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * Create `sizes` attribute value for an image.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 4.4.0
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param int          $attachment_id Image attachment ID.
- * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
- *                                    values in pixels (in that order). Default 'medium'.
- * @return string|bool A 'srcset' value string or false.
- */
-function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium' ) {
-       $srcset_array = wp_get_attachment_image_srcset_array( $attachment_id, $size );
-
-       // Only return a srcset value if there is more than one source.
-       if ( count( $srcset_array ) <= 1 ) {
-               return false;
-       }
-
-       $srcset = '';
-       foreach ( $srcset_array as $source ) {
-               $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', ';
-       }
-
-       /**
-        * Filter the output of wp_get_attachment_image_srcset().
-        *
-        * @since 4.4.0
-        *
-        * @param string       $srcset        A source set formated for a `srcset` attribute.
-        * @param int          $attachment_id Attachment ID for image.
-        * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
-        *                                    values in pixels (in that order). Default 'medium'.
-        */
-       return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size );
-}
-
-/**
- * Retrieves a source size attribute for an image from an array of values.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param array|string $size          Image size. Accepts any valid image size name (thumbnail, medium, etc.),
+ *                                    or an array of width and height values in pixels (in that order).
+ * @param array        $image_meta    Optional. The image meta data.
+ * @param int          $attachment_id Optional. Image attachment ID. Either $image_meta or $attachment_id is needed
+ *                                    when using image size name.
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @since 4.4.0
- *
- * @param int          $attachment_id Image attachment ID.
- * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
- *                                    values in pixels (in that order). Default 'medium'.
- * @param int          $width         Optional. Display width of the image.
</del><span class="cx" style="display: block; padding: 0 10px">  * @return string|bool A valid source size value for use in a 'sizes' attribute or false.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width = null ) {
-       // Try to get the image width from the $width parameter.
-       if ( is_numeric( $width ) ) {
-               $img_width = (int) $width;
-       // Next, see if a width value was passed in the $size parameter.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0 ) {
+       $width = 0;
+
+       if ( is_numeric( $size ) ) {
+               $width = absint( $size );
</ins><span class="cx" style="display: block; padding: 0 10px">         } elseif ( is_array( $size ) ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $img_width = $size[0];
-       // Finally, use the $size name to return the width of the image.
-       } else {
-               $image = image_get_intermediate_size( $attachment_id, $size );
-               $img_width = $image ? $image['width'] : false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $width = absint( $size[0] );
+       } elseif ( is_string( $size ) ) {
+               if ( ! $image_meta && $attachment_id ) {
+                       $image_meta = wp_get_attachment_metadata( $attachment_id );
+               }
+
+               if ( $image_meta ) {
+                       $width = _wp_get_image_size_from_meta( $size, $image_meta );
+                       if ( $width ) {
+                               $width = $width[0];
+                       }
+               }
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Bail early if $img_width isn't set.
-       if ( ! $img_width ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( ! $width ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return false;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        // Setup the default sizes attribute.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $img_width );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', (int) $width );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * Filter the output of wp_get_attachment_image_sizes().
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1074,12 +1140,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @since 4.4.0
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @param string       $sizes         A source size value for use in a 'sizes' attribute.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @param int          $attachment_id Post ID of the original image.
</del><span class="cx" style="display: block; padding: 0 10px">          * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
</span><span class="cx" style="display: block; padding: 0 10px">         *                                    values in pixels (in that order). Default 'medium'.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @param int          $width         Display width of the image.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @param array        $image_meta    The image meta data.
+        * @param int          $attachment_id Post ID of the original image.
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $attachment_id, $size, $width );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $image_meta, $attachment_id );
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1087,7 +1153,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @since 4.4.0
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @see wp_img_add_srcset_and_sizes()
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @see wp_image_add_srcset_and_sizes()
</ins><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @param string $content The raw post content to be filtered.
</span><span class="cx" style="display: block; padding: 0 10px">  * @return string Converted content with 'srcset' and 'sizes' attributes added to images.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1095,29 +1161,33 @@
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_make_content_images_responsive( $content ) {
</span><span class="cx" style="display: block; padding: 0 10px">        $images = get_media_embedded_in_content( $content, 'img' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $attachment_ids = array();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $selected_images = $attachment_ids = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        foreach( $images as $image ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) {
-                       $attachment_id = (int) $class_id[1];
-                       if ( $attachment_id ) {
-                               $attachment_ids[] = $attachment_id;
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) &&
+                       ( $attachment_id = absint( $class_id[1] ) ) ) {
+
+                       // If exactly the same image tag is used more than once, overwrite it.
+                       // All identical tags will be replaced later with str_replace().
+                       $selected_images[ $image ] = $attachment_id;
+                       // Overwrite the ID when the same image is included more than once.
+                       $attachment_ids[ $attachment_id ] = true;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( 0 < count( $attachment_ids ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( count( $attachment_ids ) > 1 ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 /*
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * Warm object caches for use with wp_get_attachment_metadata.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * Warm object cache for use with get_post_meta().
</ins><span class="cx" style="display: block; padding: 0 10px">                  *
</span><span class="cx" style="display: block; padding: 0 10px">                 * To avoid making a database call for each image, a single query
</span><span class="cx" style="display: block; padding: 0 10px">                 * warms the object cache with the meta information for all images.
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                _prime_post_caches( $attachment_ids, false, true );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         update_meta_cache( 'post', array_keys( $attachment_ids ) );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        foreach( $images as $image ) {
-               $content = str_replace( $image, wp_img_add_srcset_and_sizes( $image ), $content );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ foreach ( $selected_images as $image => $attachment_id ) {
+               $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
+               $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $content;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1131,74 +1201,76 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @see wp_get_attachment_image_srcset()
</span><span class="cx" style="display: block; padding: 0 10px">  * @see wp_get_attachment_image_sizes()
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- * @param string $image An HTML 'img' element to be filtered.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ * @param string $image         An HTML 'img' element to be filtered.
+ * @param array  $image_meta    The image meta data.
+ * @param int    $attachment_id Image attachment ID.
</ins><span class="cx" style="display: block; padding: 0 10px">  * @return string Converted 'img' element with `srcset` and `sizes` attributes added.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-function wp_img_add_srcset_and_sizes( $image ) {
-       // Return early if a 'srcset' attribute already exists.
-       if ( false !== strpos( $image, ' srcset="' ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) {
+       // Ensure the image meta exists
+       if ( empty( $image_meta['sizes'] ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 return $image;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // Parse id, size, width, and height from the `img` element.
-       $id     = preg_match( '/wp-image-([0-9]+)/i', $image, $match_id     ) ? (int) $match_id[1]     : false;
-       $size   = preg_match( '/size-([^\s|"]+)/i',   $image, $match_size   ) ? $match_size[1]         : false;
-       $width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : '';
+       list( $src ) = explode( '?', $src );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( $id && ! $size ) {
-               $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : false;
-
-               if ( $width && $height ) {
-                       $size = array( $width, $height );
-               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Return early if we coudn't get the image source.
+       if ( ! $src ) {
+               return $image;
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        /*
-        * If attempts to parse the size value failed, attempt to use the image
-        * metadata to match the 'src' against the available sizes for an attachment.
-        */
-       if ( $id && ! $size ) {
-               $meta = wp_get_attachment_metadata( $id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // Bail early when an image has been inserted and later edited.
+       if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) &&
+               strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) {
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Parse the image src value from the img element.
-               $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         return $image;
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Return early if the metadata does not exist or the src value is empty.
-               if ( ! $meta || ! $src ) {
-                       return $image;
-               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : 0;
+       $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        if ( ! $width || ! $height ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 /*
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                 * First, see if the file is the full size image. If not, loop through
-                * the intermediate sizes until we find a file that matches.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+          * If attempts to parse the size value failed, attempt to use the image
+                * metadata to match the image file name from 'src' against the available sizes for an attachment.
</ins><span class="cx" style="display: block; padding: 0 10px">                  */
</span><span class="cx" style="display: block; padding: 0 10px">                $image_filename = wp_basename( $src );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( $image_filename === basename( $meta['file'] ) ) {
-                       $size = 'full';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( $image_filename === wp_basename( $image_meta['file'] ) ) {
+                       $width = (int) $image_meta['width'];
+                       $height = (int) $image_meta['height'];
</ins><span class="cx" style="display: block; padding: 0 10px">                 } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        foreach( $meta['sizes'] as $image_size => $image_size_data ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 foreach( $image_meta['sizes'] as $image_size_data ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 if ( $image_filename === $image_size_data['file'] ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        $size = $image_size;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 $width = (int) $image_size_data['width'];
+                                       $height = (int) $image_size_data['height'];
</ins><span class="cx" style="display: block; padding: 0 10px">                                         break;
</span><span class="cx" style="display: block; padding: 0 10px">                                }
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        if ( ! $width || ! $height ) {
+               return $image;
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        // If ID and size exist, try for 'srcset' and 'sizes' and update the markup.
-       if ( $id && $size ) {
-               $srcset = wp_get_attachment_image_srcset( $id, $size );
-               $sizes  = wp_get_attachment_image_sizes( $id, $size, $width );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $size_array = array( $width, $height );
+       $sources = wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( $srcset && $sizes ) {
-                       // Format the srcset and sizes string and escape attributes.
-                       $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $srcset = $sizes = '';
+       // Only calculate srcset and sizes values if there is more than one source.
+       if ( count( $sources ) > 1 ) {
+               $srcset = wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id );
+               $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id );
+       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        // Add srcset and sizes attributes to the image markup.
-                       $image = preg_replace( '/<img ([^>]+)[\s?][\/?]>/', '<img $1' . $srcset_and_sizes . ' />', $image );
-               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ( $srcset && $sizes ) {
+               // Format the srcset and sizes string and escape attributes.
+               $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) );
+
+               // Add srcset and sizes attributes to the image markup.
+               $image = preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $srcset_and_sizes . ' />', $image );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        return $image;
</span></span></pre></div>
<a id="trunktestsphpunittestsmediaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/media.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/media.php       2015-10-28 04:53:56 UTC (rev 35411)
+++ trunk/tests/phpunit/tests/media.php 2015-10-28 05:40:04 UTC (rev 35412)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -716,27 +716,45 @@
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Helper function to get image size array from size "name"
+        */
+       function _get_image_size_array_from_name( $size_name ) {
+               switch ( $size_name ) {
+                       case 'thumbnail':
+                               return array( 150, 150 );
+                       case 'medium':
+                               return array( 300, 225 );
+                       case 'large':
+                               return array( 1024, 768 );
+                       case 'full':
+                               return array( 1600, 1200 ); // actual size of ../data/images/test-image-large.png
+                       default:
+                               return array( 800, 600 ); // soft-resized image
+               }
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * @ticket 33641
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function test_wp_get_attachment_image_srcset_array() {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function test_wp_calculate_image_srcset() {
</ins><span class="cx" style="display: block; padding: 0 10px">                 $year_month = date('Y/m');
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $image = wp_get_attachment_metadata( self::$large_id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $image_meta = wp_get_attachment_metadata( self::$large_id );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $expected = array(
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image['sizes']['medium']['file'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image_meta['sizes']['medium']['file'],
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'descriptor' => 'w',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'value'      => $image['sizes']['medium']['width'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'value'      => $image_meta['sizes']['medium']['width'],
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image['sizes']['large']['file'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image_meta['sizes']['large']['file'],
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'descriptor' => 'w',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'value'      => $image['sizes']['large']['width'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'value'      => $image_meta['sizes']['large']['width'],
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'],
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'descriptor' => 'w',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'value'      => $image['width'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'value'      => $image_meta['width'],
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -744,14 +762,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $sizes = array( 'medium', 'large', 'full', 'yoav' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $sizes as $size ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $this->assertSame( $expected, wp_get_attachment_image_srcset_array( self::$large_id, $size ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $image_url = wp_get_attachment_image_url( self::$large_id, $size );
+                       $size_array = $this->_get_image_size_array_from_name( $size );
+                       $this->assertSame( $expected, wp_calculate_image_srcset( $image_url, $size_array, $image_meta ) );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 33641
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function test_wp_get_attachment_image_srcset_array_no_date_uploads() {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function test_wp_calculate_image_srcset_no_date_uploads() {
</ins><span class="cx" style="display: block; padding: 0 10px">                 // Save the current setting for uploads folders
</span><span class="cx" style="display: block; padding: 0 10px">                $uploads_use_yearmonth_folders = get_option( 'uploads_use_yearmonth_folders' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -762,23 +782,23 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $filename = DIR_TESTDATA . '/images/test-image-large.png';
</span><span class="cx" style="display: block; padding: 0 10px">                $id = self::factory()->attachment->create_upload_object( $filename );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $image = wp_get_attachment_metadata( $id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $image_meta = wp_get_attachment_metadata( $id );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $expected = array(
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['sizes']['medium']['file'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['medium']['file'],
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'descriptor' => 'w',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'value'      => $image['sizes']['medium']['width'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'value'      => $image_meta['sizes']['medium']['width'],
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['sizes']['large']['file'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['large']['file'],
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'descriptor' => 'w',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'value'      => $image['sizes']['large']['width'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'value'      => $image_meta['sizes']['large']['width'],
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'],
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'descriptor' => 'w',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'value'      => $image['width'],
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'value'      => $image_meta['width'],
</ins><span class="cx" style="display: block; padding: 0 10px">                         ),
</span><span class="cx" style="display: block; padding: 0 10px">                );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -786,7 +806,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $sizes = array( 'medium', 'large', 'full', 'yoav' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $sizes as $size ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $this->assertSame( $expected, wp_get_attachment_image_srcset_array( $id, $size ) );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $size_array = $this->_get_image_size_array_from_name( $size );
+                       $image_url = wp_get_attachment_image_url( self::$large_id, $size );
+                       $this->assertSame( $expected, wp_calculate_image_srcset( $image_url, $size_array, $image_meta ) );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Leave the uploads option the way you found it.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -796,24 +818,24 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 33641
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function test_wp_get_attachment_image_srcset_array_with_edits() {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function test_wp_calculate_image_srcset_with_edits() {
</ins><span class="cx" style="display: block; padding: 0 10px">                 // For this test we're going to mock metadata changes from an edit.
</span><span class="cx" style="display: block; padding: 0 10px">                // Start by getting the attachment metadata.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $meta = wp_get_attachment_metadata( self::$large_id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $image_meta = wp_get_attachment_metadata( self::$large_id );
+               $image_url = wp_get_attachment_image_url( self::$large_id );
+               $size_array = $this->_get_image_size_array_from_name( 'medium' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Copy hash generation method used in wp_save_image().
</span><span class="cx" style="display: block; padding: 0 10px">                $hash = 'e' . time() . rand(100, 999);
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Replace file paths for full and medium sizes with hashed versions.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $filename_base = basename( $meta['file'], '.png' );
-               $meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $meta['file'] );
-               $meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $meta['sizes']['medium']['file'] );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $filename_base = basename( $image_meta['file'], '.png' );
+               $image_meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['file'] );
+               $image_meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['medium']['file'] );
+               $image_meta['sizes']['large']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['large']['file'] );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                // Save edited metadata.
-               wp_update_attachment_metadata( self::$large_id, $meta );
-
</del><span class="cx" style="display: block; padding: 0 10px">                 // Calculate a srcset array.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $sizes = wp_get_attachment_image_srcset_array( self::$large_id, 'medium' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $sizes = wp_calculate_image_srcset( $image_url, $size_array, $image_meta );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Test to confirm all sources in the array include the same edit hash.
</span><span class="cx" style="display: block; padding: 0 10px">                foreach ( $sizes as $size ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -824,8 +846,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 33641
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function test_wp_get_attachment_image_srcset_array_false() {
-               $sizes = wp_get_attachment_image_srcset_array( 99999, 'foo' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function test_wp_calculate_image_srcset_false() {
+               $sizes = wp_calculate_image_srcset( 'file.png', array( 400, 300 ), array() );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // For canola.jpg we should return
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertFalse( $sizes );
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -834,49 +856,35 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 33641
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function test_wp_get_attachment_image_srcset_array_no_width() {
-               // Filter image_downsize() output.
-               add_filter( 'wp_generate_attachment_metadata', array( $this, '_test_wp_get_attachment_image_srcset_array_no_width_filter' ) );
-
-               $old_meta = get_post_meta( self::$large_id, '_wp_attachment_metadata', true );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function test_wp_calculate_image_srcset_no_width() {
</ins><span class="cx" style="display: block; padding: 0 10px">                 $file = get_attached_file( self::$large_id );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $image_url = wp_get_attachment_image_url( self::$large_id, 'medium' );
+               $image_meta = wp_generate_attachment_metadata( self::$large_id, $file );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $data = wp_generate_attachment_metadata( self::$large_id, $file );
-               wp_update_attachment_metadata( self::$large_id, $data );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $size_array = array(0, 0);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $srcset = wp_get_attachment_image_srcset_array( self::$large_id, 'medium' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $srcset = wp_calculate_image_srcset( $image_url, $size_array, $image_meta );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                update_post_meta( self::$large_id, '_wp_attachment_metadata', $old_meta );
-
</del><span class="cx" style="display: block; padding: 0 10px">                 // The srcset should be false.
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertFalse( $srcset );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * Helper function to filter image_downsize and return zero values for width and height.
-        */
-       public function _test_wp_get_attachment_image_srcset_array_no_width_filter( $meta ) {
-               remove_filter( 'wp_generate_attachment_metadata', array( $this, __FUNCTION__ ) );
-
-               $meta['sizes']['medium']['width'] = 0;
-               $meta['sizes']['medium']['height'] = 0;
-               return $meta;
-       }
-
-       /**
</del><span class="cx" style="display: block; padding: 0 10px">          * @ticket 33641
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        function test_wp_get_attachment_image_srcset() {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $sizes = wp_get_attachment_image_srcset( self::$large_id, 'full-size' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $image_meta = wp_get_attachment_metadata( self::$large_id );
+               $size_array = array( 1600, 1200 ); // full size
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $image = wp_get_attachment_metadata( self::$large_id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $sizes = wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                 $year_month = date('Y/m');
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $expected = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month = date('Y/m') . '/'
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        . $image['sizes']['medium']['file'] . ' ' . $image['sizes']['medium']['width'] . 'w, ';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 . $image_meta['sizes']['medium']['file'] . ' ' . $image_meta['sizes']['medium']['width'] . 'w, ';
</ins><span class="cx" style="display: block; padding: 0 10px">                 $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month = date('Y/m') . '/'
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        . $image['sizes']['large']['file'] . ' ' . $image['sizes']['large']['width'] . 'w, ';
-               $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 . $image_meta['sizes']['large']['file'] . ' ' . $image_meta['sizes']['large']['width'] . 'w, ';
+               $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertSame( $expected, $sizes );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -885,11 +893,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 33641
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        function test_wp_get_attachment_image_srcset_single_srcset() {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $image_meta = wp_get_attachment_metadata( self::$large_id );
+               $size_array = array( 150, 150 );
</ins><span class="cx" style="display: block; padding: 0 10px">                 /*
</span><span class="cx" style="display: block; padding: 0 10px">                 * In our tests, thumbnails will only return a single srcset candidate,
</span><span class="cx" style="display: block; padding: 0 10px">                 * so we shouldn't return a srcset value in order to avoid unneeded markup.
</span><span class="cx" style="display: block; padding: 0 10px">                 */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $sizes = wp_get_attachment_image_srcset( self::$large_id, 'thumbnail' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $sizes = wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertFalse( $sizes );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -899,76 +909,57 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        function test_wp_get_attachment_image_sizes() {
</span><span class="cx" style="display: block; padding: 0 10px">                // Test sizes against the default WP sizes.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $intermediates = array('thumbnail', 'medium', 'large');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $intermediates = array( 'thumbnail', 'medium', 'large' );
+               $image_meta = wp_get_attachment_metadata( self::$large_id );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                foreach( $intermediates as $int ) {
-                       $width = get_option( $int . '_size_w' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         foreach( $intermediates as $int_size ) {
+                       $size_array = $this->_get_image_size_array_from_name( $int_size );
+                       list( $width, $height ) = $size_array;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $expected = '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $sizes = wp_get_attachment_image_sizes( self::$large_id, $int );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $this->assertSame($expected, $sizes);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $this->assertSame( $expected, $sizes );
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 33641
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        function test_wp_get_attachment_image_sizes_with_width() {
-               $width = 350;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ function test_wp_make_content_images_responsive() {
+               $image_meta = wp_get_attachment_metadata( self::$large_id );
+               $size_array = $this->_get_image_size_array_from_name( 'medium' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $expected = '(max-width: 350px) 100vw, 350px';
-               $sizes = wp_get_attachment_image_sizes( self::$large_id, 'medium', $width );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta ) );
+               $sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( $size_array, $image_meta, self::$large_id ) );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertSame( $expected, $sizes );
-       }
-
-       /**
-        * @ticket 33641
-        */
-       function test_wp_make_content_images_responsive() {
-               $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, 'medium' ) );
-               $sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( self::$large_id, 'medium' ) );
-
</del><span class="cx" style="display: block; padding: 0 10px">                 // Function used to build HTML for the editor.
</span><span class="cx" style="display: block; padding: 0 10px">                $img = get_image_tag( self::$large_id, '', '', '', 'medium' );
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $img_no_size = str_replace( 'size-', '', $img );
-               $img_no_size_id = str_replace( 'wp-image-', 'id-', $img_no_size );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $img_no_size_in_class = str_replace( 'size-', '', $img );
+               $img_no_width_height = str_replace( ' width="' . $size_array[0] . '"', '', $img );
+               $img_no_width_height = str_replace( ' height="' . $size_array[1] . '"', '', $img_no_width_height );
+               $img_no_size_id = str_replace( 'wp-image-', 'id-', $img );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // Manually add srcset and sizes to the markup from get_image_tag();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $respimg = preg_replace('|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img);
-               $respimg_no_size = preg_replace('|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img_no_size);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $respimg = preg_replace( '|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img );
+               $respimg_no_size_in_class = preg_replace( '|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img_no_size_in_class );
+               $respimg_no_width_height = preg_replace( '|<img ([^>]+) />|', '<img $1 ' . $srcset . ' ' . $sizes . ' />', $img_no_width_height );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $content = '<p>Welcome to WordPress!  This post contains important information.  After you read it, you can make it private to hide it from visitors but still have the information handy for future reference.</p>
-                       <p>First things first:</p>
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $content = '
+                       <p>Image, standard. Should have srcset and sizes.</p>
</ins><span class="cx" style="display: block; padding: 0 10px">                         %1$s
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        <ul>
-                       <li><a href="http://wordpress.org" title="Subscribe to the WordPress mailing list for Release Notifications">Subscribe to the WordPress mailing list for release notifications</a></li>
-                       </ul>
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 <p>Image, no size class. Should have srcset and sizes.</p>
</ins><span class="cx" style="display: block; padding: 0 10px">                         %2$s
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        <p>As a subscriber, you will receive an email every time an update is available (and only then).  This will make it easier to keep your site up to date, and secure from evildoers.<br />
-                       When a new version is released, <a href="http://wordpress.org" title="If you are already logged in, this will take you directly to the Dashboard">log in to the Dashboard</a> and follow the instructions.<br />
-                       Upgrading is a couple of clicks!</p>
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 <p>Image, no width and height attributes. Should have srcset and sizes (from matching the file name).</p>
</ins><span class="cx" style="display: block; padding: 0 10px">                         %3$s
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        <p>Then you can start enjoying the WordPress experience:</p>
-                       <ul>
-                       <li>Edit your personal information at <a href="http://wordpress.org" title="Edit settings like your password, your display name and your contact information">Users &#8250; Your Profile</a></li>
-                       <li>Start publishing at <a href="http://wordpress.org" title="Create a new post">Posts &#8250; Add New</a> and at <a href="http://wordpress.org" title="Create a new page">Pages &#8250; Add New</a></li>
-                       <li>Browse and install plugins at <a href="http://wordpress.org" title="Browse and install plugins at the official WordPress repository directly from your Dashboard">Plugins &#8250; Add New</a></li>
-                       <li>Browse and install themes at <a href="http://wordpress.org" title="Browse and install themes at the official WordPress repository directly from your Dashboard">Appearance &#8250; Add New Themes</a></li>
-                       <li>Modify and prettify your website&#8217;s links at <a href="http://wordpress.org" title="For example, select a link structure like: http://example.com/1999/12/post-name">Settings &#8250; Permalinks</a></li>
-                       <li>Import content from another system or WordPress site at <a href="http://wordpress.org" title="WordPress comes with importers for the most common publishing systems">Tools &#8250; Import</a></li>
-                       <li>Find answers to your questions at the <a href="http://wordpress.orgs" title="The official WordPress documentation, maintained by the WordPress community">WordPress Codex</a></li>
-                       </ul>';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 <p>Image, no attachment ID class. Should NOT have srcset and sizes.</p>
+                       %4$s';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $content_unfiltered = sprintf( $content, $img, $img_no_size, $img_no_size_id );
-               $content_filtered = sprintf( $content, $respimg, $respimg_no_size, $img_no_size_id );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $content_unfiltered = sprintf( $content, $img, $img_no_size_in_class, $img_no_width_height, $img_no_size_id );
+               $content_filtered = sprintf( $content, $respimg, $respimg_no_size_in_class, $respimg_no_width_height, $img_no_size_id );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $this->assertSame( $content_filtered, wp_make_content_images_responsive( $content_unfiltered ) );
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span></span></pre>
</div>
</div>

</body>
</html>