Overlay-based context menu in e10s

Hi,
We’re planning to move parts of an existing XUL-based addon to e10s so it works properly with new FF versions. We managed to find info about most of parts that need to be changed, but haven’t found some clear explanation about how context menu with access to content document should work.
We add new items to standard context menu that need to either modify the target node (set value or attribute) or get information about the node (ID, class, etc.). In current version it is done using logic that looks like the following (irrelevant code dropped for clarity):

Overlay part for menu items

<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
...
<popup id="contentAreaContextMenu">
...
        <menuitem
            id="my-addon-new-item"
            label="&myAddonNewItem.label;"
            accesskey="&myAddonNewItem.accesskey;"
            insertafter="context-selectall"
            class="menuitem-iconic"
        />
...
</popup>
...

Listening and reacting to context menu events:

// Run on browser window 'load' event
function initOverlay() {
    ...
    document.getElementById('my-addon-new-item').on('command', onMyItemClick);
    ...
}

// Runs when user clicks my addon item 
//after opening context menu on e.g. some input element
function onMyItemClick(event) {
    var elem = gContextMenu.target;
    // Here I can modify or check input element's properties
    var id = elem.id;
    elem.value = 'New value';
    ...
}

In e10s gContextMenu.target is not available since context menu handlers live in chrome process. But some things are not very clear:

  • how do we send information (ID, class, value) about the node to onMyItemClick now?
  • how do we send command to do something with the context target (set new value, add attribute)?

I’ve found some info here about context menu usage with Addon SDK but our addon doesn’t use it so we want to avoid rewriting it from scratch just to use custom context menu items.
SO answer here shows there’s also gContextMenuContentData.event.target value but it reports “unsafe/forbidden CPOW usage” to the console when retrieved.
There’s also an MDN page about some new notification we can observe, but it’s not clear how exactly it should be used with context menu item listeners.

Thanks you in advance for your answers.

require("sdk/context-menu") gives you all you need:

But I don’t know how you can use a SDK module from a XUL add-on.

Basically you can use the same concept as XUL there are only some steps to go by hand. You have to split the actions in content and chrome part and communicate with messages each other. the concept is that you build your context menu at addon startup and on every right click you hide the unneeded entries. So you have to check the target for url or/and instanceof.

frame script:

  • addEventListener(“contextmenu”, youraddon.contextContentAction, true);
  • define some vars to store your decisions
  • in contextContentAction() set the active vars for context menu according url / html elements
  • with sendAsyncMessage send the vars to chrome

chrome script:

  • window.addEventListener(“context”, youraddon.contextChromeAction, false);
  • setup in receiveMessage a call for an onContextMenuShow function
  • in onContextMenuShow you have to set unneeded entries to hidden with the attribute hidden of the menu item and your received vars from framescript
  • setup contextChromeAction() where you call your functionalities
1 Like

Thanks for clarification, @TheRave!
One more question regarding reactions to context item clicks: you have window.addEventListener("context", youraddon.contextChromeAction, false) line in description.

  • When exactly does this event occur, on each item click?
  • How do I determine which item was clicked exactly?

Is it possible to reuse separate command event listeners on each item as it’s shown in the original post?

Got the opportunity to check reuse of command event handlers: it’s working on FF 52a2 Dev edition with multi-process mode on.

The context event fires on every right click. You can check the click target by url for dedicated websites or instanceof or other attributes whatever you want.