Skip to content

Commit

Permalink
Merge pull request #921 from Automattic/fix/864-video-widget-youtube-…
Browse files Browse the repository at this point in the history
…vimeo

Fix 'Video' widget for YouTube and Vimeo, simplify 'Gallery' solution
  • Loading branch information
westonruter committed Feb 3, 2018
2 parents fc6d81c + a6e7c36 commit 4089c33
Show file tree
Hide file tree
Showing 15 changed files with 391 additions and 164 deletions.
2 changes: 1 addition & 1 deletion includes/amp-helper-functions.php
Expand Up @@ -293,7 +293,6 @@ function amp_get_content_sanitizers( $post = null ) {
*/
return apply_filters( 'amp_content_sanitizers',
array(
'AMP_Style_Sanitizer' => array(),
'AMP_Img_Sanitizer' => array(),
'AMP_Form_Sanitizer' => array(),
'AMP_Comments_Sanitizer' => array(),
Expand All @@ -303,6 +302,7 @@ function amp_get_content_sanitizers( $post = null ) {
'AMP_Iframe_Sanitizer' => array(
'add_placeholder' => true,
),
'AMP_Style_Sanitizer' => array(),
'AMP_Tag_And_Attribute_Sanitizer' => array(), // Note: This whitelist sanitizer must come at the end to clean up any remaining issues the other sanitizers didn't catch.
),
$post
Expand Down
3 changes: 2 additions & 1 deletion includes/class-amp-autoloader.php
Expand Up @@ -88,8 +88,9 @@ class AMP_Autoloader {
'AMP_WP_Utils' => 'includes/utils/class-amp-wp-utils',
'AMP_Widget_Archives' => 'includes/widgets/class-amp-widget-archives',
'AMP_Widget_Categories' => 'includes/widgets/class-amp-widget-categories',
'AMP_Widget_Media_Gallery' => 'includes/widgets/class-amp-widget-media-gallery',
'AMP_Widget_Media_Video' => 'includes/widgets/class-amp-widget-media-video',
'AMP_Widget_Recent_Comments' => 'includes/widgets/class-amp-widget-recent-comments',
'AMP_Widget_Text' => 'includes/widgets/class-amp-widget-text',
'WPCOM_AMP_Polldaddy_Embed' => 'wpcom/class-amp-polldaddy-embed',
'AMP_Test_Stub_Sanitizer' => 'tests/stubs',
'AMP_Test_World_Sanitizer' => 'tests/stubs',
Expand Down
20 changes: 16 additions & 4 deletions includes/embeds/class-amp-gallery-embed.php
Expand Up @@ -16,15 +16,13 @@ class AMP_Gallery_Embed_Handler extends AMP_Base_Embed_Handler {
* Register embed.
*/
public function register_embed() {
add_shortcode( 'gallery', array( $this, 'shortcode' ) );
add_filter( 'post_gallery', array( $this, 'override_gallery' ), 10, 2 );
}

/**
* Unregister embed.
*/
public function unregister_embed() {
remove_shortcode( 'gallery' );
}
public function unregister_embed() {}

/**
* Shortcode handler.
Expand Down Expand Up @@ -120,6 +118,20 @@ public function shortcode( $attr ) {
) );
}

/**
* Override the output of gallery_shortcode().
*
* The 'Gallery' widget also uses this function.
* This ensures that it outputs an <amp-carousel>.
*
* @param string $html Markup to filter, possibly ''.
* @param array $attributes Shortcode attributes.
* @return string $html Markup for the gallery.
*/
public function override_gallery( $html, $attributes ) {
return $this->shortcode( $attributes );
}

/**
* Render.
*
Expand Down
24 changes: 24 additions & 0 deletions includes/embeds/class-amp-vimeo-embed.php
Expand Up @@ -32,6 +32,7 @@ function __construct( $args = array() ) {
function register_embed() {
wp_embed_register_handler( 'amp-vimeo', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
add_shortcode( 'vimeo', array( $this, 'shortcode' ) );
add_filter( 'wp_video_shortcode_override', array( $this, 'video_override' ), 10, 2 );
}

public function unregister_embed() {
Expand Down Expand Up @@ -107,4 +108,27 @@ private function get_video_id_from_url( $url ) {

return $video_id;
}

/**
* Override the output of Vimeo videos.
*
* This overrides the value in wp_video_shortcode().
* The pattern matching is copied from WP_Widget_Media_Video::render().
*
* @param string $html Empty variable to be replaced with shortcode markup.
* @param array $attr The shortcode attributes.
* @return string|null $markup The markup to output.
*/
public function video_override( $html, $attr ) {
if ( ! isset( $attr['src'] ) ) {
return $html;
}
$src = $attr['src'];
$vimeo_pattern = '#^https?://(.+\.)?vimeo\.com/.*#';
if ( 1 === preg_match( $vimeo_pattern, $src ) ) {
return $this->shortcode( array( $src ) );
}
return $html;
}

}
26 changes: 25 additions & 1 deletion includes/embeds/class-amp-youtube-embed.php
Expand Up @@ -24,14 +24,15 @@ function __construct( $args = array() ) {

if ( isset( $this->args['content_max_width'] ) ) {
$max_width = $this->args['content_max_width'];
$this->args['width'] = $max_width;
$this->args['width'] = $max_width;
$this->args['height'] = round( $max_width * self::RATIO );
}
}

function register_embed() {
wp_embed_register_handler( 'amp-youtube', self::URL_PATTERN, array( $this, 'oembed' ), -1 );
add_shortcode( 'youtube', array( $this, 'shortcode' ) );
add_filter( 'wp_video_shortcode_override', array( $this, 'video_override' ), 10, 2 );
}

public function unregister_embed() {
Expand Down Expand Up @@ -125,4 +126,27 @@ private function sanitize_v_arg( $value ) {

return $value;
}

/**
* Override the output of YouTube videos.
*
* This overrides the value in wp_video_shortcode().
* The pattern matching is copied from WP_Widget_Media_Video::render().
*
* @param string $html Empty variable to be replaced with shortcode markup.
* @param array $attr The shortcode attributes.
* @return string|null $markup The markup to output.
*/
public function video_override( $html, $attr ) {
if ( ! isset( $attr['src'] ) ) {
return $html;
}
$src = $attr['src'];
$youtube_pattern = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#';
if ( 1 === preg_match( $youtube_pattern, $src ) ) {
return $this->shortcode( array( $src ) );
}
return $html;
}

}
3 changes: 2 additions & 1 deletion includes/sanitizers/class-amp-video-sanitizer.php
Expand Up @@ -124,7 +124,8 @@ public function sanitize() {
* @return array Returns HTML attributes; removes any not specifically declared above from input.
*/
private function filter_attributes( $attributes ) {
$out = array();
$out = array();
$out['style'] = 'max-width:100%'; // Note that this will get moved to amp-custom style by AMP_Style_Sanitizer.

foreach ( $attributes as $name => $value ) {
switch ( $name ) {
Expand Down
67 changes: 0 additions & 67 deletions includes/widgets/class-amp-widget-media-gallery.php

This file was deleted.

33 changes: 33 additions & 0 deletions includes/widgets/class-amp-widget-media-video.php
@@ -0,0 +1,33 @@
<?php
/**
* Class AMP_Widget_Media_Video
*
* @since 0.7.0
* @package AMP
*/

if ( class_exists( 'WP_Widget_Media_Video' ) ) {
/**
* Class AMP_Widget_Media_Video
*
* @since 0.7.0
* @package AMP
*/
class AMP_Widget_Media_Video extends WP_Widget_Media_Video {

/**
* Overrides the parent callback that strips width and height values.
*
* @param string $html Video shortcode HTML output.
* @return string HTML Output.
*/
public function inject_video_max_width_style( $html ) {
if ( is_amp_endpoint() ) {
return $html;
}
return parent::inject_video_max_width_style( $html );
}

}

}
33 changes: 33 additions & 0 deletions includes/widgets/class-amp-widget-text.php
@@ -0,0 +1,33 @@
<?php
/**
* Class AMP_Widget_Text
*
* @since 0.7.0
* @package AMP
*/

if ( class_exists( 'WP_Widget_Text' ) ) {
/**
* Class AMP_Widget_Text
*
* @since 0.7.0
* @package AMP
*/
class AMP_Widget_Text extends WP_Widget_Text {

/**
* Overrides the parent callback that strips width and height attributes.
*
* @param array $matches The matches returned from preg_replace_callback().
* @return string $html The markup, unaltered.
*/
public function inject_video_max_width_style( $matches ) {
if ( is_amp_endpoint() ) {
return $matches[0];
}
return parent::inject_video_max_width_style( $matches );
}

}

}
24 changes: 12 additions & 12 deletions tests/test-amp-video-sanitizer.php
Expand Up @@ -10,70 +10,70 @@ public function get_data() {

'simple_video' => array(
'<video width="300" height="300" src="https://example.com/video.mp4"></video>',
'<amp-video width="300" height="300" src="https://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" width="300" height="300" src="https://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),

'video_without_dimensions' => array(
'<video src="https://example.com/file.mp4"></video>',
'<amp-video src="https://example.com/file.mp4" height="400" layout="fixed-height"></amp-video>',
'<amp-video style="max-width:100%" src="https://example.com/file.mp4" height="400" layout="fixed-height"></amp-video>',
),

'autoplay_attribute' => array(
'<video width="300" height="300" src="https://example.com/video.mp4" autoplay></video>',
'<amp-video width="300" height="300" src="https://example.com/video.mp4" autoplay="" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" width="300" height="300" src="https://example.com/video.mp4" autoplay="" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),

'autoplay_attribute__false' => array(
'<video width="300" height="300" src="https://example.com/video.mp4" autoplay="false"></video>',
'<amp-video width="300" height="300" src="https://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" width="300" height="300" src="https://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),

'video_with_whitelisted_attributes__enabled' => array(
'<video width="300" height="300" src="https://example.com/video.mp4" controls loop="true" muted="muted"></video>',
'<amp-video width="300" height="300" src="https://example.com/video.mp4" controls="" loop="" muted="" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" width="300" height="300" src="https://example.com/video.mp4" controls="" loop="" muted="" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),

'video_with_whitelisted_attributes__disabled' => array(
'<video width="300" height="300" src="https://example.com/video.mp4" controls="false" loop="false" muted="false"></video>',
'<amp-video width="300" height="300" src="https://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" width="300" height="300" src="https://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),

'video_with_blacklisted_attribute' => array(
'<video width="300" height="300" src="https://example.com/video.mp4" style="border-color: red;"></video>',
'<amp-video width="300" height="300" src="https://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" width="300" height="300" src="https://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),

'video_with_sizes_attribute_is_overridden' => array(
'<video width="300" height="200" src="https://example.com/file.mp4" sizes="(min-width: 100px) 200px, 90vw"></video>',
'<amp-video width="300" height="200" src="https://example.com/file.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" width="300" height="200" src="https://example.com/file.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),

'video_with_children' => array(
'<video width="480" height="300" poster="https://example.com/video-image.gif">
<source src="https://example.com/video.mp4" type="video/mp4">
<source src="https://example.com/video.ogv" type="video/ogg">
</video>',
'<amp-video width="480" height="300" poster="https://example.com/video-image.gif" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"><source src="https://example.com/video.mp4" type="video/mp4"><source src="https://example.com/video.ogv" type="video/ogg"></amp-video>',
'<amp-video style="max-width:100%" width="480" height="300" poster="https://example.com/video-image.gif" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"><source src="https://example.com/video.mp4" type="video/mp4"><source src="https://example.com/video.ogv" type="video/ogg"></amp-video>',
),

'multiple_same_video' => array(
'<video src="https://example.com/video.mp4" width="480" height="300"></video>
<video src="https://example.com/video.mp4" width="480" height="300"></video>
<video src="https://example.com/video.mp4" width="480" height="300"></video>
<video src="https://example.com/video.mp4" width="480" height="300"></video>',
'<amp-video src="https://example.com/video.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video src="https://example.com/video.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video src="https://example.com/video.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video src="https://example.com/video.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" src="https://example.com/video.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video style="max-width:100%" src="https://example.com/video.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video style="max-width:100%" src="https://example.com/video.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video style="max-width:100%" src="https://example.com/video.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),

'multiple_different_videos' => array(
'<video src="https://example.com/video1.mp4" width="480" height="300"></video>
<video src="https://example.com/video2.ogv" width="300" height="480"></video>
<video src="https://example.com/video3.webm" height="100" width="200"></video>',
'<amp-video src="https://example.com/video1.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video src="https://example.com/video2.ogv" width="300" height="480" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video src="https://example.com/video3.webm" height="100" width="200" sizes="(min-width: 200px) 200px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" src="https://example.com/video1.mp4" width="480" height="300" sizes="(min-width: 480px) 480px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video style="max-width:100%" src="https://example.com/video2.ogv" width="300" height="480" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video><amp-video style="max-width:100%" src="https://example.com/video3.webm" height="100" width="200" sizes="(min-width: 200px) 200px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),

'https_not_required' => array(
'<video width="300" height="300" src="http://example.com/video.mp4"></video>',
'<amp-video width="300" height="300" src="http://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
'<amp-video style="max-width:100%" width="300" height="300" src="http://example.com/video.mp4" sizes="(min-width: 300px) 300px, 100vw" class="amp-wp-enforced-sizes"></amp-video>',
),
);
}
Expand Down

0 comments on commit 4089c33

Please sign in to comment.