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

Persist img of picture tag instead of removing it during sanitization. #6896

Merged
merged 16 commits into from
Mar 7, 2022

Conversation

dhaval-parekh
Copy link
Collaborator

Summary

Fixes #6676

These PR changes prevent the img tag inside the picture tag from being removed if native_img_used is false. and will mark the picture tag and its child element as px-verified-tag if native_img_used is true.

Checklist

  • My code is tested and passes existing tests.
  • My code follows the Engineering Guidelines (updates are often made to the guidelines, check it out periodically).

@dhaval-parekh dhaval-parekh marked this pull request as ready for review February 7, 2022 09:00
@github-actions
Copy link
Contributor

github-actions bot commented Feb 7, 2022

Plugin builds for 0d63423 are ready 🛎️!

@dhaval-parekh dhaval-parekh self-assigned this Feb 7, 2022
@maitreyie-chavan maitreyie-chavan added this to the v2.2.2 milestone Feb 9, 2022
@westonruter
Copy link
Member

I've asked if this will address the concerns by a support forum user: https://wordpress.org/support/topic/plugin-deleted-all-tags-picture/#post-15369498

That user wasn't able to use @milindmore22's mini plugin successfully, but I believe that is due in large part that they missed the required picture > img element. I tried adding a picture with only source children and this was flagged as an error by Validator.nu:

image

So we should require that picture > img to be present for the sanitizer to do anything.

@dhaval-parekh
Copy link
Collaborator Author

So we should require that picture > img to be present for the sanitizer to do anything.

you mean to only enable sanitization when there picture > img in the body content. But that will also prevent tag to be converted into an AMP component. And I think it should be implemented after #6805

@westonruter
Copy link
Member

What I mean is that if there is a picture without a child img, then our picture sanitizer wouldn't be able to do anything if we're looking to transform into amp-img.

@dhaval-parekh
Copy link
Collaborator Author

What I mean is that if there is a picture without a child img, then our picture sanitizer wouldn't be able to do anything if we're looking to transform into amp-img.

I have added that check in recent commit 39a57e6

…allow-child-img-of-picture

* 'develop' of github.com:ampproject/amp-wp: (135 commits)
  Bump eslint-plugin-react from 7.29.2 to 7.29.3
  Add tests for new specs
  Update tests for new component versions
  Add support for Bento extensions being defined in bundles.config.bento.json
  Update amphtml to 2202230359001 and add to latest-extension-versions
  Fix check_for_page_caching to account for wp_remote_retrieve_header() returning arrays
  Bump `@wordpress/scripts` to 22.1.0
  Revert "Prevent copying PHP files from `src/` into `assets/`"
  Use links as exported from PHP, split out functions, and make list item matching more robust
  Bump postcss-preset-env from 7.4.1 to 7.4.2
  Update namespace for Attribute and Tag interfaces
  Remove obsolete debug code
  Defer creation of post fixture until test
  Add assertion for post data being created before test
  Add yet more assertions to debug oEmbed problem on GHA
  Add oembed_request_post_id filter sooner
  Add more assertions
  Add assertions
  Ensure video shortcode is registered to test_process_text_widgets
  Use oembed_request_post_id for test
  ...
return;
}

$picture_nodes = $this->dom->getElementsByTagName( Tag::PICTURE );
Copy link
Member

Choose a reason for hiding this comment

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

This shouldn't be needed because there is an XPath query right above.

*/
protected function process_picture_elements() {

$nodes = $this->dom->xpath->query( '//picture//img' );
Copy link
Member

Choose a reason for hiding this comment

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

This could be made to select the direct descendant:

Suggested change
$nodes = $this->dom->xpath->query( '//picture//img' );
$nodes = $this->dom->xpath->query( '//picture/img' );

Copy link
Member

Choose a reason for hiding this comment

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

Or better to select picture elements that have img children:

Suggested change
$nodes = $this->dom->xpath->query( '//picture//img' );
$nodes = $this->dom->xpath->query( '//picture[ img ]' );

Copy link
Member

Choose a reason for hiding this comment

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

Or or no, the first is better, as then you can loop over the img elements and then to get the picture you just get the parentNode.

'expected' => '<h1>Page heading</h1><ul><li>Item 1</li><li>Item 2</li></ul>',
],
'picture_without_img_allow_picture_false' => [
'input' => '<picture><div class="screen-reader-text"></div><source srcset="https://interactive-examples.mdn.mozilla.net/media/cc0-images/surfer-240-200.jpg" media="(min-width: 800px)"></picture>',
Copy link
Member

Choose a reason for hiding this comment

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

Humm. Why is there a <div class="screen-reader-text"></div> as a child of the picture? I thought only source and img elements were allowed as children.

'args' => [
'allow_picture' => false,
],
'expected' => '<picture><div class="screen-reader-text"></div><source srcset="https://interactive-examples.mdn.mozilla.net/media/cc0-images/surfer-240-200.jpg" media="(min-width: 800px)"></picture>',
Copy link
Member

Choose a reason for hiding this comment

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

Since allow_picture is false, why isn't the picture converted? Oh, it's because there is no img?

Copy link
Collaborator

@delawski delawski left a comment

Choose a reason for hiding this comment

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

This looks good to me. I left some minor feedback.

Comment on lines 96 to 98
if ( 0 === $picture_img_query->length ) {
return;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess this is redundant. The $this->dom->xpath->query() returns a DOMNodeList. If it's an empty list, the foreach loop below will do 0 iterations.

Comment on lines +119 to +120
$picture_element->removeChild( $img_element );
$picture_element->parentNode->replaceChild( $img_element, $picture_element );
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't have much experience with the DOM API in PHP but is it necessary to remove the IMG tag first from the PICTURE and then replace the entire PICTURE with an IMG? Wouldn't just the replaceChild() suffice?

Copy link
Member

Choose a reason for hiding this comment

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

I recall this has been necessary since replacing a parent with a child while the child is still in the DOM could cause an error, if I remember correctly.

@westonruter westonruter merged commit f7c7230 into develop Mar 7, 2022
@westonruter westonruter deleted the bug/6676-allow-child-img-of-picture branch March 7, 2022 18:59
westonruter added a commit that referenced this pull request Mar 7, 2022
@westonruter westonruter added the Changelogged Whether the issue/PR has been added to release notes. label Apr 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelogged Whether the issue/PR has been added to release notes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Entire picture element tree is removed when img child is expected to persist
4 participants