Problem/Motivation
Doing a composer upgrade on drupal 8.8.x on php 7.1+ installs symfony/dom-crawler 4.3.3. At some point between 4.2.11 and 4.3.3, it began to cause test failures of the type: Behat\Mink\Exception\ElementNotFoundException : Element matching xpath "./ancestor::form" not found in around a dozen tests.
Okay, So the root of this comes down to a few form render arraysputting html into the #field_prefix and #field_suffix keys.
Those are rendered inside of tags, so it creates invalid html that the html parser can't parse correctly.
$element['min_resolution'] = [
'#type' => 'item',
'#title' => t('Minimum image resolution'),
'#element_validate' => [[get_class($this), 'validateResolution']],
'#weight' => 4.2,
'#field_prefix' => '<div class="container-inline">',
'#field_suffix' => '</div>',
'#description' => t('The minimum allowed image size expressed as WIDTH×HEIGHT (e.g. 640×480). Leave blank for no restriction. If a smaller image is uploaded, it will be rejected.'),
];
This ends up outputting
<span class="field_prefix"><div class='container-inline'></span>
...stuff...
<span class="field_suffix"></div></span>
There seems to be a few examples of this throughout core.
Proposed resolution
Adjust the render arrays for Drupal 8.8.
file a follow-up to add a composer conflict for dom-crawler >= 4.3.3 for 8.7
Remaining tasks
- get release manager review
- commit
User interface changes
no
API changes
no
Data model changes
no
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #10 | Screenshot 2019-08-09 at 11.39.46.png | 27.62 KB | wim leers |
| #8 | 3072752-8-with-composer-lock-changes.patch | 10.14 KB | amateescu |
| #8 | 3072752-8.patch | 5.26 KB | amateescu |
Comments
Comment #2
mikelutzHere's a composer.lock patch showing the relevant failures.
Comment #3
mikelutzComment #5
mikelutzThe code to find the xpath doesn't seem to have changed. What has changed is how the Dom is loaded into the crawler. Starting in 4.3, dom-crawler is using Masterminds/html5 to load the dom. I assume the issue is there somewhere, but it's tough to inspect these dom objects in xdebug, so I haven't yet figured out exactly what has changed.
Comment #6
mikelutzOkay, So the root of this comes down to the image field settings form putting html into the #field_prefix and #field_suffix keys.
Those are rendered inside of tags, so it creates invalid html that the html parser can't parse correctly.
There seems to be a few examples of this throughout core. Curious as to what breaks vs what is fixed if we just take it out.
Comment #7
mikelutzYeah, so that fixed the ones I expected it to. The The CK errors likely correspond to the same thing in editor.admin.inc
On the Views table one at the moment I seem to be unable to get it to pass after reverting to HEAD, so I must be missing something in my development environment right now, maybe due to all the recent composer changes. I may need to clear out my vendor directory, I'm not quite sure yet.
Comment #8
amateescu commentedI think the
#field_prefixand#field_suffixparts inImageItem::fieldSettingsForm()andeditor_image_upload_settings_form()are simply a misusage of Form API, and should be completely fine to be fixed in a minor release.Here's a fix for them and also for
StyleTableTest::testAccessibilitySettings().Comment #9
mikelutzI think this is right, tagging for RM review, and +1 to RTBC from me. The issue exists in 8.7 as well, but if the bugfix is determined to be too disruptive for a patch release, I recommend adding a conflict for symfony/dom-crawler >=4.3.0 to 8.7 to avoid using the new parser and to allow tests to pass with updated dependencies.
Comment #10
wim leersNice.
form--inlinewas added in #2333719: Abstract Views Exposed Form styling out into a reusable class in 2015. This code was originally added in #1932652: Add image uploading to WYSIWYGs through editor.module in 2013.I manually tested this and it continues to look the same:
Since all changes are in forms, and then even admin forms, and no form structure changes, only some styling-related markup changes, I am confident this change is acceptable, at least in Drupal 8.8.
Comment #11
wim leersComment #12
andypostThis clean-up is great but it needs CR about element
Comment #13
wim leersCan you elaborate on why you think this needs a change record, @andypost?
Comment #14
andypostBuild arrays are not a part of API but affects every custom(probably contrib) fields which extends core field type for image
this formally not BC break but good to know... it's hard to catch if no regression testing
Comment #15
gábor hojtsy@Wim Leers: In my understanding, despite being just admin forms, there still may be people form altering for field prefix / suffix and now will not override what they used to override. So I think that is where @andypost is coming from. Better be safe than sorry :D
Comment #16
mikelutzComment #17
mikelutzComment #18
xjmThanks everyone!
In this case I think we can forego the CR since the markup change is purely removing broken markup from a render array in one element (without any changes required to templates etc.) It's sort of on the edge, but these changes are allowed in minors and typically don't need a CR. According to the frontend BC policy, this type of change is OK in a minor release.
That said, it's a bit too disruptive to backport. Therefore, @mikelutz is going to file a followup issue for 8.7 to add a conflict for dom-crawler 4.3 so that sites don't accidentally update to a library that will cause breakage.
Comment #19
mikelutzComment #20
xjmAnd it's here: #3074039: Add a composer conflict for symfony/dom-crawler >=4 to 8.7 only.
Comment #22
xjmThis looks straightforward. Thanks also for the manual testing.
The one question I had about this is that the opening tag is now attached to one element as the prefix, and the closing tag is attached to the next element as a suffix, without any structure/nesting and so just relying on the default order of the two render elements. It's not a big deal since these essentially form one conceptual unit but it does cause psychological tension.
While we could change the render array to get around this (e.g. with
#type => 'html_tag'or such), @mikelutz, @samuel.mortenson, and I discussed the issue and agreed that would actually be more disruptive. I thought of looking for other places in core where an opening tag and a closing tag are attached to sibling elements but that's difficult to grep for... and after all, markup that might be broken under theoretical alters is less bad than markup that's 100% broken now.I think put more words into thinking about this than are in the patch. ;) Anyway, this seems alright, so committed to 8.8.x.
Thanks!
Comment #24
xjmComment #25
xjmComment #26
wim leershttps://twitter.com/wimleers/status/1160569258256011264 😁
Comment #28
kristen polPer a Slack discussion with Gábor Hojtsy regarding usage of D9 tags (Drupal 9, Drupal 9 compatibility, Drupal 9 readiness, etc.), "Drupal 9 compatibility" should be used for contributed projects that need updating and "Drupal 9" was the old tag for D8 issues before the D9 branch was ready. Doing tag cleanup here based on that discussion.
Comment #29
jibranClosed a duplicate issue #2667340: Usage of field_prefix and container-inline creates invalid markup..