Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions inc/tag_replacer.php
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,13 @@ public function add_missing_srcset_attributes( $tag, $missing_srcsets, $new_url,
}
$breakpoint = isset( $srcset_data['b'] ) ? (int) $srcset_data['b'] : 0;

// A dpr entry advertises its delivered width ("824w"): the CSS width times the dpr. The CDN
// multiplies w by dpr, so it gets the CSS width, which is also the slot in the sizes attribute.
$css_width = $dpr > 1 ? (int) round( $width / $dpr ) : $width;
$css_height = $dpr > 1 ? (int) round( $height / $dpr ) : $height;

// Generate optimized URL for this size
$optimized_url = $this->change_url_for_size( $new_url, $width, $height, $dpr );
$optimized_url = $this->change_url_for_size( $new_url, $css_width, $css_height, $dpr );

if ( $optimized_url ) {
$escaped_url = esc_url( $optimized_url );
Expand All @@ -512,7 +517,7 @@ public function add_missing_srcset_attributes( $tag, $missing_srcsets, $new_url,

// Add sizes attribute entry for responsive breakpoints
if ( $breakpoint > 0 ) {
$new_sizes_entries[] = '(max-width: ' . $breakpoint . 'px) ' . $width . 'px';
$new_sizes_entries[] = '(max-width: ' . $breakpoint . 'px) ' . $css_width . 'px';
}
}
}
Expand Down
67 changes: 64 additions & 3 deletions tests/test-srcset.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,7 @@ public function test_add_missing_srcset_attributes_retina_disabled() {
$tag_replacer = new Optml_Tag_Replacer();

// Mock settings to disable retina images
$settings = $this->getMockBuilder( 'Optml_Settings' )->getMock();
$settings->method( 'get' )->with( 'retina_images' )->willReturn( 'disabled' );
$tag_replacer->settings = $settings;
$tag_replacer->settings = $this->retina_settings( 'disabled' );

$tag = '<img src="https://example.com/image.jpg" alt="Test" />';
$missing_srcsets = [
Expand All @@ -191,6 +189,69 @@ public function test_add_missing_srcset_attributes_retina_disabled() {
$this->assertStringNotContainsString( '400w', $result );
}

/**
* With Retina enabled, the profiler sends a 1x and a 2x entry per breakpoint. The 2x entry
* advertises its delivered width (824w); the CDN multiplies w by dpr, so its URL asks for the
* CSS width (w:412/dpr:2), not w:824/dpr:2, which would deliver 1648px.
*/
public function test_add_missing_srcset_attributes_retina_entry_delivers_its_advertised_width(): void {
$tag_replacer = new Optml_Tag_Replacer();
$tag_replacer->settings = $this->retina_settings( 'enabled' );

$result = $tag_replacer->add_missing_srcset_attributes(
'<img src="https://example.com/image.jpg" alt="Test" />',
[
[ 'w' => 412, 'h' => 300, 'd' => 1, 's' => '412w', 'b' => 768 ],
[ 'w' => 824, 'h' => 600, 'd' => 2, 's' => '824w', 'b' => 768 ],
],
'https://example.i.optimole.com/w:auto/h:auto/q:mauto/https://example.com/image.jpg',
false
);

$this->assertStringContainsString( 'w:412/h:300/q:mauto/https://example.com/image.jpg 412w', $result );
$this->assertStringContainsString( 'w:412/dpr:2/h:300/q:mauto/https://example.com/image.jpg 824w', $result );
$this->assertStringNotContainsString( 'w:824', $result );
}

/**
* The 1x and 2x entries of a breakpoint share one slot: the sizes attribute gets one
* condition for it, with the CSS width, not a second one with the doubled width.
*/
public function test_add_missing_srcset_attributes_retina_entries_share_one_sizes_condition(): void {
$tag_replacer = new Optml_Tag_Replacer();
$tag_replacer->settings = $this->retina_settings( 'enabled' );

$result = $tag_replacer->add_missing_srcset_attributes(
'<img src="https://example.com/image.jpg" alt="Test" />',
[
[ 'w' => 300, 'h' => 200, 'd' => 1, 's' => '300w', 'b' => 480 ],
[ 'w' => 600, 'h' => 400, 'd' => 2, 's' => '600w', 'b' => 480 ],
[ 'w' => 412, 'h' => 300, 'd' => 1, 's' => '412w', 'b' => 768 ],
[ 'w' => 824, 'h' => 600, 'd' => 2, 's' => '824w', 'b' => 768 ],
],
'https://example.i.optimole.com/w:auto/h:auto/q:mauto/https://example.com/image.jpg',
false
);

$this->assertSame( 1, substr_count( $result, '(max-width: 480px)' ) );
$this->assertSame( 1, substr_count( $result, '(max-width: 768px)' ) );
$this->assertStringContainsString( 'sizes="(max-width: 480px) 300px, (max-width: 768px) 412px"', $result );
}

/**
* Settings mock for the Retina images option.
*
* @param string $retina_images The option value, 'enabled' or 'disabled'.
*
* @return Optml_Settings
*/
private function retina_settings( string $retina_images ): Optml_Settings {
$settings = $this->getMockBuilder( 'Optml_Settings' )->getMock();
$settings->method( 'get' )->with( 'retina_images' )->willReturn( $retina_images );

return $settings;
}

/**
* Test enhance_existing_srcset method
*/
Expand Down
Loading