Firefox工具栏按钮上下文(工具栏上的右键菜单)

时间:2015-08-21 08:10:13

标签: firefox firefox-addon xul

在Chrome中,可以为扩展程序图标制作上下文菜单项,如下所示:

enter image description here

在Firefox中模拟它的最佳和最干净的方法是什么 - 最好使用标准工具栏和标准工具栏按钮。

<toolbarpalette id="BrowserToolbarPalette">
    <toolbarbutton class="toolbarbutton-1"
                   label="My button"
                   oncommand="doSomething()" />
</toolbarpalette>

1 个答案:

答案 0 :(得分:1)

这里有一些蛋糕代码可以满足您的需求:

CustomizableUI.createWidget({
    id: 'noida',
    defaultArea: CustomizableUI.AREA_NAVBAR,
    label: 'My Widget',
    tooltiptext: 'This is my widget created with CUI.jsm',
    onCreated: function(aNode) {
        console.info('aNode:', aNode);
        aNode.setAttribute('image', 'chrome://branding/content/icon16.png');

        var myMenuJson = [
                            'xul:menupopup', {id: 'my_btns_pop'},
                                ['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'}]
                        ];
        aNode.appendChild(jsonToDOM(myMenuJson, aNode.ownerDocument, {}));
        aNode.setAttribute('contextmenu', 'my_btns_pop');
    }
});

这会使用MDN中的jsonToDOM函数:https://developer.mozilla.org/en-US/Add-ons/Overlay_Extensions/XUL_School/DOM_Building_and_HTML_Insertion#JSON_Templating

如果要复制并粘贴代码并在暂存器中运行,请复制粘贴此代码,它将jsonToDom函数复制并粘贴到:

function jsonToDOM(json, doc, nodes) {

    var namespaces = {
        html: 'http://www.w3.org/1999/xhtml',
        xul: 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'
    };
    var defaultNamespace = namespaces.html;

    function namespace(name) {
        var m = /^(?:(.*):)?(.*)$/.exec(name);        
        return [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] || defaultNamespace, vals[1]);

        for (var key in attr) {
            var val = attr[key];
            if (nodes && key == 'id')
                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, json);
}

CustomizableUI.createWidget({
    id: 'noida',
    defaultArea: CustomizableUI.AREA_NAVBAR,
    label: 'My Widget',
    tooltiptext: 'This is my widget created with CUI.jsm',
    onCreated: function(aNode) {
        console.info('aNode:', aNode);
        aNode.setAttribute('image', 'chrome://branding/content/icon16.png');

        var myMenuJson = [
                            'xul:menupopup', {id: 'my_btns_pop'},
                                ['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'}]
                        ];
        aNode.appendChild(jsonToDOM(myMenuJson, aNode.ownerDocument, {}));
        aNode.setAttribute('contextmenu', 'my_btns_pop');
    }
});

当然要破坏你的按钮元素,请执行以下代码:

CustomizableUI.destroyWidget('noida');