Skip to content

Instantly share code, notes, and snippets.

@Infocatcher
Last active December 14, 2015 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Infocatcher/5111923 to your computer and use it in GitHub Desktop.
Save Infocatcher/5111923 to your computer and use it in GitHub Desktop.
Tab Buttons example for Firefox/SeaMonkey and Custom Buttons https://addons.mozilla.org/addon/custom-buttons/
// Tab Buttons example for Custom Buttons
// (code for "initialization" section)
// (c) Infocatcher 2013
// version 0.1.0
// Note: this is just an example, added buttons isn't accessible in SeaMonkey.
var tabButtons = {
get btnPrototype() {
var btn = document.createElement("toolbarbutton");
btn.setAttribute("cb_id", "closeTab");
btn.setAttribute("oncommand", '\
for(var tab = this.parentNode; tab; tab = tab.parentNode) {\n\
if(tab.classList.contains("tabbrowser-tab")) {\n\
gBrowser.removeTab(tab);\n\
break;\n\
}\n\
}'
);
btn.tooltipText = "Close Tab";
delete this.btnPrototype;
return this.btnPrototype = btn;
},
init: function() {
addEventListener("TabOpen", this, true);
addEventListener("drop", this, true); // For moved tabs in SeaMonkey
addEventListener("mousedown", this, true); // To don't select tab after mousedown on button
this.addStyles();
this.addButtons();
},
destroy: function() {
this.removeButtons();
this.removeStyles();
},
handleEvent: function(e) {
if(e.type == "TabOpen")
this.addButton(e.originalTarget || e.target);
else if(e.type == "drop") {
for(
var tab = e.dataTransfer.mozSourceNode;
tab && "classList" in tab;
tab = tab.parentNode
) {
if(tab.classList.contains("tabbrowser-tab")) {
setTimeout(function() {
this.addButton(tab);
}.bind(this), 0);
break;
}
}
}
else if(e.type == "mousedown") {
var trg = e.originalTarget || e.target;
if(trg.getAttribute("cb_id") == "closeTab") {
e.preventDefault();
e.stopPropagation();
}
}
},
styleNode: null,
addStyles: function() {
if(this.styleNode)
return;
// We can't use "style" or "class" attribute in Firefox...
var style = '\
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\n\
toolbarbutton[cb_id="closeTab"] {\n\
list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAMAAABhq6zVAAAAq1BMVEWsP0mvQkymOUSGICh4FyGDHyj////9hYWtP0ngeXrienrtfX+pO0X6eXnebm/MlJXYqanRcXKlNkD3a2vfY2TSk5T0gYHUnp+bLDXxgIDQNDS7OTqWJzDQLS3GLS2yODnEhoeSJS3SMDC8LzDIjIzGhoeOIyvXNjbANTW9dnfEfX6/PT6LISncPT3VPD3FOzzIOzzYPT3XUFHVNTX+jo7FhYayRU6IIiruX18GggqCAAAABnRSTlOZmTOZM5nlPZ+bAAAAeklEQVR4Xi3AUwLDQBAA0Ikmtm1bbe9/sv7sA5r6EBQNID+EDCDwniiFoSR6vACKqumGaRq6pipg2Y6Lvo+uY1sQ3FH8Ir5xdAeQpFleIBZ5liZQVnWDbYtNXZXQ9cM4zfM0Dn0Hy7rtx3ke+7YuwFw/4mKA5b4Ex/4BzUsRs1W0PbwAAAAASUVORK5CYII=");\n\
margin: 1px;\n\
padding: 0;\n\
border: none;\n\
-moz-appearance: none;\n\
}';
this.styleNode = document.insertBefore(
document.createProcessingInstruction(
"xml-stylesheet",
'href="' + "data:text/css,"
+ encodeURIComponent(style) + '" type="text/css"'
),
document.firstChild
);
},
removeStyles: function() {
var sn = this.styleNode;
sn && sn.parentNode.removeChild(sn);
},
get tabs() {
var gBrowser = window.gBrowser || getBrowser();
return gBrowser.tabs || gBrowser.tabContainer.childNodes;
},
addButtons: function() {
Array.forEach(this.tabs, this.addButton, this);
},
removeButtons: function() {
Array.forEach(this.tabs, function(tab) {
var btn = this.getButton(tab);
btn && btn.parentNode.removeChild(btn);
}, this);
},
addButton: function(tab) {
if(this.getButton(tab))
return;
var doc = tab.ownerDocument;
var box = doc.getAnonymousElementByAttribute(tab, "class", "tab-middle box-inherit")
|| doc.getAnonymousElementByAttribute(tab, "class", "tab-content")
|| tab;
if(!box)
throw new Error("Can't find parent node for button");
var btn = this.btnPrototype.cloneNode(true);
box.appendChild(btn);
},
getButton: function(tab) {
return tab.ownerDocument.getAnonymousElementByAttribute(tab, "cb_id", "closeTab");
}
};
function destructor(reason) {
if(reason == "update" || reason == "delete")
tabButtons.destroy();
}
if(
typeof addDestructor == "function" // Custom Buttons 0.0.5.6pre4+
&& addDestructor != ("addDestructor" in window && window.addDestructor)
)
addDestructor(destructor, this);
else
this.onDestroy = destructor;
tabButtons.init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment