Root cause: Drupal.extlink.handleClick is reassigned on every call to attach() (which Drupal triggers on every AJAX request). Although the code already does removeEventListener before addEventListener, it uses the new function reference — so the previously registered listener (held under the old reference) is never actually removed. Event handlers accumulate, causing the confirm dialog to fire multiple times per click.

Fix: Guard the definition with || so handleClick is only created once and always holds the same reference, exactly as popupClickHandler is already handled:

// extlink.js before
const _that = this;
Drupal.extlink.handleClick = function (event) {
  const shouldNavigate = Drupal.extlink.popupClickHandler.call(_that, event);
  ...
};

// extlink.js After
Drupal.extlink.handleClick = Drupal.extlink.handleClick || function (event) {
  const shouldNavigate = Drupal.extlink.popupClickHandler(event);
  ...
};

This ensures removeEventListener and addEventListener always operate on the same stable reference, so duplicate listeners can no longer build up across successive attach() calls. The .call(_that, ...) can also be dropped since popupClickHandler is an arrow function and ignores any bound this.

Patch is attached, MR might come later.

Later edit: patch is for 2.0.5
MR!64 is for 2.0.x as of today

CommentFileSizeAuthor
extlink-duplicate_popups.patch639 bytesphily

Issue fork extlink-3591490

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

phily created an issue. See original summary.

phily’s picture

Issue summary: View changes
phily’s picture

Status: Active » Needs review
phily’s picture

Version: 2.0.5 » 2.0.x-dev
smustgrave’s picture

Status: Needs review » Needs work

Not sure I'm seeing this so may be good to get test coverage