Problem/Motivation

In reviewing #3037668-17: Improve visual coherence of the media library, @lauriii had this to say:

We shouldn't use js- prefixed classes for styling. Since this is just adding RTL styles for a pre-existing selector, we should probably just open a follow-up for this.

This is that follow-up. We should remove any styling from CSS classes that are prefixed with js-.

Proposed resolution

Remove styling rules from any Media Library CSS classes that are prefixed with js-.

Remaining tasks

Patch, review, commit.

User interface changes

There'd better be none, or we've done our job wrong.

API changes

None. These are styling changes in an experimental module.

Data model changes

None.

Release notes snippet

None needed.

Comments

phenaproxima created an issue. See original summary.

bnjmnm’s picture

Status: Active » Needs review
StatusFileSize
new43.33 KB

Added classes, updated css and created an UpdatePathTestBase test since there is a config change.
Originally tried implementing the config change in hook_update_X, but this caused other update tests to fail -- not entirely sure why admittedly. Instead it's a post_update.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
  1. +++ b/core/modules/media_library/config/install/views.view.media_library.yml
    @@ -121,7 +121,7 @@ display:
    -          element_class: js-click-to-select-checkbox
    +          element_class: js-click-to-select-checkbox click-to-select-checkbox
    
    @@ -452,7 +452,7 @@ display:
    -          element_class: js-click-to-select-checkbox
    +          element_class: js-click-to-select-checkbox click-to-select-checkbox
    
    @@ -805,7 +805,7 @@ display:
    -          element_wrapper_class: js-click-to-select-checkbox
    +          element_wrapper_class: js-click-to-select-checkbox click-to-select-checkbox
    
    @@ -1016,7 +1016,7 @@ display:
    -          element_wrapper_class: js-click-to-select-checkbox
    +          element_wrapper_class: js-click-to-select-checkbox click-to-select-checkbox
    

    👍 These retain BC.

  2. +++ b/core/modules/media_library/css/media_library.module.css
    @@ -47,7 +47,7 @@
    -.media-library-item .js-click-to-select-trigger {
    +.media-library-item .click-to-select-trigger {
    
    @@ -56,14 +56,14 @@
    -.media-library-item .js-click-to-select-checkbox {
    +.media-library-item .click-to-select-checkbox {
    
    +++ b/core/modules/media_library/css/media_library.theme.css
    @@ -404,12 +404,12 @@
    -.media-library-item--grid .js-click-to-select-checkbox input {
    +.media-library-item--grid .click-to-select-checkbox input {
    

    👍 These set the right example for contrib & custom code to follow.

  3. +++ b/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateCheckboxClassesTest.php
    @@ -0,0 +1,83 @@
    +      $has_prefixed_class = strpos($classes, 'js-click-to-select-checkbox') !== FALSE;
    +      $has_non_prefixed_class = strpos($classes, ' click-to-select-checkbox') !== FALSE;
    +      $this->assertTrue($has_prefixed_class);
    +      $this->assertFalse($has_non_prefixed_class);
    ...
    +      $has_prefixed_class = strpos($classes, 'js-click-to-select-checkbox') !== FALSE;
    +      $has_non_prefixed_class = strpos($classes, ' click-to-select-checkbox') !== FALSE;
    +      $this->assertTrue($has_prefixed_class);
    +      $this->assertTrue($has_non_prefixed_class);
    

    👍 This test coverage looks solid!

phenaproxima’s picture

StatusFileSize
new43.23 KB

Just a l'il ol' reroll, so leaving RTBC in place.

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/media_library/config/install/views.view.media_library.yml
@@ -121,7 +121,7 @@ display:
+          element_class: js-click-to-select-checkbox click-to-select-checkbox

@@ -492,7 +492,7 @@ display:
+          element_class: js-click-to-select-checkbox click-to-select-checkbox

@@ -846,7 +846,7 @@ display:
+          element_wrapper_class: js-click-to-select-checkbox click-to-select-checkbox

@@ -1057,7 +1057,7 @@ display:
+          element_wrapper_class: js-click-to-select-checkbox click-to-select-checkbox

The CSS class not prefixed with js- should use BEM. Maybe something like media-library-item__click-to-select-checkbox?

bnjmnm’s picture

Status: Needs work » Needs review
StatusFileSize
new43.82 KB
new43.82 KB

Changed to BEM and reduced CSS specificity where possible.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/modules/media_library/media_library.post_update.php
@@ -311,7 +311,8 @@ function media_library_post_update_add_status_extra_filter() {
-function media_library_post_update_add_buttons_to_page_view() {
+function media_library_post_update_add_buttons_to_page_view()
+{

🤓 Silly PHPStorm reformatted this… But that can be fixed on commit.

lauriii’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/modules/media_library/css/media_library.theme.css
    @@ -404,12 +404,12 @@
    -.media-library-item--grid .js-click-to-select-checkbox input {
    +.media-library-item__click-to-select-checkbox input {
    ...
    -.media-library-item--grid .js-click-to-select-checkbox .form-item {
    +.media-library-item--grid .media-library-item__click-to-select-checkbox .form-item {
    

    Was there a particular reason why we could remove .media-library-item--grid from the first selector but not from the second?

  2. +++ b/core/modules/media_library/css/media_library.module.css
    @@ -47,7 +47,7 @@
    +.media-library-item .click-to-select-trigger {
    
    +++ b/core/modules/media_library/media_library.module
    @@ -115,7 +115,7 @@ function media_library_preprocess_media(&$variables) {
    +    $variables['preview_attributes']->addClass('media-library-item__preview', 'js-media-library-item-preview', 'js-click-to-select-trigger', 'click-to-select-trigger');
    

    Sorry that I didn't mention this earlier but we should probably also convert this to use BEM.

bnjmnm’s picture

Status: Needs work » Needs review
StatusFileSize
new2.45 KB
new44.35 KB

#8.1

Was there a particular reason why we could remove .media-library-item--grid from the first selector but not from the second?

That was done to achieve greater specificity than the margin set by
.media-library-item--grid .form-item, I moved that rule to appear earlier in the file (adjacent to other .media-library-item--grid styles), and that was able to remove the extra selector.

#8.2 BEM-ified click-to-select-trigger, pretty much just spaced on that one 🙂

wim leers’s picture

Status: Needs review » Reviewed & tested by the community
lauriii’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/media_library/media_library.post_update.php
@@ -108,7 +108,7 @@ function media_library_post_update_table_display() {
-      'element_wrapper_class' => 'js-click-to-select-checkbox',
+      'element_wrapper_class' => 'js-click-to-select-checkbox media-library-item__click-to-select-checkbox',

This change prevents tests to fully cover all cases. This can be confirmed by removing widget_table from the display items list. Tests pass even after that.

This is all very hypothetical but given that it's upgrade paths, it's better to be safe. This post update could have been run in someone's environment already, and if the media_library_post_update_checkbox_classes doesn't have full test coverage, it could be theoretically broken without us noticing it. 😢

bnjmnm’s picture

Status: Needs work » Needs review
StatusFileSize
new727 bytes
new43.92 KB

Good catch on #11! Fortunately, that change is completely unnecessary so it's been removed.

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 12: 3049943-12.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

bnjmnm’s picture

Status: Needs work » Needs review
StatusFileSize
new42.15 KB
new70.78 KB
new45.65 KB
new42.15 KB
new70.78 KB
new45.65 KB

Even changing getEditable() to get() in the test did not address the conflicts with media_library_post_update_table_display(), which adds a display that is altered by the new post_update added here. To get around this the pre-update fixture was updated so the view has all media post_updates applied other than the one added in this issue, and post_update.existing_updates made to reflect that.

Also renamed the fixture file to include the issue ID.

phenaproxima’s picture

Status: Needs review » Needs work

I think this looks pretty good and thorough. Nice test coverage! I'd like to see a few small changes, but overall I am +1 for the approach.

  1. +++ b/core/modules/media_library/media_library.module
    @@ -115,7 +115,7 @@ function media_library_preprocess_media(&$variables) {
    -    $variables['preview_attributes']->addClass('media-library-item__preview', 'js-media-library-item-preview');
    +    $variables['preview_attributes']->addClass('media-library-item__preview', 'js-media-library-item-preview', 'js-click-to-select-trigger', 'media-library-item__click-to-select-trigger');
    

    Why was this changed? Perhaps this warrants a comment.

  2. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -529,3 +529,42 @@ function media_library_post_update_add_buttons_to_page_view() {
    +  $config = \Drupal::configFactory()->getEditable('views.view.media_library');
    

    This is a post-update function, so we can use the full Drupal APIs (e.g., View::load() and friends).

    On second thought, I see that we're doing this to improve the abstraction. So okay, we can keep it this way if we want to.

  3. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -529,3 +529,42 @@ function media_library_post_update_add_buttons_to_page_view() {
    +      'display_type' => 'default',
    

    display_type is a misleading name for this key. It's really the display_id, so let's change it to that.

  4. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -529,3 +529,42 @@ function media_library_post_update_add_buttons_to_page_view() {
    +      'class_key' => 'element_class',
    

    This is misleading too. 'class_key' doesn't really mean anything to me; this is actually a configuration option for a particular field in a particular display of the view. So maybe something like 'option' instead?

  5. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -529,3 +529,42 @@ function media_library_post_update_add_buttons_to_page_view() {
    +      'form' => 'media_bulk_form',
    

    Similarly, I think 'form' is misleading. It's the name of the field in the view, so perhaps something like 'field' would be better.

  6. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -529,3 +529,42 @@ function media_library_post_update_add_buttons_to_page_view() {
    +    if (strpos($classes, 'media-library-item__click-to-select-checkbox') === FALSE) {
    

    Although I find it extremely unlikely, this will collide with existing classes like foo--media-library-item__click-to-select-checkbox. I don't think we necessarily need to change anything here, but a safer thing to do (if we want to be extra paranoid) is to split the classes into an array and use in_array(). But that's extra complexity for, probably, little gain.

  7. +++ b/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateCheckboxClassesTest.php
    @@ -0,0 +1,83 @@
    +    $display_items = [
    +      [
    +        'display_type' => 'default',
    +        'class_key' => 'element_class',
    +        'form' => 'media_bulk_form',
    +      ],
    +      [
    +        'display_type' => 'page',
    +        'class_key' => 'element_class',
    +        'form' => 'media_bulk_form',
    +      ],
    +      [
    +        'display_type' => 'widget',
    +        'class_key' => 'element_wrapper_class',
    +        'form' => 'media_library_select_form',
    +      ],
    +      [
    +        'display_type' => 'widget_table',
    +        'class_key' => 'element_wrapper_class',
    +        'form' => 'media_library_select_form',
    +      ],
    +    ];
    

    We should change the misleading keys here too.

  8. +++ b/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateCheckboxClassesTest.php
    @@ -0,0 +1,83 @@
    +      $has_prefixed_class = strpos($classes, 'js-click-to-select-checkbox') !== FALSE;
    +      $has_non_prefixed_class = strpos($classes, 'media-library-item__click-to-select-checkbox') !== FALSE;
    +      $this->assertTrue($has_prefixed_class);
    +      $this->assertFalse($has_non_prefixed_class);
    

    This is a bit awkward to read; I think we can use assertContains() and assertNotContains() instead.

  9. +++ b/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateCheckboxClassesTest.php
    @@ -0,0 +1,83 @@
    +      $has_prefixed_class = strpos($classes, 'js-click-to-select-checkbox') !== FALSE;
    +      $has_non_prefixed_class = strpos($classes, 'media-library-item__click-to-select-checkbox') !== FALSE;
    +      $this->assertTrue($has_prefixed_class);
    +      $this->assertTrue($has_non_prefixed_class);
    

    Same here.

bnjmnm’s picture

Status: Needs work » Needs review
StatusFileSize
new7.52 KB
new45.34 KB

Addressed all the items in #16 other than #2, which also mentioned it's fine as-is.

For #16.1, that weird change was due to changes in #3062375: Media library item loses focus when hovering over item's title being committed recently. The changes have been moved to where the classes now live.

phenaproxima’s picture

Status: Needs review » Needs work

Only minor stuff, but otherwise this looks good code-wise.

  1. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -537,33 +537,34 @@ function media_library_post_update_checkbox_classes() {
    +    $classes_array = explode(' ', $classes);
    

    This needs to be preg_split(), I think, to account for the possibility of multiple spaces between class names. Something like: $classes_array = preg_split('/\s+/', $classes);.

  2. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -537,33 +537,34 @@ function media_library_post_update_checkbox_classes() {
    +    if (!in_array('media-library-item__click-to-select-checkbox', $classes_array)) {
    

    We should pass TRUE as the third argument to in_array().

  3. +++ b/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateCheckboxClassesTest.php
    @@ -32,51 +32,47 @@ public function testAddNonPrefixedClasses() {
    +      $classes = explode(' ', $config->get($config_location));
    

    Might wanna use preg_split() here too.

bnjmnm’s picture

Status: Needs work » Needs review
StatusFileSize
new2.36 KB
new45.37 KB

#18 👌On paying attention to detail even as stable looms near. Changes made.

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community

Yeah, I'm cool with it. 😎 RTBC once green on all backends.

bnjmnm’s picture

Status: Reviewed & tested by the community » Needs review

Setting back to Needs Review to see if the tests can be improved.

bnjmnm’s picture

StatusFileSize
new38.85 KB
new44.73 KB

The concerns mentioned in #11 exposed an execution order that is addressed in this patch.

phenaproxima’s picture

  1. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -529,3 +529,49 @@ function media_library_post_update_add_buttons_to_page_view() {
    + * hook_post_update_NAME() implementations within the same file are  executed
    

    Supernit: there are two spaces before "executed".

  2. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -529,3 +529,49 @@ function media_library_post_update_add_buttons_to_page_view() {
    +  $view = Views::getView('media_library');
    

    We should bail out if the view has been deleted for some reason:

    if (!$view) {
      return;
    }
    
  3. +++ b/core/modules/media_library/media_library.post_update.php
    @@ -529,3 +529,49 @@ function media_library_post_update_add_buttons_to_page_view() {
    +      $view->storage->save(TRUE);
    

    Nit: This can be $view->save().

  4. +++ b/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateCheckboxClassesTest.php
    @@ -0,0 +1,84 @@
    +    ];
    +    ¶
    +    foreach ($display_items as $item) {
    

    Whoops, looks like there's some extra white space right above the foreach.

  5. +++ b/core/modules/media_library/tests/src/Functional/Update/MediaLibraryUpdateCheckboxClassesTest.php
    @@ -0,0 +1,84 @@
    +      $this->assertContains('media-library-item__click-to-select-checkbox', $classes, "NAH $display_id.$field.$option");
    

    Should "NAH" be in there?

bnjmnm’s picture

StatusFileSize
new2.62 KB
new44.8 KB

Addresses feedback from #23

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Needs work

This is looking good. I think we can be a bit more careful with the update.

+++ b/core/modules/media_library/media_library.post_update.php
@@ -529,3 +529,52 @@ function media_library_post_update_add_buttons_to_page_view() {
+    $display = &$view->storage->getDisplay($display_id);
+    $classes = $display['display_options']['fields'][$field][$option];

This update needs to be a bit more robust and expect that the media library might have changed. So we should expect that the display might exist. And maybe the field has been removed.

phenaproxima’s picture

Another thing that might be worth looking into: over in #3081587-58: Multilingual content is shown double in the media library view, @seanB encountered a similar "hey, we can't control the order of updates" thing. His solution was to add the required changes to both updates that are affected by it, effectively removing any need for them to happen in a particular order. Is that a tactic we might be able to take advantage of here, too?

bnjmnm’s picture

Status: Needs work » Needs review
StatusFileSize
new45.04 KB
new963 bytes

Added the checks per #26

Re #27, I'd much rather keep concerns separated in their own functions now that I've confirmed it's possible to control the order of post_update calls within the same file.
From docs in module.api.php:

 * NAME can be arbitrary machine names. In contrast to hook_update_N() the
 * alphanumeric naming of functions in the file is the only thing which ensures
 * the execution order of those functions. If update order is mandatory,
 * you should add numerical prefix to NAME or make it completely numerical.

Plus I confirmed it via Xdebug since the docs for earlier versions of 8.x stated that the order was determined by their placement in the file.

phenaproxima’s picture

+++ b/core/modules/media_library/media_library.post_update.php
@@ -570,6 +570,13 @@ function media_library_post_update_update_8001_checkbox_classes() {
+    if (!$display ||
+      !isset($display['display_options']['fields'][$field]) ||
+      !isset($display['display_options']['fields'][$field][$option])) {
+      continue;
+    }

Small nit here -- we don't need to do the two isset checks, since there's implicit checking, AFAIK. So we can do something like: if (!$display || !isset($display['display_options']['fields'][$field][$option])).

bnjmnm’s picture

StatusFileSize
new843 bytes
new44.97 KB

#29 is correct! Apparently it looked redundant because it was redundant. Here's the change.

phenaproxima’s picture

Status: Needs review » Needs work
+++ b/core/modules/media_library/media_library.post_update.php
@@ -572,9 +572,7 @@ function media_library_post_update_update_8001_checkbox_classes() {
+    if (!$display || !isset($display['display_options']['fields'][$field][$option])) {

Sorry to move the goal post again -- I know how frustrating that is.

I noticed a thing here, though -- we probably shouldn't check if the option is set, since for all we know, a NULL/unset option could be totally legitimate. Views plugins work in mysterious ways. So I would remove [$option] from the isset() check.

Otherwise, this is fine. Please restore RTBC when a new patch is up.

phenaproxima’s picture

Status: Needs work » Reviewed & tested by the community

Nope! On second thought, it's good as-is. The reason being, as @bnjmnm explained in Slack, that the alternative is this:

if (!$display || !extremely_long_isset_call()) {
  continue;
}
$classes = extremely_long_isset_call() ? $display[$very][$long][$key][$ending][$with][$option] : '';

Ugh.

So no: it's fine the way it is. Let's go for it.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 0ec69d3 and pushed to 8.8.x. Thanks!

  • alexpott committed 0ec69d3 on 8.8.x
    Issue #3049943 by bnjmnm, phenaproxima, Wim Leers, lauriii, alexpott:...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.