Monday 15 August 2011

contextmenu - How to add a right click on my Firefox extension's icon? -



contextmenu - How to add a right click on my Firefox extension's icon? -

good day!

i've searched , searched 1 time again , didn't find help problem...

context : i've developed google chrome extension simple: send email 1 click. configure this, there alternative page on extension set email address send. my google chrome extension available here (english translation, text, not install).

users have asked me create extension firefox i'm working on it!

i've read tutorials on cfx , it's ok. need have extension respond right-click on extension's icon in toolbar. not on page, on icon.

i'm using actionbutton (or togglebutton) add together icon toolbar can't find way add together menu on right click (there's default firefox context menu want add together "options".)

if has solution great!

(i'm not familiar xul. so, if possible, javascript solution, please ^^ )

ps : i'm french please excuse me bad english

edit : i've found how set preferences in "package.json" file want own window. , if "bind" button "options" in add-on manager own window perfect!

edit 2 : it's not clear detail here want extension : - simple click (left click) on icon current url , send mail service address (ok this) - simple click this. extension aims very simple ! - right click on icon shows firefox's context-menu , want add together "options" here show options page - addon manager have "options" button near "deactivate" , "debug" , want alternative button show options page. => 2 way see alternative page : right click or addon manager , why need help !

general ui comments

using right-click straight activate function contrary general ui used scheme wide. right-click is, system-wide (on systems), used open context menu. in firefox in toolbar used bring context menu toolbar area. users going expect happen when utilize right-click. improve off either using shift-left-click, or letting user define combination used activate function. if attempting add together alternative context menu, accessed via right-click.

alternatives used in other add-ons:

a sec section button downwards arrow. clicking on downwards arrow opens expanded action or options menu. use tooltip display action or options menu when mouse hovered on button. done creating custom tooltip enclosing popup within <tooltip id="mytooltip"></tooltip> element , referencing in button <button tooltip="mytooltip"/> (tooltip property, tooltip attribute). using right-click

the problem appears add-on sdk actionbutton has abstracted away ability have listeners arbitrary events. not give access actual event object passed event handlers (listeners). further, click event appears command event, not click event. 1 of important differences between click , command event command event not fire on right-click.

you going need gain access button outside of actionbutton interface , add together listener click events , in click event handler, can create selection perform action based on state of event.button , event.shiftkey.

adapting code based on posted an reply different question, going want (not tested modifications):

class="lang-javascript prettyprint-override">function loadui(buttonid) { if (window === null || typeof window !== "object") { //if not have window reference, need obtain one: // add together "/" un-comment code appropriate add-on type. /* add-on sdk: var window = require('sdk/window/utils').getmostrecentbrowserwindow(); //*/ /* overlay , bootstrap (from context/scope): var window=components.classes["@mozilla.org/appshell/window-mediator;1"] .getservice(components.interfaces.nsiwindowmediator) .getmostrecentwindow("navigator:browser"); //*/ } foreachcustomizableuibyid(buttonid, loadintobutton, window); } function foreachcustomizableuibyid(buttonid ,func, mywindow) { allow groupwidgetwrap = mywindow.customizableui.getwidget(buttonid); groupwidgetwrap.instances.foreach(function(windowuiwidget) { //for each button load task. func(windowuiwidget.node); }); } function loadintobutton(buttonelement) { //make whatever changes button want here. //you may need save info original state // of button. buttonelement.addeventlistener("click",handleclickevent,true); } function unloadui(buttonid) { if (window === null || typeof window !== "object") { //if not have window reference, need obtain one: // add together "/" un-comment code appropriate add-on type. /* add-on sdk: var window = require('sdk/window/utils').getmostrecentbrowserwindow(); //*/ /* overlay , bootstrap (from context/scope): var window=components.classes["@mozilla.org/appshell/window-mediator;1"] .getservice(components.interfaces.nsiwindowmediator) .getmostrecentwindow("navigator:browser"); //*/ } foreachcustomizableuibyid(buttonid, unloadfrombutton, window); } function unloadfrombutton(buttonelement) { //return button original state buttonelement.removeeventlistener("click",handleclickevent,true); } function handleclickevent(event) { if( (event.button & 2) == 2 && event.shiftkey){ event.preventdefault(); event.stoppropagation(); domything(); } } function domything() { //whatever going do. }

as should implied above code, need create sure remove listener when uninstalling/disabling add-on. want create sure loadui() gets called when new window opens handler added new button.

adding context menu

there no direct way alter context menu icon. id context menu toolbar-context-menu. can add together items context menu hidden="true". when event right-click has happened on icon can alter state of hidden items added. in event handler called on the popuphidden event context menu (<menupopup id="toolbar-context-menu">) can set state of hidden="true" <menuitem> element(s) have added <menupopup id="toolbar-context-menu"> in each browser window.

something along lines of:

class="lang-javascript prettyprint-override">function loadintocontextmenu(win){ allow doc = win.ownerdocument; allow contextpopupel = doc.getelementbyid("toolbar-context-menu"); contextpopupel.insertadjacenthtml("beforeend", '<menuitem label="my item a" id="myextensionprefix-context-itema"' + ' oncommand="domythinga();" hidden="true" />' + '<menuitem label="my item b" id="myextensionprefix-context-itemb"' + ' oncommand="domythingb();" hidden="true" />'); contextpopupel.addeventlistener("popuphidden",hidemycontextmenuitems,true); } function unloadfromcontextmenu(win){ allow doc = win.ownerdocument; allow contextpopupel = doc.getelementbyid("toolbar-context-menu"); allow itema = doc.getelementbyid("myextensionprefix-context-itema"); allow itemb = doc.getelementbyid("myextensionprefix-context-itemb"); contextpopupel.removechild(itema); contextpopupel.removechild(itemb); contextpopupel.removeeventlistener("popuphidden",hidecontextmenuitems,true); } function sethiddenmycontextmenuitems(element,text){ //the element context menu. //text want "hidden" attribute set to. allow kid = element.firstchild; while(child !== null){ if(/myextensionprefix-context-item[ab]/.test(child.id)){ child.setattribute("hidden",text); } kid = child.nextsibling; } } function showcontextmenuitems(event){ //the target of event button want alter // context menu. need find context menu element. allow contextmenuel = event.target.ownerdocument .getelementbyid("toolbar-context-menu"); sethiddenmycontextmenuitems(contextmenuel,"false"); } function hidecontextmenuitems(event){ //this called popuphidden event of context menu. sethiddenmycontextmenuitems(event.target,"true"); } //change handleclickevent function in code within before section: function handleclickevent(event) { if( (event.button & 2) == 2){ //don't prevent propagation, nor default context menu // showing desired. showcontextmenuitems(event); } }

again, have not tested this. should demonstrate 1 way accomplish desire.

however, given talking context-menu, improve utilize contextmenu event rather click event , testing right-click. in case, alter of functions above following:

class="lang-javascript prettyprint-override">function loadintobutton(buttonelement) { //make whatever changes button want here. buttonelement.addeventlistener("contextmenu",handlecontextmenuevent,true); } function handlecontextmenuevent(event) { showcontextmenuitems(event); }

you can obtain each open primary browser window through utilize of nsiwindowmediator. next function, from mdn, run function pass 1 time each open window:

class="lang-javascript prettyprint-override">components.utils.import("resource://gre/modules/services.jsm"); function foreachopenwindow(todo) // apply function open browser windows { var windows = services.wm.getenumerator("navigator:browser"); while (windows.hasmoreelements()) { todo(windows.getnext().queryinterface(components.interfaces.nsidomwindow)); } }

in add-on sdk:

class="lang-javascript prettyprint-override">function foreachopenwindow(todo) // apply function open browser windows var windows = require("sdk/windows"); (let window of windows.browserwindows) { todo(windows.getnext().queryinterface(components.interfaces.nsidomwindow)); } }

you can add together listener calls loadintocontextmenu new windows next code (also from mdn):

class="lang-javascript prettyprint-override">components.utils.import("resource://gre/modules/services.jsm"); services.wm.addlistener(windowlistener); var windowlistener = { onopenwindow: function(xulwindow) { var window = xulwindow.queryinterface(components.interfaces.nsiinterfacerequestor) .getinterface(components.interfaces.nsidomwindow); function onwindowload() { window.removeeventlistener("load",onwindowload); if (window.document.documentelement.getattribute("windowtype") == "navigator:browser"){ loadintocontextmenu(window); //it improve current window, // not wound of them again. loadui(buttonid); } } window.addeventlistener("load",onwindowload); }, onclosewindow: function(xulwindow) { }, onwindowtitlechange: function(xulwindow, newtitle) { } };

firefox-addon contextmenu firefox-addon-sdk right-click

No comments:

Post a Comment