Skip to content
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
1b34cef
Enable captions on Gallery shortcodes
kienstra Oct 29, 2019
dde1e46
Rename a $images to $images_and_captions for clarity
kienstra Oct 29, 2019
a48d974
Address a PHPCS issue with array destructuring
kienstra Oct 29, 2019
5c7334b
Rename get_carousel_dimensions() to get_dimensions()
kienstra Oct 29, 2019
641e008
Make the $dom property protected, improve a DocBlock
kienstra Oct 29, 2019
cbd925b
Add the parameter name to the @param tag
kienstra Oct 29, 2019
5e07516
Fix a typo in 'associative'
kienstra Oct 29, 2019
93246e8
Use <amp-lightbox-gallery> for lightboxes
kienstra Oct 29, 2019
08404be
Exit if ! $images, before running count( $images )
kienstra Oct 29, 2019
0caa844
Merge branch 'develop' into add/gallery-shortcode-captions
kienstra Oct 29, 2019
2c32f41
Merge branch 'develop' into add/gallery-shortcode-captions
kienstra Nov 7, 2019
22ae686
Merge branch 'develop' of github.com:ampproject/amp-wp into add/galle…
westonruter Nov 11, 2019
82b428a
Change @since tag from 1.4.1 to 1.5.0
kienstra Nov 11, 2019
d3ba063
Commit Alain's classes to represent and collect images
kienstra Nov 11, 2019
93aa3ea
Account for 0.0 or 0 width or height in dimensions function
kienstra Nov 11, 2019
6ba9bdb
Fix phpcs issues that caused a failed Travis build
kienstra Nov 11, 2019
2ed1653
Update return tag, as it no longer returns null
kienstra Nov 11, 2019
5794193
Move the image list classes to an AMP namespace in amp/
kienstra Nov 15, 2019
78b0c75
Might revert: try adding composer dump-autoload to .travis.yml
kienstra Nov 15, 2019
3125261
Add use statements to the top of some files
kienstra Nov 15, 2019
67c7590
Revert edit to .travis.yml, try another approach
kienstra Nov 15, 2019
692d14b
Move the AMP_Carousel class to the AMP namespace
kienstra Nov 15, 2019
8eb54a8
Add internal tag to class Carousel, move tags up in other classes
kienstra Nov 15, 2019
07cfc97
Align param tag descriptions, pass '' instead of null
kienstra Nov 15, 2019
c0a5e05
Merge branch 'develop' into add/gallery-shortcode-captions
kienstra Nov 15, 2019
7e206ef
Move new classes to src/component directory, per discussion
kienstra Nov 19, 2019
3f0ee52
Import classes, preventing need for the \ operator
kienstra Nov 19, 2019
2b4a98f
In Carousel, accept Image_List in constructor
kienstra Nov 19, 2019
284b328
Remove parameter from Carousel::get_dimensions()
kienstra Nov 19, 2019
d7fdbd2
Change directory to Component, make classes PascalCase
kienstra Nov 19, 2019
be2b4e2
Correct covers and var tags
kienstra Nov 19, 2019
12c6d26
Remove the Image class, and simply use a DOMElement
kienstra Nov 21, 2019
951cd3f
Add a rule to enforce PascalCase file names in src/*
kienstra Nov 21, 2019
12f062e
Merge branch 'develop' into add/gallery-shortcode-captions
kienstra Nov 21, 2019
92a764e
Rename ImageList to DOMElementList
kienstra Nov 22, 2019
7b603ea
Commit Weston's suggestion to change the package to Amp\AmpWP
kienstra Nov 22, 2019
305e471
Change other package names
kienstra Nov 22, 2019
8de2340
Revert cloning at least for now, remove test for immutability
kienstra Nov 23, 2019
3cdd86f
Clone the DOMElementList in add(), and return the clone
kienstra Nov 24, 2019
097d1b8
Update the DocBlock of DOMElementList::add()
kienstra Nov 24, 2019
873c41a
Edit DocBlocks, include correcting var tag
kienstra Nov 24, 2019
38df209
Make $elements propert private again
kienstra Nov 25, 2019
f48d09b
Commit Alain's suggestion to make the Carousel class final
kienstra Nov 25, 2019
5a8749c
Update src/Component/Carousel.php
kienstra Nov 25, 2019
0355530
Commit Alain's suggestion to make `$images` private
kienstra Nov 25, 2019
450f9cd
In Carousel, rename $images to $slides
kienstra Nov 25, 2019
0ae904e
Also rename images to slides in Test_Carousel
kienstra Nov 25, 2019
4ac1d25
Remove optimize-autoloader from composer.json config, will apply this…
kienstra Nov 25, 2019
478f71e
Make get_dimensions() private instead of public
kienstra Nov 25, 2019
c7d5d6e
Add the -o flag to composer install for production build processes
kienstra Nov 26, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"ext-zip": "Enables the use of ZipArchive to export AMP Stories."
},
"config": {
"optimize-autoloader": true,

@kienstra kienstra Nov 15, 2019

Copy link
Copy Markdown
Contributor Author

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 with composer install. Otherwise, I think it's necessary to run composer install -o.

Copy link
Copy Markdown
Collaborator

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.

Copy link
Copy Markdown
Contributor Author

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

c7d5d6e adds the -o flag to composer install only 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:

The performance gains are not worth the trouble in a development setting.

"platform": {
"php": "5.4"
},
Expand All @@ -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/"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See questions below about whether root namespace should be AMP or Amp. That being said, should the package be AmpWP or AMP_WP? I see WP-CLI uses WP_CLI. /cc @schlessera

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Discussed in #3810

}
}
}
68 changes: 24 additions & 44 deletions includes/embeds/class-amp-gallery-embed.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
* @package AMP
*/

use Amp\AmpWP\Component\ImageList;
use Amp\AmpWP\Component\Carousel;

/**
* Class AMP_Gallery_Embed_Handler
*
Expand Down Expand Up @@ -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;
}

@kienstra kienstra Oct 29, 2019

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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 lightbox attribute on the <amp-img> or <amp-carousel>. This plugin automatically adds the amp-lightbox-gallery component script.


return $this->render( $args );
}
Expand Down Expand Up @@ -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(
Expand All @@ -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'],
Expand All @@ -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 );
}

/**
Expand Down
140 changes: 12 additions & 128 deletions includes/sanitizers/class-amp-gallery-block-sanitizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

/**

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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 AMP_Carousel.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

(Now it's AMP\Carousel)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Now, it's Amp\AmpWp\Component\Carousel

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Actually, it's Amp\AmpWP (capital_P_dangit? 😄)

For what it's worth, I do like AmpWP more than AmpWp.

* 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.
*
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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.
*
Expand Down Expand Up @@ -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';
Expand All @@ -293,6 +177,6 @@ public function possibly_get_caption_text( $element ) {
return $element->parentNode->nextSibling->textContent;
}

return null;
return '';
}
}
2 changes: 2 additions & 0 deletions phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

<rule ref="WordPress.Files.FileName.InvalidClassFileName">
<exclude-pattern>tests/*</exclude-pattern>
<exclude-pattern>src/*</exclude-pattern>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In addition to excluding the WordPress sniff for the src directory, what about including another sniff that applies only for the src directory to enforce PSR-4 filenames?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's a good idea.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Ah, good idea. I'll try that out.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Great idea, 951cd3f adds that rule only for src/*

<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>
Expand All @@ -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">
Expand Down
Loading