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

Experiment: Add native img opt-in to prevent conversion to amp-img/amp-anim #6518

Merged
merged 28 commits into from
Aug 11, 2021

Conversation

westonruter
Copy link
Member

@westonruter westonruter commented Aug 6, 2021

See #6443.

When amp_using_native_img is filtered to be true, discontinue converting img to amp-img/amp-anim but continue to supply any missing dimensions.

Once ampproject/amphtml#30442 is implemented and amp-img is deprecated, then this will become the default.

To prevent native img elements from being sanitized from the page, when native img is enabled, the page is forced into AMP Dev Mode and all img elements get data-ampdevmode attributes added to them. This is a temporary measure until img is valid. On such Dev Mode pages, when accessed by an unauthenticated user, the amp attribute will be removed from the page to prevent Google Search from flagging it as being invalid (since we already know this to be the case via the opt-in). This aspect fixes #5549.

@westonruter westonruter added this to the v2.2 milestone Aug 6, 2021
* @since 1.0
* @link https://github.com/WordPress/wordpress-develop/blob/1af1f65a21a1a697fb5f33027497f9e5ae638453/src/wp-content/themes/twentyseventeen/style.css#L2100
*/
public static function add_twentyseventeen_image_styles() {
Copy link
Member Author

Choose a reason for hiding this comment

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

This seemed to actually worsen the featured image header styling:

image

Removing the style fixes the vertical positioning and removes that grayness:

image

Copy link
Contributor

Choose a reason for hiding this comment

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

Assuming the left is non-AMP and the right AMP, I'm confused as to why in both instances the featured image look the same. Wouldn't the styles only affect the AMP version, and thus a difference on the AMP page?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry, yes, the left version is the non-AMP and the right is the AMP.

In the first screenshot (before) you can see this slight gray bar under the image. This goes away and the image is identical to the non-AMP version when these styles are removed. So it seems the original reason for this code being add in the first place was eliminated at some point, either through a change in AMP core or to the Twenty Seventeen theme.

In fact, what confuses me is that this is overriding the display to be inline-block whereas the GitHub link indicates that the theme has block. The issue may have been fixed with the introduction of disable-inline-width in #2036.

Comment on lines -815 to -817
.wp-block-image img {
display: block;
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This rule is redundant since d976798 added a amp-img:not([_]) { display: block } style which also applies to this image.

Comment on lines -5 to -8
margin-right: 0;
}

.wp-playlist .wp-playlist-current-item amp-img {
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure what was going on here originally, but since img gets converted to amp-img the result is the margin-right:0 would get immediately overridden by the subsequent margin-right: 10px. So this is just removing an overridden rule.

.amp-wp-enforced-sizes {
amp-img.amp-wp-enforced-sizes,
amp-anim.amp-wp-enforced-sizes,
.amp-wp-unknown-size {
Copy link
Member Author

Choose a reason for hiding this comment

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

For amp-img and img alike, having object-fit:contain is really only relevant when the original dimensions are unknown. Otherwise, this is currently resulting in overriding object-fit on any processed image. This behavior is retained for amp-img/amp-anim for now, but when native img are enabled we'll only apply it to images with unknown size dimensions.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is especially important to retain for amp-img/amp-anim specifically since these custom elements lack intrinsic object sizing in the browser, meaning that if the element has display:block the image could end up getting stretched.

Comment on lines -1347 to +1337
.featured-content .post-thumbnail amp-img {
.featured-content .post-thumbnail .wp-post-image {
Copy link
Member Author

Choose a reason for hiding this comment

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

This could be changed instead from amp-img to just img, but since the image will have the wp-post-image class we can target it that way instead.

@@ -188,7 +190,6 @@ protected static function get_theme_features_config( $theme_slug ) {
],
'force_fixed_background_support' => [],
'add_twentyseventeen_masthead_styles' => [],
'add_twentyseventeen_image_styles' => [],
Copy link
Member Author

Choose a reason for hiding this comment

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

See why removed below.

@westonruter westonruter changed the title Add native img opt-in to prevent conversion to amp-img/amp-anim Experiment: Add native img opt-in to prevent conversion to amp-img/amp-anim Aug 7, 2021
@westonruter westonruter marked this pull request as ready for review August 7, 2021 01:35
@github-actions
Copy link
Contributor

github-actions bot commented Aug 7, 2021

Plugin builds for 9ed515d are ready 🛎️!

@westonruter
Copy link
Member Author

@pierlon Interesting failure on the PHP 8 build:

image

@westonruter westonruter mentioned this pull request Aug 9, 2021
11 tasks
* @return array|null Array comprising of the theme config if its slug is found, null if it is not.
*/
protected static function get_theme_features_config( $theme_slug ) {
protected static function get_theme_features_config( $theme_slug, $args = [] ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason for passing around $args instead of using $this->args?

Copy link
Member Author

@westonruter westonruter Aug 10, 2021

Choose a reason for hiding this comment

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

Yes, because at this point it's a static method (so it hasn't been instantiated yet).

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh right I didn't notice the static method 😅.

return;
}

// @todo This was introduced in <https://github.com/ampproject/amp-wp/commit/e1c7462> but it doesn't seem to have any effect.
Copy link
Contributor

Choose a reason for hiding this comment

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

Haven't noticed any discrepancies with this either.

* @since 1.0
* @link https://github.com/WordPress/wordpress-develop/blob/1af1f65a21a1a697fb5f33027497f9e5ae638453/src/wp-content/themes/twentyseventeen/style.css#L2100
*/
public static function add_twentyseventeen_image_styles() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Assuming the left is non-AMP and the right AMP, I'm confused as to why in both instances the featured image look the same. Wouldn't the styles only affect the AMP version, and thus a difference on the AMP page?

@@ -136,7 +136,7 @@ public function filter_validated_url_status_actions( $actions, WP_Post $post ) {
* Initialize frontend.
*/
public function init_frontend() {
if ( ! amp_is_available() || ! amp_is_dev_mode() ) {
if ( ! amp_is_available() || ! amp_is_dev_mode() || ! is_user_logged_in() ) {
Copy link
Member Author

Choose a reason for hiding this comment

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

@pierlon The is_user_logged_in() condition is being added here and duplicated twice in MobileRedirection, which I'm not happy about. I played with extracting that into a helper method of PairedBrowsing in #6526. Curious about your thoughts given how this essentially makes it a Conditional-“light” service.

Copy link
Contributor

Choose a reason for hiding this comment

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

How about adding amp_is_dev_mode() && is_user_logged_in() to is_needed(), and then in MobileRedirection check to see if the admin.paired_browsing service exists in the service container via Services::has('admin.paired_browsing').

With that implemented, in #6526 you could then remove PairedBrowsing from the MobileRedirection constructor, and replace instances of $this->paired_browsing->is_available() with Services::has('admin.paired_browsing').

cc @schlessera

Copy link
Member 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 thought. I wondered about putting those checks inside is_needed but I didn't think it would work because is_user_logged_in() needs to run at or later than set_current_user. It seems this is doable by making the service Delayed however, and using init or wp_loaded as the action. I'm giving it a try.

Copy link
Member Author

@westonruter westonruter Aug 10, 2021

Choose a reason for hiding this comment

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

OK, that works pretty well! See 35bed57. The only problem is with testing. Namely, MobileRedirectionTest fails in test_is_using_client_side_redirection and test_add_mobile_version_switcher because the PairedBrowsing service isn't registered. Any thoughts on that?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've got something working to test, although it doesn't feel super elegant given the private access: 8097ac9. But it seems to work well.

Copy link
Member Author

Choose a reason for hiding this comment

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

But that registration happens at setUp before the test runs, so by the time the test tries doing anything the service container is already populated.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, and at that point the registration of the PairedBrowsing service would have been delayed to occur at the wp_loaded action.

It seems that the service container returned by the Services helper is not the same instance as $this->container in DependencyInjectedTestCase. Commenting the line that overrides self::container in the Services helper will cause the service container to be retrieved from $this->plugin in DependencyInjectedTestCase, and that seems to work:

diff --git a/tests/php/src/MobileRedirectionTest.php b/tests/php/src/MobileRedirectionTest.php
--- a/tests/php/src/MobileRedirectionTest.php	(revision 35bed57881c7782bfe660a8f24289f250f595771)
+++ b/tests/php/src/MobileRedirectionTest.php	(date 1628632586105)
@@ -2,6 +2,7 @@
 
 namespace AmpProject\AmpWP\Tests;
 
+use AmpProject\AmpWP\Admin\PairedBrowsing;
 use AmpProject\AmpWP\Admin\ReaderThemes;
 use AmpProject\AmpWP\Infrastructure\Registerable;
 use AmpProject\AmpWP\Infrastructure\Service;
@@ -9,6 +10,7 @@
 use AmpProject\AmpWP\PairedRouting;
 use AmpProject\AmpWP\QueryVar;
 use AmpProject\AmpWP\MobileRedirection;
+use AmpProject\AmpWP\Services;
 use AmpProject\AmpWP\Tests\Helpers\AssertContainsCompatibility;
 use AMP_Options_Manager;
 use AMP_Theme_Support;
@@ -429,10 +431,17 @@
 
 		wp_set_current_user( self::factory()->user->create( [ 'role' => 'administrator' ] ) );
 		add_filter( 'amp_dev_mode_enabled', '__return_true' );
+
+		// Trigger `PairedBrowsing` service to be registered.
+		do_action('wp_loaded');
+
 		$this->assertTrue( $this->instance->is_using_client_side_redirection() );
 		remove_filter( 'amp_dev_mode_enabled', '__return_true' );
 		wp_set_current_user( 0 );
 
+		// Remove `PairedBrowsing` service from the service container. Attempting to
+       // remove it via `$this->container->offsetUnset( 'admin.paired_browsing' )` doesn't work.
+		Services::get_container()->offsetUnset( 'admin.paired_browsing' );
+
 		$this->assertFalse( $this->instance->is_using_client_side_redirection() );
 		global $wp_customize;
 		require_once ABSPATH . 'wp-includes/class-wp-customize-manager.php';
diff --git a/tests/php/src/DependencyInjectedTestCase.php b/tests/php/src/DependencyInjectedTestCase.php
--- a/tests/php/src/DependencyInjectedTestCase.php	(revision 35bed57881c7782bfe660a8f24289f250f595771)
+++ b/tests/php/src/DependencyInjectedTestCase.php	(date 1628632830675)
@@ -51,7 +51,10 @@
 		// The static Services helper has to be modified to use the same objects
 		// as the ones that are injected into the tests.
 		$this->set_private_property( Services::class, 'plugin', $this->plugin );
-		$this->set_private_property( Services::class, 'container', $this->container );
+
+//		Let the Services helper retrieve the container directly from `$this->plugin`.
+//		$this->set_private_property( Services::class, 'container', $this->container );
+
 		$this->set_private_property( Services::class, 'injector', $this->injector );
 	}
 

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah nevermind, uncommenting that line would mean Services::$container is the original service container that was created when the plugin was being bootstrapped. The issue then would be why is the PairedBrowsing service being registered in the original service container and not the one created for the test?

Copy link
Member Author

Choose a reason for hiding this comment

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

Is not the issue that PairedBrowsing is not being registered at all because its is_needed method returns false during setUp?

Copy link
Contributor

@pierlon pierlon Aug 10, 2021

Choose a reason for hiding this comment

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

Oh right, I forgot to add this line just before calling do_action('wp_loaded'):

AMP_Options_Manager::update_option( Option::THEME_SUPPORT, AMP_Theme_Support::TRANSITIONAL_MODE_SLUG );

Which would then cause is_needed to return true.

Copy link
Contributor

@pierlon pierlon left a comment

Choose a reason for hiding this comment

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

LGTM!

@delawski
Copy link
Collaborator

QA Passed

After adding a filter like (notice the change of the filter name compared to the PR description):

add_filter( 'amp_native_img_used', '__return_true' );

img elements were not converted to amp-img/amp-anim. This happens both in Transitional and Standard mode (with sandboxing enabled, too).

Without filter With filter
Screenshot 2021-12-13 at 13 40 20 Screenshot 2021-12-13 at 13 40 36

@westonruter westonruter added the Changelogged Whether the issue/PR has been added to release notes. label Dec 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bento Changelogged Whether the issue/PR has been added to release notes. Sandboxing Experiment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Facilitate documents in AMP Dev Mode to be unmarked as AMP pages when site is in Standard mode
3 participants