filter_post_gallery_markup( $html, $attrs ); $recursing = false; } return $html; } /** * Filter the output of gallery_shortcode(). * * @param string $html Markup to filter. * @param array $attrs Shortcode attributes. * @return string Markup for the gallery. */ protected function filter_post_gallery_markup( $html, $attrs ) { // Use for the gallery if requested via amp-carousel shortcode attribute, or use by default if in legacy Reader mode. // In AMP_Gallery_Block_Sanitizer, this is referred to as carousel_required. $is_carousel = isset( $attrs['amp-carousel'] ) ? rest_sanitize_boolean( $attrs['amp-carousel'] ) : amp_is_legacy(); $is_lightbox = isset( $attrs['amp-lightbox'] ) && rest_sanitize_boolean( $attrs['amp-lightbox'] ); if ( ! $is_carousel && ! $is_lightbox ) { return $html; } if ( $is_carousel ) { $gallery_size = isset( $attrs['size'] ) ? $attrs['size'] : null; if ( $gallery_size && 'thumbnail' === $gallery_size ) { /* * If the 'gallery' shortcode has a `size` attribute of `thumbnail`, prevent outputting an . * That will often get thumbnail images around 150 x 150, * while the usually has a width of 600 and a height of 480. * That often means very low-resolution images. * So fall back to the normal 'gallery' shortcode callback, gallery_shortcode(). */ return $html; } if ( ! $gallery_size ) { // Default to `large` if no `size` attribute is specified. $attrs['size'] = 'large'; } } if ( $is_lightbox ) { // Prevent wrapping the images in anchor tags if a lightbox is specified. If that is done the link will get // preference over the lightbox when the image is clicked. $attrs['link'] = 'none'; } // Use `data` attributes to indicate which options are configured for the embed. These indications are later // processed during sanitization of the embed in `::sanitize_raw_embeds`. $filter_gallery_style = static function ( $style ) use ( $is_carousel, $is_lightbox ) { $data_attrs = []; if ( $is_lightbox ) { $data_attrs[] = 'data-amp-lightbox="true"'; } if ( $is_carousel ) { $data_attrs[] = 'data-amp-carousel="true"'; } return preg_replace( '/(?<=xpath->query( '//div[ contains( concat( " ", normalize-space( @class ), " " ), " gallery " ) and ( @data-amp-carousel or @data-amp-lightbox ) ]' ); /** @var DOMElement $node */ foreach ( $nodes as $node ) { $is_carousel = $node->hasAttribute( 'data-amp-carousel' ) && rest_sanitize_boolean( $node->getAttribute( 'data-amp-carousel' ) ); $is_lightbox = $node->hasAttribute( 'data-amp-lightbox' ) && rest_sanitize_boolean( $node->getAttribute( 'data-amp-lightbox' ) ); $img_elements = $node->getElementsByTagName( 'img' ); $this->process_gallery_embed( $is_carousel, $is_lightbox, $node, $img_elements ); } } /** * Get the caption element for the specified image element. * * @param DOMElement $img_element Image element. * @return DOMElement|null The caption element, otherwise `null` if it could not be found. */ protected function get_caption_element( DOMElement $img_element ) { $parent_element = $this->get_parent_container_for_image( $img_element ); if ( ! $parent_element instanceof DOMElement ) { return null; } // The caption should be next immediate element located next to the parent container of the image. $caption_element = $parent_element->nextSibling; while ( $caption_element && ( ! $caption_element instanceof DOMElement || ! AMP_DOM_Utils::has_class( $caption_element, 'wp-caption-text' ) ) ) { $caption_element = $caption_element->nextSibling; } if ( $caption_element instanceof DOMElement && Tag::FIGCAPTION !== $caption_element->nodeName ) { // Transform the caption element into a `figcaption`. This not only allows the `amp-lightbox` to correctly // detect and display the caption, but it is also semantically correct as the parent element will be a `figure`. $figcaption_element = AMP_DOM_Utils::create_node( Document::fromNode( $caption_element ), Tag::FIGCAPTION, [] ); while ( $caption_element->firstChild ) { $figcaption_element->appendChild( $caption_element->firstChild ); } $caption_element = $figcaption_element; } return $caption_element instanceof DOMElement ? $caption_element : null; } /** * Get the parent container for the specified image element. * * @param DOMElement $image_element Image element. * @return DOMElement|null The parent container, otherwise `null` if it could not be found. */ protected function get_parent_container_for_image( DOMElement $image_element ) { $parent_element = $image_element->parentNode; while ( $parent_element && ( ! $parent_element instanceof DOMElement || ! AMP_DOM_Utils::has_class( $parent_element, 'gallery-icon' ) ) ) { $parent_element = $parent_element->parentNode; } return $parent_element; } }