可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The add-on SDK attaches panels to widgets as seen here. I would like to achieve the same effect using the add-on SDK with a toolbar button instead.
The toolbar button I'm using is of the type menu-button, which means that the left side is an icon and has an oncommand
listener. The right side is a drop-down arrow which shows its contents on click. Here's the code to create such a button with the add-on SDK:
const doc = require('sdk/window/utils').getMostRecentBrowserWindow().document; var navBar = doc.getElementById('nav-bar') var btn = doc.createElement('toolbarbutton'); btn.setAttribute('id', 'hylytit'); btn.setAttribute('type', 'menu-button'); btn.setAttribute('class', 'toolbarbutton-1'); btn.setAttribute('image', data.url('resources/hylyt_off.png')); btn.setAttribute('orient', 'horizontal'); btn.setAttribute('label', 'Hylyt.it'); btn.addEventListener('command', function(event) { if (event.button===0) btnClick(); console.log(TAG+'button clicked'); }, false); var panel = doc.createElement('panel'); panel.setAttribute('id', 'search-panel'); panel.addEventListener('command', function(event) { console.log(TAG+'dropdown clicked'); }, false); var label = doc.createElement('label'); label.setAttribute('control', 'name'); label.setAttribute('value', 'Article List'); var textbox = doc.createElement('textbox'); textbox.setAttribute('id', 'name'); panel.appendChild(label); panel.appendChild(textbox); btn.appendChild(panel); navBar.appendChild(btn);
The panel
above is not an add-on SDK panel, it's a XUL panel and is severely limited in that it can't be styled with CSS. On top of this, the panel's onCommand
listener never fires despite the fact that the btn
's onCommand
fires as expected. The XUL panel shows itself when I click the dropdown button (as long as it has children), but because I can't access its click handler, I can't just create an add-on SDK panel on click.
So my question is this. Is there a way to access the toolbar button's menu portion's click handler or is there a way to append an add-on SDK panel as a child of a toolbar button?
回答1:
You have 900+ rep, you should know better. It is common knowledge to create another question topic rather then ask how to do something different in a comment especially after solution acceptance.
Nonetheless, this is what you do to accomplish the Pocket toolbarbutton effect. Based on code supplied by contributor above. Ask another question and I'll move this there and you can accept my solution there.
var doc = document; var navBar = doc.getElementById('nav-bar') var btn = doc.createElement('toolbarbutton'); btn.setAttribute('id', 'hylytit'); btn.setAttribute('type', 'menu-button'); btn.setAttribute('class', 'toolbarbutton-1'); btn.setAttribute('image', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMjgwMTE3NDA3MjA2ODExODcxRjlGMzUzNEZGQkNGQiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxRUM5MTQ0MkJFNkUxMUUxOUM3NzgwMzc3MDc2Rjk1MCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxRUM5MTQ0MUJFNkUxMUUxOUM3NzgwMzc3MDc2Rjk1MCIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDI4MDExNzQwNzIwNjgxMTg3MUZFQTk0QUU4RTMwMEYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDI4MDExNzQwNzIwNjgxMTg3MUY5RjM1MzRGRkJDRkIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5kJv/fAAAByUlEQVR42qRTPWvCYBC+mKiolFYURVSwfoCLkw4iGDM5WoO460/o4tKuHToV+gd0t5Ku4mQWJ8Fd/NhEpy6K3+ldakKsi+ALb3hzd89zd8+9L6MoCtyyOPpkMpl3m81WM5lMV4GOxyOsVqu3Xq/3qhIEg8Ga1+sFs9l8FcFut4P5fP6Cxz8CAvt8PmBZ9iqCw+Ggn9WaKTOB9/s9FAoF4Hn+LIjOZCMfxVGrWrWcFkRiWiwWiMfjIv6GOI77kGUZ1us15PN5SKVSz2ifttvtL2yBPRNRI1gsFiCK4pMkSVUE/GBrn5vN5i4ajVYxpFEsFuuRSIR1u91wQcAwDOAkwOl0VjBjCIFit9sdoOshl8sNsLp6IBCoOBwOME5LJSABqU8i8Pv91Kcwm83kdDrNk9/lcslYTYLi7HY7aBidIJvNTjqdziNpQBmIBDVIoFDT05TuPR6PCqbs2+0WBEGYqJWfbmKx2WxKo9FIDSAbtgDL5VLNQqRWq1Vtky4R6gDlcpnE/mYMV7nearUqw+FQJzEuDRyLxaBUKjXQVDVWoJNgFZV+vw/j8VgXi4DhcBiSySRl18H6+P5tAbekXC7p5DuLZ259jb8CDAAxmdyX9iaHkQAAAABJRU5ErkJggg=='); btn.setAttribute('orient', 'horizontal'); btn.setAttribute('label', 'Hylyt.it'); //// var toolbarbuttonPanel = doc.createElement('panel'); toolbarbuttonPanel.setAttribute('id', 'toolbarbutton-panel'); toolbarbuttonPanel.setAttribute('type', 'arrow'); var toolbarbuttonLabel = doc.createElement('label'); toolbarbuttonLabel.setAttribute('value', 'toolbarbutton panel'); toolbarbuttonPanel.appendChild(toolbarbuttonLabel); //// //// var dropmarkerPanel = doc.createElement('panel'); dropmarkerPanel.setAttribute('id', 'dropmarker-panel'); dropmarkerPanel.setAttribute('type', 'arrow'); var dropmarkerLabel = doc.createElement('label'); dropmarkerLabel.setAttribute('value', 'dropmarker panel'); dropmarkerPanel.appendChild(dropmarkerLabel); //// navBar.appendChild(btn); var mainPopupSet = document.querySelector('#mainPopupSet'); mainPopupSet.appendChild(dropmarkerPanel); mainPopupSet.appendChild(toolbarbuttonPanel); btn.addEventListener('click',function(event) { console.log('event.originalTarget',event.originalTarget); if (event.originalTarget.nodeName == 'toolbarbutton') { dropmarkerPanel.openPopup(btn); } else if (event.originalTarget.nodeName == 'xul:toolbarbutton') { toolbarbuttonPanel.openPopup(btn); } }, false);
回答2:
Panels don't have an onCommand method see MDN - Panels Article
You can make your panel stylized, give it type arrow like panel.setAttribute('type', 'arrow')
and then to attach to your button. I didn't give it type arrow below.
Heres the working code. Copy paste to scratchpad and set Environment > Browser then run it.
var doc = document; //to put this back in sdk do const doc = require('sdk/window/utils').getMostRecentBrowserWindow().document; var navBar = doc.getElementById('nav-bar') var btn = doc.createElement('toolbarbutton'); btn.setAttribute('id', 'hylytit'); btn.setAttribute('type', 'menu-button'); btn.setAttribute('class', 'toolbarbutton-1'); btn.setAttribute('image', ''); //i made this image blank because i dont have the image and im running from scratchpad btn.setAttribute('orient', 'horizontal'); btn.setAttribute('label', 'Hylyt.it'); var panel = doc.createElement('panel'); btn.addEventListener('command', function(event) { //moved this below var panel = doc.createElement because panel needs to be crated before we write this function //if (event.button===0) btnClick(); //console.log(TAG+'button clicked'); //what is TAG? its undefeined for me panel.openPopup(btn); }, false); panel.setAttribute('id', 'search-panel'); /* panel.addEventListener('command', function(event) { console.log(TAG+'dropdown clicked'); //what is TAG? its undefeined for me }, false); */ var label = doc.createElement('label'); label.setAttribute('control', 'name'); label.setAttribute('value', 'Article List'); var textbox = doc.createElement('textbox'); textbox.setAttribute('id', 'name'); panel.appendChild(label); panel.appendChild(textbox); btn.appendChild(panel); navBar.appendChild(btn);
回答3:
You can create a Toolbarbutton and Panel using the Addon SDK and some Jetpack modules. Try toolbarwidget-jplib and browser-action-jplib by Rob--W.
You can easy add a button to the toolbar and style the panel whatever you want with css / html:
var badge = require('browserAction').BrowserAction({ default_icon: 'images/icon19.png', // optional default_title: 'Badge title', // optional; shown in tooltip default_popup: 'popup.html' // optional });