profile
viewpoint
Weston Ruter westonruter @Google Portland, OR, USA https://weston.ruter.net/ Googler 👨🏻‍💻 @amphtml, PWA, & open web; @WordPress core team. Daddy² & husband. Go by 🏃🏻🚴🏻🚌🚈 Philologist & hispanohablante [ˈwɛsˌtn̩ ˈɹuːˌɾɚ]

GoogleChrome/web-vitals 1795

Essential metrics for a healthy site.

ampproject/amp-wp 1582

Enable AMP on your WordPress site, the WordPress way.

google/site-kit-wp 932

Site Kit is a one-stop solution for WordPress users to use everything Google has to offer to make them successful on the web.

ampproject/amp.dev 399

The AMP Project Website.

GoogleChromeLabs/pwa-wp 398

WordPress feature plugin to bring Progressive Web Apps (PWA) to Core

google/web-stories-wp 365

Web Stories for WordPress

GoogleChromeLabs/wp-sitemaps 93

Proposal to integrate basic XML Sitemaps in WordPress Core

GoogleChromeLabs/wordpressdev 61

WordPress development environment for core, plugins, and themes, based on Lando.

luehrsenheinrich/wp-quicklink 49

The WordPress plugin for quicklink. ⚡️Faster subsequent page-loads by prefetching in-viewport links during idle time.

GoogleChromeLabs/wp-native-lazyload 48

WordPress plugin to lazy-load media using the native browser feature.

pull request commentampproject/amp-wp

Run phpstan on staged PHP source files

I did test. It caught an issue with a staged file.

pierlon

comment created time in 11 hours

issue commentAutomattic/jetpack

Blocks: AMP Compatibility

Remaining fix for Image Compare block: #17254

jeherve

comment created time in 11 hours

issue commentAutomattic/jetpack

Image Compare Block: No caption in AMP

PR to fix: #17254

fresatomica

comment created time in 11 hours

PR opened Automattic/jetpack

Preserve block wrapper and caption for Image Compare block in AMP

Fixes #16858 See #14395

The Image Compare block on AMP pages was not including not only the caption but also the containing figure.wp-block-jetpack-image-compare wrapper element. This PR fixes that problem by just replacing the div.juxtapose element inside the block $content with the amp-image-slider element, rather than just rendering just the amp-image-slider alone.

Before

image

AMP markup for block:

<amp-image-slider layout="responsive" width="1536" height="2048">
    <amp-img id="4175" src="https://wordpressdev.lndo.site/content/uploads/2020/09/fire-before.jpg" alt="" layout="fill"></amp-img>
    <amp-img id="4176" src="https://wordpressdev.lndo.site/content/uploads/2020/09/fire-after.jpg" alt="" layout="fill"></amp-img>
</amp-image-slider>
After

image

AMP markup for block:

<figure class="wp-block-jetpack-image-compare">
    <amp-image-slider layout="responsive" width="1536" height="2048"> 
        <amp-img id="4175" src="https://wordpressdev.lndo.site/content/uploads/2020/09/fire-before.jpg" alt="" layout="fill"></amp-img>
        <amp-img id="4176" src="https://wordpressdev.lndo.site/content/uploads/2020/09/fire-after.jpg" alt="" layout="fill"></amp-img>
    </amp-image-slider>
    <figcaption>Before and after the wildfire smoke in Portland, Oregon</figcaption>
</figure>

Changes proposed in this Pull Request:

<!--- Explain what functional changes your PR includes -->

  • Include caption and original block wrapper element for Image Compare block on AMP pages.

Jetpack product discussion

<!-- If you're an Automattician, include a shortlink to the p2 discussion with Jetpack Product here. --> <!-- Make sure any changes to existing products have been discussed and agreed upon -->

Does this pull request change what data or activity we track or use?

<!--- If so, please add the "[Status] Needs Privacy Updates" label and explain what changes there are. --> <!--- Check existing Jetpack support documents for a preview of the information we need. -->

Testing instructions:

<!-- If you were reviewing this PR, how would you like the instructions to be presented? --> <!-- Please include detailed testing steps, explaining how to test your change. --> <!-- Bear in mind that context you working on is not obvious for everyone. --> <!-- Adding "simple" configuration steps will help reviewers to get to your PR as quickly as possible. --> <!-- "Before / After" screenshots can also be very helpful when the change is visual. -->

  1. Add an Image Compare block to a post, along with a caption.
  2. View the post on an AMP page.

Proposed changelog entry for your changes:

<!-- Please do not leave this empty. If no changelog entry needed, state as such. -->

  • Preserve caption for Image Compare blocks on AMP pages.
+6 -2

0 comment

1 changed file

pr created time in 11 hours

create barnchwestonruter/jetpack

branch : fix/amp-image-compare-caption

created branch time in 12 hours

issue commentAutomattic/jetpack

Image Compare Block: AMP Errors

In looking at \Automattic\Jetpack\Extensions\ImageCompare\render_amp(), the issue seems to be that it is supplying no width or height when there is no width or height supplied:

https://github.com/Automattic/jetpack/blob/3a551cbe3a56b93a89ed60a012059a865ee1fbf1/extensions/blocks/image-compare/image-compare.php#L61-L63

This is not valid AMP, as all elements need to have sizing. I suggest a fallback width/height of 1. Since since the layout is responsive, this will have the effect of making the element sized to fit its container as a square (1:1 aspect ratio).

kraftbj

comment created time in 12 hours

Pull request review commentAutomattic/jetpack

Image Compare: set width and height attributes for block's images

 function render_amp( $attr ) { 	$img_after  = $attr['imageAfter'];  	return sprintf(-		'<amp-image-slider layout="responsive" width="%1$d" height="%2$d"> <amp-img id="%3$d" src="%4$s" alt="%5$s" layout="fill"></amp-img> <amp-img id="%6$d" src="%7$s" alt="%8$s" layout="fill"></amp-img></amp-image-slider>',-		absint( $img_before['width'] ),-		absint( $img_before['height'] ),+		'<amp-image-slider layout="responsive"%1$s%2$s> <amp-img id="%3$d" src="%4$s" alt="%5$s" layout="fill"></amp-img> <amp-img id="%6$d" src="%7$s" alt="%8$s" layout="fill"></amp-img></amp-image-slider>',+		! empty( $img_before['width'] ) ? ' width="' . absint( $img_before['width'] ) . '"' : '',+		! empty( $img_before['height'] ) ? ' height="' . absint( $img_before['height'] ) . '"' : '',

This caused a regression: #16093.

Note: In AMP if the width/height are not available, instead of omitting the attributes (since they are required in AMP), the solution is to provide fallback width and height. See proposed fix in #17253.

jeherve

comment created time in 12 hours

PullRequestReviewEvent

issue commentAutomattic/jetpack

Image Compare Block: AMP Errors

PR to fix: #17253

kraftbj

comment created time in 12 hours

issue commentAutomattic/jetpack

Blocks: AMP Compatibility

PR to fix part of Image Compare: #17253

jeherve

comment created time in 12 hours

PR opened Automattic/jetpack

Fix Image Compare block in AMP when width/height are not available

Fixes #16093 See #14395

All elements in AMP need to have dimensions defined up-front so that the page will have static layout to avoid CLS (Cumulative Layout Shift). When no width or height is available for the Image Compare block, instead of omitting the width/height for the amp-image-slider component, the correct AMP fallback is to provide fallback dimensions. Since we don't know what the image dimension is, providing an aspect ratio of 1:1 seems to make sense.

Changes proposed in this Pull Request:

<!--- Explain what functional changes your PR includes -->

  • Ensure fallback dimensions are provided to Image Compare block when image size is not available

Jetpack product discussion

<!-- If you're an Automattician, include a shortlink to the p2 discussion with Jetpack Product here. --> <!-- Make sure any changes to existing products have been discussed and agreed upon -->

Does this pull request change what data or activity we track or use?

<!--- If so, please add the "[Status] Needs Privacy Updates" label and explain what changes there are. --> <!--- Check existing Jetpack support documents for a preview of the information we need. -->

Testing instructions:

<!-- If you were reviewing this PR, how would you like the instructions to be presented? --> <!-- Please include detailed testing steps, explaining how to test your change. --> <!-- Bear in mind that context you working on is not obvious for everyone. --> <!-- Adding "simple" configuration steps will help reviewers to get to your PR as quickly as possible. --> <!-- "Before / After" screenshots can also be very helpful when the change is visual. -->

Add an Image Compare block to a post and view that post on an AMP page.

I'm not sure entirely why the width or height weren't available when calling render_amp(), so the only way I know to test this is to forcibly unset them when calling the function:

unset( $img_before['width'], $img_before['height'] );

Proposed changelog entry for your changes:

<!-- Please do not leave this empty. If no changelog entry needed, state as such. -->

  • Fix AMP implementation of Image Compare block
+12 -3

0 comment

1 changed file

pr created time in 12 hours

issue commentAutomattic/jetpack

Revue widget makes illegal cross-domain call in AMP mode

This will be fixed with https://github.com/ampproject/amp-wp/issues/4191

The proposed solution I've worked on (which needs to be picked up again) is to implement a local proxy endpoint when a form is pointing to an external domain so that the CORS headers aren't an issue. This will also ensure that redirects work properly. See https://github.com/ampproject/amp-wp/pull/4212.

gravityrail

comment created time in 12 hours

issue commentampproject/amp-wp

Issue with Genesis eNews Extended form

This is also needed by the Revue widget in Jetpack: https://github.com/Automattic/jetpack/issues/16922.

chvillanuevap

comment created time in 12 hours

issue commentAutomattic/jetpack

Blocks: AMP Compatibility

PR for Contact Form: #17252

jeherve

comment created time in 13 hours

issue commentAutomattic/jetpack

Form block: Add AMP support

@brbrr Here's a PR to fix that: #17252

brbrr

comment created time in 13 hours

PR opened Automattic/jetpack

Reviewers
Fix styling of Contact Forms on the legacy AMP post template in Reader mode

Fixes #15981 See #14395

Fixes styling of Contact Forms on the legacy AMP post template in Reader mode. This is only an issue in legacy Reader mode because the old post templates do not have The Loop, and thus loop_start does not fire.

Before After
contact-form-before contact-form-after

Changes proposed in this Pull Request:

<!--- Explain what functional changes your PR includes -->

  • Fix styling of Contact Forms in legacy AMP Reader mode post templates.

Jetpack product discussion

<!-- If you're an Automattician, include a shortlink to the p2 discussion with Jetpack Product here. --> <!-- Make sure any changes to existing products have been discussed and agreed upon -->

Does this pull request change what data or activity we track or use?

<!--- If so, please add the "[Status] Needs Privacy Updates" label and explain what changes there are. --> <!--- Check existing Jetpack support documents for a preview of the information we need. -->

Testing instructions:

<!-- If you were reviewing this PR, how would you like the instructions to be presented? --> <!-- Please include detailed testing steps, explaining how to test your change. --> <!-- Bear in mind that context you working on is not obvious for everyone. --> <!-- Adding "simple" configuration steps will help reviewers to get to your PR as quickly as possible. --> <!-- "Before / After" screenshots can also be very helpful when the change is visual. -->

  1. Add a contact form to a post.
  2. Activate the AMP plugin.
  3. Switch to Reader mode and select the "AMP Legacy" Reader theme.
  4. View the post as AMP.

Proposed changelog entry for your changes:

<!-- Please do not leave this empty. If no changelog entry needed, state as such. -->

  • Fix styling of Contact Forms in legacy AMP Reader mode post templates.
+1 -0

0 comment

1 changed file

pr created time in 13 hours

create barnchwestonruter/jetpack

branch : fix/contact-form-amp-styling

created branch time in 13 hours

Pull request review commentAutomattic/jetpack

Google Calendar block: Fix full width support

 function register_block() {  * @return string  */ function load_assets( $attr ) {-	$width   = isset( $attr['width'] ) ? $attr['width'] : '800'; 	$height  = isset( $attr['height'] ) ? $attr['height'] : '600'; 	$url     = isset( $attr['url'] ) 		? \Jetpack_Gutenberg::validate_block_embed_url( $attr['url'], array( 'calendar.google.com' ) ) : 		''; 	$classes = \Jetpack_Gutenberg::block_classes( 'google-calendar', $attr ); +	\Jetpack_Gutenberg::load_assets_as_required( 'google-calendar' );+ 	if ( empty( $url ) ) { 		return; 	}  	if ( class_exists( 'Jetpack_AMP_Support' ) && \Jetpack_AMP_Support::is_amp_request() ) { 		return sprintf(-			'<div class="%1$s"><amp-iframe src="%2$s" frameborder="0" style="border:0" scrolling="no" width="%3$d" height="%4$d" sandbox="allow-scripts allow-same-origin" layout="responsive"></amp-iframe></div>',+			'<div class="%1$s"><amp-iframe src="%2$s" frameborder="0" style="border:0" scrolling="no" height="%3$d" sandbox="allow-scripts allow-same-origin" layout="responsive"></amp-iframe></div>',

This change appears to have broken Google Calendar on AMP pages, since there is no width defined, and the layout was not changed from responsive to fixed-height. Opened PR to fix in #17251.

apeatling

comment created time in 13 hours

PullRequestReviewEvent

issue commentAutomattic/jetpack

Blocks: AMP Compatibility

PR for Google Calendar block: https://github.com/Automattic/jetpack/pull/17251

jeherve

comment created time in 13 hours

PR opened Automattic/jetpack

Fix AMP compatibility for Google Calendar block

See #14395

Given this post_content:

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

<!-- wp:jetpack/google-calendar {"url":"https://calendar.google.com/calendar/embed?src=askenergy%40oregon.gov\u0026ctz=America/Los_Angeles"} -->
<a href="https://calendar.google.com/calendar/embed?src=askenergy%40oregon.gov&amp;ctz=America/Los_Angeles" class="wp-block-jetpack-google-calendar">https://calendar.google.com/calendar/embed?src=askenergy%40oregon.gov&amp;ctz=America/Los_Angeles</a>
<!-- /wp:jetpack/google-calendar -->

<!-- wp:separator -->
<hr class="wp-block-separator"/>
<!-- /wp:separator -->

Google Calendar is currently not rendering at all on an AMP page. This is because it is getting removed due to not having a width defined on the amp-iframe:

image

This PR fixes that issue by supplying the proper layout of fixed-height rather than responsive, since the width is intended to be 100%. (This appears to be a regression introduced in #14835.) Also missing in the previous implementation was the placeholder child which is required for amp-iframe elements appearing in the initial viewport. So a link to the Google Calendar was supplied as a placeholder in this case.

This PR also goes beyond just fixing AMP compatibility in that the page is actually better than the non-AMP version when JS is turned off, by supplying a the plain HTML calendar view to visitors with JS turned off. Some additional AMP-specific CSS was included here, but that will eventually not be needed once those are accounted for in AMP itself. See https://github.com/ampproject/amphtml/pull/29846.

Before
Non-AMP w/ JS Non-AMP w/o JS AMP 👎 AMP w/o JS 👎
image image image (Removed by plugin sanitizer) image (Removed by plugin sanitizer)
After
Non-AMP w/ JS Non-AMP w/o JS AMP 👍 AMP w/o JS 👍
image (No change) image (No change) image image (No-JS fallback!)

Changes proposed in this Pull Request:

<!--- Explain what functional changes your PR includes -->

  • Fix AMP compatibility in Google Calendar block.

Jetpack product discussion

<!-- If you're an Automattician, include a shortlink to the p2 discussion with Jetpack Product here. --> <!-- Make sure any changes to existing products have been discussed and agreed upon -->

Does this pull request change what data or activity we track or use?

<!--- If so, please add the "[Status] Needs Privacy Updates" label and explain what changes there are. --> <!--- Check existing Jetpack support documents for a preview of the information we need. -->

Testing instructions:

<!-- If you were reviewing this PR, how would you like the instructions to be presented? --> <!-- Please include detailed testing steps, explaining how to test your change. --> <!-- Bear in mind that context you working on is not obvious for everyone. --> <!-- Adding "simple" configuration steps will help reviewers to get to your PR as quickly as possible. --> <!-- "Before / After" screenshots can also be very helpful when the change is visual. -->

  1. Copy the above post_content into a new post.
  2. Activate the AMP plugin and enable Transitional mode.
  3. Compare the post in AMP and non-AMP (e.g. via Paired Browsing).

Proposed changelog entry for your changes:

<!-- Please do not leave this empty. If no changelog entry needed, state as such. -->

  • Fix AMP compatibility in Google Calendar block.
+60 -9

0 comment

2 changed files

pr created time in 13 hours

create barnchwestonruter/jetpack

branch : add/google-calendar-amp-compat

created branch time in 14 hours

push eventampproject/amp-wp

Renovate Bot

commit sha 07f32713b637176793def38131df8e643143f1af

Update dependency lint-staged to v10.4.0

view details

Weston Ruter

commit sha ead16c715703020fd371b308026a90914edcb948

Merge pull request #5419 from renovate-bot/renovate/lint-staged-10.x Update dependency lint-staged to v10.4.0

view details

push time in 14 hours

PR merged ampproject/amp-wp

Update dependency lint-staged to v10.4.0 cla: yes dependencies

This PR contains the following updates:

Package Type Update Change
lint-staged devDependencies minor 10.3.0 -> 10.4.0

Release Notes

<details> <summary>okonet/lint-staged</summary>

v10.4.0

Compare Source

Features

</details>


Renovate configuration

:date: Schedule: At any time (no schedule defined).

:vertical_traffic_light: Automerge: Disabled by config. Please merge this manually once you are satisfied.

:recycle: Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

:no_bell: Ignore: Close this PR and you won't be reminded about this update again.


  • [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

This PR has been generated by WhiteSource Renovate. View repository job log here.

+14 -14

0 comment

2 changed files

renovate-bot

pr closed time in 14 hours

push eventampproject/amp-wp

Renovate Bot

commit sha 89d4e52dab107141861bce12bf053162ea305f82

Update dependency eslint-plugin-react to v7.21.1

view details

Weston Ruter

commit sha 31c6ead1eb63913e20d927b5adf6e91bdedb1dbe

Merge pull request #5418 from renovate-bot/renovate/eslint-plugin-react-7.x Update dependency eslint-plugin-react to v7.21.1

view details

push time in 14 hours

PR merged ampproject/amp-wp

Update dependency eslint-plugin-react to v7.21.1 cla: yes dependencies

This PR contains the following updates:

Package Type Update Change
eslint-plugin-react devDependencies minor 7.20.6 -> 7.21.1

Release Notes

<details> <summary>yannickcr/eslint-plugin-react</summary>

v7.21.1

Compare Source

Fixed

v7.21.0

Compare Source

Added
Fixed
Changed

</details>


Renovate configuration

:date: Schedule: At any time (no schedule defined).

:vertical_traffic_light: Automerge: Disabled by config. Please merge this manually once you are satisfied.

:recycle: Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

:no_bell: Ignore: Close this PR and you won't be reminded about this update again.


  • [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

This PR has been generated by WhiteSource Renovate. View repository job log here.

+52 -15

0 comment

2 changed files

renovate-bot

pr closed time in 14 hours

push eventampproject/amp-wp

Weston Ruter

commit sha 70da394df3eac29fe66189ecd3835a2d43c63ef3

Fix undefined index notice for some layout error titles (#5425)

view details

push time in 16 hours

push eventampproject/amp-wp

Weston Ruter

commit sha 1cec3dd591600b8ab42fa10f8fc939da80a63c78

Fix undefined index notice for some layout error titles (#5425)

view details

push time in 16 hours

delete branch ampproject/amp-wp

delete branch : fix/error-title-for-auto-width-error

delete time in 16 hours

PR merged ampproject/amp-wp

Fix undefined index notice for some layout error titles Validation WS:Core cla: yes

Summary

I was testing the Google Calendar block in Jetpack and there was a validation error, but there was also a PHP notice at the same time:

<b>Notice</b>: Undefined index: width in <b>/app/public/content/plugins/amp/includes/validation/class-amp-validation-error-taxonomy.php</b> on line <b>3226</b>

The HTML block being validated indeed lacked a width:

<div class="wp-block-jetpack-google-calendar"><iframe src="https://calendar.google.com/calendar/embed?src=askenergy%40oregon.gov&amp;ctz=America/Los_Angeles" frameborder="0" style="border:0" scrolling="no" height="600"></iframe></div>

So this needs to not be assumed when we construct the error title. This PR adds the necessary isset() check.

Before After
Screen Shot 2020-09-23 at 16 50 29 Screen Shot 2020-09-23 at 16 52 14

Checklist

  • [ ] My pull request is addressing an open issue (please create one otherwise).
  • [ ] 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).
+14 -6

1 comment

1 changed file

westonruter

pr closed time in 16 hours

push eventampproject/amp-wp

Weston Ruter

commit sha fb6fed543df7b8d734080a9c15d9eb0740450c13

Fix undefined index notice for some layout error titles

view details

push time in 17 hours

PR opened ampproject/amp-wp

Reviewers
Fix undefined index notice for some layout error titles Validation WS:Core

Summary

I was testing the Google Calendar block in Jetpack and there was a validation error, but there was also a PHP notice at the same time:

<b>Notice</b>: Undefined index: width in <b>/app/public/content/plugins/amp/includes/validation/class-amp-validation-error-taxonomy.php</b> on line <b>3226</b>

The HTML block being validated indeed lacked a width:

<div class="wp-block-jetpack-google-calendar"><iframe src="https://calendar.google.com/calendar/embed?src=fobmuamv2c7cu19aq1n2gc6p8c0p90ur%40import.calendar.google.com&amp;ctz=America%2FLos_Angeles" frameborder="0" style="border:0" scrolling="no" height="600"></iframe></div>

So this needs to not be assumed when we construct the error title. This PR adds the necessary isset() check.

Before After
Screen Shot 2020-09-23 at 16 50 29 Screen Shot 2020-09-23 at 16 52 14

Checklist

  • [ ] My pull request is addressing an open issue (please create one otherwise).
  • [ ] 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).
+14 -6

0 comment

1 changed file

pr created time in 17 hours

create barnchampproject/amp-wp

branch : fix/error-title-for-auto-width-error

created branch time in 17 hours

push eventampproject/amp-wp

Pierre Gordon

commit sha 3e4af0c7d8b17a128343c68063fe6ae78ac0c22f

Run phpstan on staged PHP source files

view details

Weston Ruter

commit sha d61923e4def2718d315e9ed639b54088f9e07e41

Merge pull request #5424 from ampproject/enhancement/static-analysis-on-staged-files Run phpstan on staged PHP source files

view details

push time in 18 hours

delete branch ampproject/amp-wp

delete branch : enhancement/static-analysis-on-staged-files

delete time in 18 hours

PR merged ampproject/amp-wp

Run phpstan on staged PHP source files Infrastructure WS:Core cla: yes

Summary

This PR is a followup from #4441, which runs phpstan on staged PHP files within the includes or src folders.

Checklist

  • [ ] My pull request is addressing an open issue (please create one otherwise).
  • [ ] 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).
+3 -0

1 comment

1 changed file

pierlon

pr closed time in 18 hours

PullRequestReviewEvent

push eventwestonruter/jetpack

Paul Jacobson

commit sha 97cd2092ad18009f07c98bcb778783dc1d663fe7

Adding clip-path property to supported CSS properties (#17178)

view details

Weston Ruter

commit sha ad8ec79d5b67572e4b6d10ac8e08a542186c4032

Prevent adding adding AMP hooks for Infinite Scroll on legacy AMP post templates (#17175)

view details

renovate[bot]

commit sha 3f961e599bf981006a9e07405fe46ad068d85cf4

Update dependency preact to v10.4.8 (#17082) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

renovate[bot]

commit sha 8c77f8b0703f8d26226fa09d9e0b51167553975b

Update dependency swiper to v6.2.0 (#16770) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

renovate[bot]

commit sha 6c5efe71c326a52af39656fdf41a5cd4654b59a5

Update dependency jsdom to v16.4.0 (#16849) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

renovate[bot]

commit sha 1c5b9c3622e06bb523b07f03e57bef2274144e4f

Update dependency eslint to v7.9.0 (#17080) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

Yaroslav Kukharuk

commit sha 944f0d233db82d76e5d0cfd757ae68b17288da4a

E2E Tests: Update to support new plans (#17186) * Update E2E tests to support new plans * minor fix * fix pro blocks * return true when block is found * [not verified] [not verified] Improve Support for Jetpack Complete & Security Plans (#17177) Cherry-picked from https://github.com/Automattic/jetpack/pull/17177 Co-authored-by: Caleb Bauermeister <cbauerman@gmail.com>

view details

Jeremy Herve

commit sha e0c2edfd61f7ab1edd854e106de6e3dd1298f1e8

8.9.1: add changelog (#17107)

view details

Jeremy Herve

commit sha 508e933ad8321921a7edccc60468e024808bb570

Blocks: add new methods to new package (#17126) Co-authored-by: Brad Jorsch <anomiex@users.noreply.github.com>

view details

Răzvan Papadopol

commit sha 0fba989e34db2fdfcba543e23e13a647f6323151

Gutenboarding: save selected features as a site option (#17169) Summary: This patch is part of [[ 45148-gh-wp-calypso | #45148 ]] This patch saves the `selected_features` as a site option. We're looking to use this data during the Site setup flow (in editor) to recommend a plan based on the selected features. The option will be available only for sites created using `site_creation_flow: 'gutenboarding'`. Note: this change is a very similar to D42191-code Test Plan: Follow testing instructions in [[ 45148-gh-wp-calypso | #45148 ]] Reviewers: simison, mciampini, tomjcafferkey Reviewed By: mciampini, tomjcafferkey Tags: #touches_jetpack_files Differential Revision: D49420-code This commit syncs r213657-wpcom.

view details

Jeremy Herve

commit sha d06a8b7557165ee52644c085ed9755a628e6dd93

CodeClimate test: update node version (#17168) This needs to be done following the change in #14274, so the version used in the CodeClimate test matches the version expected for the build.

view details

Christopher Allford

commit sha 6903d4f18be177221158ad84bf4eb79886f0a5aa

Autoloader: Detect filtering of active_plugins (#17174)

view details

Eric Binnion

commit sha 5e12db68d3e8c540c69e728a1e8f99decb4d4a14

Embeds: Instagram: Allow setting own access token to bypass proxied requests (#17185)

view details

Brandon Kraft

commit sha 4262c1491c8c9299af836b6977dd29bb760b3059

Google Analytics: Move legacy code to head (#17184)

view details

Brandon Kraft

commit sha 0c3b3fcfdf66680adaa795d79a6e58344a2f94ce

a8c-mc-stats: Do not distribute test files (#17183)

view details

renovate[bot]

commit sha 422091abff9011b6e59e7e4913bb09a947fc4bbd

Update dependency css-loader to v4.3.0 (#17022) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

Geoff

commit sha d7e15e38382868f870024c0831f56ddc733c83c8

Filter only specific Wikimedia subdomains in Photon API (#17197) Some wikimedia subdomains are hosted on WPVIP and need to be able to use Photon API

view details

Atanas Angelov

commit sha aae801388df8405075aec910522ef177eedaf7dc

Jetpack_IXR_ClientMulticall: Fix sort_calls() producing undefined relative order between equal items (#17009)

view details

Yaroslav Kukharuk

commit sha 371fe20e6a221ef98d75f82caf2ed0556abb8f59

Build: Update vulnerable dependencies (#17074) * resolve security vulnerablities in dependencies * Cleanup resolutions * add `bl` resolution * add node-fetch into yarn resolutions

view details

Dion Hulse

commit sha 8f8104179df236101209af8f71aef3e70d06d340

Crowdsignal: Don't call mktime() in a deprecated manner. (#17199)

view details

push time in 18 hours

push eventampproject/amp-wp

Renovate Bot

commit sha c0860b608113502c951c9906f4c2c3fd57811173

Update dependency grunt to v1.3.0

view details

Weston Ruter

commit sha 77666c82cde98f91031b6f6af735cad98f80b853

Merge pull request #4995 from renovate-bot/renovate/grunt-1.x Update dependency grunt to v1.3.0

view details

push time in 19 hours

PR merged ampproject/amp-wp

Update dependency grunt to v1.3.0 cla: yes dependencies

This PR contains the following updates:

Package Type Update Change
grunt (source) devDependencies minor 1.2.0 -> 1.3.0

Release Notes

<details> <summary>gruntjs/grunt</summary>

v1.3.0

Compare Source

  • Merge pull request #​1720 from gruntjs/update-changelog-deps faab6be
  • Update Changelog and legacy-util dependency 520fedb
  • Merge pull request #​1719 from gruntjs/yaml-refactor 7e669ac
  • Switch to use safeLoad for loading YML files via file.readYAML. e350cea
  • Merge pull request #​1718 from gruntjs/legacy-log-bumo 7125f49
  • Bump legacy-log 00d5907

v1.2.1

Compare Source

</details>


Renovate configuration

:date: Schedule: At any time (no schedule defined).

:vertical_traffic_light: Automerge: Disabled by config. Please merge this manually once you are satisfied.

:recycle: Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

:no_bell: Ignore: Close this PR and you won't be reminded about this update again.


  • [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

This PR has been generated by WhiteSource Renovate. View repository job log here.

+79 -40

0 comment

2 changed files

renovate-bot

pr closed time in 19 hours

push eventampproject/amp-wp

Renovate Bot

commit sha 68001ae0d8ca3fa73185653d6b78dc616100f1b5

Update dependency postcss to v8.0.9

view details

Weston Ruter

commit sha a3b0aba0fe92513016ab13651a9643bcb53d965d

Merge pull request #5422 from renovate-bot/renovate/postcss-8.x Update dependency postcss to v8.0.9

view details

push time in 19 hours

PR merged ampproject/amp-wp

Update dependency postcss to v8.0.9 cla: yes dependencies

This PR contains the following updates:

Package Type Update Change
postcss (source) devDependencies patch 8.0.8 -> 8.0.9

Release Notes

<details> <summary>postcss/postcss</summary>

v8.0.9

Compare Source

  • Replace prototype in PostCSS 7 nodes instead of recreating them.
  • Added missed Transformer to exported types (by Pierre-Marie Dartus).

</details>


Renovate configuration

:date: Schedule: At any time (no schedule defined).

:vertical_traffic_light: Automerge: Disabled by config. Please merge this manually once you are satisfied.

:recycle: Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

:no_bell: Ignore: Close this PR and you won't be reminded about this update again.


  • [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

This PR has been generated by WhiteSource Renovate. View repository job log here.

+10 -10

0 comment

2 changed files

renovate-bot

pr closed time in 19 hours

push eventampproject/amp-wp

Renovate Bot

commit sha 076009dc24de069756ac55e4a5a8a6574bb965cb

Update dependency terser-webpack-plugin to v4

view details

Weston Ruter

commit sha dc8a3293fd54998db6421d949382f52257c3ed2a

Merge pull request #5163 from renovate-bot/renovate/terser-webpack-plugin-4.x Update dependency terser-webpack-plugin to v4

view details

push time in 19 hours

PR merged ampproject/amp-wp

Update dependency terser-webpack-plugin to v4 cla: yes dependencies

This PR contains the following updates:

Package Type Update Change
terser-webpack-plugin devDependencies major 3.1.0 -> 4.2.2

Release Notes

<details> <summary>webpack-contrib/terser-webpack-plugin</summary>

v4.2.2

Compare Source

v4.2.1

Compare Source

v4.2.0

Compare Source

Features
Bug Fixes

v4.1.0

Compare Source

Features
  • pass license files as related assets for webpack@5 (7d3ae95)
Bug Fixes
  • compatibility with 10.13 version of Node.js

v4.0.0

Compare Source

⚠ BREAKING CHANGES
  • the warningsFilter option was removed without replacement,
  • terser version is 5,
  • return value of the minify option was changed, only code/map/extractedComments are valid
Features
  • improved compatibility with webpack@5

</details>


Renovate configuration

:date: Schedule: At any time (no schedule defined).

:vertical_traffic_light: Automerge: Disabled by config. Please merge this manually once you are satisfied.

:recycle: Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

:no_bell: Ignore: Close this PR and you won't be reminded about this update again.


  • [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

This PR has been generated by WhiteSource Renovate. View repository job log here.

+350 -45

0 comment

2 changed files

renovate-bot

pr closed time in 19 hours

pull request commentAutomattic/jetpack

Add AMP compatibility for OpenTable block

@jeherve No longer [Status] Blocked / Hold.

westonruter

comment created time in a day

push eventwestonruter/jetpack

Chris R

commit sha ed69db2282f6ae74227afb3ca28bb87c69d00912

Jetpack_WPES_Search_Query_Parser: add method to retrieve lang suffix Summary: Addresses the following issues with the cards endpoint: * Score was not being returned for site recs * Score formatting was inconsistent * Language was not being provided to recommendation classes so all recs were English Test Plan: Use the API console and request v2 /read/tags/cards. Try using a different locale and ensure that you get site recommendations for the right language, e.g. `/read/tags/cards?tags=dogs,cats&sort=popularity&page=1&_locale=fr` Reviewers: gibrown, charlescearl Reviewed By: gibrown Tags: #touches_jetpack_files Differential Revision: D48544-code This commit syncs r213167-wpcom.

view details

Henry

commit sha 9740e6dd4b7a0b309825bbc51af8b03de7da0dfe

Earn: Stripe Connection Feedback Message (#17079)

view details

renovate[bot]

commit sha 8d9329c600e86de0f2fed6a356d8d7003a59d6bb

Update jest monorepo (#17083) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

renovate[bot]

commit sha e245daa4d4b9553e1a378a091c6ae01ebc853ade

Update dependency eslint-plugin-jsdoc to v30.3.2 (#17081) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

Filipe Varela

commit sha c1e64768b25a0b8751365c1070c0998b3e7bb9d5

Update icon property on all form variations (#17092) * Update icon property on all form variations Simplifies the icon property to have just a single value instead of an object where `src` and `foreground` were being passed onto. This formatting is not supported, nor are color changes in the variations selections (yet?). * Remove unused getIconColor import * Clean up "Send a message" block icon

view details

Jeremy Herve

commit sha d1fee2411de34ca572c87ea119819b0a9d53ec60

Live Branches Tool: add AMP plugin (#17088)

view details

Aaron Robertshaw

commit sha 7f6412425766c17555128b919281eab3116760a2

OpenTable Block: Add mobile fallback when using wide style (#16833) * Replace OpenTable wide style widget with standard when viewing via mobile

view details

Weston Ruter

commit sha c9de96bf26e099c31756803814e4845fac94715e

Add AMP compatibility for Pinterest block (#17086) Co-authored-by: Jeremy Herve <jeremy@tagada.hu>

view details

Jeremy Herve

commit sha f438233624c074bf4cc54755d7397d706cb801d3

Embeds: update song.link oEmbed to support more formats. (#17095)

view details

Jeremy Herve

commit sha 45faac438915f7bb8947ee934f71a68a744677fd

Pinterest: avoid errors when Jetpack_AMP_Support isn't available (#17098)

view details

Jeremy Herve

commit sha 2ea74258933b56b0210acb7bbcef3fb936f377f6

Form Block: remove newsletter variation on wpcom simple sites (#17061)

view details

Sten

commit sha cde3db04b6494f99c0df8989db7e84ae6b6b9918

Remove SSO JITM from Jetpack_SSO (#17077)

view details

Jeremy Herve

commit sha 73144eee334d871b116425156644e5df2b6c33ee

Blocks: introduce new package for block management (#17100) See #17099

view details

Jason Moon

commit sha 843d05603566e213a6d43ef4c2c9316f2cd9bdb1

Signature Class: Adds support for nested query strings (#17058) Also adds corresponding unit tests.

view details

Kim Brown

commit sha 414c0705e05a4148967dd27f657e3851496210d5

Tracking: fix the logic for determining when to enable tracking. (#17076)

view details

Foteini Giannaropoulou

commit sha 087af895a140187d32bd4326b60fcae05521588a

Debugger: Add token health check test (#17028) * Debugger: Add token health check test * Debugger: Fix message for test__check_if_connected failing case

view details

Fernando

commit sha 4d1a94f4622e0edbea6c93af247e3ef5face6c98

Added options to sync wc whitelist (#17075) This commit adds the options `woocommerce_task_list_hidden` and `woocommerce_onboarding_profile` to sync wc whitelist. Co-authored-by: Fernando Marichal <contacto@fernandomarichal.com>

view details

Sergey Mitroshin

commit sha 7769a2ffd72823067b3391ef9197bb3fdfca6ad8

Docker MySQL: Slow Queries Log (#17103) - logging of MySQL queries slower than 0.5 second into the file docker/logs/mysql/slow.log - docker/config/mysql.conf config file makes changing the MySQL server configuration easier

view details

leogermani

commit sha e31d275232488c9e152869996bea6d69feeba0b2

fixes copy post not copying categories in old dbs (#17102)

view details

Jeremy Herve

commit sha e0dd0b9e531da02d7003e953a25e49b30a7cdbac

Sync: stop trying to check for edit_comment capability (#17114) * Sync: switch to checking for capability to edit all comments Checking for edit_comment can only be used to check for the cap for one specific comment, which does not match our needs here. moderate_comments will allow us to check for the ability to edit all comments on the site. More dicussion: p1599656662345700-slack-jetpack-crew * Remove moderate_comments, it's already in the array

view details

push time in a day

Pull request review commentAutomattic/jetpack

Add AMP compatibility for Eventbrite block

 const FEATURE_NAME = 'eventbrite'; const BLOCK_NAME   = 'jetpack/' . FEATURE_NAME; +/**+ * Determine whether the page will be AMP.+ *+ * @return bool+ */+function is_amp_request() {+	return class_exists( 'Jetpack_AMP_Support' ) && \Jetpack_AMP_Support::is_amp_request();+}

Done in 99e2c2f

westonruter

comment created time in a day

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentAutomattic/jetpack

Add AMP compatibility for Eventbrite block

 function render_block( $attr, $content ) { 	);  	$widget_id = wp_unique_id( 'eventbrite-widget-' );--	wp_enqueue_script( 'eventbrite-widget', 'https://www.eventbrite.com/static/widgets/eb_widgets.js', array(), JETPACK__VERSION, true );--	// Add CSS to hide direct link.-	Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME );+	$is_amp    = is_amp_request();  	// Show the embedded version. 	if ( empty( $attr['useModal'] ) && ( empty( $attr['style'] ) || 'modal' !== $attr['style'] ) ) {+		return render_embed_block( $widget_id, $is_amp, $attr );+	} else {+		return render_modal_block( $widget_id, $is_amp, $attr, $content );+	}+}++/**+ * Render block with embed style.+ *+ * @param string $widget_id Widget ID to use.+ * @param bool   $is_amp    Whether AMP page.+ * @param array  $attr      Eventbrite block attributes.+ * @return string Rendered block.+ */+function render_embed_block( $widget_id, $is_amp, $attr ) {++	// $content contains a fallback link to the event that's saved in the post_content.+	// Append a div that will hold the iframe embed created by the Eventbrite widget.js.+	$classes = Jetpack_Gutenberg::block_classes( FEATURE_NAME, $attr );

Done!

westonruter

comment created time in a day

push eventwestonruter/jetpack

Marco Pereirinha

commit sha c1e93146f81831a0215f3294072d0e27f01b9b51

Infinite scroll for AMP (#16048) Co-authored-by: Jeremy Herve <jeremy@jeremy.hu>

view details

renovate[bot]

commit sha a6dd259c9d1b8f7508626e57d400bd162957b518

Update dependency husky to v4.3.0 (#17148) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

renovate[bot]

commit sha 68166d3f2845ffe398c7e24780198ff5cdc8853a

Update dependency eslint-plugin-jsdoc to v30.4.2 (#17147) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

Yaroslav Kukharuk

commit sha 4abe1df2a4ad13258f67bfafd654d08051daa7f8

E2E Tests: Fix WPORG login failures (#17131) * Wait for navigation before looking for a failed login * add 1ms delay between typing characters

view details

Yaroslav Kukharuk

commit sha 40e2c3f49324fa9fefa54c31674ab2ef27451d82

Build Artifacts: fix `nvm` not found issue (#17152) * run `nvm install` * add test steps * add nvm install one more time * Try set `-eo pipefail` * add `shell` definition into `build jetpack` step * try install nvm manually * try exporting nvm stuff * maybe like this? * lets try this one * cleanup * use ubuntu 20.04 * bunch of logging commands * . * .. * add nvm install into build jetpack step * revert back to ubuntu-latest * ... * :shrug: * . * . * .. * add `type -a nvm` * add `type -a nvm` pt 2 * run `nvm use` * run nvm install * maybe this will help :shrug: * Lets try `bash` * install nvm within script * lets try this * . * nvm install * try to move nvm install from script * final version

view details

Jeremy Herve

commit sha 49815210f347db08392569874f1c2dbb350ed10a

CodeClimate: update rules with newer version (#17153)

view details

Matthew Denton

commit sha fe55c81651d2dbefa63cb6e9bc29f87707988b3a

Adding 'review' to whitelisted comment types (#17141)

view details

Sergey Mitroshin

commit sha ab9aeb0ea9d028f51e1d776d1d97853f35ab8302

Connection: Initializing default constants for the REST authorization. (#17158) When Jetpack plugin is not installed, REST Authentication requires defaults constants to function. In particular, `JETPACK__API_VERSION` is empty, making the WP Proxy request signature verification fail. This commit: - Extracts the default constants initialization code into `Utils::init_default_constants()`. - Replaces the existing initialization with the new function call. - Adds a new initialization call for `Rest_Authentication` class so WP proxy requests signature could be properly verified.

view details

Brandon Kraft

commit sha 9c670b5651e31a5faf857ff8c441b0049a528c4f

Local Testing Suite: Skip the blog token test if site is not connected (#17163)

view details

renovate[bot]

commit sha 4400bed51e57a7a413f9e52381c44e8f1cbc9ec5

Update dependency @automattic/social-previews to v1.1.0 (#17146) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

Igor Zinovyev

commit sha f4ec85a5b38814576c555b13ee482a86fc024389

Fix early returns in Jetpack. (#17142) Barry: "Summary: We can't call switch_to_blog() and then return without also calling restore_current_blog(). One of these seems very old and the other one seems relatively new in class.media-extractor.php. It seems like we should be able to do some static or dynamic analysis to detect these cases and prevent new ones from being committed." Props @barry for the fix.

view details

Foteini Giannaropoulou

commit sha ec48e84b8d68162e0bb7d70cc4cf28c2a63c94ab

Client admin page: Add reconnect route (#17155) * Client: Trigger reconnection with 'reconnect' query parameter * Client admin page: Add reconnect route * Reconnect flow: Hide connection errors and link account notice while reconnecting * Reconnect flow: Stop dispatching SITE_RECONNECT_SUCCESS before page reload Stop dispatching SITE_RECONNECT_SUCCESS before page load so that remains true and the UX unaffected. When becomes true, the UI blur effect goes away and the connection error notices re-appear

view details

Paul Jacobson

commit sha 97cd2092ad18009f07c98bcb778783dc1d663fe7

Adding clip-path property to supported CSS properties (#17178)

view details

Weston Ruter

commit sha ad8ec79d5b67572e4b6d10ac8e08a542186c4032

Prevent adding adding AMP hooks for Infinite Scroll on legacy AMP post templates (#17175)

view details

renovate[bot]

commit sha 3f961e599bf981006a9e07405fe46ad068d85cf4

Update dependency preact to v10.4.8 (#17082) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

renovate[bot]

commit sha 8c77f8b0703f8d26226fa09d9e0b51167553975b

Update dependency swiper to v6.2.0 (#16770) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

renovate[bot]

commit sha 6c5efe71c326a52af39656fdf41a5cd4654b59a5

Update dependency jsdom to v16.4.0 (#16849) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

renovate[bot]

commit sha 1c5b9c3622e06bb523b07f03e57bef2274144e4f

Update dependency eslint to v7.9.0 (#17080) Co-authored-by: Renovate Bot <bot@renovateapp.com>

view details

Yaroslav Kukharuk

commit sha 944f0d233db82d76e5d0cfd757ae68b17288da4a

E2E Tests: Update to support new plans (#17186) * Update E2E tests to support new plans * minor fix * fix pro blocks * return true when block is found * [not verified] [not verified] Improve Support for Jetpack Complete & Security Plans (#17177) Cherry-picked from https://github.com/Automattic/jetpack/pull/17177 Co-authored-by: Caleb Bauermeister <cbauerman@gmail.com>

view details

Jeremy Herve

commit sha e0c2edfd61f7ab1edd854e106de6e3dd1298f1e8

8.9.1: add changelog (#17107)

view details

push time in a day

issue commentampproject/amp-wp

Optimize hero images

As discussed just now, let's also include the hero preloading logic detection for CSS background images that are defined with inline style attributes. For example, the Cover Image block in core is rendered on an AMP page as follows:

image

In the same way that a transformer is looking for amp-img@src, amp-video@poster, amp-iframe > amp-img (and amp-youtube per https://github.com/ampproject/amp-wp/pull/5350/files#r485283525), it can also look for any element @style (or @data-amp-original-style) to extract the background-image URL, as another candidate for the hero image.

One complication here is that an element with an inline CSS background could be tiny, and we'd have no way of using isTinyElement to detect whether it is too small to be a candidate. Perhaps this interplays with whether the element has data-hero as referenced in https://github.com/ampproject/amp-wp/pull/5350#issuecomment-697298463. Otherwise, we could have WP-specific support, so we'd automatically consider elements that have wp-block-* as a class name to be considered to be not tiny.

sebastianbenz

comment created time in a day

issue commentampproject/amphtml

Add @-moz-document to the CSS at-rule allowlist

  1. Allow @-moz-document in AMP format (I doubt email would allow this anyway due to the browser sniffing capability) without validation on the url-prefix bit. This is a small, few-line change.

I understand from Bug 1035091 that Mozilla removed support for @-moz-document entirely in Firefox 59, and then via Bug 1446470 it re-added support but only recognizes url-prefix() with an empty value. So the only concern would be for users running Firefox older than v59. I'm not sure where to find detailed browser stats broken down by version, but my assumption is that there are exceedingly small number of users still running such older versions since it has auto-updates. Firefox 59 came out in March 2018—over 2 years ago.

  1. Add validator support for understanding and validating the remainder of the @ rule parse syntax and validate that we allow only with empty url-prefix as suggested. This is a larger change, requiring more time allocated, but doable.

If not 1, then this is my preference.

westonruter

comment created time in a day

Pull request review commentampproject/amp-wp

Add PreloadHeroImage Optimizer transformer

+<?php++namespace AmpProject\Optimizer\Transformer;++use AmpProject\Amp;+use AmpProject\Attribute;+use AmpProject\Dom\Document;+use AmpProject\Extension;+use AmpProject\Layout;+use AmpProject\Optimizer\Configuration\PreloadHeroImageConfiguration;+use AmpProject\Optimizer\Error;+use AmpProject\Optimizer\ErrorCollection;+use AmpProject\Optimizer\HeroImage;+use AmpProject\Optimizer\ImageDimensions;+use AmpProject\Optimizer\Transformer;+use AmpProject\Optimizer\TransformerConfiguration;+use AmpProject\Tag;+use AmpProject\Url;+use DOMElement;+use DOMNode;++/**+ * PreloadHeroImage - this transformer optimizes image rendering times for hero images. For hero images it will:+ *+ * 1. Inject a preload hint (if possible)+ * 2. Generate an img tag enabling the browser to render the image without the AMP runtime being loaded.+ *+ * Hero images are either identified automatically or can be explicitly defined by adding an `data-hero` attribute to+ * the element.+ *+ * This transformer supports the following options:+ *+ * * `preloadHeroImage`: [true|false] - enables or disables hero image preloading. The default is `true`.+ *+ * This is ported from the NodeJS optimizer.+ *+ * @version 3429af9d91e2c9efe1af85757499e5a308755f5f+ * @link    https://github.com/ampproject/amp-toolbox/blob/3429af9d91e2c9efe1af85757499e5a308755f5f/packages/optimizer/lib/transformers/PreloadHeroImage.js+ *+ * @package ampproject/optimizer+ */+final class PreloadHeroImage implements Transformer+{++    /**+     * Class(es) to apply to a serverside-rendered image element.+     *+     * @var string+     */+    const SSR_IMAGE_CLASS = 'i-amphtml-fill-content i-amphtml-replaced-content';++    /**+     * List of attributes to copy onto an SSR'ed image.+     *+     * @var string[]+     */+    const ATTRIBUTES_TO_COPY = [+        Attribute::ALT,+        Attribute::ATTRIBUTION,+        Attribute::OBJECT_FIT,+        Attribute::OBJECT_POSITION,+        Attribute::REFERRERPOLICY,+        Attribute::SRC,+        Attribute::SRCSET,+        Attribute::SIZES,+        Attribute::TITLE,+    ];++    /**+     * Maximum number of hero images defined via data-hero attribute.+     *+     * @var int+     */+    const DATA_HERO_MAX = 2;++    /**+     * Configuration store to use.+     *+     * @var TransformerConfiguration+     */+    private $configuration;++    /**+     * Instantiate a PreloadHeroImage object.+     *+     * @param TransformerConfiguration $configuration Configuration store to use.+     */+    public function __construct(TransformerConfiguration $configuration)+    {+        $this->configuration = $configuration;+    }++    /**+     * Apply transformations to the provided DOM document.+     *+     * @param Document        $document DOM document to apply the transformations to.+     * @param ErrorCollection $errors   Collection of errors that are collected during transformation.+     * @return void+     */+    public function transform(Document $document, ErrorCollection $errors)+    {+        if ($this->configuration->get(PreloadHeroImageConfiguration::PRELOAD_HERO_IMAGE) === false) {+            return;+        }++        $heroImages    = $this->findHeroImages($document);+        $referenceNode = $document->viewport;++        $heroImageCount = count($heroImages);+        if ($heroImageCount > self::DATA_HERO_MAX) {+            $errors->add(Error\TooManyHeroImages::whenPastMaximum());+            $heroImageCount = self::DATA_HERO_MAX;+        }++        $isAmpStory = Amp::isAmpStory($document);++        for ($index = 0; $index < $heroImageCount; $index++) {+            $this->generatePreload($heroImages[$index], $document, $errors, $referenceNode);+            $this->generateImg($heroImages[$index], $document);+        }+    }++    /**+     * Find the hero images to optimize.+     *+     * @param Document $document Document to look for hero images in.+     * @return HeroImage[] Array of hero images to optimize.+     */+    private function findHeroImages(Document $document)+    {+        $heroImageCandidate = null;+        $heroImages         = [];+        $node               = $document->body;++        while ($node !== null) {+            if (! $node instanceof DOMElement) {+                $node = $this->nextNode($node);+                continue;+            }++            $heroImage = $this->detectImageWithDataHero($node);+            if ($heroImage) {+                $heroImages[] = $heroImage;+            }++            if (! $heroImageCandidate && count($heroImages) === 0) {+                $heroImageCandidate = $this->detectHeroImageCandidate($node);+            }+            if (Amp::isTemplate($node)) {+                // Ignore images inside templates.+                $node = $this->skipNodeAndChildren($node);+            } else {+                $node = $this->nextNode($node);+            }+        }++        // Optimize data-hero element if defined.+        if (count($heroImages) > 0) {+            return $heroImages;+        }++        // Fall back to auto-detected hero image if available.+        if ($heroImageCandidate) {+            return [$heroImageCandidate];+        }++        // No hero images to optimize.+        return [];+    }++    /**+     * Detect a hero image with the data-hero attribute.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image, or null if none detected.+     */+    private function detectImageWithDataHero(DOMElement $element)+    {+        if (+            $element->tagName === Extension::IMAGE+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return new HeroImage(+                $element->getAttribute(Attribute::SRC),+                $element->getAttribute(Attribute::MEDIA),+                $element->getAttribute(Attribute::SRCSET),+                $element+            );+        }++        if (+            Amp::isAmpIframe($element)+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return $this->getPlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate.+     *+     * The hero image here can come from one of <amp-img>, <amp-video>, <amp-iframe>, <amp-video-iframe>.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidate(DOMElement $element)+    {+        if (+            $element->hasAttribute(Attribute::LAYOUT)+            && $element->getAttribute(Attribute::LAYOUT) === Layout::NODISPLAY+        ) {+            return null;+        }++        if ($element->tagName === Extension::IMAGE) {+            return $this->detectHeroImageCandidateForAmpImg($element);+        }++        if ($element->tagName === EXTENSION::VIDEO) {+            return $this->detectHeroImageCandidateForPosterImage($element);+        }++        if (Amp::isAmpIframe($element)) {+            return $this->detectHeroImageCandidateForIframePlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate from an <amp-img> element.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForAmpImg(DOMElement $element)+    {+        $src = $element->getAttribute(Attribute::SRC);++        if (empty($src)) {+            return null;+        }++        if (! Url::isValidImageSrc($src)) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        $srcset = $element->getAttribute(Attribute::SRCSET);+        $media  = $element->getAttribute(Attribute::MEDIA);++        return new HeroImage($src, $media, $srcset, $element);+    }++    /**+     * Detect a hero image candidate from a video's poster (= placeholder) image.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForPosterImage(DOMElement $element)+    {+        $poster = $element->getAttribute(Attribute::POSTER);++        if (! $poster) {+            return null;+        }++        if (! Url::isValidImageSrc($poster)) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        $media = $element->getAttribute(Attribute::MEDIA);++        return new HeroImage($poster, $media, '');+    }++    /**+     * Detect a hero image candidate from an iframe's placeholder image.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForIframePlaceholderImage(DOMElement $element)
    private function detectHeroImageCandidateForPlaceholderImage(DOMElement $element)
schlessera

comment created time in a day

PullRequestReviewEvent

Pull request review commentampproject/amp-wp

Add PreloadHeroImage Optimizer transformer

+<?php++namespace AmpProject\Optimizer\Transformer;++use AmpProject\Amp;+use AmpProject\Attribute;+use AmpProject\Dom\Document;+use AmpProject\Extension;+use AmpProject\Layout;+use AmpProject\Optimizer\Configuration\PreloadHeroImageConfiguration;+use AmpProject\Optimizer\Error;+use AmpProject\Optimizer\ErrorCollection;+use AmpProject\Optimizer\HeroImage;+use AmpProject\Optimizer\ImageDimensions;+use AmpProject\Optimizer\Transformer;+use AmpProject\Optimizer\TransformerConfiguration;+use AmpProject\Tag;+use AmpProject\Url;+use DOMElement;+use DOMNode;++/**+ * PreloadHeroImage - this transformer optimizes image rendering times for hero images. For hero images it will:+ *+ * 1. Inject a preload hint (if possible)+ * 2. Generate an img tag enabling the browser to render the image without the AMP runtime being loaded.+ *+ * Hero images are either identified automatically or can be explicitly defined by adding an `data-hero` attribute to+ * the element.+ *+ * This transformer supports the following options:+ *+ * * `preloadHeroImage`: [true|false] - enables or disables hero image preloading. The default is `true`.+ *+ * This is ported from the NodeJS optimizer.+ *+ * @version 3429af9d91e2c9efe1af85757499e5a308755f5f+ * @link    https://github.com/ampproject/amp-toolbox/blob/3429af9d91e2c9efe1af85757499e5a308755f5f/packages/optimizer/lib/transformers/PreloadHeroImage.js+ *+ * @package ampproject/optimizer+ */+final class PreloadHeroImage implements Transformer+{++    /**+     * Class(es) to apply to a serverside-rendered image element.+     *+     * @var string+     */+    const SSR_IMAGE_CLASS = 'i-amphtml-fill-content i-amphtml-replaced-content';++    /**+     * List of attributes to copy onto an SSR'ed image.+     *+     * @var string[]+     */+    const ATTRIBUTES_TO_COPY = [+        Attribute::ALT,+        Attribute::ATTRIBUTION,+        Attribute::OBJECT_FIT,+        Attribute::OBJECT_POSITION,+        Attribute::REFERRERPOLICY,+        Attribute::SRC,+        Attribute::SRCSET,+        Attribute::SIZES,+        Attribute::TITLE,+    ];++    /**+     * Maximum number of hero images defined via data-hero attribute.+     *+     * @var int+     */+    const DATA_HERO_MAX = 2;++    /**+     * Configuration store to use.+     *+     * @var TransformerConfiguration+     */+    private $configuration;++    /**+     * Instantiate a PreloadHeroImage object.+     *+     * @param TransformerConfiguration $configuration Configuration store to use.+     */+    public function __construct(TransformerConfiguration $configuration)+    {+        $this->configuration = $configuration;+    }++    /**+     * Apply transformations to the provided DOM document.+     *+     * @param Document        $document DOM document to apply the transformations to.+     * @param ErrorCollection $errors   Collection of errors that are collected during transformation.+     * @return void+     */+    public function transform(Document $document, ErrorCollection $errors)+    {+        if ($this->configuration->get(PreloadHeroImageConfiguration::PRELOAD_HERO_IMAGE) === false) {+            return;+        }++        $heroImages    = $this->findHeroImages($document);+        $referenceNode = $document->viewport;++        $heroImageCount = count($heroImages);+        if ($heroImageCount > self::DATA_HERO_MAX) {+            $errors->add(Error\TooManyHeroImages::whenPastMaximum());+            $heroImageCount = self::DATA_HERO_MAX;+        }++        $isAmpStory = Amp::isAmpStory($document);++        for ($index = 0; $index < $heroImageCount; $index++) {+            $this->generatePreload($heroImages[$index], $document, $errors, $referenceNode);+            $this->generateImg($heroImages[$index], $document);+        }+    }++    /**+     * Find the hero images to optimize.+     *+     * @param Document $document Document to look for hero images in.+     * @return HeroImage[] Array of hero images to optimize.+     */+    private function findHeroImages(Document $document)+    {+        $heroImageCandidate = null;+        $heroImages         = [];+        $node               = $document->body;++        while ($node !== null) {+            if (! $node instanceof DOMElement) {+                $node = $this->nextNode($node);+                continue;+            }++            $heroImage = $this->detectImageWithDataHero($node);+            if ($heroImage) {+                $heroImages[] = $heroImage;+            }++            if (! $heroImageCandidate && count($heroImages) === 0) {+                $heroImageCandidate = $this->detectHeroImageCandidate($node);+            }+            if (Amp::isTemplate($node)) {+                // Ignore images inside templates.+                $node = $this->skipNodeAndChildren($node);+            } else {+                $node = $this->nextNode($node);+            }+        }++        // Optimize data-hero element if defined.+        if (count($heroImages) > 0) {+            return $heroImages;+        }++        // Fall back to auto-detected hero image if available.+        if ($heroImageCandidate) {+            return [$heroImageCandidate];+        }++        // No hero images to optimize.+        return [];+    }++    /**+     * Detect a hero image with the data-hero attribute.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image, or null if none detected.+     */+    private function detectImageWithDataHero(DOMElement $element)+    {+        if (+            $element->tagName === Extension::IMAGE+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return new HeroImage(+                $element->getAttribute(Attribute::SRC),+                $element->getAttribute(Attribute::MEDIA),+                $element->getAttribute(Attribute::SRCSET),+                $element+            );+        }++        if (+            Amp::isAmpIframe($element)+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return $this->getPlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate.+     *+     * The hero image here can come from one of <amp-img>, <amp-video>, <amp-iframe>, <amp-video-iframe>.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidate(DOMElement $element)+    {+        if (+            $element->hasAttribute(Attribute::LAYOUT)+            && $element->getAttribute(Attribute::LAYOUT) === Layout::NODISPLAY+        ) {+            return null;+        }++        if ($element->tagName === Extension::IMAGE) {+            return $this->detectHeroImageCandidateForAmpImg($element);+        }++        if ($element->tagName === EXTENSION::VIDEO) {+            return $this->detectHeroImageCandidateForPosterImage($element);+        }++        if (Amp::isAmpIframe($element)) {

This condition can be expanded to include all embeds, including amp-youtube, amp-vimeo, etc.

schlessera

comment created time in a day

PullRequestReviewEvent

Pull request review commentampproject/amp-wp

Add PreloadHeroImage Optimizer transformer

+<?php++namespace AmpProject\Optimizer\Transformer;++use AmpProject\Amp;+use AmpProject\Attribute;+use AmpProject\Dom\Document;+use AmpProject\Extension;+use AmpProject\Layout;+use AmpProject\Optimizer\Configuration\PreloadHeroImageConfiguration;+use AmpProject\Optimizer\Error;+use AmpProject\Optimizer\ErrorCollection;+use AmpProject\Optimizer\HeroImage;+use AmpProject\Optimizer\ImageDimensions;+use AmpProject\Optimizer\Transformer;+use AmpProject\Optimizer\TransformerConfiguration;+use AmpProject\Tag;+use AmpProject\Url;+use DOMElement;+use DOMNode;++/**+ * PreloadHeroImage - this transformer optimizes image rendering times for hero images. For hero images it will:+ *+ * 1. Inject a preload hint (if possible)+ * 2. Generate an img tag enabling the browser to render the image without the AMP runtime being loaded.+ *+ * Hero images are either identified automatically or can be explicitly defined by adding an `data-hero` attribute to+ * the element.+ *+ * This transformer supports the following options:+ *+ * * `preloadHeroImage`: [true|false] - enables or disables hero image preloading. The default is `true`.+ *+ * This is ported from the NodeJS optimizer.+ *+ * @version 3429af9d91e2c9efe1af85757499e5a308755f5f+ * @link    https://github.com/ampproject/amp-toolbox/blob/3429af9d91e2c9efe1af85757499e5a308755f5f/packages/optimizer/lib/transformers/PreloadHeroImage.js+ *+ * @package ampproject/optimizer+ */+final class PreloadHeroImage implements Transformer+{++    /**+     * Class(es) to apply to a serverside-rendered image element.+     *+     * @var string+     */+    const SSR_IMAGE_CLASS = 'i-amphtml-fill-content i-amphtml-replaced-content';++    /**+     * List of attributes to copy onto an SSR'ed image.+     *+     * @var string[]+     */+    const ATTRIBUTES_TO_COPY = [+        Attribute::ALT,+        Attribute::ATTRIBUTION,+        Attribute::OBJECT_FIT,+        Attribute::OBJECT_POSITION,+        Attribute::REFERRERPOLICY,+        Attribute::SRC,+        Attribute::SRCSET,+        Attribute::SIZES,+        Attribute::TITLE,+    ];++    /**+     * Maximum number of hero images defined via data-hero attribute.+     *+     * @var int+     */+    const DATA_HERO_MAX = 2;++    /**+     * Configuration store to use.+     *+     * @var TransformerConfiguration+     */+    private $configuration;++    /**+     * Instantiate a PreloadHeroImage object.+     *+     * @param TransformerConfiguration $configuration Configuration store to use.+     */+    public function __construct(TransformerConfiguration $configuration)+    {+        $this->configuration = $configuration;+    }++    /**+     * Apply transformations to the provided DOM document.+     *+     * @param Document        $document DOM document to apply the transformations to.+     * @param ErrorCollection $errors   Collection of errors that are collected during transformation.+     * @return void+     */+    public function transform(Document $document, ErrorCollection $errors)+    {+        if ($this->configuration->get(PreloadHeroImageConfiguration::PRELOAD_HERO_IMAGE) === false) {+            return;+        }++        $heroImages    = $this->findHeroImages($document);+        $referenceNode = $document->viewport;++        $heroImageCount = count($heroImages);+        if ($heroImageCount > self::DATA_HERO_MAX) {+            $errors->add(Error\TooManyHeroImages::whenPastMaximum());+            $heroImageCount = self::DATA_HERO_MAX;+        }++        $isAmpStory = Amp::isAmpStory($document);++        for ($index = 0; $index < $heroImageCount; $index++) {+            $this->generatePreload($heroImages[$index], $document, $errors, $referenceNode);+            $this->generateImg($heroImages[$index], $document);+        }+    }++    /**+     * Find the hero images to optimize.+     *+     * @param Document $document Document to look for hero images in.+     * @return HeroImage[] Array of hero images to optimize.+     */+    private function findHeroImages(Document $document)+    {+        $heroImageCandidate = null;+        $heroImages         = [];+        $node               = $document->body;++        while ($node !== null) {+            if (! $node instanceof DOMElement) {+                $node = $this->nextNode($node);+                continue;+            }++            $heroImage = $this->detectImageWithDataHero($node);+            if ($heroImage) {+                $heroImages[] = $heroImage;+            }++            if (! $heroImageCandidate && count($heroImages) === 0) {+                $heroImageCandidate = $this->detectHeroImageCandidate($node);+            }+            if (Amp::isTemplate($node)) {+                // Ignore images inside templates.+                $node = $this->skipNodeAndChildren($node);+            } else {+                $node = $this->nextNode($node);+            }+        }++        // Optimize data-hero element if defined.+        if (count($heroImages) > 0) {+            return $heroImages;+        }++        // Fall back to auto-detected hero image if available.+        if ($heroImageCandidate) {+            return [$heroImageCandidate];+        }++        // No hero images to optimize.+        return [];+    }++    /**+     * Detect a hero image with the data-hero attribute.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image, or null if none detected.+     */+    private function detectImageWithDataHero(DOMElement $element)+    {+        if (+            $element->tagName === Extension::IMAGE+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return new HeroImage(+                $element->getAttribute(Attribute::SRC),+                $element->getAttribute(Attribute::MEDIA),+                $element->getAttribute(Attribute::SRCSET),+                $element+            );+        }++        if (+            Amp::isAmpIframe($element)+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return $this->getPlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate.+     *+     * The hero image here can come from one of <amp-img>, <amp-video>, <amp-iframe>, <amp-video-iframe>.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidate(DOMElement $element)+    {+        if (+            $element->hasAttribute(Attribute::LAYOUT)+            && $element->getAttribute(Attribute::LAYOUT) === Layout::NODISPLAY+        ) {+            return null;+        }++        if ($element->tagName === Extension::IMAGE) {+            return $this->detectHeroImageCandidateForAmpImg($element);+        }++        if ($element->tagName === EXTENSION::VIDEO) {+            return $this->detectHeroImageCandidateForPosterImage($element);+        }++        if (Amp::isAmpIframe($element)) {+            return $this->detectHeroImageCandidateForIframePlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate from an <amp-img> element.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForAmpImg(DOMElement $element)+    {+        $src = $element->getAttribute(Attribute::SRC);++        if (empty($src)) {+            return null;+        }++        if (! Url::isValidImageSrc($src)) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        $srcset = $element->getAttribute(Attribute::SRCSET);+        $media  = $element->getAttribute(Attribute::MEDIA);++        return new HeroImage($src, $media, $srcset, $element);+    }++    /**+     * Detect a hero image candidate from a video's poster (= placeholder) image.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForPosterImage(DOMElement $element)+    {+        $poster = $element->getAttribute(Attribute::POSTER);++        if (! $poster) {+            return null;+        }++        if (! Url::isValidImageSrc($poster)) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        $media = $element->getAttribute(Attribute::MEDIA);++        return new HeroImage($poster, $media, '');+    }++    /**+     * Detect a hero image candidate from an iframe's placeholder image.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForIframePlaceholderImage(DOMElement $element)+    {+        // A placeholder <amp-img> is required to preload an image for an iframe.+        if (! $element->hasChildNodes()) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        return $this->getPlaceholderImage($element);+    }++    /**+     * Get the placeholder image for a given element.+     *+     * @param DOMElement $element Element to check the placeholder image for.+     * @return HeroImage|null Placeholder image to use or null if none found.+     */+    private function getPlaceholderImage(DOMElement $element)+    {+        foreach ($element->childNodes as $childNode) {+            if (+                ! $childNode instanceof DOMElement+                || $childNode->tagName !== Extension::IMAGE+                || ! $childNode->hasAttribute(Attribute::PLACEHOLDER)+            ) {+                continue;+            }+

Some new logic can be added here to see if $childNode->tagName === Extension::IMAGE, and if so, use its $src. Otherwise, query $childNode for the first descendant Extension::IMAGE and use it instead.

schlessera

comment created time in a day

Pull request review commentampproject/amp-wp

Add PreloadHeroImage Optimizer transformer

+<?php++namespace AmpProject\Optimizer\Transformer;++use AmpProject\Amp;+use AmpProject\Attribute;+use AmpProject\Dom\Document;+use AmpProject\Extension;+use AmpProject\Layout;+use AmpProject\Optimizer\Configuration\PreloadHeroImageConfiguration;+use AmpProject\Optimizer\Error;+use AmpProject\Optimizer\ErrorCollection;+use AmpProject\Optimizer\HeroImage;+use AmpProject\Optimizer\ImageDimensions;+use AmpProject\Optimizer\Transformer;+use AmpProject\Optimizer\TransformerConfiguration;+use AmpProject\Tag;+use AmpProject\Url;+use DOMElement;+use DOMNode;++/**+ * PreloadHeroImage - this transformer optimizes image rendering times for hero images. For hero images it will:+ *+ * 1. Inject a preload hint (if possible)+ * 2. Generate an img tag enabling the browser to render the image without the AMP runtime being loaded.+ *+ * Hero images are either identified automatically or can be explicitly defined by adding an `data-hero` attribute to+ * the element.+ *+ * This transformer supports the following options:+ *+ * * `preloadHeroImage`: [true|false] - enables or disables hero image preloading. The default is `true`.+ *+ * This is ported from the NodeJS optimizer.+ *+ * @version 3429af9d91e2c9efe1af85757499e5a308755f5f+ * @link    https://github.com/ampproject/amp-toolbox/blob/3429af9d91e2c9efe1af85757499e5a308755f5f/packages/optimizer/lib/transformers/PreloadHeroImage.js+ *+ * @package ampproject/optimizer+ */+final class PreloadHeroImage implements Transformer+{++    /**+     * Class(es) to apply to a serverside-rendered image element.+     *+     * @var string+     */+    const SSR_IMAGE_CLASS = 'i-amphtml-fill-content i-amphtml-replaced-content';++    /**+     * List of attributes to copy onto an SSR'ed image.+     *+     * @var string[]+     */+    const ATTRIBUTES_TO_COPY = [+        Attribute::ALT,+        Attribute::ATTRIBUTION,+        Attribute::OBJECT_FIT,+        Attribute::OBJECT_POSITION,+        Attribute::REFERRERPOLICY,+        Attribute::SRC,+        Attribute::SRCSET,+        Attribute::SIZES,+        Attribute::TITLE,+    ];++    /**+     * Maximum number of hero images defined via data-hero attribute.+     *+     * @var int+     */+    const DATA_HERO_MAX = 2;++    /**+     * Configuration store to use.+     *+     * @var TransformerConfiguration+     */+    private $configuration;++    /**+     * Instantiate a PreloadHeroImage object.+     *+     * @param TransformerConfiguration $configuration Configuration store to use.+     */+    public function __construct(TransformerConfiguration $configuration)+    {+        $this->configuration = $configuration;+    }++    /**+     * Apply transformations to the provided DOM document.+     *+     * @param Document        $document DOM document to apply the transformations to.+     * @param ErrorCollection $errors   Collection of errors that are collected during transformation.+     * @return void+     */+    public function transform(Document $document, ErrorCollection $errors)+    {+        if ($this->configuration->get(PreloadHeroImageConfiguration::PRELOAD_HERO_IMAGE) === false) {+            return;+        }++        $heroImages    = $this->findHeroImages($document);+        $referenceNode = $document->viewport;++        $heroImageCount = count($heroImages);+        if ($heroImageCount > self::DATA_HERO_MAX) {+            $errors->add(Error\TooManyHeroImages::whenPastMaximum());+            $heroImageCount = self::DATA_HERO_MAX;+        }++        $isAmpStory = Amp::isAmpStory($document);++        for ($index = 0; $index < $heroImageCount; $index++) {+            $this->generatePreload($heroImages[$index], $document, $errors, $referenceNode);+            $this->generateImg($heroImages[$index], $document);+        }+    }++    /**+     * Find the hero images to optimize.+     *+     * @param Document $document Document to look for hero images in.+     * @return HeroImage[] Array of hero images to optimize.+     */+    private function findHeroImages(Document $document)+    {+        $heroImageCandidate = null;+        $heroImages         = [];+        $node               = $document->body;++        while ($node !== null) {+            if (! $node instanceof DOMElement) {+                $node = $this->nextNode($node);+                continue;+            }++            $heroImage = $this->detectImageWithDataHero($node);+            if ($heroImage) {+                $heroImages[] = $heroImage;+            }++            if (! $heroImageCandidate && count($heroImages) === 0) {+                $heroImageCandidate = $this->detectHeroImageCandidate($node);+            }+            if (Amp::isTemplate($node)) {+                // Ignore images inside templates.+                $node = $this->skipNodeAndChildren($node);+            } else {+                $node = $this->nextNode($node);+            }+        }++        // Optimize data-hero element if defined.+        if (count($heroImages) > 0) {+            return $heroImages;+        }++        // Fall back to auto-detected hero image if available.+        if ($heroImageCandidate) {+            return [$heroImageCandidate];+        }++        // No hero images to optimize.+        return [];+    }++    /**+     * Detect a hero image with the data-hero attribute.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image, or null if none detected.+     */+    private function detectImageWithDataHero(DOMElement $element)+    {+        if (+            $element->tagName === Extension::IMAGE+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return new HeroImage(+                $element->getAttribute(Attribute::SRC),+                $element->getAttribute(Attribute::MEDIA),+                $element->getAttribute(Attribute::SRCSET),+                $element+            );+        }++        if (+            Amp::isAmpIframe($element)+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return $this->getPlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate.+     *+     * The hero image here can come from one of <amp-img>, <amp-video>, <amp-iframe>, <amp-video-iframe>.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidate(DOMElement $element)+    {+        if (+            $element->hasAttribute(Attribute::LAYOUT)+            && $element->getAttribute(Attribute::LAYOUT) === Layout::NODISPLAY+        ) {+            return null;+        }++        if ($element->tagName === Extension::IMAGE) {+            return $this->detectHeroImageCandidateForAmpImg($element);+        }++        if ($element->tagName === EXTENSION::VIDEO) {+            return $this->detectHeroImageCandidateForPosterImage($element);+        }++        if (Amp::isAmpIframe($element)) {+            return $this->detectHeroImageCandidateForIframePlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate from an <amp-img> element.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForAmpImg(DOMElement $element)+    {+        $src = $element->getAttribute(Attribute::SRC);++        if (empty($src)) {+            return null;+        }++        if (! Url::isValidImageSrc($src)) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        $srcset = $element->getAttribute(Attribute::SRCSET);+        $media  = $element->getAttribute(Attribute::MEDIA);++        return new HeroImage($src, $media, $srcset, $element);+    }++    /**+     * Detect a hero image candidate from a video's poster (= placeholder) image.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForPosterImage(DOMElement $element)+    {+        $poster = $element->getAttribute(Attribute::POSTER);++        if (! $poster) {+            return null;+        }++        if (! Url::isValidImageSrc($poster)) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        $media = $element->getAttribute(Attribute::MEDIA);++        return new HeroImage($poster, $media, '');+    }++    /**+     * Detect a hero image candidate from an iframe's placeholder image.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForIframePlaceholderImage(DOMElement $element)+    {+        // A placeholder <amp-img> is required to preload an image for an iframe.+        if (! $element->hasChildNodes()) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        return $this->getPlaceholderImage($element);+    }++    /**+     * Get the placeholder image for a given element.+     *+     * @param DOMElement $element Element to check the placeholder image for.+     * @return HeroImage|null Placeholder image to use or null if none found.+     */+    private function getPlaceholderImage(DOMElement $element)+    {+        foreach ($element->childNodes as $childNode) {+            if (+                ! $childNode instanceof DOMElement+                || $childNode->tagName !== Extension::IMAGE+                || ! $childNode->hasAttribute(Attribute::PLACEHOLDER)+            ) {+                continue;+            }+

Nevertheless, should it be checking for amp-anim in addition to amp-img?

schlessera

comment created time in a day

Pull request review commentampproject/amp-wp

Add PreloadHeroImage Optimizer transformer

+<?php++namespace AmpProject\Optimizer\Transformer;++use AmpProject\Amp;+use AmpProject\Attribute;+use AmpProject\Dom\Document;+use AmpProject\Extension;+use AmpProject\Layout;+use AmpProject\Optimizer\Configuration\PreloadHeroImageConfiguration;+use AmpProject\Optimizer\Error;+use AmpProject\Optimizer\ErrorCollection;+use AmpProject\Optimizer\HeroImage;+use AmpProject\Optimizer\ImageDimensions;+use AmpProject\Optimizer\Transformer;+use AmpProject\Optimizer\TransformerConfiguration;+use AmpProject\Tag;+use AmpProject\Url;+use DOMElement;+use DOMNode;++/**+ * PreloadHeroImage - this transformer optimizes image rendering times for hero images. For hero images it will:+ *+ * 1. Inject a preload hint (if possible)+ * 2. Generate an img tag enabling the browser to render the image without the AMP runtime being loaded.+ *+ * Hero images are either identified automatically or can be explicitly defined by adding an `data-hero` attribute to+ * the element.+ *+ * This transformer supports the following options:+ *+ * * `preloadHeroImage`: [true|false] - enables or disables hero image preloading. The default is `true`.+ *+ * This is ported from the NodeJS optimizer.+ *+ * @version 3429af9d91e2c9efe1af85757499e5a308755f5f+ * @link    https://github.com/ampproject/amp-toolbox/blob/3429af9d91e2c9efe1af85757499e5a308755f5f/packages/optimizer/lib/transformers/PreloadHeroImage.js+ *+ * @package ampproject/optimizer+ */+final class PreloadHeroImage implements Transformer+{++    /**+     * Class(es) to apply to a serverside-rendered image element.+     *+     * @var string+     */+    const SSR_IMAGE_CLASS = 'i-amphtml-fill-content i-amphtml-replaced-content';++    /**+     * List of attributes to copy onto an SSR'ed image.+     *+     * @var string[]+     */+    const ATTRIBUTES_TO_COPY = [+        Attribute::ALT,+        Attribute::ATTRIBUTION,+        Attribute::OBJECT_FIT,+        Attribute::OBJECT_POSITION,+        Attribute::REFERRERPOLICY,+        Attribute::SRC,+        Attribute::SRCSET,+        Attribute::SIZES,+        Attribute::TITLE,+    ];++    /**+     * Maximum number of hero images defined via data-hero attribute.+     *+     * @var int+     */+    const DATA_HERO_MAX = 2;++    /**+     * Configuration store to use.+     *+     * @var TransformerConfiguration+     */+    private $configuration;++    /**+     * Instantiate a PreloadHeroImage object.+     *+     * @param TransformerConfiguration $configuration Configuration store to use.+     */+    public function __construct(TransformerConfiguration $configuration)+    {+        $this->configuration = $configuration;+    }++    /**+     * Apply transformations to the provided DOM document.+     *+     * @param Document        $document DOM document to apply the transformations to.+     * @param ErrorCollection $errors   Collection of errors that are collected during transformation.+     * @return void+     */+    public function transform(Document $document, ErrorCollection $errors)+    {+        if ($this->configuration->get(PreloadHeroImageConfiguration::PRELOAD_HERO_IMAGE) === false) {+            return;+        }++        $heroImages    = $this->findHeroImages($document);+        $referenceNode = $document->viewport;++        $heroImageCount = count($heroImages);+        if ($heroImageCount > self::DATA_HERO_MAX) {+            $errors->add(Error\TooManyHeroImages::whenPastMaximum());+            $heroImageCount = self::DATA_HERO_MAX;+        }++        $isAmpStory = Amp::isAmpStory($document);++        for ($index = 0; $index < $heroImageCount; $index++) {+            $this->generatePreload($heroImages[$index], $document, $errors, $referenceNode);+            $this->generateImg($heroImages[$index], $document);+        }+    }++    /**+     * Find the hero images to optimize.+     *+     * @param Document $document Document to look for hero images in.+     * @return HeroImage[] Array of hero images to optimize.+     */+    private function findHeroImages(Document $document)+    {+        $heroImageCandidate = null;+        $heroImages         = [];+        $node               = $document->body;++        while ($node !== null) {+            if (! $node instanceof DOMElement) {+                $node = $this->nextNode($node);+                continue;+            }++            $heroImage = $this->detectImageWithDataHero($node);+            if ($heroImage) {+                $heroImages[] = $heroImage;+            }++            if (! $heroImageCandidate && count($heroImages) === 0) {+                $heroImageCandidate = $this->detectHeroImageCandidate($node);+            }+            if (Amp::isTemplate($node)) {+                // Ignore images inside templates.+                $node = $this->skipNodeAndChildren($node);+            } else {+                $node = $this->nextNode($node);+            }+        }++        // Optimize data-hero element if defined.+        if (count($heroImages) > 0) {+            return $heroImages;+        }++        // Fall back to auto-detected hero image if available.+        if ($heroImageCandidate) {+            return [$heroImageCandidate];+        }++        // No hero images to optimize.+        return [];+    }++    /**+     * Detect a hero image with the data-hero attribute.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image, or null if none detected.+     */+    private function detectImageWithDataHero(DOMElement $element)+    {+        if (+            $element->tagName === Extension::IMAGE+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return new HeroImage(+                $element->getAttribute(Attribute::SRC),+                $element->getAttribute(Attribute::MEDIA),+                $element->getAttribute(Attribute::SRCSET),+                $element+            );+        }++        if (+            Amp::isAmpIframe($element)+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return $this->getPlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate.+     *+     * The hero image here can come from one of <amp-img>, <amp-video>, <amp-iframe>, <amp-video-iframe>.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidate(DOMElement $element)+    {+        if (+            $element->hasAttribute(Attribute::LAYOUT)+            && $element->getAttribute(Attribute::LAYOUT) === Layout::NODISPLAY+        ) {+            return null;+        }++        if ($element->tagName === Extension::IMAGE) {+            return $this->detectHeroImageCandidateForAmpImg($element);+        }++        if ($element->tagName === EXTENSION::VIDEO) {+            return $this->detectHeroImageCandidateForPosterImage($element);+        }++        if (Amp::isAmpIframe($element)) {+            return $this->detectHeroImageCandidateForIframePlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate from an <amp-img> element.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForAmpImg(DOMElement $element)+    {+        $src = $element->getAttribute(Attribute::SRC);++        if (empty($src)) {+            return null;+        }++        if (! Url::isValidImageSrc($src)) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        $srcset = $element->getAttribute(Attribute::SRCSET);+        $media  = $element->getAttribute(Attribute::MEDIA);++        return new HeroImage($src, $media, $srcset, $element);+    }++    /**+     * Detect a hero image candidate from a video's poster (= placeholder) image.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForPosterImage(DOMElement $element)+    {+        $poster = $element->getAttribute(Attribute::POSTER);++        if (! $poster) {+            return null;+        }++        if (! Url::isValidImageSrc($poster)) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        $media = $element->getAttribute(Attribute::MEDIA);++        return new HeroImage($poster, $media, '');+    }++    /**+     * Detect a hero image candidate from an iframe's placeholder image.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidateForIframePlaceholderImage(DOMElement $element)+    {+        // A placeholder <amp-img> is required to preload an image for an iframe.+        if (! $element->hasChildNodes()) {+            return null;+        }++        if ((new ImageDimensions($element))->isTiny()) {+            return null;+        }++        return $this->getPlaceholderImage($element);+    }++    /**+     * Get the placeholder image for a given element.+     *+     * @param DOMElement $element Element to check the placeholder image for.+     * @return HeroImage|null Placeholder image to use or null if none found.+     */+    private function getPlaceholderImage(DOMElement $element)+    {+        foreach ($element->childNodes as $childNode) {+            if (+                ! $childNode instanceof DOMElement+                || $childNode->tagName !== Extension::IMAGE
schlessera

comment created time in a day

PullRequestReviewEvent
PullRequestReviewEvent

Pull request review commentampproject/amp-wp

Add PreloadHeroImage Optimizer transformer

+<?php++namespace AmpProject\Optimizer\Transformer;++use AmpProject\Amp;+use AmpProject\Attribute;+use AmpProject\Dom\Document;+use AmpProject\Extension;+use AmpProject\Layout;+use AmpProject\Optimizer\Configuration\PreloadHeroImageConfiguration;+use AmpProject\Optimizer\Error;+use AmpProject\Optimizer\ErrorCollection;+use AmpProject\Optimizer\HeroImage;+use AmpProject\Optimizer\Transformer;+use AmpProject\Optimizer\TransformerConfiguration;+use AmpProject\Tag;+use AmpProject\Url;+use DOMElement;+use DOMNode;++/**+ * PreloadHeroImage - this transformers optimizes image rendering times for hero images. For hero images it will:+ *+ * 1. Inject a preload hint (if possible)+ * 2. Generate an img tag enabling the browser to render the image without the AMP runtime being loaded.+ *+ * Hero images are either identified automatically or can be explicitly defined by adding an `data-hero` attribute to+ * the element.+ *+ * This transformer supports the following options:+ *+ * * `preloadHeroImage`: [true|false] - enables or disables hero image preloading. The default is `true`.+ *+ * This is ported from the NodeJS optimizer.+ *+ * @version 3429af9d91e2c9efe1af85757499e5a308755f5f+ * @link    https://github.com/ampproject/amp-toolbox/blob/3429af9d91e2c9efe1af85757499e5a308755f5f/packages/optimizer/lib/transformers/PreloadHeroImage.js+ *+ * @package ampproject/optimizer+ */+final class PreloadHeroImage implements Transformer+{++    /**+     * Class(es) to apply to a serverside-rendered image element.+     *+     * @var string+     */+    const SSR_IMAGE_CLASS = 'i-amphtml-fill-content i-amphtml-replaced-content';++    /**+     * List of attributes to copy onto an SSR'ed image.+     *+     * @var string[]+     */+    const ATTRIBUTES_TO_COPY = [+        Attribute::ALT,+        Attribute::ATTRIBUTION,+        Attribute::OBJECT_FIT,+        Attribute::OBJECT_POSITION,+        Attribute::REFERRERPOLICY,+        Attribute::SRC,+        Attribute::SRCSET,+        Attribute::SIZES,+        Attribute::TITLE,+    ];++    /**+     * Images smaller than 150px are considered tiny.+     *+     * @var int+     */+    const TINY_IMG_THRESHOLD = 150;++    /**+     * Maximum number of hero images defined via data-hero attribute.+     *+     * @var int+     */+    const DATA_HERO_MAX = 2;++    /**+     * Configuration store to use.+     *+     * @var TransformerConfiguration+     */+    private $configuration;++    /**+     * Instantiate a PreloadHeroImage object.+     *+     * @param TransformerConfiguration $configuration Configuration store to use.+     */+    public function __construct(TransformerConfiguration $configuration)+    {+        $this->configuration = $configuration;+    }++    /**+     * Apply transformations to the provided DOM document.+     *+     * @param Document        $document DOM document to apply the transformations to.+     * @param ErrorCollection $errors   Collection of errors that are collected during transformation.+     * @return void+     */+    public function transform(Document $document, ErrorCollection $errors)+    {+        if ($this->configuration->get(PreloadHeroImageConfiguration::PRELOAD_HERO_IMAGE) === false) {+            return;+        }++        $heroImages    = $this->findHeroImages($document);+        $referenceNode = $document->viewport;++        $heroImageCount = count($heroImages);+        if ($heroImageCount > self::DATA_HERO_MAX) {+            $errors->add(Error\TooManyHeroImages::whenPastMaximum());+            $heroImageCount = self::DATA_HERO_MAX;+        }++        $isAmpStory = Amp::isAmpStory($document);++        for ($index = 0; $index < $heroImageCount; $index++) {+            $this->generatePreload($heroImages[$index], $document, $errors, $referenceNode);+            if (! $isAmpStory) {+                // AMP Stories don't support SSR'd <amp-img> yet.+                // See https://github.com/ampproject/amphtml/issues/29850.+                $this->generateImg($heroImages[$index], $document);+            }+        }+    }++    /**+     * Find the hero images to optimize.+     *+     * @param Document $document Document to look for hero images in.+     * @return HeroImage[] Array of hero images to optimize.+     */+    private function findHeroImages(Document $document)+    {+        $heroImageCandidate = null;+        $heroImages         = [];+        $node               = $document->body;++        while ($node !== null) {+            if (! $node instanceof DOMElement) {+                $node = $this->nextNode($node);+                continue;+            }++            $heroImage = $this->detectImageWithDataHero($node);+            if ($heroImage) {+                $heroImages[] = $heroImage;+            }++            if (! $heroImageCandidate && count($heroImages) === 0) {+                $heroImageCandidate = $this->detectHeroImageCandidate($node);+            }+            if (Amp::isTemplate($node)) {+                // Ignore images inside templates.+                $node = $this->skipNodeAndChildren($node);+            } else {+                $node = $this->nextNode($node);+            }+        }++        // Optimize data-hero element if defined.+        if (count($heroImages) > 0) {+            return $heroImages;+        }++        // Fall back to auto-detected hero image if available.+        if ($heroImageCandidate) {+            return [$heroImageCandidate];+        }++        // No hero images to optimize.+        return [];+    }++    /**+     * Detect a hero image with the data-hero attribute.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image, or null if none detected.+     */+    private function detectImageWithDataHero(DOMElement $element)+    {+        if (+            $element->tagName === Extension::IMAGE+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return new HeroImage(+                $element->getAttribute(Attribute::SRC),+                $element->getAttribute(Attribute::MEDIA),+                $element->getAttribute(Attribute::SRCSET),+                $element+            );+        }++        if (+            Amp::isAmpIframe($element)+            && $element->hasAttribute(Attribute::DATA_HERO)+        ) {+            return $this->getPlaceholderImage($element);+        }++        return null;+    }++    /**+     * Detect a hero image candidate.+     *+     * The hero image here can come from one of <amp-img>, <amp-video>, <amp-iframe>, <amp-video-iframe>.+     *+     * @param DOMElement $element Element to detect for.+     * @return HeroImage|null Detected hero image candidate, or null if none detected.+     */+    private function detectHeroImageCandidate(DOMElement $element)+    {+        if (+            $element->hasAttribute(Attribute::LAYOUT)+            && $element->getAttribute(Attribute::LAYOUT) === Layout::NODISPLAY+        ) {+            return null;+        }++        if ($element->tagName === Extension::IMAGE) {+            return $this->detectHeroImageCandidateForAmpImg($element);+        }++        if ($element->tagName === EXTENSION::VIDEO) {+            return $this->detectHeroImageCandidateForPosterImage($element);+        }++        if (Amp::isAmpIframe($element)) {+            return $this->detectHeroImageCandidateForIframePlaceholderImage($element);+        }

Apparently to support this, the detectHeroImageCandidateForIframePlaceholderImage method can just be renamed to detectHeroImageCandidateForPlaceholderImage, and instead of looking for direct descendants of the element for image placeholders, it should look for a placeholder direct descendant and then check if either it is an amp-img or it has an amp-img as a descendant (as in the case of a placeholder link having an image inside).

schlessera

comment created time in a day

PullRequestReviewEvent

push eventampproject/amp-wp

Renovate Bot

commit sha aab68318aa0c39105cc17b8a56132c4ac43f7fcc

Update dependency postcss to v8.0.8

view details

Weston Ruter

commit sha 95e1cd17a4b003b0a509e52cfa98bb60319d00f1

Merge pull request #5417 from renovate-bot/renovate/postcss-8.x Update dependency postcss to v8.0.8

view details

push time in a day

PR merged ampproject/amp-wp

Update dependency postcss to v8.0.8 cla: yes dependencies

This PR contains the following updates:

Package Type Update Change
postcss (source) devDependencies patch 8.0.7 -> 8.0.8

Release Notes

<details> <summary>postcss/postcss</summary>

v8.0.8

Compare Source

  • Fix 8.0.7 regression on PostCSS 7 nodes converting (by Adam Wathan).

</details>


Renovate configuration

:date: Schedule: At any time (no schedule defined).

:vertical_traffic_light: Automerge: Disabled by config. Please merge this manually once you are satisfied.

:recycle: Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

:no_bell: Ignore: Close this PR and you won't be reminded about this update again.


  • [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

This PR has been generated by WhiteSource Renovate. View repository job log here.

+10 -10

0 comment

2 changed files

renovate-bot

pr closed time in a day

push eventampproject/amp-wp

Ryan Kienstra

commit sha 16d2a7164821ae0990660f44f36655adc3c161e6

In linting commands, only lint diff from develop As Weston suggested, there's not much need to lint files that have no diff. This should run in Travis builds, as it does npm run lint.

view details

Ryan Kienstra

commit sha 404b770fd20ba2b2a6fbdbc167997c6bc21083c9

If there is no diff to develop, don't lint As described in the issue, there's no need to lint a file with no diff to develop.

view details

Ryan Kienstra

commit sha 89ee859a237904ba197004eb26a80827c7bcafca

Add a helper script to be more DRY There probably isn't a need to copy the same command to 3 other places. So add a helper script.

view details

Ryan Kienstra

commit sha 546126733ef4d5703b04fa2857d819c2eac4a591

Change diff:develop to diff-develop It looks like most package.json scripts with a colon are for when there are multiple scripts that have the same prefix.

view details

Ryan Kienstra

commit sha 740f3d130777dc07cda92ec464a762c81eb78890

Remove pre-commit hook

view details

Ryan Kienstra

commit sha 7d35852b1a1efa74b1dc71acd1162bc11e0d7edd

Merge branch 'develop' into update/lint-changed-develop

view details

Ryan Kienstra

commit sha 4973402bf40a46e15230822f53781acb20a33dc8

Commit Weston's suggestion for the regex of lint:css Co-Authored-By: Weston Ruter <westonruter@google.com>

view details

Ryan Kienstra

commit sha 83e21556ba66a5a33464a9486e883c6ca990c785

Replace diff-develop script with simple git command Instead of registering a new script, simply use that git command.

view details

Pierre Gordon

commit sha 4c40a7537e392258faca25ce80a7b5cc5d4c8b51

Merge branch 'develop' into update/lint-changed-develop

view details

Pierre Gordon

commit sha 6af326bbee51362c8964f96b07011ed38646ee8e

Only run lint command when there are changes

view details

Pierre Gordon

commit sha 485bdfce1a7717ada225f7c90a5e9db382854d08

Remove external script

view details

Pierre Gordon

commit sha c365250ebd5a1df71610b991dc234b235ebef509

Detect file renames

view details

Pierre Gordon

commit sha ab034bce6c1a879c07fedcd4b943ed1413bae14d

Use lint-staged package to perform linting on staged files

view details

Pierre Gordon

commit sha 76a97167473966a7311c92343fde871436c0434e

Only lint, not fix

view details

Pierre Gordon

commit sha 2c8505746cbedc939ad0dc39821565d6ec96bd7f

Directly use phpcs command instead of `lint:plugin-bootstrap` npm script Co-authored-by: Weston Ruter <westonruter@google.com>

view details

Weston Ruter

commit sha 047e28fb964143b51c468355cdf00f51d7a8b4f6

Merge pull request #4441 from ampproject/update/lint-changed-develop In linting scripts, only lint diff from develop

view details

push time in a day

delete branch ampproject/amp-wp

delete branch : update/lint-changed-develop

delete time in a day

PR merged ampproject/amp-wp

Reviewers
In linting scripts, only lint diff from develop WS:Core cla: yes

Summary

  • In package.json linting scripts, this only lints the diff from develop
  • ~Adds a pre-commit hook, using husky (maybe out of scope for this PR)~
  • ~If we don't all want a pre-commit hook, maybe I should revert it. It's not optional in the way the wp-dev-lib pre-commit hook is. It's installed on npm install.~
  • ~The pre-commit hook doesn't overwrite existing pre-commit hooks~
  • ~Please do npm install to install the pre-commit hook~

Fixes #4402

Checklist

  • [x] My pull request is addressing an open issue (please create one otherwise).
  • [x] My code is tested and passes existing tests. (Manually tested, but unit testing doesn't really apply)
  • [x] My code follows the Engineering Guidelines (updates are often made to the guidelines, check it out periodically).
+626 -7

8 comments

2 changed files

kienstra

pr closed time in a day

issue closedampproject/amp-wp

Limit linting and fixing to files changed with develop

Feature description

Currently running linting commands like npm run lint:php is slow because it checks every file. We should limit to just checking the files that have changed in comparison with develop. In other words,

vendor/bin/phpcs $(git diff develop --name-only | grep php)

If no PHP files are changed, then it should also just short-circuit.

This should be done for PHP, JS, and CSS.

This will then allow for the lint commands to be added to a pre-commit hook.

The lint:fix commands could also benefit from this.


Do not alter or remove anything below. The following sections will be managed by moderators only.

Acceptance criteria

  • <!-- One or more bullet points for acceptance criteria. -->

Implementation brief

  • <!-- One or more bullet points for how to technically resolve the issue. For significant Implementation Design, it is ok use a Google document accessible by anyone. -->

QA testing instructions

  • <!-- One or more bullet points to describe how to test the implementation in QA. -->

Demo

  • <!-- A video or screenshots demoing the implementation. -->

Changelog entry

  • <!-- One sentence summarizing the PR, to be used in the changelog. -->

closed time in a day

westonruter
PullRequestReviewEvent

Pull request review commentampproject/amp-wp

In linting scripts, only lint diff from develop

     "test:php": "phpunit",     "test:php:help": "npm run test:php -- --help"   },+  "lint-staged": {+    "package.json": [+      "npm run lint:pkg-json"+    ],+    "**/*.css": [+      "npm run lint:css"+    ],+    "**/*.js": [+      "npm run lint:js"+    ],+    "**/!(amp).php": [+      "npm run lint:php"+    ],+    "amp.php": [+      "npm run lint:plugin-bootstrap"

This fixes the issue above when linting amp.php:

      "vendor/bin/phpcs --runtime-set testVersion 5.2-"
kienstra

comment created time in 2 days

PullRequestReviewEvent

Pull request review commentampproject/amp-wp

In linting scripts, only lint diff from develop

     "lint:js": "wp-scripts lint-js",     "lint:js:fix": "npm run lint:js -- --fix",     "lint:php": "vendor/bin/phpcs",-    "lint:plugin-bootstrap": "vendor/bin/phpcs --runtime-set testVersion 5.2- amp.php",     "lint:php:fix": "./bin/phpcbf.sh",+    "lint:plugin-bootstrap": "vendor/bin/phpcs --runtime-set testVersion 5.2- amp.php",

Notice how it is invoking phpcs:

vendor/bin/phpcs --runtime-set testVersion 5.2- amp.php "/app/public/content/plugins/amp/amp.php"

Notice amp.php is being added twice.

kienstra

comment created time in 2 days

PullRequestReviewEvent

Pull request review commentampproject/amp-wp

In linting scripts, only lint diff from develop

     "lint:js": "wp-scripts lint-js",     "lint:js:fix": "npm run lint:js -- --fix",     "lint:php": "vendor/bin/phpcs",-    "lint:plugin-bootstrap": "vendor/bin/phpcs --runtime-set testVersion 5.2- amp.php",     "lint:php:fix": "./bin/phpcbf.sh",+    "lint:plugin-bootstrap": "vendor/bin/phpcs --runtime-set testVersion 5.2- amp.php",

For some reason this command is failing for me, when invoked via lint-staged:

$ npm run lint:staged

> amp-wp@ lint:staged /app/public/content/plugins/amp
> lint-staged

✔ Preparing...
✔ Hiding unstaged changes to partially staged files...
⚠ Running tasks...
  ↓ No staged files match package.json [SKIPPED]
  ↓ No staged files match **/*.css [SKIPPED]
  ↓ No staged files match **/*.js [SKIPPED]
  ✔ Running tasks for **/!(amp).php
  ❯ Running tasks for amp.php
    ✖ npm run lint:plugin-bootstrap [FAILED]
↓ Skipped because of errors from tasks. [SKIPPED]
↓ Skipped because of errors from tasks. [SKIPPED]
✔ Reverting to original state because of errors...
✔ Cleaning up...

✖ npm run lint:plugin-bootstrap:
PHP Fatal error:  Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: Undefined index:  in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Files/FileList.php on line 187 in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php:606
Stack trace:
#0 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Files/FileList.php(187): PHP_CodeSniffer\Runner->handleErrors(8, 'Undefined index...', '/app/public/con...', 187, Array)
#1 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php(487): PHP_CodeSniffer\Files\FileList->current()
#2 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php(114): PHP_CodeSniffer\Runner->run()
#3 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/bin/phpcs(18): PHP_CodeSniffer\Runner->runPHPCS()
#4 {main}
  thrown in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php on line 606
PHP Fatal error:  Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: One or more child processes failed to run in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php:544
Stack trace:
#0 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php(114): PHP_CodeSniffer\Runner->run()
#1 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/bin/phpcs(18): PHP_CodeSniffer\Runner->runPHPCS()
#2 {main}
  thrown in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php on line 544
npm ERR! code ELIFECYCLE
npm ERR! errno 255
npm ERR! amp-wp@ lint:plugin-bootstrap: `vendor/bin/phpcs --runtime-set testVersion 5.2- amp.php "/app/public/content/plugins/amp/amp.php"`
npm ERR! Exit status 255
npm ERR!
npm ERR! Failed at the amp-wp@ lint:plugin-bootstrap script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /var/www/.npm/_logs/2020-09-23T03_46_30_988Z-debug.log

> amp-wp@ lint:plugin-bootstrap /app/public/content/plugins/amp
> vendor/bin/phpcs --runtime-set testVersion 5.2- amp.php "/app/public/content/plugins/amp/amp.php"


Fatal error: Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: Undefined index:  in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Files/FileList.php on line 187 in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php:606
Stack trace:
#0 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Files/FileList.php(187): PHP_CodeSniffer\Runner->handleErrors(8, 'Undefined index...', '/app/public/con...', 187, Array)
#1 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php(487): PHP_CodeSniffer\Files\FileList->current()
#2 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php(114): PHP_CodeSniffer\Runner->run()
#3 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/bin/phpcs(18): PHP_CodeSniffer\Runner->runPHPCS()
#4 {main}
  thrown in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php on line 606

Fatal error: Uncaught PHP_CodeSniffer\Exceptions\RuntimeException: One or more child processes failed to run in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php:544
Stack trace:
#0 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php(114): PHP_CodeSniffer\Runner->run()
#1 /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/bin/phpcs(18): PHP_CodeSniffer\Runner->runPHPCS()
#2 {main}
  thrown in /app/public/content/plugins/amp/vendor/squizlabs/php_codesniffer/src/Runner.php on line 544
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! amp-wp@ lint:staged: `lint-staged`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the amp-wp@ lint:staged script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /var/www/.npm/_logs/2020-09-23T03_46_34_383Z-debug.log
kienstra

comment created time in 2 days

PullRequestReviewEvent

push eventampproject/amp-wp

Weston Ruter

commit sha 9771152d7f69242331dec9cc194ee0e146fafd68

Bump stable tag 2.0.4 and regenerate docs

view details

push time in 2 days

push eventampproject/amp-wp

Weston Ruter

commit sha 83f588f53ed1671849a00bc9f5a9fa8cc4a8b518

Bump 2.0.5-alpha

view details

push time in 2 days

created tagampproject/amp-wp

tag2.0.4-built

Enable AMP on your WordPress site, the WordPress way.

created time in 2 days

created tagampproject/amp-wp

tag2.0.4

Enable AMP on your WordPress site, the WordPress way.

created time in 2 days

release ampproject/amp-wp

2.0.4

amp.zip 1.52MB

released time in 2 days

push eventampproject/amp-wp

Weston Ruter

commit sha 823ae999158fcd1ae0b2c5c93736103a23fecae9

Bump 2.0.4 and update docs

view details

push time in 2 days

GollumEvent
GollumEvent
GollumEvent

pull request commentampproject/amp-wp

Prevent enabling all post types for AMP when migrating to 2.0 when Reader mode active

Confirmed that when the amp-options option is reset via:

echo '{"theme_support":"reader","supported_post_types":["post"],"analytics":[],"all_templates_supported":true,"supported_templates":["is_singular"],"version":"1.5.5"}' | wp --skip-plugins option set amp-options --format=json

The Supported Templates does not include content types other than post as enabled (since all_templates_supported is not respected):

image

If I change the theme_support to transitional as follows:

echo '{"theme_support":"transitional","supported_post_types":["post"],"analytics":[],"all_templates_supported":true,"supported_templates":["is_singular"],"version":"1.5.5"}' | wp --skip-plugins option set amp-options --format=json

Then all post types are enabled by default as expected (since all_templates_supported is respected):

image

westonruter

comment created time in 2 days

issue closedWordPress/gutenberg

Media upload component does not select or highlight a file in the media library.

Describe the bug I am using a duplicate of the Post Featured Image component for a Newsletter attachment which saves to its own post meta.

However I noticed that the value prop of MediaUpload does not select the file in the media library.

The only way I could get this to happen is to use the unstableFeaturedImageFlow prop, but this is not ideal as it changes the modal to have the wording for a Featured Image - so I had to remove it and live with the file not being pre-selected.

I think this could be fixed by extending the MediaUpload component myself, but its a bit beyond my knowledge at this point. I also don't understand why it should be necessary when the README for the Media Upload component says:

value Media ID (or media IDs if multiple is true) to be selected by default when opening the media library.

To reproduce Make a duplicate of the Post Featured Image component in your own custom sidebar panel. Remove unstableFeaturedImageFlow prop and rely on just the value prop to select the file in the media library.

Expected behavior Value prop of MediaUpload should select the file in the media library using the ID.

Editor version (please complete the following information):

  • WordPress version: 5.5.1
  • Does the website has Gutenberg plugin installed, or is it using the block editor that comes by default? default

closed time in 2 days

ThatStevensGuy

issue commentWordPress/gutenberg

Media upload component does not select or highlight a file in the media library.

AMP plugin issue: https://github.com/ampproject/amp-wp/issues/5379. Fixed via https://github.com/ampproject/amp-wp/pull/5412. This will be part of AMP plugin v2.0.4, which we are releasing today.

ThatStevensGuy

comment created time in 2 days

issue commentampproject/amp-wp

WordPress MediaUpload component does not select files when AMP plugin is active.

QA Passed.

I added an audio block, an image block, and set the featured image.

When clicking “replace” for the audio block, the previously-selected audio file was automatically selected:

image

The same was true for the featured image and image blocks.

ThatStevensGuy

comment created time in 2 days

push eventampproject/amp-wp

Weston Ruter

commit sha 0e03b6469cc9eff98f549e834d535d77383a8296

Bump 2.0.4-RC1

view details

push time in 2 days

push eventampproject/amp-wp

Weston Ruter

commit sha 307028c4e69ea86505874428cb30c435a608f7cf

Guard against infinite recursion error when validating AMP pages using a Reader theme (#5410) Co-authored-by: Alain Schlesser <alain.schlesser@gmail.com>

view details

push time in 2 days

push eventampproject/amp-wp

Weston Ruter

commit sha 54acb48f5b829153cfbba89c8381e590eb027145

Prevent FileReflection from triggering hooks when Reader theme loaded

view details

Alain Schlesser

commit sha bf3d65190ddee8d2df2f67c7ce6d5707c79143fb

Add DI-specific test case

view details

Alain Schlesser

commit sha 5e4d7b38499bdd165e9e7ff35046485ecbd1bd4c

Use injector for ErrorPage as well and make the IDE recognize the return type

view details

Alain Schlesser

commit sha de212723696eeed56712db6a6e82266be6fc0d85

Add missing doc comment

view details

Weston Ruter

commit sha b724da524b85830bf9b7357c70598d899ecbe42d

Fix test_analyze_backtrace by ensuring custom theme's functions.php is required

view details

Weston Ruter

commit sha 1afdf5a2957f0165110e22b844ec7fbf7f1b414d

Fix test_filter_wp_prepare_themes_to_indicate_reader_theme

view details

Weston Ruter

commit sha 3520815b220cecdd7348ce0b3a7ebe77a87fa8f2

Mark DependencyInjectedTestCase as abstract to skip from being tested

view details

Weston Ruter

commit sha 3cd294ea8d80d19a980c1869d80fb96c67d4b0cf

Deep-link to Reader Themes section from theme card

view details

Alain Schlesser

commit sha 80b4cfb51e4b884ad8b3fb6638f6f1c2a4d520c3

Avoid service container in tests and use injector instead

view details

Alain Schlesser

commit sha b676efbb8c073db6b506c6fa3ef09258137e67e5

Add clarifying comment to DependencyInjectionTestCase about plugin factory

view details

Alain Schlesser

commit sha 51c60a0b6ed7b7a218a270f0bd60b67205022fce

Fix unset index error in reader theme test

view details

Alain Schlesser

commit sha 1179cca2fe23f9661494259af892890bac33a999

Add recursion protection to file reflector

view details

Alain Schlesser

commit sha efd9afcc3db5d325edb6e617cd3fda721087f4e9

Revert previous fix effort

view details

Alain Schlesser

commit sha 90a102be25e3403cc48dbe5e9f425c5fa4026bfd

Fix PHPStan issues

view details

Weston Ruter

commit sha 639cb4402bd4127910c2720dfe38eaf1ee0ae87a

Remove obsolete ReaderThemeLoader dependency

view details

Weston Ruter

commit sha ae8afad7eb1e1839e0379cd8ddb98c8f2554d373

Remove amp_options_updating filters to work around unexpected test failure

view details

Alain Schlesser

commit sha 589e8bc9a3311ce2014f419aac426e9925c62eec

Add tearDown() to DependencyInjectedTestCase

view details

Alain Schlesser

commit sha 6513409a058e34e29f0b144132d66fe117b6ba51

Fix PHPCS issue

view details

Alain Schlesser

commit sha ae8766be80dc5818799e90227cad440593a08fa8

Remove unneeded comment

view details

Weston Ruter

commit sha 5ef559ef2e6466e94087f4554c731a8bb08bdc8e

Merge pull request #5410 from ampproject/fix/reader-theme-validation Guard against infinite recursion error when validating AMP pages using a Reader theme

view details

push time in 2 days

delete branch ampproject/amp-wp

delete branch : fix/reader-theme-validation

delete time in 2 days

PR merged ampproject/amp-wp

Guard against infinite recursion error when validating AMP pages using a Reader theme cla: yes

Summary

Fixes #5409

~This PR prevents FileReflection from causing infinite recursion when a Reader theme has been loaded. When the theme has been overridden with a Reader theme, the current theme is obtained via ReaderThemeLoader as opposed to using global functions that have filters.~

This PR adds recursion prevention to \AmpProject\AmpWP\DevTools\FileReflection::get_file_source(). When a Reader theme is loaded (via ReaderThemeLoader), hooks are added to override which theme is active. When validating an AMP page with such a Reader theme, applying those filters can cause infinite recursion since the get_file_source also needs to apply the same filters to determine where a callback is coming from.

Checklist

  • [x] My pull request is addressing an open issue (please create one otherwise).
  • [x] My code is tested and passes existing tests.
  • [x] My code follows the Engineering Guidelines (updates are often made to the guidelines, check it out periodically).
+355 -111

22 comments

24 changed files

westonruter

pr closed time in 2 days

issue closedampproject/amp-wp

Validation requests fail due to infinite recursion when Reader theme is selected

Bug Description

I noticed that when a Reader theme is selected, attempting to validate a URL will fail:

image

The PHP error log includes:

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 978944 bytes) in /app/public/content/plugins/amp/includes/validation/class-amp-validation-manager.php on line 1328

The issue is that there is either infinite recursion or infinite loop happening here:

https://github.com/ampproject/amp-wp/blob/27718b00bfbaacd4013f1cdbb590dc3f4371b4bf/includes/validation/class-amp-validation-manager.php#L1313-L1323

When the hook is one of:

  • template
  • stylesheet
  • pre_option_template
  • pre_option_stylesheet
  • pre_option_template_root
  • pre_option_stylesheet_root

This function loop will continue on infinitely and PHP will run out of memory.

These hooks are added by the ReaderThemeLoader:

https://github.com/ampproject/amp-wp/blob/27718b00bfbaacd4013f1cdbb590dc3f4371b4bf/src/ReaderThemeLoader.php#L321-L346

I believe this is a regression introduced by #5289. Specifically, the issue is with FileReflection in these methods:

https://github.com/ampproject/amp-wp/blob/27718b00bfbaacd4013f1cdbb590dc3f4371b4bf/src/DevTools/FileReflection.php#L216-L270

We need to avoid calling get_template_directory() and other such functions

Expected Behaviour

Validation should succeed.

Steps to reproduce

  1. Activate Reader mode.
  2. Select a Reader theme.
  3. Validate a page.
  4. See error.

Do not alter or remove anything below. The following sections will be managed by moderators only.

Acceptance criteria

  • <!-- One or more bullet points for acceptance criteria. -->

Implementation brief

  • <!-- One or more bullet points for how to technically resolve the issue. For significant Implementation Design, it is ok use a Google document accessible by anyone. -->

QA testing instructions

  • <!-- One or more bullet points to describe how to test the implementation in QA. -->

Demo

  • <!-- A video or screenshots demoing the implementation. -->

Changelog entry

  • <!-- One sentence summarizing the PR, to be used in the changelog. -->

closed time in 2 days

westonruter

issue commentampproject/amp-wp

Increase clarity and improve placement of featured image size recommendation

  1. The reason for the recommendation should be made clear. If I understand correctly, it derives from the recommendations here: https://developers.google.com/search/docs/data-types/article#article_types But valid structured data might not be important to all users.

That is correct. The reason it doesn't mention AMP specifically, is that it is a general Google Search recommendation/requirement. Nevertheless, you're right that some users won't care. It's just that when Google Search Console complains about missing structured data or an image that is too small, we want to be able to say that we warned them.

johnwatkins0

comment created time in 2 days

issue commentampproject/amp-wp

Improve discoverability of “Save Changes” button on AMP settings screen

@jwold I don't think the button should become the notice, as otherwise what will the user click to retry? Clicking “Save Error” seems to indicate that the error would be saved. I think the success and error notices should be floated to the right.

westonruter

comment created time in 2 days

Pull request review commentampproject/amp-wp

Guard against infinite recursion error when validating AMP pages using a Reader theme

+<?php++namespace AmpProject\AmpWP\Tests;++use AmpProject\AmpWP\AmpWpPlugin;+use AmpProject\AmpWP\Infrastructure\Injector;+use AmpProject\AmpWP\Infrastructure\ServiceContainer;+use AmpProject\AmpWP\Services;+use AmpProject\AmpWP\Tests\Helpers\PrivateAccess;+use WP_UnitTestCase;++abstract class DependencyInjectedTestCase extends WP_UnitTestCase {++	use PrivateAccess;++	/**+	 * Plugin instance to test with.+	 *+	 * @var AmpWpPlugin+	 */+	protected $plugin;++	/**+	 * Service container instance to test with.+	 *+	 * @var ServiceContainer+	 */+	protected $container;++	/**+	 * Injector instance to test with.+	 *+	 * @var Injector+	 */+	protected $injector;++	/**+	 * Runs the routine before each test is executed.+	 */+	public function setUp() {+		parent::setUp();++		// We're intentionally avoiding the AmpWpPluginFactory here as it uses a+		// static instance, because its whole point is to allow reuse across consumers.+		$this->plugin = new AmpWpPlugin();+		$this->plugin->register();++		$this->container = $this->plugin->get_container();+		$this->injector  = $this->container->get( 'injector' );++		// 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 );+		$this->set_private_property( Services::class, 'injector', $this->injector );

Looks good: 589e8bc9a3311ce2014f419aac426e9925c62eec

westonruter

comment created time in 2 days

more