Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve handling of YouTube embeds #3358

Merged
merged 21 commits into from
Nov 10, 2019
Merged

Conversation

westonruter
Copy link
Member

@westonruter westonruter commented Sep 27, 2019

This pull request aims to clean up handling of YouTube embed handling, in large part to apply similar improvements as #2722 for SoundCloud.

Fixes #3348. Fixes #3313.

Relates to #3309 in that the shortcode logic needs to be removed/moved to Jetpack.

@googlebot googlebot added the cla: yes Signed the Google CLA label Sep 27, 2019
@westonruter westonruter added this to the v1.3.1 milestone Sep 27, 2019
@westonruter
Copy link
Member Author

This PR is free for anyone to take over.

@swissspidy swissspidy modified the milestones: v1.3.1, v1.4 Oct 17, 2019
@westonruter westonruter modified the milestones: v1.4, v.1.4.1 Oct 29, 2019
@westonruter westonruter modified the milestones: v.1.4.1, v1.5 Nov 7, 2019
@googlebot
Copy link

All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter.

We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only @googlebot I consent. in this pull request.

Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the cla label to yes (if enabled on your project).

ℹ️ Googlers: Go here for more info.

@googlebot googlebot added cla: no Has not signed the Google CLA and removed cla: yes Signed the Google CLA labels Nov 8, 2019
@pierlon pierlon marked this pull request as ready for review November 8, 2019 01:42
@westonruter
Copy link
Member Author

@googlebot I consent.

1 similar comment
@pierlon
Copy link
Contributor

pierlon commented Nov 8, 2019

@googlebot I consent.

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@googlebot googlebot added cla: yes Signed the Google CLA and removed cla: no Has not signed the Google CLA labels Nov 8, 2019
*
* @param array $matches URL pattern matches.
* @param array $attr Shortcode attribues.
* @param string $url URL.
* @return string Rendered oEmbed.
*/
public function oembed( $matches, $attr, $url ) {
_deprecated_function( __METHOD__, '1.3.1' );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_deprecated_function( __METHOD__, '1.3.1' );
_deprecated_function( __METHOD__, '1.5.0' );

]
);

if ( empty( $args['video_id'] ) ) {
return AMP_HTML_Utils::build_tag(
'a',
[
'href' => esc_url( $args['url'] ),
'href' => esc_url( $url ),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just realized that this needs to rather be esc_url_raw() since the HTML entity encoding will be handled by the DOM. If there are other places where esc_url() is being used in this way, it should be updated to be esc_url_raw() as well.

@@ -162,7 +223,7 @@ private function get_video_id_from_url( $url ) {
} else {
/* phpcs:ignore Squiz.PHP.CommentedOutCode.Found
The query looks like ?v={id} or ?list={id} */
parse_str( $parsed_url['query'], $query_args );
parse_str( $parsed_url['query'], $query_args ); // @todo Bug! See <https://github.com/ampproject/amp-wp/issues/3348>.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be done in this PR or another?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That needs to be removed as the embed_oembed_html filter correctly handles the URL and transforms it into an embeddable one.

);
}

/**
* Determine the video ID from the URL.
*
* @todo Needs to be totally refactored.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this PR or another?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will be done in this PR.

/**
* @dataProvider get_conversion_data
*/
public function test__conversion( $source, $expected, $fallback = null ) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you rename $fallback to be something else here? It gets confusing with fallback content in AMP. Perhaps $expected_without_fallback would be better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, OK. $expected_without_fallback seems a bit confusing as well, how about something direct like $fallback_for_expected?

if ( preg_match( '#<iframe[^>]*?title="(?P<title>[^"]+)"#s', $html, $matches ) ) {
$props['title'] = $matches['title'];
$props['fallback'] = sprintf(
'<a fallback href="%s">%s</a>',
Copy link
Member Author

@westonruter westonruter Nov 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I keep arguing with myself whether this should be a fallback or a placeholder: https://amp.dev/documentation/guides-and-tutorials/develop/style_and_layout/placeholders/

Actually, I think the answer is this should be changed to rather be an amp-img as a placeholder as shown on the amp-youtube docs:

  <amp-youtube
      id="myLiveChannel"
      data-live-channelid="UCB8Kb4pxYzsDsHxzBfnid4Q"
      width="358"
      height="204"
      layout="responsive">
    <amp-img
      src="https://i.ytimg.com/vi/Wm1fWz-7nLQ/hqdefault_live.jpg"
      placeholder
      layout="fill"
      />
  </amp-youtube>

The example there is incomplete however. In particular, the amp-img should have an alt attribute provided which is the title of the video.

Also, instead of actually generating an amp-img here, just output a regular img as it will get converted into an amp-img later by the image sanitizer.

Also, the amp-img placeholder would be suitable even when there is no title available, it's just that the alt would have to be blank.

Also, keeping the link to the original YouTube video is good.

So what to do:

  1. Unconditionally construct the link regardless of whether the iframe has a title.
  2. Change this to be placeholder instead of fallback.
  3. Parse construct the HQ video thumbnail from the video ID (e.g. https://i.ytimg.com/vi/$video_id/hqdefault.jpg).
  4. Supply an img element as the child of the a link.
  5. Supply the title of the iframe as the img[alt], if available.

So in the end, it should look like this:

<p>
    <amp-youtube data-videoid="kfVsfOSbJY0" layout="responsive" width="480" height="270" title="Rebecca Black - Friday">
        <a placeholder href="https://www.youtube.com/watch?v=kfVsfOSbJY0">
            <img src="https://i.ytimg.com/vi/kfVsfOSbJY0/hqdefault.jpg" alt="Rebecca Black &#8211; Friday" data-amp-layout="fill">
        </a>
    </amp-youtube>
</p>

And in WordPress<5.2, the only difference would be no alt attribute on the img and no title on the amp-youtube.

@googlebot googlebot added the cla: yes Signed the Google CLA label Nov 9, 2019
@pierlon
Copy link
Contributor

pierlon commented Nov 9, 2019

Hey @schlessera, you're needed to give consent over here again 😄

@schlessera
Copy link
Collaborator

@pierlon It's already done.

@pierlon
Copy link
Contributor

pierlon commented Nov 9, 2019

Ah, thanks!

@pierlon
Copy link
Contributor

pierlon commented Nov 9, 2019

@westonruter on WP <5.2, the title attribute on amp-youtube and the alt attribute on img lingers without a value. Would that be of concern?

@westonruter
Copy link
Member Author

on WP <5.2, the title attribute on amp-youtube and the alt attribute on img lingers without a value. Would that be of concern?

@pierlon Yeah, it would probably be best if the attributes were removed on PHP 5.2. I've adjusted them in 97e8db5.

@westonruter
Copy link
Member Author

I've improved the display of the placeholder image in fc0e9e0 by using object-fit=cover.

Before:

Screen Shot 2019-11-09 at 16 27 33

After:

Screen Shot 2019-11-09 at 16 27 46

@westonruter
Copy link
Member Author

Aside: I'm curious why the amp-youtube element doesn't provide such a placeholder by default.

* @param string[] $attribute_names Attribute names.
* @return string Regular expression pattern.
*/
protected function get_html_attribute_pattern( $tag_name, $attribute_names ) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you make this reusable, why not include the preg_match() call? Something like match_element_attributes( $tag_name, $attribute_names ).

This way, usage could be simplified:

$props = $this->match_element_attributes( 'iframe', [ 'src', 'title', 'width', 'height' ] );

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent point. I didn't refactor far enough. See d45fd59.

includes/embeds/class-amp-base-embed-handler.php Outdated Show resolved Hide resolved
includes/embeds/class-amp-base-embed-handler.php Outdated Show resolved Hide resolved
@westonruter westonruter merged commit acdad29 into develop Nov 10, 2019
@westonruter westonruter deleted the update/youtube-handling branch November 10, 2019 16:28
@westonruter
Copy link
Member Author

I'm excited about the changes here. Huge improvements to YouTube embed handling. Great fallback even for when JS is turned off in the browser:

image

@csossi
Copy link

csossi commented Nov 12, 2019

Verified in QA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Signed the Google CLA QA passed Has passed QA and is done
Projects
None yet
6 participants