Introduce OD_Element class and improve PHP API#1585
Conversation
| * @return array<string, non-empty-array<int, OD_Element>> Keys are XPaths and values are the element instances. | ||
| */ | ||
| public function get_all_denormalized_elements(): array { | ||
| public function get_all_elements(): array { |
There was a problem hiding this comment.
I don't really like the get_all_elements name. It's more like get_elements_grouped_by_xpath.
There was a problem hiding this comment.
How about get_all_elements_by_xpath()?
There was a problem hiding this comment.
That works, but then it would seem like you could pass an $xpath to get just the elements with the given XPath.
There was a problem hiding this comment.
Like document.getElementById()
There was a problem hiding this comment.
That's fair, though I'm not sure how including the word grouped would clarify that. FWIW to me that all helps to clarify this will return "all" elements, not just the elements filtered by something.
There was a problem hiding this comment.
How about get_xpath_elements_map()?
f8485bd to
c3e55f9
Compare
3de4632 to
57964fb
Compare
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
@felixarntz Thoughts on this? |
felixarntz
left a comment
There was a problem hiding this comment.
@westonruter This looks great so far. Only a few points of feedback.
| $resized_bounding_client_rect = $element->get( 'resizedBoundingClientRect' ); | ||
| if ( ! is_array( $resized_bounding_client_rect ) ) { | ||
| continue; | ||
| } | ||
| $group = $element->url_metric->group; | ||
| $group_min_width = $group->get_minimum_viewport_width(); | ||
| if ( ! isset( $minimums[ $group_min_width ] ) ) { | ||
| $minimums[ $group_min_width ] = array( | ||
| 'group' => $group, | ||
| 'height' => $element['resizedBoundingClientRect']['height'], | ||
| 'height' => $resized_bounding_client_rect['height'], | ||
| ); | ||
| } else { | ||
| $minimums[ $group_min_width ]['height'] = min( | ||
| $minimums[ $group_min_width ]['height'], | ||
| $element['resizedBoundingClientRect']['height'] | ||
| $resized_bounding_client_rect['height'] |
There was a problem hiding this comment.
Just curious: Wouldn't all this marked code also have worked in the way it was before this change, given OD_Element implements ArrayAccess?
There was a problem hiding this comment.
Yes, it would have worked the same. I made this change because of a PHPStan issue where attempting to access $element['resizedBoundingClientRect']['height'] results in a PHPStan error:
phpstan: Cannot access offset 'height' on array{width: float, height: float, x: float, y: float, top: float, right: float, bottom: float, left: float}|bool|float|non-empty-string.
PHPStan isn't constraining the type based on the type of $element['resizedBoundingClientRect'] based on the key resizedBoundingClientRect so the possible types are a union of all values in ElementData, which also doesn't necessarily include this extended resizedBoundingClientRect key's type (although here it is a DOMRect).
This goes back to wanting to be able to provide richer typing in PHPStan for getters like this, but in the meantime resorting to using OD_Element::get() which returns mixed and then checking the return value as being an array avoids the PHPStan error.
Although I'm a bit surprised it's not complaining that the $resized_bounding_client_rect['height'] key may not be defined since if I do PHPStan\dumpType($resized_bounding_client_rect) it is typed as just array. But this appears to be as expected: https://phpstan.org/r/bc084e48-691a-4232-be15-7b806fda8b3e. I recall there was some PHPStan extension to make checks even more strict than strict rules mandate all array keys be checked as well, but I can't find how to do that off hand.
| * @return array<string, non-empty-array<int, OD_Element>> Keys are XPaths and values are the element instances. | ||
| */ | ||
| public function get_all_denormalized_elements(): array { | ||
| public function get_all_elements(): array { |
There was a problem hiding this comment.
How about get_all_elements_by_xpath()?
| * @var OD_URL_Metric | ||
| * @readonly | ||
| */ | ||
| public $url_metric; |
There was a problem hiding this comment.
Let's not use a public property, as we wouldn't want this to be writable (the annotation is not enough). Can you instead add e.g. a get_url_metric() method? For convenience, you may even want to add a get_url_metric_group() or get_group() method as a shorthand, given that $group was previously easily accessible in the return value of the get_all_denormalized_elements() method.
There was a problem hiding this comment.
What about the public $group property on OD_URL_Metric? It has to be mutable since \OD_URL_Metric_Group::add_url_metric() needs to be able to assign it to the group when it is added.
There was a problem hiding this comment.
I must have missed that one before. Better to use a setter then for OD_URL_Metric::$group.
For this one though, would we even need to set it?
There was a problem hiding this comment.
No, I don't think there is a need for a set_url_metric(). I'll add a getter for both and a setter for one.
felixarntz
left a comment
There was a problem hiding this comment.
@westonruter Thanks, LGTM!
See https://github.com/WordPress/performance/pull/1373/files#r1792652840:
The
OD_Elementclass implementsArrayAccessso it is fully backwards-compatible with using values as arrays. So where existing plugins may do$element['isLCP']this will still continue to work, although$element->is_lcp()would now be preferable. There is also a$element->get()method which allows accessing extended element data. This is closely related to #1492 which did the same forOD_URL_Metric.