From 7e13a32663677b07a92e8b237a414ff21df4802b Mon Sep 17 00:00:00 2001 From: selul Date: Fri, 15 Mar 2019 14:39:34 +0200 Subject: [PATCH] fix: lazyload placeholder replacement affecting non-src urls, improving compatibility with Woocommerce --- inc/lazyload_replacer.php | 24 +++++++++++++----------- inc/tag_replacer.php | 15 ++++++++------- tests/test-lazyload.php | 19 +++++++++++++++++-- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/inc/lazyload_replacer.php b/inc/lazyload_replacer.php index 190ae944..1eb61f0b 100644 --- a/inc/lazyload_replacer.php +++ b/inc/lazyload_replacer.php @@ -94,7 +94,7 @@ function () { return 1; } ); - add_filter( 'optml_tag_replace', array( $this, 'lazyload_tag_replace' ), 2, 5 ); + add_filter( 'optml_tag_replace', array( $this, 'lazyload_tag_replace' ), 2, 6 ); } @@ -106,12 +106,13 @@ function () { * @param string $new_url The optimized URL. * @param array $optml_args Options passed for URL optimization. * @param bool $is_slashed If the url needs slashes. + * @param string $full_tag Full tag, wrapper included. * * @return string */ - public function lazyload_tag_replace( $new_tag, $original_url, $new_url, $optml_args, $is_slashed = false ) { + public function lazyload_tag_replace( $new_tag, $original_url, $new_url, $optml_args, $is_slashed = false, $full_tag = '' ) { - if ( ! $this->can_lazyload_for( $original_url, $new_tag ) ) { + if ( ! $this->can_lazyload_for( $original_url, $full_tag ) ) { return Optml_Tag_Replacer::instance()->regular_tag_replace( $new_tag, $original_url, $new_url, $optml_args, $is_slashed ); } $optml_args['quality'] = 'eco'; @@ -120,7 +121,7 @@ public function lazyload_tag_replace( $new_tag, $original_url, $new_url, $optml_ $low_url = $is_slashed ? addcslashes( $low_url, '/' ) : $low_url; $opt_format = ''; - if ( $this->should_add_data_tag( $new_tag ) ) { + if ( $this->should_add_data_tag( $full_tag ) ) { $opt_format = ' data-opt-src="%s" '; $opt_format = $is_slashed ? addslashes( $opt_format ) : $opt_format; } @@ -134,20 +135,21 @@ public function lazyload_tag_replace( $new_tag, $original_url, $new_url, $optml_ $new_url, $new_tag ); - $new_tag = str_replace( + $new_tag = preg_replace( [ - $original_url, - ' src=', - 'srcset=', // Not ideal to disable srcset, we should aim to remove the srcset completely from code. + '/( src(?>=|"|\'|\s|\\\\)*)' . preg_quote( $original_url, '/' ) . '/m', + '/ src=/m', ], [ - $low_url, + "$1$low_url", $opt_src . ' src=', - 'old-srcset=', ], - $new_tag + $new_tag, + 1 ); + $new_tag = str_replace( 'srcset=', 'old-srcset=', $new_tag ); + return $new_tag . ''; } diff --git a/inc/tag_replacer.php b/inc/tag_replacer.php index 85afa6cc..e42091bc 100644 --- a/inc/tag_replacer.php +++ b/inc/tag_replacer.php @@ -47,7 +47,7 @@ public function init() { return; } - add_filter( 'optml_tag_replace', array( $this, 'regular_tag_replace' ), 1, 5 ); + add_filter( 'optml_tag_replace', array( $this, 'regular_tag_replace' ), 1, 6 ); add_filter( 'image_downsize', array( $this, 'filter_image_downsize' ), PHP_INT_MAX, 3 ); add_filter( 'wp_calculate_image_srcset', array( $this, 'filter_srcset_attr' ), PHP_INT_MAX, 5 ); add_filter( 'wp_calculate_image_sizes', array( $this, 'filter_sizes_attr' ), 1, 2 ); @@ -68,7 +68,7 @@ public function process_image_tags( $content, $images = array() ) { foreach ( $images[0] as $index => $tag ) { $width = $height = false; - $new_tag = $tag; + $image_tag = $images['img_tag'][ $index ]; $is_slashed = strpos( $images['img_url'][ $index ], '\/' ) !== false; @@ -112,7 +112,7 @@ public function process_image_tags( $content, $images = array() ) { continue; // @codeCoverageIgnore } - $new_tag = str_replace( + $image_tag = str_replace( [ 'width="' . $width . '"', 'width=\"' . $width . '\"', @@ -125,11 +125,11 @@ public function process_image_tags( $content, $images = array() ) { 'height="' . $optml_args['height'] . '"', 'height=\"' . $optml_args['height'] . '\"', ], - $new_tag + $image_tag ); - $new_tag = apply_filters( 'optml_tag_replace', $new_tag, $images['img_url'][ $index ], $new_url, $optml_args, $is_slashed ); + $image_tag = apply_filters( 'optml_tag_replace', $image_tag, $images['img_url'][ $index ], $new_url, $optml_args, $is_slashed, $tag ); - $content = str_replace( $tag, $new_tag, $content ); + $content = str_replace( $images['img_tag'][ $index ], $image_tag, $content ); } return $content; @@ -176,10 +176,11 @@ private function parse_dimensions_from_tag( $tag, $image_sizes, $args = array() * @param string $new_url The optimized URL. * @param array $optml_args Options passed for URL optimization. * @param bool $is_slashed Url needs to slashed. + * @param string $full_tag Full tag, wrapper included. * * @return string */ - public function regular_tag_replace( $new_tag, $original_url, $new_url, $optml_args, $is_slashed = false ) { + public function regular_tag_replace( $new_tag, $original_url, $new_url, $optml_args, $is_slashed = false, $full_tag = '' ) { return str_replace( $original_url, diff --git a/tests/test-lazyload.php b/tests/test-lazyload.php index 50c2da23..315b060b 100644 --- a/tests/test-lazyload.php +++ b/tests/test-lazyload.php @@ -55,7 +55,7 @@ public function test_lazy_load() { } - public function test_lazyload_json_data() { + public function test_lazyload_json_data_valid() { $some_html_content = [ 'html' => 'How to monetize a blog http://example.org/wp-content/uploads/2018/06/start-a-blog-1-5.png ' @@ -63,15 +63,30 @@ public function test_lazyload_json_data() { $content = wp_json_encode( $some_html_content ); $replaced_content = Optml_Manager::instance()->replace_content( $content ); + $replaced_content2 = Optml_Manager::instance()->replace_content( $replaced_content ); $this->assertEquals( $replaced_content, $replaced_content2 ); + $this->assertArrayHasKey( 'html', json_decode( $replaced_content2, true ) ); + $this->assertEquals( 1, substr_count( $replaced_content, 'q:eco' ) ); $this->assertEquals( 4, substr_count( $replaced_content2, '/http:\/\/' ) ); } + public function test_lazyload_tag_sanity_check(){ + $text = ' How to monetize a blog'; + + $replaced_content = Optml_Manager::instance()->replace_content( $text ); + + $this->assertContains( '', $replaced_content, 'Noscript tag should be inside the wrapper tag and after image tag' ); + $this->assertNotContains( '"http://example.org', $replaced_content ); + $this->assertEquals( 1, substr_count( $replaced_content, 'q:eco' ) ); + $this->assertEquals( 2, substr_count( $replaced_content, 'old-srcset' ) ); + + + } public function test_replacement_with_jetpack_photon() { $content = '