可以向小部件添加上下文菜单吗? [英] can I add a context menu to a widget?

查看:85
本文介绍了可以向小部件添加上下文菜单吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向小部件添加上下文菜单 这是菜单:

I'm trying to add a context menu to a widget This is the menu:

var widgets = require("sdk/widget");
var tabs = require("sdk/tabs");
var contextMenu = require("sdk/context-menu");

var menu = widgets.Widget({
    id: "menu",
    label: "Menu",
    contentURL: data.url("icon.png"),
    onClick: function() {
        //show a menu here
    }
});

是否可以向该图标添加菜单?
或者单击显示上下文菜单时以某种方式显示?

Is it possible to add a menu to this icon?
Or somehow when click show a context menu?

推荐答案

这里是这样的:

好吧,这是简化的示例.然后我将上传您的xpi. //立即创建并添加面板 var doc = document; var myElement = doc.getElementById('ElementToAttachPanelToId'); //我们将菜单附加到该元素

Ok man here is the simplified example. And I'll upload your xpi in a second. //create and add the panel now var doc = document; var myElement= doc.getElementById('ElementToAttachPanelToId'); //we attach menu to this element

var myMenuJson = 
                ['xul:menupopup', {id: 'myMenu1'},
                    ['xul:menuitem', {label:'menu item1'}],
                    ['xul:menu', {label:'menu item2 is submenu1'},
                        ['xul:menupopup', {},
                            ['xul:menuitem', {label:'submenu1 item1'}],
                            ['xul:menuitem', {label:'submenu1 item2'}],
                            ['xul:menuitem', {label:'submenu1 item3'}]
                        ]
                    ],
                    ['xul:menuitem', {label:'menu item3 is before a seperator'}],
                    ['xul:menuseparator', {}],
                    ['xul:menuitem', {label:'menu item4 is after a seperator'}]
                ];

var mainPopupSet = doc.getElementById('mainPopupSet');
mainPopupSet.appendChild(jsonToDOM(myMenuJson, doc, {}));

myElement.setAttribute('context', 'myMenu1');

我们可以通过将菜单的context属性设置为我们要提供的菜单的ID来添加菜单

we can add menu to anything by setting the context attribute of it to the id of the menu we want to give it

要查看jsonToDOM函数,请参见此处.按原样安装您的插件,然后从该Gist复制代码,并将其粘贴到便笺本中并运行它,然后右键单击您的小部件,它将弹出. 要点:Noitidart/_ff-addon-snippet-CreateMenuWithSubmenuAndAttachToWidget.js

To see the jsonToDOM function see this gist here. Install your addon as is, then copy the code from this Gist and paste it into scratchpad and run it, then right click on your widget and it will pop up. GIST IS HERE: Noitidart / _ff-addon-snippet-CreateMenuWithSubmenuAndAttachToWidget.js

现在在您的main.js中,我无法对其进行测试,因为它没有对require("chrome")的许可.如果不起作用,请添加到main.js var {Cc, Ci, Cu} = require("chrome"); Cu.import("resource://gre/modules/Services.jsm");的顶部,然后再次编译并重新上传,请经过不良测试后再发送回去.

Now in your main.js I couldn't test it because it doesn't have permission to require("chrome"). If it doesnt work add in at the top of your main.js var {Cc, Ci, Cu} = require("chrome"); Cu.import("resource://gre/modules/Services.jsm"); and then compile and upload again, Ill test do it and send back.

好吧,如果它可以在这里的第一张照片上工作,那就是粘贴到您的main.js中的代码.不难,我只是将引导程序样板复制到您的插件sdk中,因为我非常确定插件sdk不允许您执行此操作.它看起来很长,但有很多复制和粘贴,尤其是jsonToDOM函数,请在我链接到您的要旨的底部阅读有关此内容的信息.

Ok anyways, if it works on first shot here it is, the code to paste into your main.js. It wasn't hard I just copied the bootstrap boilerplate into your addon sdk, because Im pretty sure the addon sdk doesnt allow you to do this. It looks long but its a bunch of copy and pasting, Especially the jsonToDOM function, read about this stuff in the bottom of the gist I linked you.

var data = require("sdk/self").data;

var panel = require("sdk/panel").Panel({
    width: 200,
    height: 150,
    contentURL: data.url("menu.html"),
    contentScriptFile: data.url("menu.js")
});

var menu = require("sdk/widget").Widget({
    id: "open-traveleye",
    label: "TravelEye",
    contentURL: data.url("earth-icon.png"),
    panel: panel
});

//putting this after the .Widget thing as we need the widget insert into browser before running this code
var {Cc, Ci, Cu} = require("chrome");
Cu.import("resource://gre/modules/Services.jsm");

var windowListener = {
    //DO NOT EDIT HERE
    onOpenWindow: function(aXULWindow) {
        // Wait for the window to finish loading
        let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
        aDOMWindow.addEventListener('load', function() {
            aDOMWindow.removeEventListener('load', arguments.callee, false);
            windowListener.loadIntoWindow(aDOMWindow);
        }, false);
    },
    onCloseWindow: function(aXULWindow) {},
    onWindowTitleChange: function(aXULWindow, aNewTitle) {},
    register: function() {
         // Load into any existing windows
        var DOMWindows = Services.wm.getEnumerator('navigator:browser');
        while (DOMWindows.hasMoreElements()) {
            let aDOMWindow = DOMWindows.getNext();
            windowListener.loadIntoWindow(aDOMWindow);
        }
         // Listen to new windows
         wm.addListener(windowListener);
    },
    unregister: function() {
        // Unload from any existing windows
        var DOMWindows = Services.wm.getEnumerator('navigator:browser');
        while (DOMWindows.hasMoreElements()) {
            let aDOMWindow = DOMWindows.getNext();
            windowListener.unloadFromWindow(aDOMWindow;
        }
        //Stop listening so future added windows dont get this attached
        wm.removeListener(windowListener);
    },
    //END - DO NOT EDIT HERE
    loadIntoWindow: function (aDOMWindow, aXULWindow) {
        var window = aDOMWindow;
        if (!window) { return; }

        createAndAttachMenu(window);

    },
    unloadFromWindow: function (aDOMWindow, aXULWindow) {
        var window = aDOMWindow;
        if (!window) { return; }

        destroyMenu(window);

    }
};

function createAndAttachMenu(window) {
    var doc = window.document;
    var myWidget = doc.getElementById('widget:jid1-lwNbwJJiiMXM4A@jetpack-open-traveleye'); //we add the menu to this widget, we can add menu to anything by setting the context attribute of it to the id of the menu we want to give it

    var myMenuJson = 
                    ['xul:menupopup', {id: 'myMenu1'},
                        ['xul:menuitem', {label:'menu item1'}],
                        ['xul:menu', {label:'menu item2 is submenu1'},
                            ['xul:menupopup', {},
                                ['xul:menuitem', {label:'submenu1 item1'}],
                                ['xul:menuitem', {label:'submenu1 item2'}],
                                ['xul:menuitem', {label:'submenu1 item3'}]
                            ]
                        ],
                        ['xul:menuitem', {label:'menu item3 is before a seperator'}],
                        ['xul:menuseparator', {}],
                        ['xul:menuitem', {label:'menu item4 is after a seperator'}]
                    ];

    var mainPopupSet = doc.getElementById('mainPopupSet');
    mainPopupSet.appendChild(jsonToDOM(myMenuJson, doc, {}));

    myWidget.setAttribute('context', 'myMenu1');
}

function destroyMenu(window) {
    var myMenu = doc.getElementById('myMenu1');
    if (myMenu) {
        myMenu.parentNode.removeChild(myMenu);
    }
}

/*dom insertion library function from MDN - https://developer.mozilla.org/en-US/docs/XUL_School/DOM_Building_and_HTML_Insertion*/
jsonToDOM.namespaces = {
    html: 'http://www.w3.org/1999/xhtml',
    xul: 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'
};
jsonToDOM.defaultNamespace = jsonToDOM.namespaces.html;
function jsonToDOM(xml, doc, nodes) {
    function namespace(name) {
        var m = /^(?:(.*):)?(.*)$/.exec(name);        
        return [jsonToDOM.namespaces[m[1]], m[2]];
    }

    function tag(name, attr) {
        if (Array.isArray(name)) {
            var frag = doc.createDocumentFragment();
            Array.forEach(arguments, function (arg) {
                if (!Array.isArray(arg[0]))
                    frag.appendChild(tag.apply(null, arg));
                else
                    arg.forEach(function (arg) {
                        frag.appendChild(tag.apply(null, arg));
                    });
            });
            return frag;
        }

        var args = Array.slice(arguments, 2);
        var vals = namespace(name);
        var elem = doc.createElementNS(vals[0] || jsonToDOM.defaultNamespace, vals[1]);

        for (var key in attr) {
            var val = attr[key];
            if (nodes && key == 'key')
                nodes[val] = elem;

            vals = namespace(key);
            if (typeof val == 'function')
                elem.addEventListener(key.replace(/^on/, ''), val, false);
            else
                elem.setAttributeNS(vals[0] || '', vals[1], val);
        }
        args.forEach(function(e) {
            try {
                elem.appendChild(
                                    Object.prototype.toString.call(e) == '[object Array]'
                                    ?
                                        tag.apply(null, e)
                                    :
                                        e instanceof doc.defaultView.Node
                                        ?
                                            e
                                        :
                                            doc.createTextNode(e)
                                );
            } catch (ex) {
                elem.appendChild(doc.createTextNode(ex));
            }
        });
        return elem;
    }
    return tag.apply(null, xml);
}
/*end - dom insertion library function from MDN*/

//end added stuff

var tabs = require("sdk/tabs");
panel.port.on("noformatting", function() {
    tabs.activeTab.attach({
        contentScriptFile: data.url('no-formatting.js')
    });
});

panel.port.on("bold", function() {
    tabs.activeTab.attach({
        contentScriptFile: data.url('bold.js')
    });
});

panel.port.on("italic", function() {
    tabs.activeTab.attach({
        contentScriptFile: data.url('italic.js')
    });
});

panel.port.on("eye", function() {
    tabs.activeTab.attach({
        contentScriptFile: data.url('eye.js')
    });
});

这篇关于可以向小部件添加上下文菜单吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆