Skip to content

Instantly share code, notes, and snippets.

@Infocatcher
Created September 8, 2013 13:03
Show Gist options
  • Select an option

  • Save Infocatcher/6484572 to your computer and use it in GitHub Desktop.

Select an option

Save Infocatcher/6484572 to your computer and use it in GitHub Desktop.
URLs menu example for Custom Buttons https://addons.mozilla.org/addon/custom-buttons/
// https://gist.github.com/Infocatcher/6484572
// Based on https://gist.github.com/Infocatcher/5891622
var options = {
showTooltips: true,
openInBackground: false
};
var menu = [
// cb_url:
// %URL% - encodeURIComponent(content.location.href)
// %RAW_URL% - content.location.href
{ label: "Search in Google Cache", cb_url: "https://www.google.com/search?q=cache:%URL%", image: "https://www.google.com/favicon.ico" },
{ label: "Search in web.archive.org", cb_url: "http://web.archive.org/web/*/%RAW_URL%", image: "http://archive.org/images/glogo.jpg" },
{ label: "View over anonymouse.org", cb_url: "http://anonymouse.org/cgi-bin/anon-www.cgi/%RAW_URL%", image: "http://anonymouse.org/favicon.ico" },
"menuseparator",
{ label: "View page source", cb_url: "view-source:%RAW_URL%" },
"menuseparator",
[
"Menu label",
"https://www.google.com/favicon.ico",
{ label: "Sub item 1", cb_url: "https://www.google.com/" },
{ label: "Sub item 2", cb_url: "http://www.yandex.ru/" }
],
[
"Menu label 2",
{ label: "Sub item 3", cb_url: "http://nigma.ru/" },
{ label: "Sub item 4", cb_url: "http://www.bing.com/" }
]
];
function getURLs(url) {
// Simplified example!
var out = [];
if(/#/.test(url))
out.push((url = RegExp.leftContext));
if(/\?/.test(url))
out.push((url = RegExp.leftContext));
var protocol = "";
if(/^[^\/:]+:\/*/.test(url)) {
protocol = RegExp.lastMatch;
url = RegExp.rightContext;
//LOG("protocol: " + protocol);
}
url = url.replace(/\/+$/, "");
while(/\/[^\/]+$/.test(url)) {
url = RegExp.leftContext;
if(!url)
break;
out.push(protocol + url + "/");
}
return out;
}
function parseItem(arr, parent) {
if(!parent)
parent = document.createElement("menupopup");
arr.forEach(function(item) {
var node;
if(item == "menuseparator")
node = document.createElement("menuseparator");
else if(Array.isArray(item)) {
node = document.createElement("menu");
node.setAttribute("label", item[0]);
var icon = item[1];
if(typeof icon == "string") {
node.className = "menu-iconic";
node.setAttribute("image", icon);
}
else {
node.className = "menu-iconic bookmark-item";
node.setAttribute("container", "true");
}
var mp = document.createElement("menupopup");
parseItem(item, mp);
node.appendChild(mp);
}
else if(typeof item == "object" && item) {
node = document.createElement("menuitem");
if(/*item.hasOwnProperty("image") && */!item.hasOwnProperty("class"))
item.class = "menuitem-iconic bookmark-item menuitem-with-favicon";
for(var attr in item) if(item.hasOwnProperty(attr))
node.setAttribute(attr, item[attr]);
}
node && parent.appendChild(node);
});
return parent;
}
var mp = document.createElement("menupopup");
var firstStaticItem;
mp.setAttribute("onpopupshowing", "if(event.target == this) this.parentNode.buildMenu(this);");
mp.setAttribute("oncommand", "this.parentNode.handleCommand(event);");
mp.setAttribute("onclick", "if(event.button != 0) this.parentNode.handleCommand(event);");
mp.setAttribute("oncontextmenu", "return false;");
addEventListener("DOMMenuItemActive", showLink, false, mp);
addEventListener("DOMMenuItemInactive", showLink, false, mp);
this.type = "menu";
this.orient = "horizontal";
this.appendChild(mp);
function showLink(e) {
if(e.type == "DOMMenuItemActive") {
var mi = e.target;
var url = getURL(mi.getAttribute("cb_url") || "");
if(url && options.showTooltips && mi.getAttribute("tooltiptext") != url)
mi.setAttribute("tooltiptext", url);
XULBrowserWindow.setOverLink(url, null);
}
else if(e.type == "DOMMenuItemInactive") {
XULBrowserWindow.setOverLink("", null);
}
}
this.buildMenu = function(popup) {
if(!firstStaticItem) {
parseItem(menu, popup);
firstStaticItem = mp.firstChild;
}
for(var node; (node = popup.firstChild) && node != firstStaticItem;)
popup.removeChild(node);
var df = document.createDocumentFragment();
getURLs(content.location.href).forEach(function(url) {
if(url == "menuseparator") {
df.appendChild(document.createElement("menuseparator"));
return;
}
var mi = document.createElement("menuitem");
mi.setAttribute("label", url);
mi.setAttribute("cb_url", url);
mi.className = "menuitem-iconic bookmark-item menuitem-with-favicon";
df.appendChild(mi);
});
if(df.hasChildNodes())
df.appendChild(document.createElement("menuseparator"));
mp.insertBefore(df, firstStaticItem);
};
this.handleCommand = function(e) {
var trg = e.target;
var url = trg.getAttribute("cb_url");
if(!url)
return;
var btn = e.type == "click" && e.button || 0;
if(btn == 2)
return;
btn && closeMenus(trg); // See chrome://browser/content/utilityOverlay.js
//alert("Button: " + btn + "\nURL: " + url);
url = getURL(url);
if(btn > 0 || e.ctrlKey || e.shiftKey || e.altKey || e.metaKey) {
var tab = gBrowser.addTab(url);
if(options.openInBackground)
gBrowser.selectedTab = tab;
}
else {
loadURI(url);
}
};
function getURL(template) {
var curURL = content.location.href;
return template
.replace(/%URL%/g, encodeURIComponent(curURL))
.replace(/%RAW_URL%/g, curURL);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment