-
Notifications
You must be signed in to change notification settings - Fork 378
Enable captions on Gallery shortcodes #3659
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
Changes from 31 commits
1b34cef
dde1e46
a48d974
5c7334b
641e008
cbd925b
5e07516
93246e8
08404be
0caa844
2c32f41
22ae686
82b428a
d3ba063
93aa3ea
6ba9bdb
2ed1653
5794193
78b0c75
3125261
67c7590
692d14b
8eb54a8
07cfc97
c0a5e05
7e206ef
3f0ee52
2b4a98f
284b328
d7fdbd2
be2b4e2
12c6d26
951cd3f
12f062e
92a764e
7b603ea
305e471
8de2340
3cdd86f
097d1b8
873c41a
38df209
f48d09b
5a8749c
0355530
450f9cd
0ae904e
4ac1d25
478f71e
c7d5d6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,7 @@ | |
| "ext-zip": "Enables the use of ZipArchive to export AMP Stories." | ||
| }, | ||
| "config": { | ||
| "optimize-autoloader": true, | ||
| "platform": { | ||
| "php": "5.4" | ||
| }, | ||
|
|
@@ -44,5 +45,10 @@ | |
| "PHP-CSS-Parser: Fix parsing CSS selectors which contain commas <https://github.com/sabberworm/PHP-CSS-Parser/pull/138>": "https://github.com/sabberworm/PHP-CSS-Parser/commit/fa139f65c5b098ae652c970b25e6eb03fc495eb4.diff" | ||
| } | ||
| } | ||
| }, | ||
| "autoload": { | ||
| "psr-4": { | ||
| "Amp\\AmpWP\\": "src/" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See questions below about whether root namespace should be
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discussed in #3810 |
||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,9 @@ | |
| * @package AMP | ||
| */ | ||
|
|
||
| use Amp\AmpWP\Component\ImageList; | ||
| use Amp\AmpWP\Component\Carousel; | ||
|
|
||
| /** | ||
| * Class AMP_Gallery_Embed_Handler | ||
| * | ||
|
|
@@ -129,25 +132,14 @@ public function shortcode( $attr ) { | |
| 'width' => $width, | ||
| 'height' => $height, | ||
| 'alt' => trim( wp_strip_all_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ), // Logic from wp_get_attachment_image(). | ||
| 'id' => $attachment_id, | ||
| ]; | ||
| } | ||
|
|
||
| $args = [ | ||
| 'images' => $urls, | ||
| 'images' => $urls, | ||
| 'lightbox' => ! empty( $atts['lightbox'] ), | ||
| ]; | ||
| if ( ! empty( $atts['lightbox'] ) ) { | ||
| $args['lightbox'] = true; | ||
| $lightbox_tag = AMP_HTML_Utils::build_tag( | ||
| 'amp-image-lightbox', | ||
| [ | ||
| 'id' => AMP_Base_Sanitizer::AMP_IMAGE_LIGHTBOX_ID, | ||
| 'layout' => 'nodisplay', | ||
| 'data-close-button-aria-label' => __( 'Close', 'amp' ), | ||
| ] | ||
| ); | ||
| /* We need to add lightbox tag, too. @todo Could there be a better alternative for this? */ | ||
| return $this->render( $args ) . $lightbox_tag; | ||
| } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is now using amp-lightbox-gallery as recommended by amphtml, so all that's needed is a |
||
|
|
||
| return $this->render( $args ); | ||
| } | ||
|
|
@@ -211,6 +203,7 @@ public function maybe_override_gallery( $html, $attributes ) { | |
| * @return string Rendered. | ||
| */ | ||
| public function render( $args ) { | ||
| $dom = new DOMDocument(); | ||
| $this->did_convert_elements = true; | ||
|
|
||
| $args = wp_parse_args( | ||
|
|
@@ -224,11 +217,7 @@ public function render( $args ) { | |
| return ''; | ||
| } | ||
|
|
||
| $max_aspect_ratio = 0; | ||
| $carousel_width = 0; | ||
| $carousel_height = 0; | ||
|
|
||
| $images = []; | ||
| $images = new ImageList(); | ||
| foreach ( $args['images'] as $props ) { | ||
| $image_atts = [ | ||
| 'src' => $props['url'], | ||
|
|
@@ -241,47 +230,38 @@ public function render( $args ) { | |
| $image_atts['srcset'] = $props['srcset']; | ||
| } | ||
|
|
||
| $this_aspect_ratio = $props['width'] / $props['height']; | ||
| if ( $this_aspect_ratio > $max_aspect_ratio ) { | ||
| $max_aspect_ratio = $this_aspect_ratio; | ||
| $carousel_width = $props['width']; | ||
| $carousel_height = $props['height']; | ||
| } | ||
|
|
||
| if ( ! empty( $args['lightbox'] ) ) { | ||
| $image_atts['lightbox'] = ''; | ||
| $image_atts['on'] = 'tap:' . AMP_Img_Sanitizer::AMP_IMAGE_LIGHTBOX_ID; | ||
| $image_atts['role'] = 'button'; | ||
| $image_atts['tabindex'] = 0; | ||
| } | ||
| $image = AMP_HTML_Utils::build_tag( | ||
| $image = AMP_DOM_Utils::create_node( | ||
| $dom, | ||
| 'amp-img', | ||
| $image_atts | ||
| ); | ||
|
|
||
| if ( ! empty( $props['href'] ) ) { | ||
| $image = AMP_HTML_Utils::build_tag( | ||
| $previous_image = $image; | ||
| $image = AMP_DOM_Utils::create_node( | ||
| $dom, | ||
| 'a', | ||
| [ | ||
| 'href' => $props['href'], | ||
| ], | ||
| $image | ||
| ] | ||
| ); | ||
| $image->appendChild( $previous_image ); | ||
| } | ||
|
|
||
| $images[] = $image; | ||
| $caption = isset( $props['id'] ) ? wp_get_attachment_caption( $props['id'] ) : ''; | ||
| $images->add( $image, $caption ); | ||
| } | ||
|
|
||
| return AMP_HTML_Utils::build_tag( | ||
| 'amp-carousel', | ||
| [ | ||
| 'width' => $carousel_width, | ||
| 'height' => $carousel_height, | ||
| 'type' => 'slides', | ||
| 'layout' => 'responsive', | ||
| ], | ||
| implode( PHP_EOL, $images ) | ||
| ); | ||
| $amp_carousel = new Carousel( $dom, $images ); | ||
| $carousel_node = $amp_carousel->get_dom_element(); | ||
|
|
||
| // Prevent an error in get_content_from_dom_node() when it calls $node->parentNode->insertBefore(). | ||
| $dom->appendChild( $carousel_node ); | ||
|
|
||
| return AMP_DOM_Utils::get_content_from_dom_node( $dom, $carousel_node ); | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,31 +5,16 @@ | |
| * @package AMP | ||
| */ | ||
|
|
||
| use Amp\AmpWP\Component\ImageList; | ||
| use Amp\AmpWP\Component\Carousel; | ||
|
|
||
| /** | ||
| * Class AMP_Gallery_Block_Sanitizer | ||
| * | ||
| * Modifies gallery block to match the block's AMP-specific configuration. | ||
| */ | ||
| class AMP_Gallery_Block_Sanitizer extends AMP_Base_Sanitizer { | ||
|
|
||
| /** | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no intended change to the Gallery block, only a refactoring of this logic into the class
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Now it's
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now, it's
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, it's For what it's worth, I do like |
||
| * Value used for width of amp-carousel. | ||
| * | ||
| * @since 1.0 | ||
| * | ||
| * @const int | ||
| */ | ||
| const FALLBACK_WIDTH = 600; | ||
|
|
||
| /** | ||
| * Value used for height of amp-carousel. | ||
| * | ||
| * @since 1.0 | ||
| * | ||
| * @const int | ||
| */ | ||
| const FALLBACK_HEIGHT = 480; | ||
|
|
||
| /** | ||
| * Tag. | ||
| * | ||
|
|
@@ -93,12 +78,6 @@ public function sanitize() { | |
| } | ||
|
|
||
| foreach ( $nodes as $node ) { | ||
| /** | ||
| * Element | ||
| * | ||
| * @var DOMElement $node | ||
| */ | ||
|
|
||
| // In WordPress 5.3, the Gallery block's <ul> is wrapped in a <figure class="wp-block-gallery">, so look for that node also. | ||
| $gallery_node = isset( $node->parentNode ) && AMP_DOM_Utils::has_class( $node->parentNode, self::$class ) ? $node->parentNode : $node; | ||
| $attributes = AMP_DOM_Utils::get_node_attributes_as_assoc_array( $gallery_node ); | ||
|
|
@@ -128,128 +107,33 @@ public function sanitize() { | |
| continue; | ||
| } | ||
|
|
||
| $images = []; | ||
| $images = new ImageList(); | ||
|
|
||
| // If it's not AMP lightbox, look for links first. | ||
| if ( ! $is_amp_lightbox ) { | ||
| foreach ( $node->getElementsByTagName( 'a' ) as $element ) { | ||
| $images[] = $element; | ||
| $images->add( $element, $this->possibly_get_caption_text( $element ) ); | ||
| } | ||
| } | ||
|
|
||
| // If not linking to anything then look for <amp-img>. | ||
| if ( empty( $images ) ) { | ||
| if ( 0 === count( $images ) ) { | ||
| foreach ( $node->getElementsByTagName( 'amp-img' ) as $element ) { | ||
| $images[] = $element; | ||
| $images->add( $element, $this->possibly_get_caption_text( $element ) ); | ||
| } | ||
| } | ||
|
|
||
| // Skip if no images found. | ||
| if ( empty( $images ) ) { | ||
| if ( 0 === count( $images ) ) { | ||
| continue; | ||
| } | ||
|
|
||
| list( $width, $height ) = $this->get_carousel_dimensions( $node ); | ||
|
|
||
| $amp_carousel = AMP_DOM_Utils::create_node( | ||
| $this->dom, | ||
| 'amp-carousel', | ||
| [ | ||
| 'width' => $width, | ||
| 'height' => $height, | ||
| 'type' => 'slides', | ||
| 'layout' => 'responsive', | ||
| ] | ||
| ); | ||
|
|
||
| foreach ( $images as $image ) { | ||
| $slide = AMP_DOM_Utils::create_node( | ||
| $this->dom, | ||
| 'div', | ||
| [ 'class' => 'slide' ] | ||
| ); | ||
|
|
||
| // Ensure the image fills the entire <amp-carousel>, so the possible caption looks right. | ||
| if ( 'amp-img' === $image->tagName ) { | ||
| $image->setAttribute( 'layout', 'fill' ); | ||
| $image->setAttribute( 'object-fit', 'cover' ); | ||
| } elseif ( isset( $image->firstChild->tagName ) && 'amp-img' === $image->firstChild->tagName ) { | ||
| // If the <amp-img> is wrapped in an <a>. | ||
| $image->firstChild->setAttribute( 'layout', 'fill' ); | ||
| $image->firstChild->setAttribute( 'object-fit', 'cover' ); | ||
| } | ||
|
|
||
| $possible_caption_text = $this->possibly_get_caption_text( $image ); | ||
| $slide->appendChild( $image ); | ||
|
|
||
| // Wrap the caption in a <div> and <span>, and append it to the slide. | ||
| if ( $possible_caption_text ) { | ||
| $caption_wrapper = AMP_DOM_Utils::create_node( | ||
| $this->dom, | ||
| 'div', | ||
| [ 'class' => 'amp-wp-gallery-caption' ] | ||
| ); | ||
| $caption_span = AMP_DOM_Utils::create_node( $this->dom, 'span', [] ); | ||
| $text_node = $this->dom->createTextNode( $possible_caption_text ); | ||
|
|
||
| $caption_span->appendChild( $text_node ); | ||
| $caption_wrapper->appendChild( $caption_span ); | ||
| $slide->appendChild( $caption_wrapper ); | ||
| } | ||
|
|
||
| $amp_carousel->appendChild( $slide ); | ||
| } | ||
|
|
||
| $gallery_node->parentNode->replaceChild( $amp_carousel, $gallery_node ); | ||
| $amp_carousel = new Carousel( $this->dom, $images ); | ||
| $gallery_node->parentNode->replaceChild( $amp_carousel->get_dom_element(), $gallery_node ); | ||
| } | ||
| $this->did_convert_elements = true; | ||
| } | ||
|
|
||
| /** | ||
| * Get carousel height by containing images. | ||
| * | ||
| * @param DOMElement $element The UL element. | ||
| * @return array { | ||
| * Dimensions. | ||
| * | ||
| * @type int $width Width. | ||
| * @type int $height Height. | ||
| * } | ||
| */ | ||
| protected function get_carousel_dimensions( $element ) { | ||
| /** | ||
| * Elements. | ||
| * | ||
| * @var DOMElement $image | ||
| */ | ||
| $images = $element->getElementsByTagName( 'amp-img' ); | ||
| $num_images = $images->length; | ||
|
|
||
| $max_aspect_ratio = 0; | ||
| $carousel_width = 0; | ||
| $carousel_height = 0; | ||
|
|
||
| if ( 0 === $num_images ) { | ||
| return [ self::FALLBACK_WIDTH, self::FALLBACK_HEIGHT ]; | ||
| } | ||
| foreach ( $images as $image ) { | ||
| if ( ! is_numeric( $image->getAttribute( 'width' ) ) || ! is_numeric( $image->getAttribute( 'height' ) ) ) { | ||
| continue; | ||
| } | ||
| $width = (float) $image->getAttribute( 'width' ); | ||
| $height = (float) $image->getAttribute( 'height' ); | ||
|
|
||
| $this_aspect_ratio = $width / $height; | ||
| if ( $this_aspect_ratio > $max_aspect_ratio ) { | ||
| $max_aspect_ratio = $this_aspect_ratio; | ||
| $carousel_width = $width; | ||
| $carousel_height = $height; | ||
| } | ||
| } | ||
|
|
||
| return [ $carousel_width, $carousel_height ]; | ||
| } | ||
|
|
||
| /** | ||
| * Set lightbox related attributes to <amp-img> within gallery. | ||
| * | ||
|
|
@@ -280,7 +164,7 @@ protected function add_lightbox_attributes_to_image_nodes( $element ) { | |
| * Gets the caption of an image, if it exists. | ||
| * | ||
| * @param DOMElement $element The element for which to search for a caption. | ||
| * @return string|null The caption for the image, or null. | ||
| * @return string The caption for the image, or ''. | ||
| */ | ||
| public function possibly_get_caption_text( $element ) { | ||
| $caption_tag = 'figcaption'; | ||
|
|
@@ -293,6 +177,6 @@ public function possibly_get_caption_text( $element ) { | |
| return $element->parentNode->nextSibling->textContent; | ||
| } | ||
|
|
||
| return null; | ||
| return ''; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,7 @@ | |
|
|
||
| <rule ref="WordPress.Files.FileName.InvalidClassFileName"> | ||
| <exclude-pattern>tests/*</exclude-pattern> | ||
| <exclude-pattern>src/*</exclude-pattern> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In addition to excluding the WordPress sniff for the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good idea.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So far, I couldn't find a sniff for this. But I'll look more. A sniff that this issue recomments, Slevomat, requires PHP ^7.2. Likewise, Suin requires >=7.1.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, good idea. I'll try that out.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great idea, 951cd3f adds that rule only for |
||
| <exclude-pattern>includes/admin/class-amp-customizer.php</exclude-pattern> | ||
| <exclude-pattern>includes/embeds/class-amp-dailymotion-embed.php</exclude-pattern> | ||
| <exclude-pattern>includes/embeds/class-amp-facebook-embed.php</exclude-pattern> | ||
|
|
@@ -46,6 +47,7 @@ | |
| <exclude-pattern>includes/actions/class-amp-paired-post-actions.php</exclude-pattern> | ||
| </rule> | ||
| <rule ref="WordPress.Files.FileName.NotHyphenatedLowercase"> | ||
| <exclude-pattern>src/*</exclude-pattern> | ||
| <exclude-pattern>includes/templates/single-amp_story.php</exclude-pattern> | ||
| </rule> | ||
| <rule ref="WordPress.NamingConventions.ValidVariableName"> | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This ensures that the classmaps for the files in
src/are regenerated withcomposer install. Otherwise, I think it's necessary to runcomposer install -o.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be removed, and a corresponding change should be made to the build process instead.
If an optimized autoloader is forced, then you'll have to constantly rebuild the plugin on filesystem changes even during development.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, it's removed in 4ac1d25. Next, I'll apply in in the build processes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c7d5d6e adds the
-oflag tocomposer installonly for production build processes and when creating a pre-release.Maybe it should should also be added to
.travis.yml, but I thought the optimization wouldn't be worth the trouble in debugging if the build is cached: