-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disambiguate XPaths for children of BODY with id
, class
, or role
attributes
#1797
base: trunk
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## trunk #1797 +/- ##
=======================================
Coverage 57.38% 57.39%
=======================================
Files 84 84
Lines 6517 6549 +32
=======================================
+ Hits 3740 3759 +19
- Misses 2777 2790 +13
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Oh, I just discovered that the Image block with a lightbox is involved here. With the changes in this PR applied, WordPress outputs a <div
class="wp-lightbox-overlay zoom"
data-wp-interactive="core/image"
data-wp-context='{}'
data-wp-bind--role="state.roleAttribute"
data-wp-bind--aria-label="state.currentImage.ariaLabel"
data-wp-bind--aria-modal="state.ariaModal"
data-wp-class--active="state.overlayEnabled"
data-wp-class--show-closing-animation="state.showClosingAnimation"
data-wp-watch="callbacks.setOverlayFocus"
data-wp-on--keydown="actions.handleKeydown"
data-wp-on-async--touchstart="actions.handleTouchStart"
data-wp-on--touchmove="actions.handleTouchMove"
data-wp-on-async--touchend="actions.handleTouchEnd"
data-wp-on-async--click="actions.hideLightbox"
data-wp-on-async-window--resize="callbacks.setOverlayStyles"
data-wp-on-async-window--scroll="actions.handleScroll"
tabindex="-1"
>
<button type="button" aria-label="Close" style="fill: var(--wp--preset--color--contrast)" class="close-button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" aria-hidden="true" focusable="false"><path d="m13.06 12 6.47-6.47-1.06-1.06L12 10.94 5.53 4.47 4.47 5.53 10.94 12l-6.47 6.47 1.06 1.06L12 13.06l6.47 6.47 1.06-1.06L13.06 12Z"></path></svg>
</button>
<div class="lightbox-image-container">
<figure data-wp-bind--class="state.currentImage.figureClassNames" data-wp-bind--style="state.figureStyles">
<img class="od-missing-dimensions" data-od-added-class data-od-xpath="/HTML/BODY/DIV[@class='wp-lightbox-overlay zoom']/*[2][self::DIV]/*[1][self::FIGURE]/*[1][self::IMG]" data-wp-bind--alt="state.currentImage.alt" data-wp-bind--class="state.currentImage.imgClassNames" data-wp-bind--style="state.imgStyles" data-wp-bind--src="state.currentImage.currentSrc">
</figure>
</div>
<div class="lightbox-image-container">
<figure data-wp-bind--class="state.currentImage.figureClassNames" data-wp-bind--style="state.figureStyles">
<img class="od-missing-dimensions" data-od-added-class data-od-xpath="/HTML/BODY/DIV[@class='wp-lightbox-overlay zoom']/*[3][self::DIV]/*[1][self::FIGURE]/*[1][self::IMG]" data-wp-bind--alt="state.currentImage.alt" data-wp-bind--class="state.currentImage.imgClassNames" data-wp-bind--style="state.imgStyles" data-wp-bind--src="state.enlargedSrc">
</figure>
</div>
<div class="scrim" style="background-color: var(--wp--preset--color--base)" aria-hidden="true"></div>
<style data-wp-text="state.overlayStyles"></style>
</div> Note the XPath for the
Without the disambiguation, this would be:
This could be confused with an Image block appearing somewhere especially when Important If this change is made to add the disambiguation predicates to To ease this migration, we may want to add an performance/plugins/optimization-detective/class-od-element.php Lines 56 to 64 in 6ca5c4b
Then anywhere that we compare XPaths we should use this helper function as opposed to using Update: This is not so straightforward. For example, This is also the case for code that uses Up until now, the XPath has been very constrained in its format, so it has been a reliably fixed string for comparisons. Changing the XPath construction has impacts that need to be carefully evaluated. |
@westonruter I'm not sure I fully understand.
Are you saying this is only inserted with this change? Why that? OD shouldn't alter which DOM elements are inserted by any features right?
So are you saying without this PR merged, there would be a risk of a duplicate? If so, it would be a good indicator that the risk we assessed as small on the other PR isn't actually that small and we should cater for it.
Why that? Would it invalidate even URL metrics that have an index (how they're currently stored, without the recent |
No, I'm saying that this was already being added to the page by Gutenberg. I wasn't aware that Gutenberg was outputting lightbox elements at
Correct.
What I mean is that URL Metrics currently stored use the node index, for example |
@westonruter Makes sense. So maybe we need to leave old data intact for now then and only migrate when we have all the context we need (i.e. in a request to the relevant URL). Since #1790 is not in any release yet, at least we don't have to worry about migrating from that. But we probably should fix it before this upcoming release. This complicates things of course, but given we already found an exception in Core itself, this is probably going to happen more. Any plugin may add some |
@felixarntz Well, I mean, "migration" will happen eventually as URL Metrics turn stale and get purged from the site. It would be ideal if a change to the XPath structure didn't result in this, however. It would be as if someone installed the plugin anew without any data collected. |
This is a follow-up to #1790 which fixed #1787.
It is now possible for a generated XPath may not uniquely identify an element in a page. Consider the following example:
DIV
for header and footer,<div id="header" role="banner">
and<div id="footer" role="contentinfo">
, which are direct children of theBODY
.DIV
:In this case, both of the
IMG
tags here will have the same XPath:/HTML/BODY/DIV/*[1][self::IMG]
.I did a search for
<div[^>]*role=["']?banner
in WPDirectory and the only example I could find with a header and footer being direct children ofBODY
is the Prose theme (2,000 active installs and not updated in 12 years): https://themes.trac.wordpress.org/browser/prose/1.1/header.phpGranted, this search assumes that a theme is using the right ARIA roles. It wouldn't account for someone using
<div id="header">
.As noted in #1790 (comment):
This is experimented on in this PR, by adding the
id
,class
, androle
attributes to the XPaths generated for children of theBODY
element. So in the example above, instead of both elements having the same XPath of/HTML/BODY/DIV/*[1][self::IMG]
they would then be distinct:/HTML/BODY/DIV[@id='header'][@role='banner']/*[1][self::IMG]
/HTML/BODY/DIV[@id='footer'][@role='contentinfo']/*[1][self::IMG]
The key changes in this PR are found in
plugins/optimization-detective/class-od-html-tag-processor.php
. All the other changes are adjustments to the tests.