Problem/Motivation
There are numerous assumptions in the responsive image code of sort ordering of image multipliers. Including the following code comment:
// Retrieve all breakpoints and multipliers and reverse order of breakpoints.
// By default, breakpoints are ordered from smallest weight to largest:
// the smallest weight is expected to have the smallest breakpoint width,
// while the largest weight is expected to have the largest breakpoint
// width. For responsive images, we need largest breakpoint widths first, so
// we need to reverse the order of these breakpoints.
Steps to reproduce
Found this while working on #3192234: Apply width and height attributes to allow responsive image tag use loading="lazy".
Proposed resolution
Force the order of all responsive image mappings to a known (proper) order.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comments
Comment #2
heddnComment #3
heddnComment #4
heddnComment #6
heddnComment #7
fabianx commentedRTBC - Looks great - nice catch!
But needs tests as this is a bug report.
Comment #8
heddnTest added
Comment #9
heddnComment #10
fabianx commentedPlease add a fail only patch as well.
Usually core committees want to see that …
Comment #11
heddnHere's a fail patch.
Comment #12
heddn\
The fail patch doesn't have these lines.
Comment #14
heddnI took another look at the fail patch this morning. We still need the
SORT_NUMERICin BreakpointManager. Because that is what forces the order when rendering the image styles mapping page. We don't want the page to print 1.5x, 1x, 2x, etc. As a side-product, that was also forcing a certain (incorrect) order of mapping when saving the form. The incorrect order was only enforced because the order the render elements were printed on the page. The new approach/solution is to add apreSaveon the responsive image style itself. This is more resilient and covers any means that the image style can be interacted with. But it doesn't solve the mapping page rendering issue. So we need both hunks of code. But the fail patch shows that any incorrectly ordered image style doesn't get fixed on save. And that the fix patch resolves this problem.Comment #15
fabianx commentedRTBC - thanks for the failing test and test.
This is good to go now!
Comment #18
heddnTo keep the testbot from re-testing the fail patch, re-uploading the latest patch from #11. No other changes, so leaving in RTBC.
Comment #21
catchCommitted/pushed to 10.0.x and cherry-picked to 9.4.x, thanks!
Comment #22
xjmThis broke 10.0.x HEAD, presumably because it uses the old 9.0.0 DB dumps that don't exist anymore. This fail is even shown in #11.
Reverting from both branches. We probably want a patch that uses the 9.3.0 database dumps for both branches. Thanks!
Comment #25
heddnComment #26
fabianx commentedBack to RTBC
Comment #27
larowlanCouple of questions:
Are we realistically able to remove this?
Is 'deprecated methods' accurate, wouldn't it be 'deprecated config'?
Should we be triggering a deprecation error so that e.g. install profiles can know that their config is outdated? This would require a second argument, a boolean $emit_deprecation that we'd pass FALSE to in the update hook, and TRUE to from the preSave.
supernit, but do we need the variable here?
nit: This comments doesn't describe the intention of this file, which is a fixture, not a test.
nit: should we call array_unique here too?
nit: missing a docblock here
Comment #28
heddnresponses to #27:
1) If a profile is invoking reasonable test coverage itself, it would start to fail its own tests because the before/after config after install wouldn't match. In fact, that is the default with an BTB of the install profile and you would have to go out of your way to disable it by setting
strictConfigSchema = false. So I don't think we need to add deprecation logic. However, I did clean-up the comment (it was copy/pasta from views code). Interestingly enough, views also looks suspect to the same, "Is this really something that can realistically ever get removed?"2) I tried it the other way around just now by having direct returns of true or false. I didn't like it. Having a variable that flags if something is changed is more self explanatory. With just returning true/false, I have to provide a lot more context what the boolean return values signify. So I left that hunk as-is This is also a copy/pasta from View's previous work on writing config updates, so there is some precedent for using it.
3) Fixed
4) Layout builder doesn't do that in
core/modules/layout_builder/tests/fixtures/update/layout-builder.php. This is modeled after that same approach. Is the fixture suspect of having duplicate array keys for the same previously installed post_update's?5) Fixed
Comment #29
boulaffasae commentedRTBC
Comment #30
heddnChanging status based on #29.
Comment #31
catchInstall profiles and modules that ship config need to update their shipped config via new exports every major release to keep up.
However I think @larowlan's correct that we should be triggering deprecations for the shipped config case. Even if it gets caught for profiles, it won't for modules and themes.
ViewsConfigUpdater handles this:
See for example
processEntityLinkUrlHandler()Comment #34
heddnBack to NR now that #31 is addressed. Note there is a 10x and 9.4.x branch open to handle the differences between how we need to handle BC.
Comment #35
catchDrupal 10 patch is failing tests because it's removing the update - the update needs to be in both branches because no-one can update to 9.4 yet before updating to Drupal 10, and we so far won't prevent people going from 9.3.x to Drupal 10.
I think it would probably be easiest to make the deprecations for removal in Drupal 11, and have exactly the same MR apply to both 10.x and 9.4.x. (turned myself around twice in the MR comments until I realised what exactly was going wrong).
Comment #37
heddnClosing the 10.x branch as we don't need distinct code. Changed deprecation to removal in Drupal 11 and switched to using the 9.3 db fixture.
Comment #38
catchThose changes all look much better to me, moving back to RTBC.
Comment #39
larowlanHiding patches because there's an MR
Comment #40
larowlanDidn't mean to change the status, but then reviewed the MR and I think we've got the triggering around the wrong way, unless I'm missing something?
Comment #41
catchThe triggering is wrong in the update hook (it should set deprecations to FALSE), but not in presave() (where the default is for deprecations to be on anyway) - left a comment on the MR and marking needs work for that.
Comment #42
heddnComment #43
heddnHaving the presave is nice for continually maintaining a normalized configuration. But the underlying bug is addressed with the form re-ordering. We might want to keep it long-term, among other reasons, to support the upgrade path from picture module in Drupal 7. But let's leave that decision to the issue that removes all this logic in prep for Drupal 11. That is sufficient time to determine if we should move the logic into something more permanent. Or if we just adjust the D7 upgrade migration to appropriately sort order the multiplier itself.
Comment #44
graber commentedRTBCing that. Just one concern with IDE-specific usually useless asserts added here and there that'd probably need a discussion but I'm not going to let it block the issue.
Comment #45
larowlanCan we get a 10.0.x MR here too so we can test on both branches?
Thanks
Comment #47
heddnComment #48
heddnActually, I don't know why I created 2 patches. They are both identical between 9.5.x and 10.0.x
Comment #49
steveoriolOK, cool, I confirm that pacth #47 also works with D9.4.0 after an "drush updb".
Comment #50
larowlanHad a chat with xjm and she agreed at this stage, this issue would be 10.1 only now because of the update hook and new deprecations
So can we get this re-rolled with an updated depreciation notice that references 10.1 instead of 9.4
Then we can get this into 10.1 ASAP
Comment #51
heddnRebased on 10.1. Cleaned up the MR and updated the version string accordingly. Hopefully things pass green and this is ready for a quick RTBC.
Comment #52
smustgrave commentedThis looks good. See there was already a tests-only patch sweet!
FYI though it was hard to follow between switching back n forth between patches and MR.
Comment #53
larowlanComment #54
larowlanCouple of unresolved threads on the MR
Comment #55
heddnI'm not saying that the feedback can't be done. I spell out how it can in the MR. But it really feels icky letting DI force us down a work around path when
addImageStyleMappingshould be sorting as it adds items to the list.Comment #56
heddnActually, before I go down that road of fixing the non trivial aspects, bumping back to NR for input first.
Comment #57
heddnResponded to the whitespace feedback. Pending more feedback on DI question. To add more the debate, calling
\Drupal::service('breakpoint.manager')_already_ happens incalculateDependencies. If we want to remove that DI failure, I think we need to open a follow-up to see how we can untangle the required dependencies between breakpoints and responsive images.For now, flipping this back to RTBC since all feedback that _can_ be addressed is addressed and the only change was a small whitespace fixup.
Comment #58
catchNeeds updating to use the 9.4.0 database dumps.
Comment #59
heddnFixed fixture. That test passed locally so I'm going to move this back to RTBC again in the theory that testbot will also agree.
Comment #60
catchIf we're already calling the breakpoint manager, then the current patch isn't really making things worse, so I think we can proceed here once there's a follow-up to look into the interdependency - no idea how to resolve that cleanly tbh.
Comment #61
heddnOpened #3305192: Untangle interdependencies of ResponsiveImageStyle from Breakpoints to work on the dependency complexities.
Comment #62
alina.basarabeanu commentedWe are using patch #47 on drupal 9.4.2, PHP version 8.0.21 together with the issue https://www.drupal.org/project/drupal/issues/3192234
It applies cleanly and solves the issue in our project.
Comment #63
alina.basarabeanu commentedApologise, I changed the version by mistake
Comment #64
hitchshock+1 RTBC
It works well on my projects.
I'm using the patch from #47 + #191 from https://www.drupal.org/project/drupal/issues/3192234
Comment #65
catchCommitted 4c87cc0 and pushed to 10.1.x. Thanks!
Let's open a follow-up for the dependency injection cross-dependencies.
Comment #67
catchComment #68
heddnre #65: #3305192: Untangle interdependencies of ResponsiveImageStyle from Breakpoints was opened back in #61.
Comment #69
quietone commentedUpdated the branch/version info and published the CR.
Comment #71
dave reidSince the original commits on this issue were also committed to Drupal 9, is there a chance we could still get #47 committed to 9.5.x due to this being a bug please?
Comment #72
larowlanDiscussed #71 in slack with @Dave Reid, but here's my comment for posterity
See https://www.drupal.org/about/core/policies/core-change-policies/allowed-... and https://www.drupal.org/about/core/policies/core-change-policies/allowed-... for the sections in the 'allowed changes' regarding those two policies
The same was detailed above in #50 too