From 74018406d66edfb70d1f7f27c51ee6fddedf3df8 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Wed, 1 Apr 2020 02:21:59 -0400 Subject: [PATCH 01/45] Sanitize DailyMotion embeds --- .../class-amp-dailymotion-embed-handler.php | 116 +++++++++--------- .../test-amp-dailymotion-embed-handler.php | 18 ++- 2 files changed, 73 insertions(+), 61 deletions(-) diff --git a/includes/embeds/class-amp-dailymotion-embed-handler.php b/includes/embeds/class-amp-dailymotion-embed-handler.php index e1c7e262b36..26cd01d96aa 100644 --- a/includes/embeds/class-amp-dailymotion-embed-handler.php +++ b/includes/embeds/class-amp-dailymotion-embed-handler.php @@ -5,6 +5,8 @@ * @package AMP */ +use AmpProject\Dom\Document; + /** * Class AMP_DailyMotion_Embed_Handler * @@ -12,8 +14,7 @@ */ class AMP_DailyMotion_Embed_Handler extends AMP_Base_Embed_Handler { - const URL_PATTERN = '#https?:\/\/(www\.)?dailymotion\.com\/video\/.*#i'; - const RATIO = 0.5625; + const RATIO = 0.5625; /** * Default width. @@ -48,86 +49,89 @@ public function __construct( $args = [] ) { * Register embed. */ public function register_embed() { - wp_embed_register_handler( 'amp-dailymotion', self::URL_PATTERN, [ $this, 'oembed' ], -1 ); + // Not implemented. } /** * Unregister embed. */ public function unregister_embed() { - wp_embed_unregister_handler( 'amp-dailymotion', -1 ); + // Not implemented. } /** - * Render oEmbed. + * Sanitize all DailyMotion '; + return ''; }, 10, 2 @@ -63,17 +63,17 @@ public function get_conversion_data() { 'url_simple' => [ 'https://gfycat.com/tautwhoppingcougar' . PHP_EOL, - '

' . PHP_EOL, + '' . PHP_EOL, ], 'url_with_detail' => [ 'https://gfycat.com/gifs/detail/tautwhoppingcougar' . PHP_EOL, - '

' . PHP_EOL, + '' . PHP_EOL, ], 'url_with_params' => [ 'https://gfycat.com/gifs/detail/tautwhoppingcougar?foo=bar' . PHP_EOL, - '

' . PHP_EOL, + '' . PHP_EOL, ], ]; @@ -89,9 +89,14 @@ public function get_conversion_data() { public function test__conversion( $source, $expected ) { $embed = new AMP_Gfycat_Embed_Handler(); $embed->register_embed(); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $content = AMP_DOM_Utils::get_content_from_dom( $dom ); - $this->assertEquals( $expected, $filtered_content ); + $this->assertEquals( $expected, $content ); } /** @@ -122,9 +127,12 @@ public function get_scripts_data() { public function test__get_scripts( $source, $expected ) { $embed = new AMP_Gfycat_Embed_Handler(); $embed->register_embed(); - $source = apply_filters( 'the_content', $source ); - $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( AMP_DOM_Utils::get_dom_from_content( $source ) ); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); $whitelist_sanitizer->sanitize(); $scripts = array_merge( From 7e1ccf00112cf2d92c011192a72b9df16665c9a5 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Mon, 27 Apr 2020 15:50:41 -0400 Subject: [PATCH 03/45] Unwrap Instagram embeds --- .../class-amp-instagram-embed-handler.php | 99 +++----------- .../php/test-amp-instagram-embed-handler.php | 121 +++++++----------- 2 files changed, 64 insertions(+), 156 deletions(-) diff --git a/includes/embeds/class-amp-instagram-embed-handler.php b/includes/embeds/class-amp-instagram-embed-handler.php index 313d455d8fb..97cef09aa31 100644 --- a/includes/embeds/class-amp-instagram-embed-handler.php +++ b/includes/embeds/class-amp-instagram-embed-handler.php @@ -13,8 +13,8 @@ * Much of this class is borrowed from Jetpack embeds */ class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler { - const SHORT_URL_HOST = 'instagr.am'; - const URL_PATTERN = '#https?:\/\/(www\.)?instagr(\.am|am\.com)\/(p|tv)\/([A-Za-z0-9-_]+)#i'; + + const URL_PATTERN = '#https?:\/\/(www\.)?instagr(\.am|am\.com)\/(p|tv)\/([A-Za-z0-9-_]+)#i'; /** * Default width. @@ -40,7 +40,7 @@ class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler { /** * Tag. * - * @var string AMP amp-facebook tag + * @var string AMP amp-instagram tag */ private $amp_tag = 'amp-instagram'; @@ -48,87 +48,14 @@ class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler { * Registers embed. */ public function register_embed() { - wp_embed_register_handler( $this->amp_tag, self::URL_PATTERN, [ $this, 'oembed' ], -1 ); + // Not implemented. } /** * Unregisters embed. */ public function unregister_embed() { - wp_embed_unregister_handler( $this->amp_tag, -1 ); - } - - /** - * WordPress OEmbed rendering callback. - * - * @param array $matches URL pattern matches. - * @param array $attr Matched attributes. - * @param string $url Matched URL. - * @return string HTML markup for rendered embed. - */ - public function oembed( $matches, $attr, $url ) { - return $this->render( - [ - 'url' => $url, - 'instagram_id' => end( $matches ), - ] - ); - } - - /** - * Gets the rendered embed markup. - * - * @param array $args Embed rendering arguments. - * @return string HTML markup for rendered embed. - */ - public function render( $args ) { - $args = wp_parse_args( - $args, - [ - 'url' => false, - 'instagram_id' => false, - ] - ); - - if ( empty( $args['instagram_id'] ) ) { - return AMP_HTML_Utils::build_tag( - 'a', - [ - 'href' => esc_url_raw( $args['url'] ), - 'class' => 'amp-wp-embed-fallback', - ], - esc_html( $args['url'] ) - ); - } - - $this->did_convert_elements = true; - - return AMP_HTML_Utils::build_tag( - $this->amp_tag, - [ - 'data-shortcode' => $args['instagram_id'], - 'data-captioned' => '', - 'layout' => 'responsive', - 'width' => $this->args['width'], - 'height' => $this->args['height'], - ] - ); - } - - /** - * Get Instagram ID from URL. - * - * @param string $url URL. - * @return string|false The ID parsed from the URL or false if not found. - */ - private function get_instagram_id_from_url( $url ) { - $found = preg_match( self::URL_PATTERN, $url, $matches ); - - if ( ! $found ) { - return false; - } - - return end( $matches ); + // Not implemented. } /** @@ -190,6 +117,22 @@ private function create_amp_instagram_and_replace_node( $dom, $node ) { $this->did_convert_elements = true; } + /** + * Get Instagram ID from URL. + * + * @param string $url URL. + * @return string|false The ID parsed from the URL or false if not found. + */ + private function get_instagram_id_from_url( $url ) { + $found = preg_match( self::URL_PATTERN, $url, $matches ); + + if ( ! $found ) { + return false; + } + + return end( $matches ); + } + /** * Removes Instagram's embed ' ), // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine + '', + ], + + 'blockquote_tv_embed' => [ + wpautop( '
Lorem ipsum
' ), // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine + '', + ], + + 'blockquote_embed_with_caption' => [ + wpautop( '
Lorem ipsum
' ), // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine + '', ], ]; } @@ -37,9 +57,14 @@ public function get_conversion_data() { public function test__conversion( $source, $expected ) { $embed = new AMP_Instagram_Embed_Handler(); $embed->register_embed(); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $content = AMP_DOM_Utils::get_content_from_dom( $dom ); - $this->assertEquals( $expected, $filtered_content ); + $this->assertEquals( $expected, $content ); } /** @@ -70,9 +95,12 @@ public function get_scripts_data() { public function test__get_scripts( $source, $expected ) { $embed = new AMP_Instagram_Embed_Handler(); $embed->register_embed(); - $source = apply_filters( 'the_content', $source ); - $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( AMP_DOM_Utils::get_dom_from_content( $source ) ); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); $whitelist_sanitizer->sanitize(); $scripts = array_merge( @@ -80,69 +108,6 @@ public function test__get_scripts( $source, $expected ) { $whitelist_sanitizer->get_scripts() ); - $this->assertEquals( $expected, $scripts ); - } - - /** - * Data for test__raw_embed_sanitizer. - * - * @return array - */ - public function get_raw_embed_dataset() { - return [ - 'no_embed' => [ - '

Hello world.

', - '

Hello world.

', - ], - 'embed_blockquote_without_instagram' => [ - '

lorem ipsum

', - '

lorem ipsum

', - ], - - 'blockquote_embed' => [ - wpautop( '
Lorem ipsum
' ), // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine - '' . "\n\n", - ], - - 'blockquote_tv_embed' => [ - wpautop( '
Lorem ipsum
' ), // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine - '' . "\n\n", - ], - - 'blockquote_embed_notautop' => [ - '
Lorem ipsum
', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine - ' ', - ], - - 'blockquote_embed_with_caption' => [ - wpautop( '
Lorem ipsum
' ), // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine - '' . "\n\n", - ], - - 'blockquote_embed_with_caption_notautop' => [ - '
Lorem ipsum
', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript, WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine - ' ', - ], - ]; - } - - /** - * Test raw_embed_sanitizer. - * - * @param string $source Content. - * @param string $expected Expected content. - * @dataProvider get_raw_embed_dataset - * @covers AMP_Instagram_Embed_Handler::sanitize_raw_embeds() - */ - public function test__raw_embed_sanitizer( $source, $expected ) { - $dom = AMP_DOM_Utils::get_dom_from_content( $source ); - $embed = new AMP_Instagram_Embed_Handler(); - - $embed->sanitize_raw_embeds( $dom ); - - $content = AMP_DOM_Utils::get_content_from_dom( $dom ); - $content = preg_replace( '/(?<=>)\s+(?=<)/', '', $content ); - - $this->assertEquals( $expected, $content ); + $this->assertEquals( $expected . PHP_EOL . PHP_EOL, $scripts ); } } From 3bb9d3e20b9f69d0203c5a77bb964cb4e895fcac Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Mon, 4 May 2020 15:54:17 -0400 Subject: [PATCH 04/45] Unwrap Scribd embeds --- .../embeds/class-amp-base-embed-handler.php | 11 +-- .../embeds/class-amp-scribd-embed-handler.php | 79 ++++++++++--------- includes/utils/class-amp-dom-utils.php | 15 ++++ tests/php/test-amp-scribd-embed-handler.php | 20 +++-- 4 files changed, 74 insertions(+), 51 deletions(-) diff --git a/includes/embeds/class-amp-base-embed-handler.php b/includes/embeds/class-amp-base-embed-handler.php index d9677a1f146..ec52ee7c500 100644 --- a/includes/embeds/class-amp-base-embed-handler.php +++ b/includes/embeds/class-amp-base-embed-handler.php @@ -115,15 +115,12 @@ function ( $attr_name ) { * @param DOMElement $node Node. */ protected function maybe_unwrap_p_element( DOMElement $node ) { - $parent_node = $node->parentNode; - while ( $parent_node && ! ( $parent_node instanceof DOMElement ) ) { - $parent_node = $parent_node->parentNode; - } + $parent_element = AMP_DOM_Utils::get_parent_element( $node ); - if ( 'p' === $parent_node->nodeName && false === $parent_node->hasAttributes() ) { - $children = $parent_node->getElementsByTagName( '*' ); + if ( $parent_element && 'p' === $parent_element->nodeName && false === $parent_element->hasAttributes() ) { + $children = $parent_element->getElementsByTagName( '*' ); if ( 1 === $children->length ) { - $parent_node->parentNode->replaceChild( $node, $parent_node ); + $parent_element->parentNode->replaceChild( $node, $parent_element ); } } } diff --git a/includes/embeds/class-amp-scribd-embed-handler.php b/includes/embeds/class-amp-scribd-embed-handler.php index 3cefd301ff0..11b4449f30d 100644 --- a/includes/embeds/class-amp-scribd-embed-handler.php +++ b/includes/embeds/class-amp-scribd-embed-handler.php @@ -6,6 +6,8 @@ * @since 1.4 */ +use AmpProject\Dom\Document; + /** * Class AMP_Scribd_Embed_Handler */ @@ -15,63 +17,66 @@ class AMP_Scribd_Embed_Handler extends AMP_Base_Embed_Handler { * Registers embed. */ public function register_embed() { - add_filter( 'embed_oembed_html', [ $this, 'filter_embed_oembed_html' ], 10, 2 ); + // Not implemented. } /** * Unregisters embed. */ public function unregister_embed() { - remove_filter( 'embed_oembed_html', [ $this, 'filter_embed_oembed_html' ] ); + // Not implemented. } /** - * Filter oEmbed HTML for Scribd to be AMP compatible. + * Sanitize all gfycat .*$#s', - function ( $matches ) { - $attrs = $matches['iframe_attributes']; + private function sanitize_raw_embed( DOMElement $iframe_node ) { + $required_sandbox_permissions = 'allow-popups allow-scripts'; + $iframe_node->setAttribute( + 'sandbox', + sprintf( '%s %s', $iframe_node->getAttribute( 'sandbox' ), $required_sandbox_permissions ) + ); - // Amend the required keywords to the iframe's sandbox. - $sandbox = 'allow-popups allow-scripts'; - $replaced = 0; - $attrs = preg_replace( - '#(?<=\ssandbox=["\'])#', - "{$sandbox} ", // whitespace is necessary to separate prior permissions. - $attrs, - 1, - $replaced - ); + // Remove the accompanied script tag so that the iframe can be later unwrapped. + if ( 'script' === $iframe_node->nextSibling->nodeName ) { + $parent_element = AMP_DOM_Utils::get_parent_element( $iframe_node ); + if ( $parent_element ) { + $parent_element->removeChild( $iframe_node->nextSibling ); + } + } - // If no sandbox attribute was found, then add the attribute. - if ( 0 === $replaced ) { - $attrs .= sprintf( ' sandbox="%s"', $sandbox ); - } + $iframe_node->setAttribute( 'layout', 'responsive' ); - // The iframe sanitizer will convert this into an amp-iframe. - return ""; - }, - $html - ); + $this->maybe_unwrap_p_element( $iframe_node ); + + // The iframe sanitizer will further sanitize and convert this into an amp-iframe. } } diff --git a/includes/utils/class-amp-dom-utils.php b/includes/utils/class-amp-dom-utils.php index ffa2aff6085..4bef288329b 100644 --- a/includes/utils/class-amp-dom-utils.php +++ b/includes/utils/class-amp-dom-utils.php @@ -499,4 +499,19 @@ public static function copy_attributes( $attributes, DOMElement $from, DOMElemen } } } + + /** + * Get closest parent element for specified DOM node. + * + * @param DOMNode $node DOMNode. + * @return DOMElement|null + */ + public static function get_parent_element( DOMNode $node ) { + $parent_node = $node->parentNode; + while ( $parent_node && ! ( $parent_node instanceof DOMElement ) ) { + $parent_node = $parent_node->parentNode; + } + + return $parent_node; + } } diff --git a/tests/php/test-amp-scribd-embed-handler.php b/tests/php/test-amp-scribd-embed-handler.php index c9352a1b488..7d08d7a6c3d 100644 --- a/tests/php/test-amp-scribd-embed-handler.php +++ b/tests/php/test-amp-scribd-embed-handler.php @@ -91,7 +91,7 @@ public function get_conversion_data() { 'document_embed' => [ $this->scribd_doc_url . PHP_EOL, - '

' . PHP_EOL, + '' . PHP_EOL, ], ]; @@ -99,7 +99,7 @@ public function get_conversion_data() { if ( version_compare( strtok( get_bloginfo( 'version' ), '-' ), '5.2', '<' ) ) { $data['document_embed'] = [ $this->scribd_doc_url . PHP_EOL, - '

' . PHP_EOL, + '' . PHP_EOL, ]; } @@ -109,8 +109,6 @@ public function get_conversion_data() { /** * Test conversion. * - * @covers AMP_Scribd_Embed_Handler::filter_embed_oembed_html() - * @covers AMP_Scribd_Embed_Handler::sanitize_iframe() * @dataProvider get_conversion_data * * @param $source @@ -119,9 +117,14 @@ public function get_conversion_data() { public function test__conversion( $source, $expected ) { $embed = new AMP_Scribd_Embed_Handler(); $embed->register_embed(); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $content = AMP_DOM_Utils::get_content_from_dom( $dom ); - $this->assertEquals( $expected, $filtered_content ); + $this->assertEquals( $expected, $content ); } /** @@ -154,9 +157,12 @@ public function get_scripts_data() { public function test__get_scripts( $source, $expected ) { $embed = new AMP_Scribd_Embed_Handler(); $embed->register_embed(); - $source = apply_filters( 'the_content', $source ); - $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( AMP_DOM_Utils::get_dom_from_content( $source ) ); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); $whitelist_sanitizer->sanitize(); $scripts = array_merge( From be260f89b9f934450e08afa7b5810a113b5df322 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Tue, 5 May 2020 07:31:20 -0400 Subject: [PATCH 05/45] Unwrap SoundCloud embeds --- .../class-amp-soundcloud-embed-handler.php | 161 ++++++------------ .../php/test-amp-soundcloud-embed-handler.php | 21 ++- 2 files changed, 63 insertions(+), 119 deletions(-) diff --git a/includes/embeds/class-amp-soundcloud-embed-handler.php b/includes/embeds/class-amp-soundcloud-embed-handler.php index c65bd5da358..799704e0dec 100644 --- a/includes/embeds/class-amp-soundcloud-embed-handler.php +++ b/includes/embeds/class-amp-soundcloud-embed-handler.php @@ -5,6 +5,8 @@ * @package AMP */ +use AmpProject\Dom\Document; + /** * Class AMP_SoundCloud_Embed_Handler * @@ -23,163 +25,100 @@ class AMP_SoundCloud_Embed_Handler extends AMP_Base_Embed_Handler { * Register embed. */ public function register_embed() { - add_filter( 'embed_oembed_html', [ $this, 'filter_embed_oembed_html' ], 10, 2 ); + // Not implemented. } /** * Unregister embed. */ public function unregister_embed() { - remove_filter( 'embed_oembed_html', [ $this, 'filter_embed_oembed_html' ], 10 ); + // Not implemented. } /** - * Render oEmbed. - * - * @see \WP_Embed::shortcode() + * Sanitize all SoundCloud ' . PHP_EOL, ], ]; } /** - * Test filter_oembed_html + * Test conversion. * - * @dataProvider get_filter_oembed_data - * @covers AMP_WordPress_TV_Embed_Handler::filter_oembed_html() + * @dataProvider get_conversion_data * - * @param mixed $cache The cached markup. - * @param string $url The URL of the embed. + * @param string $source Source. * @param string $expected The expected return value. */ - public function test_filter_oembed_html( $cache, $url, $expected ) { - if ( null === $expected ) { - $expected = $cache; - } + public function test_conversion( $source, $expected ) { + $embed = new AMP_WordPress_TV_Embed_Handler(); + $embed->register_embed(); + + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); - $handler = new AMP_WordPress_TV_Embed_Handler(); - $this->assertEquals( - $expected, - $handler->filter_oembed_html( $cache, $url ) - ); + $content = AMP_DOM_Utils::get_content_from_dom( $dom ); + $this->assertEquals( $expected, $content ); } } From 575f173ed9b519bf649415e7c08ca01d053ec494 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Fri, 8 May 2020 07:19:09 -0400 Subject: [PATCH 10/45] Sanitize Hulu embeds --- .../embeds/class-amp-hulu-embed-handler.php | 108 ++++++++++++------ .../php/test-class-amp-hulu-embed-handler.php | 22 ++-- 2 files changed, 82 insertions(+), 48 deletions(-) diff --git a/includes/embeds/class-amp-hulu-embed-handler.php b/includes/embeds/class-amp-hulu-embed-handler.php index e9dca1df449..9ccc24a8600 100644 --- a/includes/embeds/class-amp-hulu-embed-handler.php +++ b/includes/embeds/class-amp-hulu-embed-handler.php @@ -6,6 +6,8 @@ * @since 1.0 */ +use AmpProject\Dom\Document; + /** * Class AMP_Hulu_Embed_Handler */ @@ -28,60 +30,92 @@ class AMP_Hulu_Embed_Handler extends AMP_Base_Embed_Handler { * Register embed. */ public function register_embed() { - add_filter( 'embed_oembed_html', [ $this, 'filter_embed_oembed_html' ], 10, 3 ); + // Not implemented. } /** * Unregister embed. */ public function unregister_embed() { - remove_filter( 'embed_oembed_html', [ $this, 'filter_embed_oembed_html' ], 10 ); + // Not implemented. } /** - * Filter oEmbed HTML for Hulu to prepare it for AMP. + * Sanitize all Hulu ' . PHP_EOL, ], From bd606bf81d22fc2e6082066343c0c7a1121306f8 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Mon, 18 May 2020 11:42:43 -0400 Subject: [PATCH 12/45] Make child element count more robust --- includes/embeds/class-amp-base-embed-handler.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/includes/embeds/class-amp-base-embed-handler.php b/includes/embeds/class-amp-base-embed-handler.php index eff3a67091d..4f2660caab3 100644 --- a/includes/embeds/class-amp-base-embed-handler.php +++ b/includes/embeds/class-amp-base-embed-handler.php @@ -118,8 +118,15 @@ protected function maybe_unwrap_p_element( DOMElement $node ) { $parent_element = AMP_DOM_Utils::get_parent_element( $node ); if ( $parent_element && 'p' === $parent_element->nodeName && false === $parent_element->hasAttributes() ) { - $children = $parent_element->getElementsByTagName( '*' ); - if ( 1 === $children->length ) { + $child_element_count = array_sum( + array_map( + static function ( DOMNode $child ) { + return $child instanceof DOMElement ? 1 : 0; + }, + iterator_to_array( $node->childNodes ) + ) + ); + if ( 1 === $child_element_count ) { $parent_element->parentNode->replaceChild( $node, $parent_element ); } } From 8e492b25a1d0b48ef3f626eef670aaea8c70bdb3 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Mon, 18 May 2020 11:43:37 -0400 Subject: [PATCH 13/45] Extract base embed URLs as class constants --- .../embeds/class-amp-dailymotion-embed-handler.php | 14 ++++++++++---- includes/embeds/class-amp-gfycat-embed-handler.php | 7 ++++--- includes/embeds/class-amp-hulu-embed-handler.php | 7 ++++--- includes/embeds/class-amp-scribd-embed-handler.php | 9 ++++++++- .../embeds/class-amp-soundcloud-embed-handler.php | 9 ++++++++- includes/embeds/class-amp-vimeo-embed-handler.php | 9 ++++++++- .../class-amp-wordpress-tv-embed-handler.php | 9 ++++++++- 7 files changed, 50 insertions(+), 14 deletions(-) diff --git a/includes/embeds/class-amp-dailymotion-embed-handler.php b/includes/embeds/class-amp-dailymotion-embed-handler.php index 58ca2644c4a..26791477a9c 100644 --- a/includes/embeds/class-amp-dailymotion-embed-handler.php +++ b/includes/embeds/class-amp-dailymotion-embed-handler.php @@ -16,6 +16,13 @@ class AMP_DailyMotion_Embed_Handler extends AMP_Base_Embed_Handler { const RATIO = 0.5625; + /** + * Base URL used for identifying embeds. + * + * @var string + */ + const BASE_EMBED_URL = 'https://www.dailymotion.com/embed/video/'; + /** * Default width. * @@ -65,7 +72,7 @@ public function unregister_embed() { * @param Document $dom DOM. */ public function sanitize_raw_embeds( Document $dom ) { - $nodes = $dom->xpath->query( '//iframe[ starts-with( @src, "https://www.dailymotion.com/embed/video/" ) ]' ); + $nodes = $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', self::BASE_EMBED_URL ) ); foreach ( $nodes as $node ) { if ( ! $this->is_raw_embed( $node ) ) { @@ -93,9 +100,8 @@ protected function is_raw_embed( DOMElement $node ) { private function sanitize_raw_embed( DOMElement $iframe_node ) { $iframe_src = $iframe_node->getAttribute( 'src' ); - if ( preg_match( '#video/(?P[a-zA-Z0-9]+)#', $iframe_src, $matches ) ) { - $video_id = $matches['video_id']; - + $video_id = strtok( substr( $iframe_src, strlen( self::BASE_EMBED_URL ) ), '/?#' ); + if ( ! empty( $video_id ) ) { $amp_node = AMP_DOM_Utils::create_node( Document::fromNode( $iframe_node ), 'amp-dailymotion', diff --git a/includes/embeds/class-amp-gfycat-embed-handler.php b/includes/embeds/class-amp-gfycat-embed-handler.php index 45a3f11ad4e..0d81e5afee8 100644 --- a/includes/embeds/class-amp-gfycat-embed-handler.php +++ b/includes/embeds/class-amp-gfycat-embed-handler.php @@ -12,12 +12,13 @@ * Class AMP_Gfycat_Embed_Handler */ class AMP_Gfycat_Embed_Handler extends AMP_Base_Embed_Handler { + /** - * Regex matched to produce output amp-gfycat. + * Base URL used for identifying embeds. * * @var string */ - const URL_PATTERN = '#https?://(www\.)?gfycat\.com/.*#i'; + const BASE_EMBED_URL = 'www.hulu.com/embed.html'; /** * Register embed. @@ -39,7 +40,7 @@ public function unregister_embed() { * @param Document $dom DOM. */ public function sanitize_raw_embeds( Document $dom ) { - $nodes = $dom->xpath->query( '//iframe[ starts-with( @src, "https://gfycat.com/ifr/" ) ]' ); + $nodes = $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', self::BASE_EMBED_URL ) ); foreach ( $nodes as $node ) { if ( ! $this->is_raw_embed( $node ) ) { diff --git a/includes/embeds/class-amp-hulu-embed-handler.php b/includes/embeds/class-amp-hulu-embed-handler.php index 07ae31c232b..d201413e60d 100644 --- a/includes/embeds/class-amp-hulu-embed-handler.php +++ b/includes/embeds/class-amp-hulu-embed-handler.php @@ -12,12 +12,13 @@ * Class AMP_Hulu_Embed_Handler */ class AMP_Hulu_Embed_Handler extends AMP_Base_Embed_Handler { + /** - * Regex matched to produce output amp-hulu. + * Base URL used for identifying embeds. * * @var string */ - const URL_PATTERN = '#https?://(www\.)?hulu\.com/.*#i'; + const BASE_EMBED_URL = 'www.hulu.com/embed.html'; /** * Default height. @@ -46,7 +47,7 @@ public function unregister_embed() { * @param Document $dom DOM. */ public function sanitize_raw_embeds( Document $dom ) { - $nodes = $dom->xpath->query( '//iframe[ contains( @src, "www.hulu.com/embed.html" ) ]' ); + $nodes = $dom->xpath->query( sprintf( '//iframe[ contains( @src, "%s" ) ]', self::BASE_EMBED_URL ) ); foreach ( $nodes as $node ) { if ( ! $this->is_raw_embed( $node ) ) { diff --git a/includes/embeds/class-amp-scribd-embed-handler.php b/includes/embeds/class-amp-scribd-embed-handler.php index 9b2cf721b0b..0c2937d1b45 100644 --- a/includes/embeds/class-amp-scribd-embed-handler.php +++ b/includes/embeds/class-amp-scribd-embed-handler.php @@ -13,6 +13,13 @@ */ class AMP_Scribd_Embed_Handler extends AMP_Base_Embed_Handler { + /** + * Base URL used for identifying embeds. + * + * @var string + */ + const BASE_EMBED_URL = 'https://www.scribd.com/embeds/'; + /** * Registers embed. */ @@ -33,7 +40,7 @@ public function unregister_embed() { * @param Document $dom DOM. */ public function sanitize_raw_embeds( Document $dom ) { - $nodes = $dom->xpath->query( '//iframe[ starts-with( @src, "https://www.scribd.com/embeds/" ) ]' ); + $nodes = $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', self::BASE_EMBED_URL ) ); foreach ( $nodes as $node ) { if ( ! $this->is_raw_embed( $node ) ) { diff --git a/includes/embeds/class-amp-soundcloud-embed-handler.php b/includes/embeds/class-amp-soundcloud-embed-handler.php index 3cb73e2c5e4..aa46eef442d 100644 --- a/includes/embeds/class-amp-soundcloud-embed-handler.php +++ b/includes/embeds/class-amp-soundcloud-embed-handler.php @@ -14,6 +14,13 @@ */ class AMP_SoundCloud_Embed_Handler extends AMP_Base_Embed_Handler { + /** + * Base URL used for identifying embeds. + * + * @var string + */ + const BASE_EMBED_URL = 'https://w.soundcloud.com/player/'; + /** * Default height. * @@ -41,7 +48,7 @@ public function unregister_embed() { * @param Document $dom DOM. */ public function sanitize_raw_embeds( Document $dom ) { - $nodes = $dom->xpath->query( '//iframe[ starts-with( @src, "https://w.soundcloud.com/player/" ) ]' ); + $nodes = $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', self::BASE_EMBED_URL ) ); foreach ( $nodes as $node ) { if ( ! $this->is_raw_embed( $node ) ) { diff --git a/includes/embeds/class-amp-vimeo-embed-handler.php b/includes/embeds/class-amp-vimeo-embed-handler.php index 15a23cbce11..9a5f18f20ba 100644 --- a/includes/embeds/class-amp-vimeo-embed-handler.php +++ b/includes/embeds/class-amp-vimeo-embed-handler.php @@ -14,6 +14,13 @@ */ class AMP_Vimeo_Embed_Handler extends AMP_Base_Embed_Handler { + /** + * Base URL used for identifying embeds. + * + * @var string + */ + const BASE_EMBED_URL = 'https://player.vimeo.com/video/'; + /** * The aspect ratio. * @@ -70,7 +77,7 @@ public function unregister_embed() { * @param Document $dom DOM. */ public function sanitize_raw_embeds( Document $dom ) { - $nodes = $dom->xpath->query( '//iframe[ starts-with( @src, "https://player.vimeo.com/video/" ) ]' ); + $nodes = $dom->xpath->query( sprintf( '//iframe[ contains( @src, "%s" ) ]', self::BASE_EMBED_URL ) ); foreach ( $nodes as $node ) { if ( ! $this->is_raw_embed( $node ) ) { diff --git a/includes/embeds/class-amp-wordpress-tv-embed-handler.php b/includes/embeds/class-amp-wordpress-tv-embed-handler.php index 318cc7fe210..078878814a2 100644 --- a/includes/embeds/class-amp-wordpress-tv-embed-handler.php +++ b/includes/embeds/class-amp-wordpress-tv-embed-handler.php @@ -15,6 +15,13 @@ */ class AMP_WordPress_TV_Embed_Handler extends AMP_Base_Embed_Handler { + /** + * Base URL used for identifying embeds. + * + * @var string + */ + const BASE_EMBED_URL = 'https://video.wordpress.com/embed/'; + /** * The URL pattern to determine if an embed URL is for this type, copied from WP_oEmbed. * @@ -42,7 +49,7 @@ public function unregister_embed() { * @param Document $dom DOM. */ public function sanitize_raw_embeds( Document $dom ) { - $nodes = $dom->xpath->query( '//iframe[ starts-with( @src, "https://video.wordpress.com/embed/" ) ]' ); + $nodes = $dom->xpath->query( sprintf( '//iframe[ contains( @src, "%s" ) ]', self::BASE_EMBED_URL ) ); foreach ( $nodes as $node ) { if ( ! $this->is_raw_embed( $node ) ) { From 3f4f9ae6824318feffcb0ea9f9a977dbbd56901f Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Mon, 18 May 2020 11:52:50 -0400 Subject: [PATCH 14/45] Get dimensions from iframe if available --- .../class-amp-dailymotion-embed-handler.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/includes/embeds/class-amp-dailymotion-embed-handler.php b/includes/embeds/class-amp-dailymotion-embed-handler.php index 26791477a9c..41c6469e9a9 100644 --- a/includes/embeds/class-amp-dailymotion-embed-handler.php +++ b/includes/embeds/class-amp-dailymotion-embed-handler.php @@ -102,16 +102,22 @@ private function sanitize_raw_embed( DOMElement $iframe_node ) { $video_id = strtok( substr( $iframe_src, strlen( self::BASE_EMBED_URL ) ), '/?#' ); if ( ! empty( $video_id ) ) { - $amp_node = AMP_DOM_Utils::create_node( - Document::fromNode( $iframe_node ), - 'amp-dailymotion', - [ + $args = [ 'data-videoid' => $video_id, 'layout' => 'responsive', 'width' => $this->args['width'], 'height' => $this->args['height'], - ] - ); + ]; + + if ( $iframe_node->hasAttribute( 'width' ) ) { + $args['width'] = $iframe_node->getAttribute( 'width' ); + } + + if ( $iframe_node->hasAttribute( 'height' ) ) { + $args['height'] = $iframe_node->getAttribute( 'height' ); + } + + $amp_node = AMP_DOM_Utils::create_node( Document::fromNode( $iframe_node ), 'amp-dailymotion', $args ); $this->maybe_unwrap_p_element( $iframe_node ); From 085d1cc3ede2a3a0dd83ab87f7f9d6b2882a1f9b Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Mon, 18 May 2020 18:50:05 -0400 Subject: [PATCH 15/45] Refactor logic for removing script sibling --- .../embeds/class-amp-base-embed-handler.php | 47 +++++++++++++++++++ .../class-amp-instagram-embed-handler.php | 37 +-------------- .../embeds/class-amp-tiktok-embed-handler.php | 37 +-------------- .../class-amp-twitter-embed-handler.php | 43 +++-------------- 4 files changed, 55 insertions(+), 109 deletions(-) diff --git a/includes/embeds/class-amp-base-embed-handler.php b/includes/embeds/class-amp-base-embed-handler.php index 4f2660caab3..faccc37e931 100644 --- a/includes/embeds/class-amp-base-embed-handler.php +++ b/includes/embeds/class-amp-base-embed-handler.php @@ -112,6 +112,8 @@ function ( $attr_name ) { * Replace the node's parent with itself if the parent is a

tag, has no attributes and has no other children. * This usually happens while `wpautop()` processes the element. * + * @since 1.6 + * * @param DOMElement $node Node. */ protected function maybe_unwrap_p_element( DOMElement $node ) { @@ -131,4 +133,49 @@ static function ( DOMNode $child ) { } } } + + /** + * Removes the node's nearest #s', '', $cache ); - return null !== $modified_block_content ? $modified_block_content : $cache; - } } From 6893a47898b28aab23978330f269e447d65ea916 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Mon, 18 May 2020 20:05:25 -0400 Subject: [PATCH 17/45] Fix tests --- .../embeds/class-amp-base-embed-handler.php | 20 ++++++++++--------- .../embeds/class-amp-gfycat-embed-handler.php | 6 +++--- .../class-amp-soundcloud-embed-handler.php | 8 ++++---- .../class-amp-twitter-embed-handler.php | 2 +- .../test-amp-dailymotion-embed-handler.php | 4 ++-- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/includes/embeds/class-amp-base-embed-handler.php b/includes/embeds/class-amp-base-embed-handler.php index faccc37e931..39ae75e9048 100644 --- a/includes/embeds/class-amp-base-embed-handler.php +++ b/includes/embeds/class-amp-base-embed-handler.php @@ -125,7 +125,7 @@ protected function maybe_unwrap_p_element( DOMElement $node ) { static function ( DOMNode $child ) { return $child instanceof DOMElement ? 1 : 0; }, - iterator_to_array( $node->childNodes ) + iterator_to_array( $parent_element->childNodes ) ) ); if ( 1 === $child_element_count ) { @@ -151,17 +151,19 @@ protected function maybe_remove_script_sibling( DOMElement $node, $base_src_url // Handle case where script is wrapped in paragraph by wpautop. if ( $next_element_sibling instanceof DOMElement && 'p' === $next_element_sibling->nodeName ) { - $children = array_map( - static function ( DOMNode $child ) { - return $child instanceof DOMElement ? 1 : 0; - }, - iterator_to_array( $node->childNodes ) + $children_elements = array_values( + array_filter( + iterator_to_array( $next_element_sibling->childNodes ), + static function ( DOMNode $child ) { + return $child instanceof DOMElement; + } + ) ); if ( - 1 === count( $children) && - 'script' === $children[0]->nodeName && - false !== strpos( $children->item( 0 )->getAttribute( 'src' ), $base_src_url ) + 1 === count( $children_elements ) && + 'script' === $children_elements[0]->nodeName && + false !== strpos( $children_elements[0]->getAttribute( 'src' ), $base_src_url ) ) { $next_element_sibling->parentNode->removeChild( $next_element_sibling ); return; diff --git a/includes/embeds/class-amp-gfycat-embed-handler.php b/includes/embeds/class-amp-gfycat-embed-handler.php index 2e5b1be8164..73b9d679e40 100644 --- a/includes/embeds/class-amp-gfycat-embed-handler.php +++ b/includes/embeds/class-amp-gfycat-embed-handler.php @@ -18,7 +18,7 @@ class AMP_Gfycat_Embed_Handler extends AMP_Base_Embed_Handler { * * @var string */ - const BASE_EMBED_URL = 'www.hulu.com/embed.html'; + const BASE_EMBED_URL = 'https://gfycat.com/ifr/'; /** * Register embed. @@ -77,8 +77,8 @@ private function sanitize_raw_embed( DOMElement $iframe_node ) { $attributes = [ 'data-gfyid' => $gfycat_id, 'layout' => 'responsive', - 'width' => $this->args['width'], - 'height' => $this->args['height'], + 'height' => $this->args['height'], + 'width' => $this->args['width'], ]; if ( $iframe_node->hasAttribute( 'width' ) ) { diff --git a/includes/embeds/class-amp-soundcloud-embed-handler.php b/includes/embeds/class-amp-soundcloud-embed-handler.php index 18590daa789..c5460580f9c 100644 --- a/includes/embeds/class-amp-soundcloud-embed-handler.php +++ b/includes/embeds/class-amp-soundcloud-embed-handler.php @@ -74,14 +74,14 @@ protected function is_raw_embed( DOMElement $node ) { * @param DOMElement $iframe_node The node to make AMP compatible. */ private function sanitize_raw_embed( DOMElement $iframe_node ) { - $src = $iframe_node->getAttribute( 'src' ); + $iframe_src = $iframe_node->getAttribute( 'src' ); - parse_str( wp_parse_url( $src, PHP_URL_QUERY ), $query ); + parse_str( wp_parse_url( $iframe_src, PHP_URL_QUERY ), $query ); if ( empty( $query['url'] ) ) { return; } - $embed_id = $this->parse_embed_id_from_url( $query['url'] ); + $embed_id = $this->parse_embed_id_from_url( $query['url'] ); if ( null === $embed_id ) { return; } @@ -127,7 +127,7 @@ private function sanitize_raw_embed( DOMElement $iframe_node ) { * @return array|null Array with key being the embed type and value being the embed ID, or null if embed type and ID could not be found. */ private function parse_embed_id_from_url( $url ) { - if ( preg_match( '#/player/(?Ptracks|playlists)/(?P\d+)#', $url, $matches ) ) { + if ( preg_match( '#/(?Ptracks|playlists)/(?P\d+)#', $url, $matches ) ) { if ( 'tracks' === $matches['type'] ) { return [ 'track_id' => $matches['id'] ]; } diff --git a/includes/embeds/class-amp-twitter-embed-handler.php b/includes/embeds/class-amp-twitter-embed-handler.php index d86245cf507..43d304ae29d 100644 --- a/includes/embeds/class-amp-twitter-embed-handler.php +++ b/includes/embeds/class-amp-twitter-embed-handler.php @@ -264,7 +264,7 @@ private function get_moment_id( $url ) { private function remove_br_sibling_elements( DOMElement $node ) { $next_element_sibling = $node->nextSibling; - while ( $next_element_sibling && $next_element_sibling instanceof DOMElement &&'br' === $next_element_sibling->nodeName ) { + while ( $next_element_sibling && $next_element_sibling instanceof DOMElement && 'br' === $next_element_sibling->nodeName ) { $next_element_sibling->parentNode->removeChild( $next_element_sibling ); $next_element_sibling = $node->nextSibling; } diff --git a/tests/php/test-amp-dailymotion-embed-handler.php b/tests/php/test-amp-dailymotion-embed-handler.php index c316e860d47..d4058752b56 100644 --- a/tests/php/test-amp-dailymotion-embed-handler.php +++ b/tests/php/test-amp-dailymotion-embed-handler.php @@ -11,12 +11,12 @@ public function get_conversion_data() { 'url_simple' => [ 'https://www.dailymotion.com/video/x5awwth' . PHP_EOL, - '' . PHP_EOL, + '' . PHP_EOL, ], 'url_with_title' => [ 'http://www.dailymotion.com/video/x5awwth_snatched-official-trailer-2-hd_shortfilms' . PHP_EOL, - '' . PHP_EOL, + '' . PHP_EOL, ], ]; } From 34ca29c16c4fb8226cc3ca2fe76859ce7a19eba6 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Thu, 21 May 2020 10:35:37 -0400 Subject: [PATCH 18/45] Implement the Template Method design pattern --- .../embeds/class-amp-base-embed-handler.php | 72 ++++++- .../class-amp-dailymotion-embed-handler.php | 89 +++----- .../class-amp-facebook-embed-handler.php | 195 ++++++++---------- .../embeds/class-amp-gfycat-embed-handler.php | 67 ++---- .../embeds/class-amp-hulu-embed-handler.php | 71 +++---- .../class-amp-instagram-embed-handler.php | 66 ++---- .../embeds/class-amp-scribd-embed-handler.php | 68 +----- .../class-amp-soundcloud-embed-handler.php | 69 ++----- .../embeds/class-amp-tiktok-embed-handler.php | 60 ++---- .../class-amp-twitter-embed-handler.php | 41 ++-- .../embeds/class-amp-vimeo-embed-handler.php | 79 +++---- .../class-amp-wordpress-tv-embed-handler.php | 64 +----- .../class-amp-youtube-embed-handler.php | 84 +++----- .../sanitizers/class-amp-embed-sanitizer.php | 6 +- .../test-amp-dailymotion-embed-handler.php | 2 - tests/php/test-amp-facebook-embed-handler.php | 2 - .../php/test-amp-instagram-embed-handler.php | 2 - tests/php/test-amp-scribd-embed-handler.php | 2 - .../php/test-amp-soundcloud-embed-handler.php | 2 - tests/php/test-amp-twitter-embed-handler.php | 2 - tests/php/test-amp-vimeo-embed-handler.php | 2 - .../test-class-amp-gfycat-embed-handler.php | 2 - .../php/test-class-amp-hulu-embed-handler.php | 2 - .../test-class-amp-tiktok-embed-handler.php | 1 - ...t-class-amp-wordpress-tv-embed-handler.php | 1 - .../test-class-amp-youtube-embed-handler.php | 4 - 26 files changed, 353 insertions(+), 702 deletions(-) diff --git a/includes/embeds/class-amp-base-embed-handler.php b/includes/embeds/class-amp-base-embed-handler.php index 39ae75e9048..6d16065d5c1 100644 --- a/includes/embeds/class-amp-base-embed-handler.php +++ b/includes/embeds/class-amp-base-embed-handler.php @@ -7,6 +7,8 @@ * @package AMP */ +use AmpProject\Dom\Document; + /** * Class AMP_Base_Embed_Handler */ @@ -40,14 +42,18 @@ abstract class AMP_Base_Embed_Handler { protected $did_convert_elements = false; /** - * Registers embed. + * Default AMP tag to be used when sanitizing embeds. + * + * @var string */ - abstract public function register_embed(); + protected $amp_tag = 'amp-iframe'; /** - * Unregisters embed. + * Base URL used for identifying embeds. + * + * @var string */ - abstract public function unregister_embed(); + protected $base_embed_url = ''; /** * Constructor. @@ -64,6 +70,49 @@ public function __construct( $args = [] ) { ); } + /** + * Sanitize all embeds on the page to be AMP compatible. + * + * @param Document $dom DOM. + */ + public function sanitize_raw_embeds( Document $dom ) { + $nodes = $this->get_raw_embed_nodes( $dom ); + + foreach ( $nodes as $node ) { + if ( ! $this->is_raw_embed( $node ) ) { + continue; + } + $this->sanitize_raw_embed( $node ); + } + } + + /** + * Get all raw embeds from the DOM. + * + * @param Document $dom Document. + * @return DOMNodeList A list of DOMElement nodes. + */ + protected function get_raw_embed_nodes( Document $dom ) { + return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); + } + + /** + * Determine if the node is indeed a raw embed. + * + * @param DOMElement $node DOM element. + * @return bool True if it is a raw embed, false otherwise. + */ + protected function is_raw_embed( DOMElement $node ) { + return $node->parentNode && $this->amp_tag !== $node->parentNode->nodeName; + } + + /** + * Make embed AMP compatible. + * + * @param DOMElement $node DOM element. + */ + abstract protected function sanitize_raw_embed( DOMElement $node ); + /** * Get mapping of AMP component names to AMP script URLs. * @@ -139,10 +188,11 @@ static function ( DOMNode $child ) { * * @since 1.6 * - * @param DOMElement $node The DOMNode to whose sibling is the script to be removed. + * @param DOMElement $node The DOMNode to whose sibling is the script to be removed. * @param string $base_src_url Script URL to match against. + * @param string $content Text content of node to match against. */ - protected function maybe_remove_script_sibling( DOMElement $node, $base_src_url ) { + protected function maybe_remove_script_sibling( DOMElement $node, $base_src_url, $content = '' ) { $next_element_sibling = $node->nextSibling; while ( $next_element_sibling && ! ( $next_element_sibling instanceof DOMElement ) ) { @@ -163,7 +213,10 @@ static function ( DOMNode $child ) { if ( 1 === count( $children_elements ) && 'script' === $children_elements[0]->nodeName && - false !== strpos( $children_elements[0]->getAttribute( 'src' ), $base_src_url ) + ( + ( $base_src_url && false !== strpos( $children_elements[0]->getAttribute( 'src' ), $base_src_url ) ) || + ( $content && false !== strpos( $children_elements[0]->textContent, $content ) ) + ) ) { $next_element_sibling->parentNode->removeChild( $next_element_sibling ); return; @@ -174,7 +227,10 @@ static function ( DOMNode $child ) { $is_embed_script = ( $next_element_sibling instanceof DOMElement && 'script' === strtolower( $next_element_sibling->nodeName ) && - false !== strpos( $next_element_sibling->getAttribute( 'src' ), $base_src_url ) + ( + ( $base_src_url && false !== strpos( $next_element_sibling->getAttribute( 'src' ), $base_src_url ) ) || + ( $content && false !== strpos( $next_element_sibling->textContent, $content ) ) + ) ); if ( $is_embed_script ) { $next_element_sibling->parentNode->removeChild( $next_element_sibling ); diff --git a/includes/embeds/class-amp-dailymotion-embed-handler.php b/includes/embeds/class-amp-dailymotion-embed-handler.php index d358d791731..58cf7ac6742 100644 --- a/includes/embeds/class-amp-dailymotion-embed-handler.php +++ b/includes/embeds/class-amp-dailymotion-embed-handler.php @@ -21,13 +21,6 @@ class AMP_DailyMotion_Embed_Handler extends AMP_Base_Embed_Handler { */ const RATIO = 0.5625; - /** - * Base URL used for identifying embeds. - * - * @var string - */ - const BASE_EMBED_URL = 'https://www.dailymotion.com/embed/video/'; - /** * Default width. * @@ -42,6 +35,20 @@ class AMP_DailyMotion_Embed_Handler extends AMP_Base_Embed_Handler { */ protected $DEFAULT_HEIGHT = 338; + /** + * Default AMP tag to be used when sanitizing embeds. + * + * @var string + */ + protected $amp_tag = 'amp-dailymotion'; + + /** + * Base URL used for identifying embeds. + * + * @var string + */ + protected $base_embed_url = 'https://www.dailymotion.com/embed/video/'; + /** * AMP_DailyMotion_Embed_Handler constructor. * @@ -58,54 +65,14 @@ public function __construct( $args = [] ) { } /** - * Register embed. - */ - public function register_embed() { - // Not implemented. - } - - /** - * Unregister embed. - */ - public function unregister_embed() { - // Not implemented. - } - - /** - * Sanitize all DailyMotion ' . PHP_EOL, + '' . PHP_EOL, ], ]; } From 5b2ece9842d7dcc392046a2e8d1550c67af9bfb1 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Fri, 19 Jun 2020 00:59:01 -0400 Subject: [PATCH 30/45] Update mocked responses --- tests/php/test-amp-dailymotion-embed-handler.php | 2 +- tests/php/test-amp-twitter-embed-handler.php | 8 ++++---- tests/php/test-class-amp-gfycat-embed-handler.php | 2 +- tests/php/test-class-amp-hulu-embed-handler.php | 4 ++++ tests/php/test-class-amp-wordpress-tv-embed-handler.php | 2 +- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/php/test-amp-dailymotion-embed-handler.php b/tests/php/test-amp-dailymotion-embed-handler.php index b31fbf65b38..f97aebf8604 100644 --- a/tests/php/test-amp-dailymotion-embed-handler.php +++ b/tests/php/test-amp-dailymotion-embed-handler.php @@ -37,7 +37,7 @@ public function mock_http_request( $pre, $r, $url ) { return $pre; } - $body = '{"type":"video","version":"1.0","provider_name":"Dailymotion","provider_url":"https:\/\/www.dailymotion.com","title":"Snatched - Official Trailer 2 (HD)","description":"M\u00e1s info http:\/\/trailersyestrenos.es\/snatched-jonathan-levine\/ - TWITTER: https:\/\/twitter.com\/TrailersyEstren - FACEBOOK: https:\/\/www.facebook.com\/trailersyestrenos - GOOGLE+: https:\/\/www.google.com\/+TrailersyEstrenos Sinopsis: Una madre y una hija se enfrentar\u00e1n a distintos problemas que surgen mientras est\u00e1n de vacaciones Director: Jonathan Levine Reparto: Amy Schumer, Ike Barinholtz, Goldie Hawn, Christopher Meloni, Randall Park, Wanda Sykes, \u00d3scar Jaenada, Colin Quinn, Tom Bateman, Kevin Kane, Sharon M. Bell (El trailer pertenece a la productora y distribuidora de la pel\u00edcula y ha sido subido sin \u00e1nimo de lucro)","author_name":"Trailers y Estrenos","author_url":"https:\/\/www.dailymotion.com\/TrailersyEstrenos","width":480,"height":204,"html":"'; + return ''; }, 10, 2 diff --git a/tests/php/test-class-amp-hulu-embed-handler.php b/tests/php/test-class-amp-hulu-embed-handler.php index 9c5ec2cc627..fb5e1893c59 100644 --- a/tests/php/test-class-amp-hulu-embed-handler.php +++ b/tests/php/test-class-amp-hulu-embed-handler.php @@ -98,6 +98,10 @@ public function test__conversion( $url, $expected ) { $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); $embed->sanitize_raw_embeds( $dom ); + if ( self::is_external_http_test_suite() && "

$url

" === trim( $filtered_content ) ) { + $this->markTestSkipped( 'Endpoint is down.' ); + } + $content = AMP_DOM_Utils::get_content_from_dom( $dom ); $this->assertEquals( $expected, $content ); diff --git a/tests/php/test-class-amp-wordpress-tv-embed-handler.php b/tests/php/test-class-amp-wordpress-tv-embed-handler.php index 7f13db7cb44..d4ef574cb47 100644 --- a/tests/php/test-class-amp-wordpress-tv-embed-handler.php +++ b/tests/php/test-class-amp-wordpress-tv-embed-handler.php @@ -44,7 +44,7 @@ public function mock_http_request( $preempt, $r, $url ) { } return [ - 'body' => '{"type":"video","version":"1.0","title":null,"width":500,"height":281,"html":"

', + '' . PHP_EOL, $poll_response, ], 'polldaddy_poll' => [ 'https://polldaddy.com/poll/7012505/', - '

', + '' . PHP_EOL, $poll_response, ], 'polldaddy_survey' => [ 'https://rydk.polldaddy.com/s/test-survey', - '

View Survey

', + '' . PHP_EOL . PHP_EOL, $survey_response, ], ]; @@ -64,7 +64,7 @@ public function get_conversion_data() { if ( version_compare( get_bloginfo( 'version' ), '5.2.0', '>=' ) ) { $data['survey.fm'] = [ 'https://rydk.survey.fm/test-survey', - '

View Survey

', + '' . PHP_EOL . PHP_EOL, $survey_response, ]; } @@ -106,12 +106,14 @@ static function ( $pre, $r, $request_url ) use ( $oembed_response ) { ); $embed = new AMP_Crowdsignal_Embed_Handler(); - $embed->register_embed(); + $filtered_content = apply_filters( 'the_content', $url ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); - $expected = $this->adapt_iframe_title( $expected ); + $content = AMP_DOM_Utils::get_content_from_dom( $dom ); - $this->assertEquals( trim( $expected ), trim( $filtered_content ) ); + $this->assertEquals( $expected, $content ); } private function adapt_iframe_title( $html ) { From 4885788ab498d9ea72acb54ee6f69df7387d6ced Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Fri, 19 Jun 2020 15:00:53 -0400 Subject: [PATCH 34/45] Sanitize Pinterest embeds --- .../class-amp-pinterest-embed-handler.php | 36 ++++++++++++++++--- .../php/test-amp-pinterest-embed-handler.php | 18 +++++++--- .../php/test-class-amp-hulu-embed-handler.php | 4 +++ 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/includes/embeds/class-amp-pinterest-embed-handler.php b/includes/embeds/class-amp-pinterest-embed-handler.php index a0debc6e855..6732f796cec 100644 --- a/includes/embeds/class-amp-pinterest-embed-handler.php +++ b/includes/embeds/class-amp-pinterest-embed-handler.php @@ -5,6 +5,8 @@ * @package AMP */ +use AmpProject\Dom\Document; + /** * Class AMP_Pinterest_Embed_Handler */ @@ -26,12 +28,19 @@ class AMP_Pinterest_Embed_Handler extends AMP_Base_Embed_Handler { */ protected $DEFAULT_HEIGHT = 750; + /** + * Default AMP tag to be used when sanitizing embeds. + * + * @var string + */ + protected $amp_tag = 'amp-pinterest'; + /** * Registers embed. */ public function register_embed() { wp_embed_register_handler( - 'amp-pinterest', + $this->amp_tag, self::URL_PATTERN, [ $this, 'oembed' ], -1 @@ -42,7 +51,7 @@ public function register_embed() { * Unregisters embed. */ public function unregister_embed() { - wp_embed_unregister_handler( 'amp-pinterest', -1 ); + wp_embed_unregister_handler( $this->amp_tag, -1 ); } /** @@ -75,10 +84,8 @@ public function render( $args ) { return ''; } - $this->did_convert_elements = true; - return AMP_HTML_Utils::build_tag( - 'amp-pinterest', + $this->amp_tag, [ 'width' => $this->args['width'], 'height' => $this->args['height'], @@ -87,4 +94,23 @@ public function render( $args ) { ] ); } + + /** + * Get all raw embeds from the DOM. + * + * @param Document $dom Document. + * @return DOMNodeList A list of DOMElement nodes. + */ + protected function get_raw_embed_nodes( Document $dom ) { + return $dom->xpath->query( sprintf( '//%s', $this->amp_tag ) ); + } + + /** + * Make embed AMP compatible. + * + * @param DOMElement $node DOM element. + */ + protected function sanitize_raw_embed( DOMElement $node ) { + $this->unwrap_p_element( $node ); + } } diff --git a/tests/php/test-amp-pinterest-embed-handler.php b/tests/php/test-amp-pinterest-embed-handler.php index 62467fc7f5f..5794484433b 100644 --- a/tests/php/test-amp-pinterest-embed-handler.php +++ b/tests/php/test-amp-pinterest-embed-handler.php @@ -10,11 +10,11 @@ public function get_conversion_data() { ], 'simple_url_https' => [ 'https://www.pinterest.com/pin/606156431067611861/' . PHP_EOL, - '

' . PHP_EOL, + '' . PHP_EOL, ], 'simple_url_http' => [ 'http://www.pinterest.com/pin/606156431067611861/' . PHP_EOL, - '

' . PHP_EOL, + '' . PHP_EOL, ], ]; } @@ -25,9 +25,14 @@ public function get_conversion_data() { public function test__conversion( $source, $expected ) { $embed = new AMP_Pinterest_Embed_Handler(); $embed->register_embed(); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $content = AMP_DOM_Utils::get_content_from_dom( $dom ); - $this->assertEquals( $expected, $filtered_content ); + $this->assertEquals( $expected, $content ); } public function get_scripts_data() { @@ -49,9 +54,12 @@ public function get_scripts_data() { public function test__get_scripts( $source, $expected ) { $embed = new AMP_Pinterest_Embed_Handler(); $embed->register_embed(); - $source = apply_filters( 'the_content', $source ); - $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( AMP_DOM_Utils::get_dom_from_content( $source ) ); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); $whitelist_sanitizer->sanitize(); $scripts = array_merge( diff --git a/tests/php/test-class-amp-hulu-embed-handler.php b/tests/php/test-class-amp-hulu-embed-handler.php index fb5e1893c59..04626164dd7 100644 --- a/tests/php/test-class-amp-hulu-embed-handler.php +++ b/tests/php/test-class-amp-hulu-embed-handler.php @@ -139,6 +139,10 @@ public function test__get_scripts( $url, $expected ) { $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); $embed->sanitize_raw_embeds( $dom ); + if ( self::is_external_http_test_suite() && "

$url

" === trim( $filtered_content ) ) { + $this->markTestSkipped( 'Endpoint is down.' ); + } + $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); $whitelist_sanitizer->sanitize(); From 59066e889f33652fc609a9bb191570fa8f491212 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Sun, 21 Jun 2020 17:01:33 -0400 Subject: [PATCH 35/45] Sanitize Vine embeds --- .../embeds/class-amp-vine-embed-handler.php | 36 ++++++++++++++++--- tests/php/test-amp-vine-embed-handler.php | 16 ++++++--- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/includes/embeds/class-amp-vine-embed-handler.php b/includes/embeds/class-amp-vine-embed-handler.php index 1848c58634f..7f43bbbea0b 100644 --- a/includes/embeds/class-amp-vine-embed-handler.php +++ b/includes/embeds/class-amp-vine-embed-handler.php @@ -5,6 +5,8 @@ * @package AMP */ +use AmpProject\Dom\Document; + /** * Class AMP_Vine_Embed_Handler */ @@ -25,18 +27,25 @@ class AMP_Vine_Embed_Handler extends AMP_Base_Embed_Handler { */ protected $DEFAULT_HEIGHT = 400; + /** + * Default AMP tag to be used when sanitizing embeds. + * + * @var string + */ + protected $amp_tag = 'amp-vine'; + /** * Registers embed. */ public function register_embed() { - wp_embed_register_handler( 'amp-vine', self::URL_PATTERN, [ $this, 'oembed' ], -1 ); + wp_embed_register_handler( $this->amp_tag, self::URL_PATTERN, [ $this, 'oembed' ], -1 ); } /** * Unregisters embed. */ public function unregister_embed() { - wp_embed_unregister_handler( 'amp-vine', -1 ); + wp_embed_unregister_handler( $this->amp_tag, -1 ); } /** @@ -82,10 +91,8 @@ public function render( $args ) { ); } - $this->did_convert_elements = true; - return AMP_HTML_Utils::build_tag( - 'amp-vine', + $this->amp_tag, [ 'data-vineid' => $args['vine_id'], 'layout' => 'responsive', @@ -94,4 +101,23 @@ public function render( $args ) { ] ); } + + /** + * Get all raw embeds from the DOM. + * + * @param Document $dom Document. + * @return DOMNodeList A list of DOMElement nodes. + */ + protected function get_raw_embed_nodes( Document $dom ) { + return $dom->xpath->query( sprintf( '//%s', $this->amp_tag ) ); + } + + /** + * Make embed AMP compatible. + * + * @param DOMElement $node DOM element. + */ + protected function sanitize_raw_embed( DOMElement $node ) { + $this->unwrap_p_element( $node ); + } } diff --git a/tests/php/test-amp-vine-embed-handler.php b/tests/php/test-amp-vine-embed-handler.php index 68365990e11..3b140f1a017 100644 --- a/tests/php/test-amp-vine-embed-handler.php +++ b/tests/php/test-amp-vine-embed-handler.php @@ -10,7 +10,7 @@ public function get_conversion_data() { ], 'simple_url' => [ 'https://vine.co/v/MdKjXez002d' . PHP_EOL, - '

' . PHP_EOL, + '' . PHP_EOL, ], ]; } @@ -21,9 +21,14 @@ public function get_conversion_data() { public function test__conversion( $source, $expected ) { $embed = new AMP_Vine_Embed_Handler(); $embed->register_embed(); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $content = AMP_DOM_Utils::get_content_from_dom( $dom ); - $this->assertEquals( $expected, $filtered_content ); + $this->assertEquals( $expected, $content ); } public function get_scripts_data() { @@ -45,9 +50,12 @@ public function get_scripts_data() { public function test__get_scripts( $source, $expected ) { $embed = new AMP_Vine_Embed_Handler(); $embed->register_embed(); - $source = apply_filters( 'the_content', $source ); - $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( AMP_DOM_Utils::get_dom_from_content( $source ) ); + $filtered_content = apply_filters( 'the_content', $source ); + $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); + $embed->sanitize_raw_embeds( $dom ); + + $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); $whitelist_sanitizer->sanitize(); $scripts = array_merge( From 7c03ced475170a193f516e4c873ba3398c9f2a81 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Sun, 21 Jun 2020 19:06:06 -0400 Subject: [PATCH 36/45] Add `Registerable` interface to indicate embed handlers that hook into WordPress --- includes/class-amp-theme-support.php | 5 ++-- .../embeds/class-amp-base-embed-handler.php | 14 +++++---- .../embeds/class-amp-core-block-handler.php | 3 +- .../class-amp-gallery-embed-handler.php | 11 +++---- .../class-amp-playlist-embed-handler.php | 4 ++- includes/templates/class-amp-content.php | 8 ++--- src/Embed/Registerable.php | 29 +++++++++++++++++++ 7 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 src/Embed/Registerable.php diff --git a/includes/class-amp-theme-support.php b/includes/class-amp-theme-support.php index 5e41b559e20..75381ba3d67 100644 --- a/includes/class-amp-theme-support.php +++ b/includes/class-amp-theme-support.php @@ -6,6 +6,7 @@ */ use AmpProject\Amp; +use AmpProject\AmpWP\Embed\Registerable; use AmpProject\AmpWP\Option; use AmpProject\AmpWP\RemoteRequest\CachedRemoteGetRequest; use AmpProject\AmpWP\ConfigurationArgument; @@ -1179,9 +1180,7 @@ public static function register_content_embed_handlers() { ); continue; } - - // @todo Conditional below can be removed once all embed handlers can sanitize raw embeds. - if ( method_exists( $embed_handler, 'register_embed' ) ) { + if ( $embed_handler instanceof Registerable ) { $embed_handler->register_embed(); } $embed_handlers[] = $embed_handler; diff --git a/includes/embeds/class-amp-base-embed-handler.php b/includes/embeds/class-amp-base-embed-handler.php index 46e729c9b72..697ab13d9ef 100644 --- a/includes/embeds/class-amp-base-embed-handler.php +++ b/includes/embeds/class-amp-base-embed-handler.php @@ -78,6 +78,11 @@ public function __construct( $args = [] ) { public function sanitize_raw_embeds( Document $dom ) { $nodes = $this->get_raw_embed_nodes( $dom ); + if ( null === $nodes ) { + // Bail since embed handler does not sanitize embeds. + return; + } + if ( 0 === $nodes->length ) { return; } @@ -92,13 +97,12 @@ public function sanitize_raw_embeds( Document $dom ) { /** * Get all raw embeds from the DOM. - * // @todo This method can be made abstract once all embed handlers can sanitize raw embeds. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, otherwise null if method is not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - return new DOMNodeList(); + return null; } /** @@ -113,12 +117,12 @@ protected function is_raw_embed( DOMElement $node ) { /** * Make embed AMP compatible. - * // @todo Make this method abstract once all embed handlers have `sanitize_raw_embeds` implemented. * * @param DOMElement $node DOM element. + * @return null If method is not implemented. */ protected function sanitize_raw_embed( DOMElement $node ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - // To be overridden. + return null; } /** diff --git a/includes/embeds/class-amp-core-block-handler.php b/includes/embeds/class-amp-core-block-handler.php index 94de522b13a..5be3b743e5a 100644 --- a/includes/embeds/class-amp-core-block-handler.php +++ b/includes/embeds/class-amp-core-block-handler.php @@ -5,6 +5,7 @@ * @package AMP */ +use AmpProject\AmpWP\Embed\Registerable; use AmpProject\Attribute; use AmpProject\Dom\Document; @@ -13,7 +14,7 @@ * * @since 1.0 */ -class AMP_Core_Block_Handler extends AMP_Base_Embed_Handler { +class AMP_Core_Block_Handler extends AMP_Base_Embed_Handler implements Registerable { /** * Attribute to store the original width on a video or iframe just before WordPress removes it. diff --git a/includes/embeds/class-amp-gallery-embed-handler.php b/includes/embeds/class-amp-gallery-embed-handler.php index 875ad3e793a..a11c93dd9ab 100644 --- a/includes/embeds/class-amp-gallery-embed-handler.php +++ b/includes/embeds/class-amp-gallery-embed-handler.php @@ -5,6 +5,7 @@ * @package AMP */ +use AmpProject\AmpWP\Embed\Registerable; use AmpProject\Dom\Document; use AmpProject\AmpWP\Dom\ElementList; use AmpProject\AmpWP\Component\Carousel; @@ -14,7 +15,7 @@ * * @since 0.2 */ -class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler { +class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler implements Registerable { /** * Register embed. @@ -220,7 +221,7 @@ public function render( $args ) { $images = new ElementList(); foreach ( $args['images'] as $props ) { - $image_atts = [ + $image_attrs = [ 'src' => $props['url'], 'width' => $props['width'], 'height' => $props['height'], @@ -228,16 +229,16 @@ public function render( $args ) { 'alt' => $props['alt'], ]; if ( ! empty( $props['srcset'] ) ) { - $image_atts['srcset'] = $props['srcset']; + $image_attrs['srcset'] = $props['srcset']; } if ( ! empty( $args['lightbox'] ) ) { - $image_atts['lightbox'] = ''; + $image_attrs['lightbox'] = ''; } $image = AMP_DOM_Utils::create_node( $dom, 'img', - $image_atts + $image_attrs ); if ( ! empty( $props['href'] ) ) { diff --git a/includes/embeds/class-amp-playlist-embed-handler.php b/includes/embeds/class-amp-playlist-embed-handler.php index 271f5ab8656..f1e0c5a5113 100644 --- a/includes/embeds/class-amp-playlist-embed-handler.php +++ b/includes/embeds/class-amp-playlist-embed-handler.php @@ -6,6 +6,8 @@ * @since 0.7 */ +use AmpProject\AmpWP\Embed\Registerable; + /** * Class AMP_Playlist_Embed_Handler * @@ -13,7 +15,7 @@ * * @package AMP */ -class AMP_Playlist_Embed_Handler extends AMP_Base_Embed_Handler { +class AMP_Playlist_Embed_Handler extends AMP_Base_Embed_Handler implements Registerable { /** * The tag of the shortcode. diff --git a/includes/templates/class-amp-content.php b/includes/templates/class-amp-content.php index efa06bba235..1174abeefeb 100644 --- a/includes/templates/class-amp-content.php +++ b/includes/templates/class-amp-content.php @@ -5,6 +5,8 @@ * @package AMP */ +use AmpProject\AmpWP\Embed\Registerable; + /** * Class AMP_Content * @@ -184,8 +186,7 @@ private function register_embed_handlers( $embed_handler_classes ) { continue; } - // @todo Conditional below can be removed once all embed handlers can sanitize raw embeds. - if ( method_exists( $embed_handler, 'register_embed' ) ) { + if ( $embed_handler instanceof Registerable ) { $embed_handler->register_embed(); } $embed_handlers[] = $embed_handler; @@ -201,8 +202,7 @@ private function register_embed_handlers( $embed_handler_classes ) { */ private function unregister_embed_handlers( $embed_handlers ) { foreach ( $embed_handlers as $embed_handler ) { - // @todo Conditional below can be removed once all embed handlers can sanitize raw embeds. - if ( method_exists( $embed_handler, 'unregister_embed' ) ) { + if ( $embed_handler instanceof Registerable ) { $embed_handler->unregister_embed(); } } diff --git a/src/Embed/Registerable.php b/src/Embed/Registerable.php new file mode 100644 index 00000000000..d20d842cd43 --- /dev/null +++ b/src/Embed/Registerable.php @@ -0,0 +1,29 @@ + Date: Sun, 21 Jun 2020 19:39:55 -0400 Subject: [PATCH 37/45] Fix lint and static analysis errors --- .../embeds/class-amp-base-embed-handler.php | 25 ++++++++----------- .../embeds/class-amp-core-block-handler.php | 18 +++++++++++++ .../class-amp-crowdsignal-embed-handler.php | 2 +- .../class-amp-dailymotion-embed-handler.php | 2 +- .../class-amp-facebook-embed-handler.php | 2 +- .../class-amp-gallery-embed-handler.php | 18 +++++++++++++ .../embeds/class-amp-gfycat-embed-handler.php | 2 +- .../embeds/class-amp-hulu-embed-handler.php | 2 +- .../embeds/class-amp-imgur-embed-handler.php | 2 +- .../class-amp-instagram-embed-handler.php | 2 +- .../embeds/class-amp-issuu-embed-handler.php | 2 +- .../embeds/class-amp-meetup-embed-handler.php | 2 +- .../class-amp-pinterest-embed-handler.php | 2 +- .../class-amp-playlist-embed-handler.php | 19 ++++++++++++++ .../embeds/class-amp-reddit-embed-handler.php | 2 +- .../embeds/class-amp-scribd-embed-handler.php | 2 +- .../class-amp-soundcloud-embed-handler.php | 2 +- .../embeds/class-amp-tiktok-embed-handler.php | 2 +- .../embeds/class-amp-tumblr-embed-handler.php | 2 +- .../class-amp-twitter-embed-handler.php | 11 +++++++- .../embeds/class-amp-vimeo-embed-handler.php | 2 +- .../embeds/class-amp-vine-embed-handler.php | 2 +- .../class-amp-wordpress-tv-embed-handler.php | 2 +- .../class-amp-youtube-embed-handler.php | 2 +- 24 files changed, 94 insertions(+), 35 deletions(-) diff --git a/includes/embeds/class-amp-base-embed-handler.php b/includes/embeds/class-amp-base-embed-handler.php index 697ab13d9ef..1c5dc6d0deb 100644 --- a/includes/embeds/class-amp-base-embed-handler.php +++ b/includes/embeds/class-amp-base-embed-handler.php @@ -79,7 +79,7 @@ public function sanitize_raw_embeds( Document $dom ) { $nodes = $this->get_raw_embed_nodes( $dom ); if ( null === $nodes ) { - // Bail since embed handler does not sanitize embeds. + // Bail if the embed handler returns null. return; } @@ -95,16 +95,6 @@ public function sanitize_raw_embeds( Document $dom ) { } } - /** - * Get all raw embeds from the DOM. - * - * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, otherwise null if method is not implemented. - */ - protected function get_raw_embed_nodes( Document $dom ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - return null; - } - /** * Determine if the node is indeed a raw embed. * @@ -115,15 +105,20 @@ protected function is_raw_embed( DOMElement $node ) { return $node->parentNode && $this->amp_tag !== $node->parentNode->nodeName; } + /** + * Get all raw embeds from the DOM. + * + * @param Document $dom Document. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + */ + abstract protected function get_raw_embed_nodes( Document $dom ); + /** * Make embed AMP compatible. * * @param DOMElement $node DOM element. - * @return null If method is not implemented. */ - protected function sanitize_raw_embed( DOMElement $node ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - return null; - } + abstract protected function sanitize_raw_embed( DOMElement $node ); /** * Get mapping of AMP component names to AMP script URLs. diff --git a/includes/embeds/class-amp-core-block-handler.php b/includes/embeds/class-amp-core-block-handler.php index 5be3b743e5a..161562416d4 100644 --- a/includes/embeds/class-amp-core-block-handler.php +++ b/includes/embeds/class-amp-core-block-handler.php @@ -356,4 +356,22 @@ private function process_text_widgets( Document $dom ) { } } } + + /** + * Get all raw embeds from the DOM. + * + * @param Document $dom Document. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + */ + protected function get_raw_embed_nodes( Document $dom ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + return null; + } + + /** + * Make embed AMP compatible. + * + * @param DOMElement $node DOM element. + */ + protected function sanitize_raw_embed( DOMElement $node ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + } } diff --git a/includes/embeds/class-amp-crowdsignal-embed-handler.php b/includes/embeds/class-amp-crowdsignal-embed-handler.php index a2e606645e8..3d9f1e74f68 100644 --- a/includes/embeds/class-amp-crowdsignal-embed-handler.php +++ b/includes/embeds/class-amp-crowdsignal-embed-handler.php @@ -19,7 +19,7 @@ class AMP_Crowdsignal_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { $queries = [ diff --git a/includes/embeds/class-amp-dailymotion-embed-handler.php b/includes/embeds/class-amp-dailymotion-embed-handler.php index 9b9204534b5..fe0489453b2 100644 --- a/includes/embeds/class-amp-dailymotion-embed-handler.php +++ b/includes/embeds/class-amp-dailymotion-embed-handler.php @@ -68,7 +68,7 @@ public function __construct( $args = [] ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-facebook-embed-handler.php b/includes/embeds/class-amp-facebook-embed-handler.php index 6de59892360..671fd733c91 100644 --- a/includes/embeds/class-amp-facebook-embed-handler.php +++ b/includes/embeds/class-amp-facebook-embed-handler.php @@ -49,7 +49,7 @@ public function sanitize_raw_embeds( Document $dom ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->getElementsByTagName( 'div' ); diff --git a/includes/embeds/class-amp-gallery-embed-handler.php b/includes/embeds/class-amp-gallery-embed-handler.php index a11c93dd9ab..fe097637af0 100644 --- a/includes/embeds/class-amp-gallery-embed-handler.php +++ b/includes/embeds/class-amp-gallery-embed-handler.php @@ -286,4 +286,22 @@ public function print_styles() { xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-hulu-embed-handler.php b/includes/embeds/class-amp-hulu-embed-handler.php index 3e1a1dd5559..d0b907998a4 100644 --- a/includes/embeds/class-amp-hulu-embed-handler.php +++ b/includes/embeds/class-amp-hulu-embed-handler.php @@ -38,7 +38,7 @@ class AMP_Hulu_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ contains( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-imgur-embed-handler.php b/includes/embeds/class-amp-imgur-embed-handler.php index e19d3f25866..b34002cd519 100644 --- a/includes/embeds/class-amp-imgur-embed-handler.php +++ b/includes/embeds/class-amp-imgur-embed-handler.php @@ -38,7 +38,7 @@ class AMP_Imgur_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//blockquote[ @class = "imgur-embed-pub" ]' ); diff --git a/includes/embeds/class-amp-instagram-embed-handler.php b/includes/embeds/class-amp-instagram-embed-handler.php index 4713d9c7c47..49aa23b8069 100644 --- a/includes/embeds/class-amp-instagram-embed-handler.php +++ b/includes/embeds/class-amp-instagram-embed-handler.php @@ -41,7 +41,7 @@ class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//blockquote[ @data-instgrm-permalink ]' ); diff --git a/includes/embeds/class-amp-issuu-embed-handler.php b/includes/embeds/class-amp-issuu-embed-handler.php index 03312522bc8..e6fa9d4897f 100644 --- a/includes/embeds/class-amp-issuu-embed-handler.php +++ b/includes/embeds/class-amp-issuu-embed-handler.php @@ -17,7 +17,7 @@ class AMP_Issuu_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//div[ @class="issuuembed" and @data-url ]' ); diff --git a/includes/embeds/class-amp-meetup-embed-handler.php b/includes/embeds/class-amp-meetup-embed-handler.php index ed3712bec35..ab260075728 100644 --- a/includes/embeds/class-amp-meetup-embed-handler.php +++ b/includes/embeds/class-amp-meetup-embed-handler.php @@ -30,7 +30,7 @@ protected function is_raw_embed( DOMElement $node ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//div[ @id="meetup_oembed" ]//div[ @class="photo" ]/img' ); diff --git a/includes/embeds/class-amp-pinterest-embed-handler.php b/includes/embeds/class-amp-pinterest-embed-handler.php index 6732f796cec..7f55a6bcb06 100644 --- a/includes/embeds/class-amp-pinterest-embed-handler.php +++ b/includes/embeds/class-amp-pinterest-embed-handler.php @@ -99,7 +99,7 @@ public function render( $args ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//%s', $this->amp_tag ) ); diff --git a/includes/embeds/class-amp-playlist-embed-handler.php b/includes/embeds/class-amp-playlist-embed-handler.php index f1e0c5a5113..1bc6e7704ff 100644 --- a/includes/embeds/class-amp-playlist-embed-handler.php +++ b/includes/embeds/class-amp-playlist-embed-handler.php @@ -7,6 +7,7 @@ */ use AmpProject\AmpWP\Embed\Registerable; +use AmpProject\Dom\Document; /** * Class AMP_Playlist_Embed_Handler @@ -332,4 +333,22 @@ public function get_title( $track ) { return ''; } + + /** + * Get all raw embeds from the DOM. + * + * @param Document $dom Document. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + */ + protected function get_raw_embed_nodes( Document $dom ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + return null; + } + + /** + * Make embed AMP compatible. + * + * @param DOMElement $node DOM element. + */ + protected function sanitize_raw_embed( DOMElement $node ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + } } diff --git a/includes/embeds/class-amp-reddit-embed-handler.php b/includes/embeds/class-amp-reddit-embed-handler.php index b4e8f9212a0..531541c097b 100644 --- a/includes/embeds/class-amp-reddit-embed-handler.php +++ b/includes/embeds/class-amp-reddit-embed-handler.php @@ -24,7 +24,7 @@ class AMP_Reddit_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { /* diff --git a/includes/embeds/class-amp-scribd-embed-handler.php b/includes/embeds/class-amp-scribd-embed-handler.php index 4849cb5db46..c4beea0eb16 100644 --- a/includes/embeds/class-amp-scribd-embed-handler.php +++ b/includes/embeds/class-amp-scribd-embed-handler.php @@ -24,7 +24,7 @@ class AMP_Scribd_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-soundcloud-embed-handler.php b/includes/embeds/class-amp-soundcloud-embed-handler.php index 54685998df5..b4da8a47151 100644 --- a/includes/embeds/class-amp-soundcloud-embed-handler.php +++ b/includes/embeds/class-amp-soundcloud-embed-handler.php @@ -39,7 +39,7 @@ class AMP_SoundCloud_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-tiktok-embed-handler.php b/includes/embeds/class-amp-tiktok-embed-handler.php index 1cbb1bfadbd..d37790946f8 100644 --- a/includes/embeds/class-amp-tiktok-embed-handler.php +++ b/includes/embeds/class-amp-tiktok-embed-handler.php @@ -23,7 +23,7 @@ class AMP_TikTok_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//blockquote[ contains( @class, "tiktok-embed" ) ]' ); diff --git a/includes/embeds/class-amp-tumblr-embed-handler.php b/includes/embeds/class-amp-tumblr-embed-handler.php index 914287d5e6f..01751dcd89e 100644 --- a/includes/embeds/class-amp-tumblr-embed-handler.php +++ b/includes/embeds/class-amp-tumblr-embed-handler.php @@ -34,7 +34,7 @@ class AMP_Tumblr_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//div[ @class = "tumblr-post" and starts-with( @data-href, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-twitter-embed-handler.php b/includes/embeds/class-amp-twitter-embed-handler.php index 37bfe5e7540..8f2f95dc7af 100644 --- a/includes/embeds/class-amp-twitter-embed-handler.php +++ b/includes/embeds/class-amp-twitter-embed-handler.php @@ -86,13 +86,22 @@ private function sanitize_moment_embeds( Document $dom ) { $this->sanitize_raw_embeds_with_type( 'moment', $nodes ); } + /** + * Get all raw embeds from the DOM. + * + * @param Document $dom Document. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + */ + protected function get_raw_embed_nodes( Document $dom ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable + return null; + } + /** * Make embed AMP compatible. * * @param DOMElement $node DOM element. */ protected function sanitize_raw_embed( DOMElement $node ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable - // Not implemented. } /** diff --git a/includes/embeds/class-amp-vimeo-embed-handler.php b/includes/embeds/class-amp-vimeo-embed-handler.php index a37726c723f..22c4958be4e 100644 --- a/includes/embeds/class-amp-vimeo-embed-handler.php +++ b/includes/embeds/class-amp-vimeo-embed-handler.php @@ -68,7 +68,7 @@ public function __construct( $args = [] ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-vine-embed-handler.php b/includes/embeds/class-amp-vine-embed-handler.php index 7f43bbbea0b..bb19f90c57b 100644 --- a/includes/embeds/class-amp-vine-embed-handler.php +++ b/includes/embeds/class-amp-vine-embed-handler.php @@ -106,7 +106,7 @@ public function render( $args ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//%s', $this->amp_tag ) ); diff --git a/includes/embeds/class-amp-wordpress-tv-embed-handler.php b/includes/embeds/class-amp-wordpress-tv-embed-handler.php index de34896c473..f1fe7e75059 100644 --- a/includes/embeds/class-amp-wordpress-tv-embed-handler.php +++ b/includes/embeds/class-amp-wordpress-tv-embed-handler.php @@ -26,7 +26,7 @@ class AMP_WordPress_TV_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-youtube-embed-handler.php b/includes/embeds/class-amp-youtube-embed-handler.php index 7a757593927..472ca534892 100644 --- a/includes/embeds/class-amp-youtube-embed-handler.php +++ b/includes/embeds/class-amp-youtube-embed-handler.php @@ -69,7 +69,7 @@ public function __construct( $args = [] ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList A list of DOMElement nodes. + * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. */ protected function get_raw_embed_nodes( Document $dom ) { $query_segments = array_map( From beadf512b26f239519f76bf5b8a13be24439110f Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Sun, 21 Jun 2020 19:48:33 -0400 Subject: [PATCH 38/45] Rename `whitelist_sanitizer` to `validating_sanitizer` --- tests/php/test-amp-reddit-embed-handler.php | 6 +++--- tests/php/test-amp-tumblr-embed-handler.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/php/test-amp-reddit-embed-handler.php b/tests/php/test-amp-reddit-embed-handler.php index 6711599d44b..20796114a23 100644 --- a/tests/php/test-amp-reddit-embed-handler.php +++ b/tests/php/test-amp-reddit-embed-handler.php @@ -111,12 +111,12 @@ public function test__get_scripts( $source, $expected ) { $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); $embed->sanitize_raw_embeds( $dom ); - $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); - $whitelist_sanitizer->sanitize(); + $validating_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); + $validating_sanitizer->sanitize(); $scripts = array_merge( $embed->get_scripts(), - $whitelist_sanitizer->get_scripts() + $validating_sanitizer->get_scripts() ); $this->assertEquals( $expected, $scripts ); diff --git a/tests/php/test-amp-tumblr-embed-handler.php b/tests/php/test-amp-tumblr-embed-handler.php index 1d433fe182e..10e7050e73e 100644 --- a/tests/php/test-amp-tumblr-embed-handler.php +++ b/tests/php/test-amp-tumblr-embed-handler.php @@ -100,12 +100,12 @@ public function test__get_scripts( $source, $expected ) { $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); $embed->sanitize_raw_embeds( $dom ); - $whitelist_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); - $whitelist_sanitizer->sanitize(); + $validating_sanitizer = new AMP_Tag_And_Attribute_Sanitizer( $dom ); + $validating_sanitizer->sanitize(); $scripts = array_merge( $embed->get_scripts(), - $whitelist_sanitizer->get_scripts() + $validating_sanitizer->get_scripts() ); $this->assertEquals( $expected, $scripts ); From b0157a1860b670d733ad0f0ba56bb5dd83bb3a8a Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Wed, 24 Jun 2020 21:38:57 -0400 Subject: [PATCH 39/45] Mark Pinterest and Vine embed handlers as registerable --- includes/embeds/class-amp-pinterest-embed-handler.php | 3 ++- includes/embeds/class-amp-vine-embed-handler.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/includes/embeds/class-amp-pinterest-embed-handler.php b/includes/embeds/class-amp-pinterest-embed-handler.php index 7f55a6bcb06..6435a5255e1 100644 --- a/includes/embeds/class-amp-pinterest-embed-handler.php +++ b/includes/embeds/class-amp-pinterest-embed-handler.php @@ -5,12 +5,13 @@ * @package AMP */ +use AmpProject\AmpWP\Embed\Registerable; use AmpProject\Dom\Document; /** * Class AMP_Pinterest_Embed_Handler */ -class AMP_Pinterest_Embed_Handler extends AMP_Base_Embed_Handler { +class AMP_Pinterest_Embed_Handler extends AMP_Base_Embed_Handler implements Registerable { const URL_PATTERN = '#https?://(www\.)?pinterest\.com/pin/.*#i'; diff --git a/includes/embeds/class-amp-vine-embed-handler.php b/includes/embeds/class-amp-vine-embed-handler.php index bb19f90c57b..1a8ef23d390 100644 --- a/includes/embeds/class-amp-vine-embed-handler.php +++ b/includes/embeds/class-amp-vine-embed-handler.php @@ -5,12 +5,13 @@ * @package AMP */ +use AmpProject\AmpWP\Embed\Registerable; use AmpProject\Dom\Document; /** * Class AMP_Vine_Embed_Handler */ -class AMP_Vine_Embed_Handler extends AMP_Base_Embed_Handler { +class AMP_Vine_Embed_Handler extends AMP_Base_Embed_Handler implements Registerable { const URL_PATTERN = '#https?://vine\.co/v/([^/?]+)#i'; /** From b3a2c1c10f6595b60f2801a506dc426ab06b4837 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Thu, 25 Jun 2020 00:16:35 -0400 Subject: [PATCH 40/45] Add oEmbed provider URLs for embeds not supported in WP 5.1 --- .../class-amp-crowdsignal-embed-handler.php | 34 ++++++++++++++++++- .../class-amp-instagram-embed-handler.php | 27 ++++++++++++++- .../test-amp-crowdsignal-embed-handler.php | 16 ++++----- .../php/test-amp-instagram-embed-handler.php | 2 ++ 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/includes/embeds/class-amp-crowdsignal-embed-handler.php b/includes/embeds/class-amp-crowdsignal-embed-handler.php index 3d9f1e74f68..6f020d9250b 100644 --- a/includes/embeds/class-amp-crowdsignal-embed-handler.php +++ b/includes/embeds/class-amp-crowdsignal-embed-handler.php @@ -8,12 +8,44 @@ * @since 1.2 */ +use AmpProject\AmpWP\Embed\Registerable; use AmpProject\Dom\Document; /** * Class AMP_Crowdsignal_Embed_Handler */ -class AMP_Crowdsignal_Embed_Handler extends AMP_Base_Embed_Handler { +class AMP_Crowdsignal_Embed_Handler extends AMP_Base_Embed_Handler implements Registerable { + + /** + * Register the embed. + * + * @return void + */ + public function register_embed() { + if ( version_compare( get_bloginfo( 'version' ), '5.1', '>=' ) ) { + return; + } + + // The oEmbed providers for CrowdSignal embeds are outdated on WP < 5.1. Updating the providers here will + // allow for the oEmbed HTML to be fetched, and can then sanitized later below. + $formats = [ + '#https?://(.+\.)?polldaddy\.com/.*#i', + '#https?://poll\.fm/.*#i', + '#https?://(.+\.)?survey\.fm/.*#i', + ]; + + foreach ( $formats as $format ) { + wp_oembed_add_provider( $format, 'https://api.crowdsignal.com/oembed', true ); + } + } + + /** + * Unregister the embed. + * + * @return void + */ + public function unregister_embed() { + } /** * Get all raw embeds from the DOM. diff --git a/includes/embeds/class-amp-instagram-embed-handler.php b/includes/embeds/class-amp-instagram-embed-handler.php index 49aa23b8069..65d458726e9 100644 --- a/includes/embeds/class-amp-instagram-embed-handler.php +++ b/includes/embeds/class-amp-instagram-embed-handler.php @@ -5,6 +5,7 @@ * @package AMP */ +use AmpProject\AmpWP\Embed\Registerable; use AmpProject\Dom\Document; /** @@ -12,7 +13,7 @@ * * Much of this class is borrowed from Jetpack embeds */ -class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler { +class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler implements Registerable { const URL_PATTERN = '#https?:\/\/(www\.)?instagr(\.am|am\.com)\/(p|tv)\/([A-Za-z0-9-_]+)#i'; @@ -37,6 +38,30 @@ class AMP_Instagram_Embed_Handler extends AMP_Base_Embed_Handler { */ protected $amp_tag = 'amp-instagram'; + /** + * Register the embed. + * + * @return void + */ + public function register_embed() { + if ( version_compare( get_bloginfo( 'version' ), '5.1', '>=' ) ) { + return; + } + + // The oEmbed provider for Instagram does not accommodate Instagram TV URLs on WP < 5.1. Modifying the provider format + // here will allow for the oEmbed HTML to be fetched, and can then sanitized later below. + wp_oembed_remove_provider( '#https?://(www\.)?instagr(\.am|am\.com)/p/.*#i' ); + wp_oembed_add_provider( self::URL_PATTERN, 'https://api.instagram.com/oembed', true ); + } + + /** + * Unregister the embed. + * + * @return void + */ + public function unregister_embed() { + } + /** * Get all raw embeds from the DOM. * diff --git a/tests/php/test-amp-crowdsignal-embed-handler.php b/tests/php/test-amp-crowdsignal-embed-handler.php index c929366e364..1835252f963 100644 --- a/tests/php/test-amp-crowdsignal-embed-handler.php +++ b/tests/php/test-amp-crowdsignal-embed-handler.php @@ -55,19 +55,13 @@ public function get_conversion_data() { '' . PHP_EOL . PHP_EOL, $survey_response, ], - ]; - /* - * There is a bug with WordPress's oEmbed handling for Crowdsignal surveys. - * See . - */ - if ( version_compare( get_bloginfo( 'version' ), '5.2.0', '>=' ) ) { - $data['survey.fm'] = [ + 'survey.fm' => [ 'https://rydk.survey.fm/test-survey', '' . PHP_EOL . PHP_EOL, $survey_response, - ]; - } + ], + ]; return $data; } @@ -106,12 +100,14 @@ static function ( $pre, $r, $request_url ) use ( $oembed_response ) { ); $embed = new AMP_Crowdsignal_Embed_Handler(); + $embed->register_embed(); $filtered_content = apply_filters( 'the_content', $url ); $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); $embed->sanitize_raw_embeds( $dom ); - $content = AMP_DOM_Utils::get_content_from_dom( $dom ); + $content = AMP_DOM_Utils::get_content_from_dom( $dom ); + $expected = $this->adapt_iframe_title( $expected ); $this->assertEquals( $expected, $content ); } diff --git a/tests/php/test-amp-instagram-embed-handler.php b/tests/php/test-amp-instagram-embed-handler.php index ced41235003..29c76e38b50 100644 --- a/tests/php/test-amp-instagram-embed-handler.php +++ b/tests/php/test-amp-instagram-embed-handler.php @@ -102,6 +102,7 @@ public function get_conversion_data() { */ public function test__conversion( $source, $expected ) { $embed = new AMP_Instagram_Embed_Handler(); + $embed->register_embed(); $filtered_content = apply_filters( 'the_content', $source ); $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); @@ -139,6 +140,7 @@ public function get_scripts_data() { */ public function test__get_scripts( $source, $expected ) { $embed = new AMP_Instagram_Embed_Handler(); + $embed->register_embed(); $filtered_content = apply_filters( 'the_content', $source ); $dom = AMP_DOM_Utils::get_dom_from_content( $filtered_content ); From dfaf3e5df71b8cfec72802146a3373df90bd7d9c Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Thu, 25 Jun 2020 00:17:10 -0400 Subject: [PATCH 41/45] Fix YouTube embed test --- includes/embeds/class-amp-youtube-embed-handler.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/includes/embeds/class-amp-youtube-embed-handler.php b/includes/embeds/class-amp-youtube-embed-handler.php index 472ca534892..e8da507141c 100644 --- a/includes/embeds/class-amp-youtube-embed-handler.php +++ b/includes/embeds/class-amp-youtube-embed-handler.php @@ -96,7 +96,6 @@ protected function sanitize_raw_embed( DOMElement $node ) { 'layout' => 'responsive', 'width' => $this->args['width'], 'height' => $this->args['height'], - 'title' => null, ]; if ( ! empty( $node->getAttribute( 'title' ) ) ) { @@ -117,7 +116,7 @@ protected function sanitize_raw_embed( DOMElement $node ) { $attributes ); - $this->append_placeholder( $amp_node, $video_id, $attributes['title'] ); + $this->append_placeholder( $amp_node, $video_id, isset( $attributes['title'] ) ? $attributes['title'] : null ); $this->unwrap_p_element( $node ); From a857f255ca9a51e22c151b08dcb83aba2dfb2252 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Thu, 25 Jun 2020 00:31:35 -0400 Subject: [PATCH 42/45] Remove unused vars --- tests/php/test-class-amp-imgur-embed-handler.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/php/test-class-amp-imgur-embed-handler.php b/tests/php/test-class-amp-imgur-embed-handler.php index 248fe85ce41..dfc149ffd19 100644 --- a/tests/php/test-class-amp-imgur-embed-handler.php +++ b/tests/php/test-class-amp-imgur-embed-handler.php @@ -57,9 +57,6 @@ static function( $pre, $r, $url ) { * @return array */ public function get_conversion_data() { - $width = 500; - $height = 750; - return [ 'no_embed' => [ '

Hello world.

', From 434660ad5b868fb66787c5b2e45394de9faf2ea8 Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Thu, 25 Jun 2020 00:58:07 -0400 Subject: [PATCH 43/45] Fix tests failures related to Gutenberg --- tests/php/test-amp-issuu-embed-handler.php | 8 +++++++- tests/php/test-amp-reddit-embed-handler.php | 8 +++++++- tests/php/test-amp-tumblr-embed-handler.php | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/php/test-amp-issuu-embed-handler.php b/tests/php/test-amp-issuu-embed-handler.php index ab640254d66..6a72b7fda94 100644 --- a/tests/php/test-amp-issuu-embed-handler.php +++ b/tests/php/test-amp-issuu-embed-handler.php @@ -1,12 +1,18 @@ prevent_block_pre_render(); // Mock the HTTP request. add_filter( 'pre_http_request', [ $this, 'mock_http_request' ], 10, 3 ); diff --git a/tests/php/test-amp-reddit-embed-handler.php b/tests/php/test-amp-reddit-embed-handler.php index 20796114a23..b28d0664afb 100644 --- a/tests/php/test-amp-reddit-embed-handler.php +++ b/tests/php/test-amp-reddit-embed-handler.php @@ -1,12 +1,18 @@ prevent_block_pre_render(); // Mock the HTTP request. add_filter( 'pre_http_request', [ $this, 'mock_http_request' ], 10, 3 ); diff --git a/tests/php/test-amp-tumblr-embed-handler.php b/tests/php/test-amp-tumblr-embed-handler.php index 10e7050e73e..83c8e24750f 100644 --- a/tests/php/test-amp-tumblr-embed-handler.php +++ b/tests/php/test-amp-tumblr-embed-handler.php @@ -1,12 +1,18 @@ prevent_block_pre_render(); // Mock the HTTP request. add_filter( 'pre_http_request', [ $this, 'mock_http_request' ], 10, 3 ); From 986c036a8114b9c050806f2b742709d21f97bedd Mon Sep 17 00:00:00 2001 From: Pierre Gordon Date: Thu, 25 Jun 2020 01:44:44 -0400 Subject: [PATCH 44/45] Add oEmbed provider URL for Crowdsignal surveys on WP 5.2. --- includes/embeds/class-amp-crowdsignal-embed-handler.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/embeds/class-amp-crowdsignal-embed-handler.php b/includes/embeds/class-amp-crowdsignal-embed-handler.php index 6f020d9250b..b5bd516430d 100644 --- a/includes/embeds/class-amp-crowdsignal-embed-handler.php +++ b/includes/embeds/class-amp-crowdsignal-embed-handler.php @@ -22,7 +22,7 @@ class AMP_Crowdsignal_Embed_Handler extends AMP_Base_Embed_Handler implements Re * @return void */ public function register_embed() { - if ( version_compare( get_bloginfo( 'version' ), '5.1', '>=' ) ) { + if ( version_compare( get_bloginfo( 'version' ), '5.2', '>=' ) ) { return; } @@ -31,7 +31,7 @@ public function register_embed() { $formats = [ '#https?://(.+\.)?polldaddy\.com/.*#i', '#https?://poll\.fm/.*#i', - '#https?://(.+\.)?survey\.fm/.*#i', + '#https?://(.+\.)?survey\.fm/.*#i', // Not available on WP 5.2. ]; foreach ( $formats as $format ) { From 0860f489b9e59357abb1c2941d13030b194b12be Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Thu, 25 Jun 2020 16:54:34 -0700 Subject: [PATCH 45/45] Update phpdoc to reflect where methods do not return null --- includes/embeds/class-amp-crowdsignal-embed-handler.php | 2 +- includes/embeds/class-amp-dailymotion-embed-handler.php | 2 +- includes/embeds/class-amp-facebook-embed-handler.php | 3 ++- includes/embeds/class-amp-gfycat-embed-handler.php | 2 +- includes/embeds/class-amp-hulu-embed-handler.php | 2 +- includes/embeds/class-amp-imgur-embed-handler.php | 2 +- includes/embeds/class-amp-instagram-embed-handler.php | 2 +- includes/embeds/class-amp-issuu-embed-handler.php | 2 +- includes/embeds/class-amp-meetup-embed-handler.php | 2 +- includes/embeds/class-amp-pinterest-embed-handler.php | 2 +- includes/embeds/class-amp-reddit-embed-handler.php | 2 +- includes/embeds/class-amp-scribd-embed-handler.php | 2 +- includes/embeds/class-amp-soundcloud-embed-handler.php | 2 +- includes/embeds/class-amp-tiktok-embed-handler.php | 2 +- includes/embeds/class-amp-tumblr-embed-handler.php | 2 +- includes/embeds/class-amp-vimeo-embed-handler.php | 2 +- includes/embeds/class-amp-vine-embed-handler.php | 2 +- includes/embeds/class-amp-wordpress-tv-embed-handler.php | 2 +- includes/embeds/class-amp-youtube-embed-handler.php | 2 +- 19 files changed, 20 insertions(+), 19 deletions(-) diff --git a/includes/embeds/class-amp-crowdsignal-embed-handler.php b/includes/embeds/class-amp-crowdsignal-embed-handler.php index b5bd516430d..23adc3899d9 100644 --- a/includes/embeds/class-amp-crowdsignal-embed-handler.php +++ b/includes/embeds/class-amp-crowdsignal-embed-handler.php @@ -51,7 +51,7 @@ public function unregister_embed() { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { $queries = [ diff --git a/includes/embeds/class-amp-dailymotion-embed-handler.php b/includes/embeds/class-amp-dailymotion-embed-handler.php index fe0489453b2..9b9204534b5 100644 --- a/includes/embeds/class-amp-dailymotion-embed-handler.php +++ b/includes/embeds/class-amp-dailymotion-embed-handler.php @@ -68,7 +68,7 @@ public function __construct( $args = [] ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-facebook-embed-handler.php b/includes/embeds/class-amp-facebook-embed-handler.php index 671fd733c91..2619024f906 100644 --- a/includes/embeds/class-amp-facebook-embed-handler.php +++ b/includes/embeds/class-amp-facebook-embed-handler.php @@ -49,7 +49,7 @@ public function sanitize_raw_embeds( Document $dom ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->getElementsByTagName( 'div' ); @@ -135,6 +135,7 @@ private function remove_fb_root_nodes( Document $dom ) { $script_query = $dom->xpath->query( '//script[ starts-with( @src, "https://connect.facebook.net" ) and contains( @src, "sdk.js" ) ]' ); foreach ( $script_query as $script ) { + /** @var DOMElement $parent_node */ $parent_node = $script->parentNode; $parent_node->removeChild( $script ); diff --git a/includes/embeds/class-amp-gfycat-embed-handler.php b/includes/embeds/class-amp-gfycat-embed-handler.php index ee7123e9dab..a5790f44661 100644 --- a/includes/embeds/class-amp-gfycat-embed-handler.php +++ b/includes/embeds/class-amp-gfycat-embed-handler.php @@ -31,7 +31,7 @@ class AMP_Gfycat_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-hulu-embed-handler.php b/includes/embeds/class-amp-hulu-embed-handler.php index d0b907998a4..3e1a1dd5559 100644 --- a/includes/embeds/class-amp-hulu-embed-handler.php +++ b/includes/embeds/class-amp-hulu-embed-handler.php @@ -38,7 +38,7 @@ class AMP_Hulu_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ contains( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-imgur-embed-handler.php b/includes/embeds/class-amp-imgur-embed-handler.php index b34002cd519..e19d3f25866 100644 --- a/includes/embeds/class-amp-imgur-embed-handler.php +++ b/includes/embeds/class-amp-imgur-embed-handler.php @@ -38,7 +38,7 @@ class AMP_Imgur_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//blockquote[ @class = "imgur-embed-pub" ]' ); diff --git a/includes/embeds/class-amp-instagram-embed-handler.php b/includes/embeds/class-amp-instagram-embed-handler.php index 65d458726e9..1dddaf67d47 100644 --- a/includes/embeds/class-amp-instagram-embed-handler.php +++ b/includes/embeds/class-amp-instagram-embed-handler.php @@ -66,7 +66,7 @@ public function unregister_embed() { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//blockquote[ @data-instgrm-permalink ]' ); diff --git a/includes/embeds/class-amp-issuu-embed-handler.php b/includes/embeds/class-amp-issuu-embed-handler.php index e6fa9d4897f..03312522bc8 100644 --- a/includes/embeds/class-amp-issuu-embed-handler.php +++ b/includes/embeds/class-amp-issuu-embed-handler.php @@ -17,7 +17,7 @@ class AMP_Issuu_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//div[ @class="issuuembed" and @data-url ]' ); diff --git a/includes/embeds/class-amp-meetup-embed-handler.php b/includes/embeds/class-amp-meetup-embed-handler.php index ab260075728..ed3712bec35 100644 --- a/includes/embeds/class-amp-meetup-embed-handler.php +++ b/includes/embeds/class-amp-meetup-embed-handler.php @@ -30,7 +30,7 @@ protected function is_raw_embed( DOMElement $node ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//div[ @id="meetup_oembed" ]//div[ @class="photo" ]/img' ); diff --git a/includes/embeds/class-amp-pinterest-embed-handler.php b/includes/embeds/class-amp-pinterest-embed-handler.php index 6435a5255e1..681d711a193 100644 --- a/includes/embeds/class-amp-pinterest-embed-handler.php +++ b/includes/embeds/class-amp-pinterest-embed-handler.php @@ -100,7 +100,7 @@ public function render( $args ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//%s', $this->amp_tag ) ); diff --git a/includes/embeds/class-amp-reddit-embed-handler.php b/includes/embeds/class-amp-reddit-embed-handler.php index 531541c097b..b4e8f9212a0 100644 --- a/includes/embeds/class-amp-reddit-embed-handler.php +++ b/includes/embeds/class-amp-reddit-embed-handler.php @@ -24,7 +24,7 @@ class AMP_Reddit_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { /* diff --git a/includes/embeds/class-amp-scribd-embed-handler.php b/includes/embeds/class-amp-scribd-embed-handler.php index c4beea0eb16..4849cb5db46 100644 --- a/includes/embeds/class-amp-scribd-embed-handler.php +++ b/includes/embeds/class-amp-scribd-embed-handler.php @@ -24,7 +24,7 @@ class AMP_Scribd_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-soundcloud-embed-handler.php b/includes/embeds/class-amp-soundcloud-embed-handler.php index b4da8a47151..54685998df5 100644 --- a/includes/embeds/class-amp-soundcloud-embed-handler.php +++ b/includes/embeds/class-amp-soundcloud-embed-handler.php @@ -39,7 +39,7 @@ class AMP_SoundCloud_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-tiktok-embed-handler.php b/includes/embeds/class-amp-tiktok-embed-handler.php index d37790946f8..1cbb1bfadbd 100644 --- a/includes/embeds/class-amp-tiktok-embed-handler.php +++ b/includes/embeds/class-amp-tiktok-embed-handler.php @@ -23,7 +23,7 @@ class AMP_TikTok_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( '//blockquote[ contains( @class, "tiktok-embed" ) ]' ); diff --git a/includes/embeds/class-amp-tumblr-embed-handler.php b/includes/embeds/class-amp-tumblr-embed-handler.php index 01751dcd89e..914287d5e6f 100644 --- a/includes/embeds/class-amp-tumblr-embed-handler.php +++ b/includes/embeds/class-amp-tumblr-embed-handler.php @@ -34,7 +34,7 @@ class AMP_Tumblr_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//div[ @class = "tumblr-post" and starts-with( @data-href, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-vimeo-embed-handler.php b/includes/embeds/class-amp-vimeo-embed-handler.php index 22c4958be4e..a37726c723f 100644 --- a/includes/embeds/class-amp-vimeo-embed-handler.php +++ b/includes/embeds/class-amp-vimeo-embed-handler.php @@ -68,7 +68,7 @@ public function __construct( $args = [] ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-vine-embed-handler.php b/includes/embeds/class-amp-vine-embed-handler.php index 1a8ef23d390..efe1a346cd6 100644 --- a/includes/embeds/class-amp-vine-embed-handler.php +++ b/includes/embeds/class-amp-vine-embed-handler.php @@ -107,7 +107,7 @@ public function render( $args ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//%s', $this->amp_tag ) ); diff --git a/includes/embeds/class-amp-wordpress-tv-embed-handler.php b/includes/embeds/class-amp-wordpress-tv-embed-handler.php index f1fe7e75059..de34896c473 100644 --- a/includes/embeds/class-amp-wordpress-tv-embed-handler.php +++ b/includes/embeds/class-amp-wordpress-tv-embed-handler.php @@ -26,7 +26,7 @@ class AMP_WordPress_TV_Embed_Handler extends AMP_Base_Embed_Handler { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { return $dom->xpath->query( sprintf( '//iframe[ starts-with( @src, "%s" ) ]', $this->base_embed_url ) ); diff --git a/includes/embeds/class-amp-youtube-embed-handler.php b/includes/embeds/class-amp-youtube-embed-handler.php index e8da507141c..89467426f02 100644 --- a/includes/embeds/class-amp-youtube-embed-handler.php +++ b/includes/embeds/class-amp-youtube-embed-handler.php @@ -69,7 +69,7 @@ public function __construct( $args = [] ) { * Get all raw embeds from the DOM. * * @param Document $dom Document. - * @return DOMNodeList|null A list of DOMElement nodes, or null if not implemented. + * @return DOMNodeList A list of DOMElement nodes. */ protected function get_raw_embed_nodes( Document $dom ) { $query_segments = array_map(