Problem/Motivation

When swapping out the body element, then Drupal behaviors are not applied by core/drupal.htmx library's htmx-behaviors.js.

The file htmx-behaviors.js contains following event listener:

  htmx.on('htmx:drupal:load', ({ detail }) => {
    attachFromHtmx = true;
    Drupal.attachBehaviors(detail.elt, drupalSettings);
    attachFromHtmx = false;
  });

It's being triggered by the logic within htmx-assets.js (also part of core/drupal.htmx):

  htmx.on('htmx:afterSettle', ({ detail }) => {
    requestAssetsLoaded.get(detail.xhr).then(() => {
      // Some HTMX swaps put the incoming element before or after detail.elt.
      htmx.trigger(detail.elt.parentNode, 'htmx:drupal:load');
      // This should be automatic but don't wait for the garbage collector.
      requestAssetsLoaded.delete(detail.xhr);
    });
  });

This logic does not trigger the event listener when the element being swapped is the <body> element.

Steps to reproduce

Add hx-boost="true" as an attribute to the <body> element and add core/drupal.htmx library via template_preprocess_html.

Proposed resolution

This part of the logic within htmx-assets.js passes along the parent element:

htmx.trigger(detail.elt.parentNode, 'htmx:drupal:load');

When doing this instead:

      if (detail.elt.tagName === 'BODY') {
        htmx.trigger(detail.elt, 'htmx:drupal:load');
      }
      else {
        htmx.trigger(detail.elt.parentNode, 'htmx:drupal:load');
      }

Then the event listener is triggered and behaviors are attached as expected. So maybe we need to handle the body element as some sort of exception at this place?

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3560659

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

mxh created an issue. See original summary.

nod_’s picture

Makes sense, htmx does have an exception for the body when using outerHTML, we could do that too. I'm not super happy with how we figure out what is the element passed to attachbehaviors but I don't have better to propose.

fathershawn’s picture

Component: asset library system » ajax system
quietone’s picture

Version: 11.3.x-dev » 11.x-dev

Just adjusting version.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

fathershawn’s picture

Status: Active » Needs review

Tests passing. Test only branch provided as Nightwatch tests are not run by the test only job, as far as I know.

godotislate’s picture

Couple questions on the MR. Otherwise changes look pretty straightforward. Nice work!

Nightwatch test fails as expected on test-only MR: https://git.drupalcode.org/issue/drupal-3560659/-/jobs/8259106

godotislate’s picture

Status: Needs review » Reviewed & tested by the community

Think this looks good now.

longwave’s picture

Status: Reviewed & tested by the community » Fixed

Backported to 11.3.x as a low risk eligible bug fix.

Committed and pushed 07d426b4075 to main and cf25b3cd1b7 to 11.x and 25e70b1b59b to 11.3.x. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • longwave committed 25e70b1b on 11.3.x
    fix: #3560659 HTMX Drupal behaviors are not applied when swapped element...

  • longwave committed cf25b3cd on 11.x
    fix: #3560659 HTMX Drupal behaviors are not applied when swapped element...

  • longwave committed 07d426b4 on main
    fix: #3560659 HTMX Drupal behaviors are not applied when swapped element...
mxh’s picture

Hey, this is great news. Thank you guys so much for all the work to fix this.

Status: Fixed » Closed (fixed)

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