The context menu of Firefox behaves differently between the Windows and Linux platforms. On Linux, the context menu pops up as soon as you press down the right button of the mouse; While on Windows, it shows when you press down and
release the right button.
The Linux style behavior makes it difficult for an extension to capture and hack the
mousedown event. We can do a little hack to emulate the Windows style behavior on the Linux platform.
The idea is that we capture the
mousedown event and suppress the context menu. When the user release the mouse button, we capture the
mouseup event and fire a fake
contextmenu event.
Here is the demo source code.
1. Capture the mousedown event and suppress the context menu.
1.1 Capture the mousedown event
addEventListener("mousedown", myMouseDown, true);
function myMouseDown(event)
{
if (2 == event.button) // right-click
{
if (navigator.platform != "Win32") // No need for Windows
{
// Capture the contextmenu event.
addEventListener("contextmenu", myNoContextMenu, true);
// remove the listener right after to avoid mess up the other
// contextmenu events.
setTimeout(function(){ removeEventListener("contextmenu", myNoContextMenu, true); }, 0);
}
}
}
1.2 Suppress the context menu
function myNoContextMenu(event)
{
// Prevent the default action, i.e. context menu poping up
event.preventDefault();
event.stopPropagation();
}
2. Capture the mouseup event and pop up the context menu.
1.1 Capture the mouseup event
addEventListener("mouseup", myMouseUp, true);
function myMouseUp(event)
{
if (2 == event.button) // right-click
{
myShowContextMenu(event);
}
}
1.2 Pop up the context menu
function myShowContextMenu(event)
{
if (navigator.platform == "Win32")
return; // on Window context menu is already shown on mouseup.
// create a contextmenu event.
var newEv = event.view.document.createEvent("MouseEvents");
newEv.initMouseEvent("contextmenu", true, true, event.view, 1,
event.screenX, event.screenY, event.clientX, event.clientY,
false, false, false, false, 2, null);
// fire the new event.
event.originalTarget.dispatchEvent(newEv);
}