Ben
Ben

Reputation: 911

Show an item in context menu only when it clicked on an image in FireFox

[UPDATE] I may have explained the issue wrong: I know how to hide the menu element - but how to test if the clicked element is editable? Chrome detects an editable element - how to achieve it in ff.

I'm trying to get my item in a the context menu to be shown only when it was clicked on an image

this is my emailpicture.js

code:

function showHideItems(event)
{   
      var show = document.getElementById("emailImage");
      show.hidden = !(gContextMenu.onImage);
}

and the xul code:

<?xml version="1.0"?>
<overlay id="emailpicture" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://emailpicture/content/emailpicture.js"/>

<menupopup id="contentAreaContextMenu">
  <menuitem id="emailImage" label="Email This Image" onpopupshowing="showHideItems()" oncommand=""/>

</menupopup>


</overlay>

the result of this is showing on every object in the browser a bunch of items(might be all the items of FireFox) should i use the onpopupshowing event? or another one? am i using it right?

Thanks for the answers

Upvotes: 0

Views: 836

Answers (1)

Paul S.
Paul S.

Reputation: 66364

If you look at the ContextMenu MDN page they have an example of just this. The main issue with your current code is that you've put onpopupshowing on the <menuitem> when it should be on <menupopup>. Furthermore, if you look at the MDN for document.popupNode it says you're encouraged to use .triggerNode instead. Additionally, looking at the popupshowing event reference we see it has a .target, but it isn't clear whether this is the <menupopup> (I assumed this below), the node that was clicked or something else (see comment in code).

The following code makes use of the above and attaches the listener using .addEventListener to make sure there isn't a conflict with anything else that might use the onpopupshowing attribute.

In your emailpicture.js

// First define listener
function showHideItems(e) {
    var menupopup = e.target, // I believe `.target` is the <menupopup>, otherwise use `this`. 
        triggerNode = menupopup.triggerNode, // get node that was clicked to open context menu
        triggerIsImage = (triggerNode instanceof Components.interfaces.nsIImageLoadingContent && triggerNode.currentURI),
          // test if it is an image (as from MDN, I would've gone with `.nodeType` and `.nodeName` checks?)
        elmToHide = menupopup.getElementById('emailImage');
    if(elmToHide)
        elmToHide.hidden = !triggerIsImage;
}
// Then attach it to <menupopup>, remember the element has to exist before you can do this so you might want to wait for DOMContentLoaded
document.getElementById('contentAreaContextMenu')
    .addEventListener('popupshowing', showHideItems, false);

Then for the XUL don't include the attribute onpopupshowing.

I'll point out that I've not tested this so if it isn't working, first check the even is fired then check .target is as I assumed (and possibly clarify MDN for others in future).

Upvotes: 3

Related Questions