Firefox: Event delegation bug

A Firefox issue where right click on a button results in a click event listener firing because of event delegation performed automatically by a JavaScript SPA framework.

Summary

Firefox dispatches click event from right click of button when delegating on window or document. This can occur even if you don’t realize you’re using event delegation, because it’s performed automatically by many front-end frameworks.

This appears to relate to the following issue: Bugzilla Bug 184051

Expected behavior

Primary click dispatches an event from the clicked element, and secondary click does nothing.

Secondary buttons (like the middle or right button on a standard mouse) MUST NOT fire click events.

Actual behavior

Secondary click on the window or document buttons results in the ancestor event listener firing and an event delegation check matching the button as the target.

Additionally, the event listener on the target element itself is not fired, indicating the event is not dispatched from the clicked button element in a way that is bubbled up through the DOM. I’ve corroborated this through an additional test (listening via an intermediary ancestor) that is not present in the test case for the sake of clarity.

Test case — view the example here

<button class="test-window">
  Test window
</button>
 
<button class="test-document">
  Test document
</button>
 
<button class="test-body">
  Test body
</button>
const buttons = {
  window: document.querySelector('.test-window'),
  document: document.querySelector('.test-document'),
  body: document.querySelector('.test-body'),
};
 
const test = element => event => {
  if (element === event.target) {
    console.log('Ancestor listener fired with matching event target element');
  }
};
 
window.addEventListener('click', test(buttons.window));
document.addEventListener('click', test(buttons.document));
document.body.addEventListener('click', test(buttons.body));
 
const testTarget = event => console.log('Listener fired on event target');
 
buttons.window.addEventListener('click', testTarget);
buttons.document.addEventListener('click', testTarget);
buttons.body.addEventListener('click', testTarget);