About Custom Buttons add-on
Custom Buttons allows you to create custom toolbarbuttons that can perform almost any task within your application. The language used in this buttons is JavaScript.
People who have never used or seen this scripting language, at the end of this documentation will find a basic guide to JavaScript.
About this documentation
- You can double click on code blocks to select all code.
- Code blocks highlighted in green are from the official Custom Buttons documentation.
- Code blocks highlighted in red are modified/added by me (Odyseus).
- Code blocks highlighted in orange are extracted from the Russian forum.
- Code blocks not highlighted have not been reviewed or tested. Which means that the code could be non-functional (due to its possible deprecation) or its just bad translated by me (due to the use of an automatic translator).
- I've made very minor changes to the examples of the original documentation. Like replacing all instances of "Components.classes" for the variable "Cc", etc.
- I have also added examples that were removed from the original documentation, like "menu-button" and "menu" buttons examples.
Getting started
Description of the user inteface
- Button URL: By entering a button URI into this field, a currently installed button can be updated with code from said URI. Or install a new button.
- Name: Name of the button.
- Image: Image for the button. An image can be:
- An URL containing an online image, e.g., "https://duckduckgo.com/favicon.ico".
- A "chrome" URL, e.g., "chrome://branding/content/icon32.png".
- A "file:///" URI, e.g., "file:///C:/Users/UserName/Desktop/Image.png", "file:///home/UserName/ Pictures/ Image.png".
- A data URI, e.g., "data:image/png;base64,...base64 code...".
- A "moz-icon", e.g., "moz-icon://.png?size=16".
- Browse: It allows you to browse for a local image.
- => base64: It converts any image from any source to Base64 format. This facilitates sharing the button without worrying about the source of the image.
- Tabs
The code inside this tab is executed every time the button is clicked with left mouse button.
The code inside this tab is executed every time the button is initialized.
A button is initialized when:
- The application starts.
- The button is edited and saved, either by pressing the "OK" or the "Save" buttons.
- Leaving the applications customize mode. In applications using CustomizableUI. jsm (Australis), the button also is initialized each time is moved from toolbar to toolbar while in customize mode.
- Can also be programmatically initialized with
this.init();
and/orself.init();
The content of this tab is diplayed when the menuitem "Button Help" from the Custom Buttons context menu is clicked. The Help tab of a Custom Buttons button can also be used in several usefull ways.
By default, there is a "separator" [,] that can be used to "divide" the Help tab content.
Example:
The "Button Help" menu item from the button shown in the image above will display...
...and the rest of the content can be called as follow...
/*Code*/ var usefulCode = this.Help.split("[,]")[1]; alert(usefulCode);
or...
/*Code*/ var usefulCode = self.getAttribute("Help").split("[,]")[1]; alert(usefulCode);
...whose result will be...
Using the same "separator" [,] as in the previous example, the content of the Help tab can be "divided" into several parts in order to use these parts separately.
The different parts can be called like this...
var usefulCodePartOne = this.Help.split("[,]")[1]; var usefulCodePartTwo = this.Help.split("[,]")[2]; var usefulCodePartThree = this.Help.split("[,]")[3];
...or like this...
var usefulCodePartOne = self.getAttribute("Help").split("[,]")[1]; var usefulCodePartTwo = self.getAttribute("Help").split("[,]")[2]; var usefulCodePartThree = self.getAttribute("Help").split("[,]")[3];
This procedure is the one I like and use in my buttons. I like it because I do not have to remember nor pay attention to the index in which the code I want is, which would be necessary to recall in the example number one.
/*Initialization*/ var usefulCodeOne = getHelp("MarkerOne"); var usefulCodeTwo = getHelp("MarkerTwo"); var usefulCodeThree = getHelp("MarkerThree"); function getHelp(aMarker) { // Get specific data from the Help tab. return document.getElementById(self.id).getAttribute("Help").split("<!--" + aMarker + "-->")[1]; }
IMPORTANT!!! Markers should ALWAYS exist in pairs and be unique. <!--MarkerThree--> Usefull code that can be called from JavaScript. <!--MarkerThree--> <!--MarkerOne--> Usefull code that can be called from JavaScript. <!--MarkerOne--> <!--MarkerTwo--> Usefull code that can be called from JavaScript. <!--MarkerTwo-->
In this tab a hotkey can be configured to execute the button. To delete an already configured hotkey, focus/click the "Hotkey" textbox and press Esc.
- Save: By pressing "Save", all changes made to the button are saved and the button is re-initialized.
- OK: By pressing "OK", the edit window is closed, all changes made to the button are saved and the button is re-initialized.
- Edit external...: It allows to edit the content of the current selected tab in an external editor.
- To avoid headaches, use a text editor that deserves to be called as such. That is, anything but the Windows Notepad!
- To change the text editor, reset the preference called "extensions.custombuttons.external_editor". When you press again the "Edit external..." button, you will be able to choose another editor.
- Cancel: By pressing "Cancel", the edit window is closed, all changes to the button are discarded and the button is not re-initialized.
How to use this feature without losing your mind
Every time you press the "Edit external..." button to edit a button, a temporary file is created inside your profile folder (inside a folder called Temp_ExternalEditor) and opened with the text editor of your choice. While you are editing this file, DO NOT re-focus the edit window of the button you are editing. Once you've made all changes you needed/wanted, SAVE the file and THEN re-focus the edit window of the button and save the button. The instant the edit window is focused, that temporary file no longer exists/is deleted.
Notes
Your First Custom Button
- Left click View → Add new button… in the Menu Bar - or right click a toolbar and left click Add new button…
- Type Hello World in the "Name" field.
- Type http://www.mozilla.org/favicon.ico in the "Image" field.
- Type
alert("Hello world");
on a blank line in the "Code" section. - Left click OK to close the Edit button dialog.
- Left click View → Toolbars → Customize… in the Menu Bar - or right click a toolbar and left click Customize….
- Find the button and drag it to a toolbar.
- Left click Done to close the Customize Toolbar window.
- Left click the button to show the alert.
- Right click the button to show the context popup.
Context Popup
Image | Action | Comments |
---|---|---|
Edit button... | ||
Delete button | ||
Clone button | Middle click to add new blank button. | |
Copy to clipboard | ||
Update Button | Hidden unless clipboard has a button URL. | |
Bookmark Button | ||
Button Help | Hidden unless "Help" section has text. | |
Customize... | ||
Add new button... |
Editor Keyboard Shortcuts
Shortcut | Action |
---|---|
Ctrl + F | Open search dialog in forward direction. |
Ctrl + Shift + F | Open search dialog in backward direction. |
F3 | Find next. |
Shift + F3 | Find previous. |
Ctrl + / | Incremental search. |
Ctrl + H | Open replace dialog in forward direction. |
Ctrl + Shift + H | Open replace dialog in backward direction. |
Ctrl + Shift + A | Comment or uncomment selected lines. |
Tab | Indent selected lines. |
Shift + Tab | Unindent selected lines. |
Ctrl + W | Toggle word wrapping. |
Ctrl + G | Goto line number. |
F9 | Execute code from "Code" section. |
F11 | Maximize or restore editor window. |
Ctrl + Enter | Save changes and close editor. |
Custom Buttons Options
Option | Comments |
---|---|
Show "Save" button in code editor | |
Disable buttons initialization | For debug purposes. |
Enable install buttons from mail messages | Only on Thunderbird/SeaMonkey. |
Save size and position of editor windows separately for each custom button |
Command Line Parameter
- firefox.exe
- -custombuttons disable-buttons-initialization
- seamonkey.exe
- -custombuttons disable-buttons-initialization
- thunderbird.exe
- -custombuttons disable-buttons-initialization
- sunbird.exe
- -custombuttons disable-buttons-initialization
- kompozer.exe
- -custombuttons disable-buttons-initialization
- flock.exe
- -custombuttons disable-buttons-initialization
Predefined Global Variables
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
var Cr = Components.results;
var self = this; // "this" is the button itself.
var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; // Namespace for XUL elements.
var xhtmlns = "http://www.w3.org/1999/xhtml"; // Namespace for HTML elements inside XUL elements.
var _id = this.id; // The id of the button.
var _doc = document;
var _uri = buttonURI; // The button URI.
var cbu = custombuttonsUtils;
Using Mouse Handlers
All middle click events with modifiers are "broken". Web browsers nowadays do not allow the use of modifier keys (Alt, Ctrl, etc.) in conjunction with the middle mouse button.
/*Initialization code*/
// right click button and shift - open custom button context popup
this.buttonClick = function (event) {
event.preventDefault();
if (event.button == 0 && !event.altKey && !event.ctrlKey && !event.shiftKey)
alert("left click");
if (event.button == 1 && !event.altKey && !event.ctrlKey && !event.shiftKey)
alert("middle click");
if (event.button == 2 && !event.altKey && !event.ctrlKey && !event.shiftKey)
alert(" right click");
if (event.button == 2 && !event.altKey && !event.ctrlKey && event.shiftKey)
gShowPopup(this);
}
this.setAttribute("onclick", "this.buttonClick(event)");
/*Initialization code*/
this. leftclick = function(event) { alert(" leftclick"); }
this. aleftclick = function(event) { alert(" aleftclick"); } // a for alt
this. cleftclick = function(event) { alert(" cleftclick"); } // c for ctrl
this. sleftclick = function(event) { alert(" sleftclick"); } // s for shift
this. midclick = function(event) { alert(" midclick"); }
this. amidclick = function(event) { alert(" amidclick"); }
this. cmidclick = function(event) { alert(" cmidclick"); }
this. smidclick = function(event) { alert(" smidclick"); }
this. rightclick = function(event) { alert(" rightclick"); gShowPopup(this); }
this. arightclick = function(event) { alert(" arightclick"); }
this. crightclick = function(event) { alert(" crightclick"); }
this. srightclick = function(event) { alert(" srightclick"); } // not available
this. leftDclick = function(event) { alert(" leftDclick"); } // capital d for double
this. aleftDclick = function(event) { alert(" aleftDclick"); }
this. cleftDclick = function(event) { alert(" cleftDclick"); }
this. sleftDclick = function(event) { alert(" sleftDclick"); }
this. midDclick = function(event) { alert(" midDclick"); }
this. amidDclick = function(event) { alert(" amidDclick"); }
this. cmidDclick = function(event) { alert(" cmidDclick"); }
this. smidDclick = function(event) { alert(" smidDclick"); }
this. rightDclick = function(event) { alert(" rightDclick"); }
this.arightDclick = function(event) { alert("arightDclick"); }
this.crightDclick = function(event) { alert("crightDclick"); }
this.srightDclick = function(event) { alert("srightDclick"); } // not available
this.setAttribute("onclick", "custombuttons.gQuot.mHandler(event, this)");
this.setAttribute("ondblclick", "custombuttons.gQuot.mHandler(event, this)");
/*Initialization code*/
this.acsleftDclick = function (event) {
alert("alt ctrl shift left double click");
}
this.setAttribute("ondblclick", "custombuttons.gQuot.mHandler(event, this)");
Change Button Image
/*Initialization code*/
this.image = "http://www.mozilla.org/favicon.ico";
this.setAttribute("onmouseup", "this.image = 'chrome://custombuttons/skin/button.png'");
this.setAttribute("onmousedown", "this.image = 'chrome://custombuttons/skin/stdicons/rbutton.png'");
this.setAttribute("onmouseout", "this.image = 'chrome://custombuttons/skin/stdicons/gbutton.png'");
this.setAttribute("onmouseover", "this.image = 'chrome://custombuttons/skin/stdicons/bbutton.png'");
Change Button Opacity
/*Initialization code*/
this.style.opacity = "0.65";
this.setAttribute("onmouseout", "custombuttons.ButtonDim(event)");
this.setAttribute("onmouseover", "custombuttons.ButtonBrt(event)");
Run Once Per Session
/*Initialization code*/
// click "Save" or "OK" in the editor initializes one button
// close the customize toolbar window initializes all buttons
var uid = "__unique_identifier_" + this.id;
if (!(uid in window)) {
alert("test");
window[uid] = true;
}
// comment in the next line to re-execute
// delete window[uid];
Using DOM Inspector in Firefox, SeaMonkey, Thunderbird
/*Code*/
if (typeof(inspectDOMDocument) == "undefined") {
alert("DOM Inspector is not enabled or installed.");
return;
}
function runInspector(node) {
if (node instanceof Document) {
inspectDOMDocument(node);
} else if (node instanceof Node) {
inspectDOMNode(node);
} else if (node !== null && typeof(node) != "undefined") {
inspectObject(node);
}
}
runInspector(document);
runInspector(content.document);
runInspector(document.getElementsByTagName("toolbar")[0]);
runInspector(document.getElementById("custombuttons-button0"));
runInspector(navigator);
runInspector(Cc["@mozilla.org/xre/app-info;1"].
getService(Ci.nsIXULAppInfo));
Using onDestroy Method
/*Initialization code*/
// constructor example - change button type property
// destructor example - close window
// update example - edit button
// delete example - delete button
LOG("test 2");
this.onDestroy = function (reason) {
LOG("test 1");
if (reason == "constructor")
LOG("constructor");
if (reason == "destructor")
LOG("destructor");
if (reason == "update")
LOG("update");
if (reason == "delete")
LOG("delete");
}
Using Commands
/*Code*/
// some commands are only legal when there is a selection or when the focus is on a text field
var cmd;
cmd = "cmd_paste"; // cmd_paste command is implemented by a controller
cmd = "cmd_close";
var controller = document.commandDispatcher.getControllerForCommand(cmd);
if (controller) {
if (controller.isCommandEnabled(cmd)) {
controller.doCommand(cmd);
}
} else {
var element = document.getElementById(cmd);
if (element) {
element.doCommand();
}
}
/*Code*/
goDoCommand("cmd_paste");
/*Code*/
document.getElementById("cmd_close").doCommand();
Using Style Sheet Service - Firefox, SeaMonkey and Thunderbird
Example 1
/*Initialization code*/
// #000000 black
// #0000FF blue
// #00FF00 lime
// #00FFFF aqua
// #FF0000 red
// #FF00FF fuchsia
// #FFFF00 yellow
// #FFFFFF white
var ios = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var sss = Cc["@mozilla.org/content/style-sheet-service;1"].
getService(Ci.nsIStyleSheetService);
var css = "menubar { background: #00FF00 !important; }";
css += "#" + this.id + " { background: #000000 !important; }";
css += "#" + this.id + ":hover { background: #FFFFFF !important; }";
var uss = ios.newURI("data:text/css," + encodeURIComponent(css), null, null);
// comment out the next line to disable style
if (!sss.sheetRegistered(uss, sss.USER_SHEET))
sss.loadAndRegisterSheet(uss, sss.USER_SHEET);
this.onDestroy = function (reason) {
if (reason == "update") {
var uss = ios.newURI("data:text/css," + encodeURIComponent(css), null, null);
if (sss.sheetRegistered(uss, sss.USER_SHEET))
sss.unregisterSheet(uss, sss.USER_SHEET);
}
if (reason == "delete") {
var uss = ios.newURI("data:text/css," + encodeURIComponent(css), null, null);
if (sss.sheetRegistered(uss, sss.USER_SHEET))
sss.unregisterSheet(uss, sss.USER_SHEET);
alert("style sheet unregistered");
}
}
Example 2
Using Event Listeners - Firefox and SeaMonkey
/*Code*/
var browser = gBrowser.getBrowserForTab(gBrowser.addTab("about:logo"));
browser.addEventListener("load", function (event) {
browser.removeEventListener("load", arguments.callee, true);
alert("test");
}, true);
/*Code*/
// custom button event listener is deleted automatically when a button is destroyed
var browser = gBrowser.getBrowserForTab(gBrowser.addTab("about:logo"));
addEventListener("load", function (event) {
removeEventListener("load", arguments.callee, true, browser);
alert("test" + "\n" + "handlers length: " + this._handlers.length);
}, true, browser);
Using Error Console
/*Code*/
var consoleService = Cc["@mozilla.org/consoleservice;1"].
getService(Ci.nsIConsoleService);
consoleService.logStringMessage("test 1");
LOG("test 2");
alert(LOG(2 + 2));
try {
toErrorConsole(); // console2.mozdev.org
} catch (e) {
toJavaScriptConsole();
}
/*Code*/
// left click entry in error console to go directly to the error
this.is.an.error;
Error : this.is is undefined
Source File : chrome : //custombuttons/content/button.js?windowId=Firefox&id=custombuttons-button0@code
Line : 3
Toggle Page Style - Firefox, SeaMonkey and Thunderbird
/*Code*/
var element = content.document.getElementById("blackify");
if (element) {
element.parentNode.removeChild(element);
} else {
var style = content.document.createElement("style");
style.setAttribute("type", "text/css");
style.setAttribute("id", "blackify");
style.innerHTML = "* { background: #000000 !important; }" +
"* { color: #CCCCCC !important; }" +
"a { color: #FFCC66 !important; }" +
"a:hover { color: #FFFFCC !important; }" +
"a:visited { color: #FFB720 !important; }";
content.document.getElementsByTagName("head")[0].appendChild(style);
}
Working with buttons, mouse, menus, etc
Toolbar Button Type 'menu' - Firefox and SeaMonkey
The following three examples create the exact same button. The difference lies in the way the menu for this button is created. In the first example, the menu is created by parsing a variable that stores an XML string. In the second example, the menu is created with pure JavaScript. And in the third example, the menu is stored indide the "Help" tab of the button.
Example 1 - Menu created from an XML string
/*Initialization code*/
/**
* left click on button - Open menu popup
* right click on button - Open custom button context popup
* left click on menuitems - Open page in the current tab
* middle click on menuitems - Open page in a new tab in the background
* right click on menuitems - Open page in a new tab in the foreground
*/
const cbNS = "http://xsms.nm.ru/custombuttons/";
// xulns = http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul.
// Is a global variable defined by Custom Buttons.
var menu = "<menupopup xmlns=\"" + xulns + "\" xmlns:cb=\"" + cbNS + "\"" +
" onclick=\"this.parentNode.menuClick(event);\">" +
"<menu" +
" class=\"menu-iconic\"" +
" image=\"chrome://global/skin/dirListing/folder.png\"" +
" label=\"Search\">" +
"<menupopup>" +
"<menuitem" +
" class=\"menuitem-iconic\"" +
" image=\"http://www.google.com/favicon.ico\"" +
" label=\"Google\"" +
" cb:url=\"http://www.google.com/\"/>" +
"<menuitem" +
" class=\"menuitem-iconic\"" +
" image=\"http://search.yahoo.com/favicon.ico\"" +
" label=\"Yahoo\"" +
" cb:url=\"http://search.yahoo.com/\"/>" +
"<menuitem" +
" class=\"menuitem-iconic\"" +
" image=\"http://www.bing.com/favicon.ico\"" +
" label=\"Bing\"" +
" cb:url=\"http://www.bing.com/\"/>" +
"<menuseparator/>" +
"<menuitem" +
" label=\"Open All in Tabs\"" +
" onclick=\"document.getElementById(\'" + this.id + "\').openAllInTabs(event);\"/>" +
"</menupopup>" +
"</menu>" +
"<menuitem" +
" class=\"menuitem-iconic\"" +
" image=\"http://en.wikipedia.org/favicon.ico\"" +
" label=\"Wikipedia\"" +
" cb:url=\"http://en.wikipedia.org/\"/>" +
"</menupopup>";
this.appendChild($XML(menu)); // This appends the menu itself to the button.
var nodeList = this.getElementsByTagName("menuitem"); // Gets all menuitems in this button.
for (var i = 0; i < nodeList.length; i++) { // This loop sets the tooltip for each menuitem.
var label = nodeList[i].getAttribute("label");
var url = nodeList[i].getAttributeNS(cbNS, "url");
if (label && url)
nodeList[i].setAttribute("tooltiptext", label + "\n" + url);
}
this.type = "menu";
this.orient = "horizontal";
this.menuClick = function (event) {
event.preventDefault();
event.stopPropagation();
this.open = false; // This closes the popup after middle/right clicks on menuitems.
var url = event.target.getAttributeNS(cbNS, "url");
if (url && event.button == 0) // Left click
loadURI(url);
if (url && event.button == 1) // Middle click
gBrowser.addTab(url);
if (url && event.button == 2) // Right click
gBrowser.selectedTab = gBrowser.addTab(url);
};
this.openAllInTabs = function (event) {
var nodeList = event.target.parentNode.childNodes;
for (var i = 0; i < nodeList.length; i++) {
var url = nodeList[i].getAttributeNS(cbNS, "url");
if (url)
gBrowser.addTab(url);
}
};
function $XML(aXML) { // Return parsed XML
aXML = aXML.replace(/>\s+</g, "><"); // Linearize XML
return (new DOMParser).parseFromString(aXML, "application/xml").documentElement;
}
Example 2 - Menu created with JavaScript
/*Initialization code*/
/**
* left click on button - Open menu popup
* right click on button - Open custom button context popup
* left click on menuitems - Open page in the current tab
* middle click on menuitems - Open page in a new tab in the background
* right click on menuitems - Open page in a new tab in the foreground
*/
const cbNS = "http://xsms.nm.ru/custombuttons/";
// xulns = http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul.
// Is a global variable defined by Custom Buttons.
var mainPopup = document.createElementNS(xulns, "menupopup");
mainPopup.setAttribute("xmlns:cb", cbNS);
mainPopup.setAttribute("onclick", "this.parentNode.menuClick(event);");
var subMenu = mainPopup.appendChild(document.createElementNS(xulns, "menu"));
subMenu.setAttribute("class", "menu-iconic");
subMenu.setAttribute("label", "Search");
subMenu.setAttribute("image", "chrome://global/skin/dirListing/folder.png");
var subPopup = subMenu.appendChild(document.createElementNS(xulns, "menupopup"));
var mItem1 = subPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem1.setAttribute("class", "menuitem-iconic");
mItem1.setAttribute("label", "Google");
mItem1.setAttribute("image", "http://www.google.com/favicon.ico");
mItem1.setAttributeNS(cbNS, "cb:url", "https://www.google.com");
var mItem2 = subPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem2.setAttribute("class", "menuitem-iconic");
mItem2.setAttribute("label", "Yahoo");
mItem2.setAttribute("image", "http://search.yahoo.com/favicon.ico");
mItem2.setAttributeNS(cbNS, "cb:url", "https://search.yahoo.com");
var mItem3 = subPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem3.setAttribute("class", "menuitem-iconic");
mItem3.setAttribute("label", "Bing");
mItem3.setAttribute("image", "http://www.bing.com/favicon.ico");
mItem3.setAttributeNS(cbNS, "cb:url", "https://www.bing.com");
subPopup.appendChild(document.createElementNS(xulns, "menuseparator"));
var mItem4 = subPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem4.setAttribute("label", "Open All in Tabs");
mItem4.setAttribute("onclick", "document.getElementById('" + this.id + "').openAllInTabs(event);");
var mItem5 = mainPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem5.setAttribute("class", "menuitem-iconic");
mItem5.setAttribute("label", "Wikipedia");
mItem5.setAttribute("image", "http://en.wikipedia.org/favicon.ico");
mItem5.setAttributeNS(cbNS, "cb:url", "http://en.wikipedia.org");
this.appendChild(mainPopup); // This appends the menu itself to the button.
var nodeList = this.getElementsByTagName("menuitem"); // Gets all menuitems in this button.
for (var i = 0; i < nodeList.length; i++) { // This loop sets the tooltip for each menuitem.
var label = nodeList[i].getAttribute("label");
var url = nodeList[i].getAttributeNS(cbNS, "url");
if (label && url)
nodeList[i].setAttribute("tooltiptext", label + "\n" + url);
}
this.type = "menu";
this.orient = "horizontal";
this.menuClick = function (event) {
event.preventDefault();
event.stopPropagation();
this.open = false; // This closes the popup after middle/right clicks on menuitems.
var url = event.target.getAttributeNS(cbNS, "url");
if (url && event.button == 0) // Left click
loadURI(url);
if (url && event.button == 1) // Middle click
gBrowser.addTab(url);
if (url && event.button == 2) // Right click
gBrowser.selectedTab = gBrowser.addTab(url);
};
this.openAllInTabs = function (event) {
var nodeList = event.target.parentNode.childNodes;
for (var i = 0; i < nodeList.length; i++) {
var url = nodeList[i].getAttributeNS(cbNS, "url");
if (url)
gBrowser.addTab(url);
}
};
Example 3 - Menu stored inside "Help" tab
Toolbar Button Type 'menu-button' - Firefox and SeaMonkey
The following three examples create the exact same button. The difference lies in the way the menu for this button is created. In the first example, the menu is created by parsing a variable that stores an XML string. In the second example, the menu is created with pure JavaScript. And in the third example, the menu is stored indide the "Help" tab of the button.
Example 1 - Menu created by parsing an XML string
/*Initialization code*/
/**
* Left click on button - Open page in a new window
* Left click on dropmarker - Open menu popup
* Right click on button or dropmarker - Open custom button context popup
* Left click on menuitems - Open page in the current tab
* Middle click on menuitems - Open page in a new tab in the background
* Right click on menuitems - Open page in a new tab in the foreground
*/
const cbNS = "http://xsms.nm.ru/custombuttons/";
// xulns = http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul.
// Is a global variable defined by Custom Buttons.
var menu = "<menupopup xmlns=\"" + xulns + "\" xmlns:cb=\"" + cbNS + "\"" +
" onclick=\"this.parentNode.menuClick(event)\"" +
" oncommand=\"this.parentNode.menuCommand(event)\">" +
"<menu class=\"menu-iconic\"" +
" image=\"chrome://global/skin/dirListing/folder.png\" label=\"Search\">" +
"<menupopup>" +
"<menuitem" +
" class=\"menuitem-iconic\"" +
" image=\"http://www.google.com/favicon.ico\"" +
" label = \"Google\"" +
" cb:url=\"https://www.google.com/\"/>" +
"<menuitem" +
" class=\"menuitem-iconic\"" +
" image=\"http://search.yahoo.com/favicon.ico\"" +
" label=\"Yahoo\"" +
" cb:url=\"https://search.yahoo.com/\"/>" +
"<menuitem" +
" class=\"menuitem-iconic\"" +
" image=\"http://www.bing.com/favicon.ico\"" +
" label=\"Bing\"" +
" cb:url=\"https://www.bing.com/\"/>" +
"<menuseparator/>" +
"<menuitem" +
" label=\"Open All in Tabs\"" +
" onclick=\"document.getElementById('" + this.id + "').openAllInTabs(event);\"/>" +
"</menupopup>" +
"</menu>" +
"<menuitem" +
" class=\"menuitem-iconic\"" +
" image=\"http://en.wikipedia.org/favicon.ico\"" +
" label=\"Wikipedia\"" +
" cb:url=\"http://en.wikipedia.org/\"/>" +
"</menupopup>";
this.appendChild($XML(menu)); // This appends the menu itself to the button.
var nodeList = this.getElementsByTagName("menuitem"); // Gets all menuitems in this button.
for (var i = 0; i < nodeList.length; i++) { // This loop sets the tooltip for each menuitem.
var label = nodeList[i].getAttribute("label");
var url = nodeList[i].getAttributeNS(cbNS, "url");
if (label && url)
nodeList[i].setAttribute("tooltiptext", label + "\n" + url);
}
this.type = "menu-button";
this.orient = "horizontal";
this.menuClick = function (event) {
event.preventDefault();
event.stopPropagation();
this.open = false; // This closes the popup after middle/right clicks on menuitems.
var url = event.target.getAttributeNS(cbNS, "url");
if (url && event.button == 1) // Middle click
gBrowser.addTab(url);
if (url && event.button == 2) // Right click
gBrowser.selectedTab = gBrowser.addTab(url);
};
this.menuCommand = function (event) { // Left click
event.stopPropagation();
var url = event.target.getAttributeNS(cbNS, "url");
if (url)
loadURI(url);
};
this.buttonCommand = function (event) { // Left click on button, not dropmarker
var url = "about:config";
window.open(url, "_blank", "chrome,centerscreen,width=640,height=480");
};
this.openAllInTabs = function (event) {
var nodeList = event.target.parentNode.childNodes;
for (var i = 0; i < nodeList.length; i++) {
var url = nodeList[i].getAttributeNS(cbNS, "url");
if (url)
gBrowser.addTab(url);
}
};
this.setAttribute("oncommand", "this.buttonCommand(event)");
function $XML(aXML) { // Return parsed XML
aXML = aXML.replace(/>\s+</g, "><"); // Linearize XML
return (new DOMParser).parseFromString(aXML, "application/xml").documentElement;
}
Example 2 - Menu created with JavaScript
/*Initialization code*/
/**
* Left click on button - Open page in a new window
* Left click on dropmarker - Open menu popup
* Right click on button or dropmarker - Open custom button context popup
* Left click on menuitems - Open page in the current tab
* Middle click on menuitems - Open page in a new tab in the background
* Right click on menuitems - Open page in a new tab in the foreground
*/
const cbNS = "http://xsms.nm.ru/custombuttons/";
// xulns = http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul.
// Is a global variable defined by Custom Buttons.
var mainPopup = document.createElementNS(xulns, "menupopup");
mainPopup.setAttribute("xmlns:cb", cbNS);
mainPopup.setAttribute("onclick", "this.parentNode.menuClick(event);");
mainPopup.setAttribute("oncommand", "this.parentNode.menuCommand(event);");
var subMenu = mainPopup.appendChild(document.createElementNS(xulns, "menu"));
subMenu.setAttribute("class", "menu-iconic");
subMenu.setAttribute("label", "Search");
subMenu.setAttribute("image", "chrome://global/skin/dirListing/folder.png");
var subPopup = subMenu.appendChild(document.createElementNS(xulns, "menupopup"));
var mItem1 = subPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem1.setAttribute("class", "menuitem-iconic");
mItem1.setAttribute("label", "Google");
mItem1.setAttribute("image", "http://www.google.com/favicon.ico");
mItem1.setAttributeNS(cbNS, "cb:url", "https://www.google.com");
var mItem2 = subPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem2.setAttribute("class", "menuitem-iconic");
mItem2.setAttribute("label", "Yahoo");
mItem2.setAttribute("image", "http://search.yahoo.com/favicon.ico");
mItem2.setAttributeNS(cbNS, "cb:url", "https://search.yahoo.com");
var mItem3 = subPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem3.setAttribute("class", "menuitem-iconic");
mItem3.setAttribute("label", "Bing");
mItem3.setAttribute("image", "http://www.bing.com/favicon.ico");
mItem3.setAttributeNS(cbNS, "cb:url", "https://www.bing.com");
subPopup.appendChild(document.createElementNS(xulns, "menuseparator"));
var mItem4 = subPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem4.setAttribute("label", "Open All in Tabs");
mItem4.setAttribute("onclick", "document.getElementById('" + this.id + "').openAllInTabs(event);");
var mItem5 = mainPopup.appendChild(document.createElementNS(xulns, "menuitem"));
mItem5.setAttribute("class", "menuitem-iconic");
mItem5.setAttribute("label", "Wikipedia");
mItem5.setAttribute("image", "http://en.wikipedia.org/favicon.ico");
mItem5.setAttributeNS(cbNS, "cb:url", "http://en.wikipedia.org");
this.appendChild(mainPopup); // This appends the menu itself to the button.
var nodeList = this.getElementsByTagName("menuitem"); // Gets all menuitems in this button.
for (var i = 0; i < nodeList.length; i++) { // This loop sets the tooltip for each menuitem.
var label = nodeList[i].getAttribute("label");
var url = nodeList[i].getAttributeNS(cbNS, "url");
if (label && url)
nodeList[i].setAttribute("tooltiptext", label + "\n" + url);
}
this.type = "menu-button";
this.orient = "horizontal";
this.menuClick = function (event) {
event.preventDefault();
event.stopPropagation();
this.open = false; // This closes the popup after middle/right clicks on menuitems.
var url = event.target.getAttributeNS(cbNS, "url");
if (url && event.button == 1) // Middle click
gBrowser.addTab(url);
if (url && event.button == 2) // Right click
gBrowser.selectedTab = gBrowser.addTab(url);
};
this.menuCommand = function (event) { // Left click
event.stopPropagation();
var url = event.target.getAttributeNS(cbNS, "url");
if (url)
loadURI(url);
};
this.buttonCommand = function (event) { // Left click on button, not dropmarker
var url = "about:config";
window.open(url, "_blank", "chrome,centerscreen,width=640,height=480");
};
this.openAllInTabs = function (event) {
var nodeList = event.target.parentNode.childNodes;
for (var i = 0; i < nodeList.length; i++) {
var url = nodeList[i].getAttributeNS(cbNS, "url");
if (url)
gBrowser.addTab(url);
}
};
this.setAttribute("oncommand", "this.buttonCommand(event)");
Example 3 - Menu stored inside "Help" tab
Drag&Drop capabilities
Example 1
/*Initialization code*/
this.dragAndDropHandler = {
handleEvent : function (aEvt) {
var types = aEvt.dataTransfer.types; // All data types found in the dragged data.
switch (aEvt.type) {
case "dragover":
// Warning!!! The dragover event is triggered "every few hundred milliseconds".
// That's what MDN docs says. https://developer.mozilla.org/en-US/docs/Web/Events/dragover
// In the past, I think to remember that said every 100 milliseconds.
// So be carefull what you put in here because it will run several times per second.
aEvt.preventDefault();
break;
case "drop":
if (types.contains("text/html") || types.contains("text/plain") ||
types.contains("text/x-moz-text-internal")) {
let data = aEvt.dataTransfer.getData('text/html');
var urlArr = /href="?([^"\s]+)"?\s*/.exec(data); // Check if what is been dragged contains a link.
if (!urlArr) // If it's not a link...
urlArr = aEvt.dataTransfer.getData('text/plain') ||
aEvt.dataTransfer.getData('text/x-moz-text-internal'); // ...treat it as plain text.
if (urlArr) {
if (typeof urlArr === "object") // If an URL was found, log the URL...
LOG(urlArr[1]);
else // ...else, log plain text.
LOG(urlArr);
}
}
aEvt.preventDefault();
break;
}
}
};
this.dragAndDropHandler
can be used by setting attributes...
/*Initialization code*/
// The "drop" event will not trigger if the "dragover" event is not declared.
this.setAttribute("ondragover", "this.dragAndDropHandler.handleEvent(event);");
this.setAttribute("ondrop", "this.dragAndDropHandler.handleEvent(event);");
...or by adding event listeners.
/*Initialization code*/
var uid = "__unique_identifier_" + this.id;
if (!(uid in window)) { // Ensures that event listeners are added just once.
window[uid] = true;
// The "drop" event will not trigger if the "dragover" event is not declared.
this.addEventListener("dragover", this.dragAndDropHandler, false);
this.addEventListener("drop", this.dragAndDropHandler, false);
}
Example 2 - Simpler examples
By setting attributes
/*Initialization code*/
// The "drop" event will not trigger if the "dragover" event is not declared.
this.ondragover = function (aEvt) {
aEvt.preventDefault();
};
// This will log to the console all data types found in the droped data.
this.ondrop = function (aEvt) {
var listOfTypes = [];
for (var type = 0; type < aEvt.dataTransfer.types.length; type++)
listOfTypes.push(aEvt.dataTransfer.types[type]);
LOG(listOfTypes.join("\n"));
aEvt.preventDefault();
};
By adding event listeners
/*Initialization code*/
var uid = "__unique_identifier_" + this.id;
if (!(uid in window)) { // Ensures that event listeners are added just once.
window[uid] = true;
// The "drop" event will not trigger if the "dragover" event is not declared.
this.addEventListener("dragover", function (aEvt) {
aEvt.preventDefault();
}, false);
// This will log to the console all data types found in the droped data.
this.addEventListener("drop", function (aEvt) {
var listOfTypes = [];
for (var type = 0; type < aEvt.dataTransfer.types.length; type++)
listOfTypes.push(aEvt.dataTransfer.types[type]);
LOG(listOfTypes.join("\n"));
aEvt.preventDefault();
}, false);
}
Hide dropmarker - for "menu" and/or "menu-button" types
Example 1
/*Initialization*/
this.hideDropMarker = function () {
var dropMarker = document.getAnonymousElementByAttribute(self, "class", "toolbarbutton-menu-dropmarker");
if (dropMarker) {
dropMarker.setAttribute("hidden", "true");
} else {
setTimeout(self.hideDropMarker, 10);
}
}
this.hideDropMarker();
Example 2
/*Initialization*/
(function dropmarkerVisibility() {
let dropMarker = document.getAnonymousElementByAttribute(self, "class", "toolbarbutton-menu-dropmarker");
if (dropMarker)
dropMarker.setAttribute("hidden", true);
else
setTimeout(function () {
dropmarkerVisibility();
}, 50);
})();
Open menu on mouse over and hide on mouse out
Example 1
/*Initialization*/
this.timer = 0;
// Opens de menu on mouse over.
this.onmouseover = function (event) {
this.open = true;
clearTimeout(this.timer);
};
// Closes de menu on mouse out.
this.onmouseout = function (event) {
if (!event.relatedTarget || Array.indexOf(this.getElementsByTagName("*"), event.relatedTarget) === -1) {
clearTimeout(this.timer);
this.timer = setTimeout(function () {
self.open = false;
}, 200); // 200 - delay for closing the menu in milliseconds.
}
};
Example 2 - variation with open delay
/*Initialization*/
this.timer = 0;
// Opens de menu on mouse over.
this.onmouseover = function () {
clearTimeout(this.timer);
this.timer = setTimeout(function () {
self.open = true;
}, 200); // 200 - delay for open the menu in milliseconds.
};
// Closes de menu on mouse out.
this.onmouseout = function () {
clearTimeout(this.timer);
this.timer = setTimeout(function () {
self.open = false;
}, 200); // 200 - delay for closing the menu in milliseconds.
};
Example 3 - variation targeting the menu popup
/*Initialization*/
let thisMenupopup = this.getElementsByTagName("menupopup")[0];
if (thisMenupopup) {
this.timer = 0;
// Opens de menu on mouse over.
this.onmouseover = function () {
clearTimeout(this.timer);
this.timer = setTimeout(function () {
thisMenupopup.openPopup(self, "after_start", 0, 0, false, false);
}, 200); // 200 - delay for open the menu in milliseconds.
};
// Closes de menu on mouse out.
this.onmouseout = function () {
clearTimeout(this.timer);
this.timer = setTimeout(function () {
thisMenupopup.hidePopup();
}, 200); // 200 - delay for closing the menu in milliseconds.
};
}
Prompts, alerts, etc
Examples of the various output messages, examples of data requests from the user and so forth
Using Prompt Dialogs
/*Code*/
createMsg("title").aMsg("message");
/*Code*/
custombuttons.alertBox("title", "description");
/*Code*/
custombuttons.alertSlide("title", "description");
/*Code*/
// close window or click cancel alerts "false,default,false"
var box = custombuttons.promptBox("title", "description", "default");
if (box[0]) {
alert(box[0] + "," + box[1] + "," + box[2]);
} else {
alert(box[0] + "," + box[1] + "," + box[2]);
}
/*Code*/
// close window or click cancel alerts "false,default,true"
var box = custombuttons.promptBox("title", "description", "default", {
value : true,
prompt : "option"
});
if (box[0]) {
alert(box[0] + "," + box[1] + "," + box[2]);
} else {
alert(box[0] + "," + box[1] + "," + box[2]);
}
/*Code*/
// close window alerts "option b"
var box = custombuttons.confirmBox("title", "description", "option a", "option b");
if (box) {
alert("option a");
} else {
alert("option b");
}
/*Code*/
// close window alerts "option c"
var box = custombuttons.confirmBox3("title", "description", "option a", "option c", "option b");
if (box == 0)
alert("option a");
if (box == 1)
alert("option c");
if (box == 2)
alert("option b");
/*Code*/
// close window or click cancel alerts "false,option a"
var arr = ["option a", "option b", "option c"];
var box = custombuttons.selectBox("title", "description", arr);
if (box[0]) {
alert(box[0] + "," + arr[box[1].value]);
} else {
alert(box[0] + "," + arr[box[1].value]);
}
/*Code*/
// close window or click no alerts "option a,true,option b,true,option c,true"
var arr = new Array();
arr[0] = ["option a", true];
arr[1] = ["option b", true];
arr[2] = ["option c", true];
var dialog = custombuttons.checkboxDialog(this, arr,
"title", "group", "header", "description", "yes", "no",
"help", "help message", "disclosure", "disclosure message");
if (dialog) {
alert(arr);
for (var i = 0; i < dialog.chosen.length; i++)
alert(dialog.chosen[i].index + "," + dialog.chosen[i].label);
} else {
alert(arr);
}
/*Code*/
// close window or click no alerts "option a,true,option b,false,option c,false"
var arr = new Array();
arr[0] = ["option a", true];
arr[1] = ["option b", false];
arr[2] = ["option c", false];
var dialog = custombuttons.radioboxDialog(this, arr,
"title", "group", "header", "description", "yes", "no",
"help", "help message", "disclosure", "disclosure message");
if (dialog) {
alert(arr);
for (var i = 0; i < dialog.chosen.length; i++)
alert(dialog.chosen[i].index + "," + dialog.chosen[i].label);
} else {
alert(arr);
}
Notification function - Firefox, SeaMonkey and Thunderbird
This function is similar to the custombuttons.alertSlide
function, but this one allows you to use a custom image. It also works (should) on platforms that don't implement nsIAlertsService.
function notifyme(aImg, aTitle, aMsg) {
let notFeature = custombuttons.getPrefs("notification.feature.enabled");
try {
let nsIAlertsService = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService);
if (!notFeature) {
custombuttons.setPrefs("notification.feature.enabled", true);
setTimeout(function () {
nsIAlertsService.showAlertNotification(aImg, aTitle, aMsg, false, "", null);
custombuttons.setPrefs("notification.feature.enabled", false);
}, 100);
} else
nsIAlertsService.showAlertNotification(aImg, aTitle, aMsg, false, "", null);
} catch (aEr) {
let win = Cc['@mozilla.org/embedcomp/window-watcher;1']
.getService(Ci.nsIWindowWatcher)
.openWindow(null, 'chrome://global/content/alerts/alert.xul',
'_blank', 'chrome,titlebar=no,popup=yes', null);
win.arguments = [aImg, aTitle, aMsg, false, ''];
}
}
// Usage
notifyme("chrome://branding/content/icon32.png", "Title", "Message");
Doorhanger notifications - Firefox and SeaMonkey
This is a very basic example of usage of the PopupNotifications.jsm module.
function notify(aMsg, aDel) {
let nt = PopupNotifications.show(gBrowser.selectedBrowser, self.id +
"-Door-Hanger", aMsg, self.id, null, null, null);
(aDel) && nt.remove();
}
// Usage
notify("Message"); // Show door hanger notification
setTimeout(function () {
notify("", true); // Remove after...
}, 5000); // ...5 seconds.
Play sounds
var soundFile = "C:\\WINDOWS\\Media\\notify.wav";
var sound = Cc["@mozilla.org/sound;1"].createInstance(Ci.nsISound);
sound.playSystemSound(soundFile);
Working with files
Launch Notepad
/*Code*/
var localFile = Cc["@mozilla.org/file/local;1"].
createInstance(Ci.nsILocalFile);
localFile.initWithPath("C:\\WINDOWS\\system32\\notepad.exe");
localFile.launch();
Open README.txt File in Notepad
/*Code*/
var localFile = Cc["@mozilla.org/file/local;1"].
createInstance(Ci.nsILocalFile);
var process = Cc["@mozilla.org/process/util;1"].
createInstance(Ci.nsIProcess);
var args = ["C:\\Program Files\\Mozilla Firefox\\README.txt"];
localFile.initWithPath("C:\\WINDOWS\\system32\\notepad.exe");
process.init(localFile);
process.run(false, args, args.length);
Open userChrome.css File in Notepad
/*Code*/
// chrome folder does not exist by default
var file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("UChrm", Ci.nsIFile);
file.append("userChrome.css");
var localFile = Cc["@mozilla.org/file/local;1"].
createInstance(Ci.nsILocalFile);
var process = Cc["@mozilla.org/process/util;1"].
createInstance(Ci.nsIProcess);
var args = [file.path];
localFile.initWithPath("C:\\WINDOWS\\system32\\notepad.exe");
process.init(localFile);
process.run(false, args, args.length);
Open Personal Folder in Explorer
/*Code*/
// single pane
var localFile = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("Home", Ci.nsILocalFile);
localFile.reveal();
/*Code*/
// default view
var file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("Home", Ci.nsIFile);
var localFile = Cc["@mozilla.org/file/local;1"].
createInstance(Ci.nsILocalFile);
var process = Cc["@mozilla.org/process/util;1"].
createInstance(Ci.nsIProcess);
var args = ["/e,", file.path];
localFile.initWithPath("C:\\WINDOWS\\explorer.exe");
process.init(localFile);
process.run(false, args, args.length);
Open custombuttons Folder in Command Prompt
/*Code*/
var file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("ProfD", Ci.nsIFile);
file.append("custombuttons");
var environment = Cc["@mozilla.org/process/environment;1"].
getService(Ci.nsIEnvironment);
var localFile = Cc["@mozilla.org/file/local;1"].
createInstance(Ci.nsILocalFile);
var process = Cc["@mozilla.org/process/util;1"].
createInstance(Ci.nsIProcess);
var args = ["/k", "cd /d " + file.path + " & title Custom Buttons & dir"];
localFile.initWithPath(environment.get("ComSpec"));
process.init(localFile);
process.run(false, args, args.length);
Function to open any file/folder
function openPath(aPath, aArgs) {
var nsIFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
nsIFile.initWithPath(aPath);
try {
if (nsIFile.isDirectory()) // If aPath is a Directory...
nsIFile.reveal(); // ...try to open it.
else if (!nsIFile.isDirectory() && !nsIFile.isExecutable()) // If aPath is not a Directory nor an executable...
nsIFile.launch(); // ...try to launch it.
else if (!nsIFile.isDirectory() && nsIFile.isExecutable()) { // If aPath is an executable, try to execute it.
var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
try {
process.init(nsIFile); // Initialize nsIProcess.
(aArgs === undefined || aArgs[0] === "") // Check if there are arguments.
? process.runw(false, null, null) // Run nsIFile WITHOUT arguments...
: process.runw(false, aArgs, aArgs.length); // ...or run nsIFile WITH arguments.
} catch (aError) {
Cu.reportError(aError);
}
}
} catch (aError) {
Cu.reportError(aError);
}
}
Usage
Usage:openPath(aPath, aArgs);
- aPath: Any valid and existent path. Absolute or "constructed".
- Path examples absolute:
"C:\\Windows\\notepad.exe" // Windows path
"/usr/bin/kwrite" // "Linux" path
- Path example from OS.File API:
OS.Constants.Path.desktopDir // Desktop path in all platforms
- Path example from "Directory service":
Services.dirsvc.get("Desk", Ci.nsIFile) // Desktop path in all platforms
- Path example "constructed" with OS.File API:
OS.Path.join(OS.Constants.Path.libDir, "seamonkey.exe")
- Path example "constructed" with "Directory service":
let baseDir = Services.dirsvc.get("CurProcD", Ci.nsIFile);
baseDir.append("seamonkey.exe");
- Path examples absolute:
- aArgs: An array of arguments. ONLY for executable files.
- Example with one argument:
["arg"]
- Example with n arguments:
["arg-1", "arg-2", "arg-n"]
- Example with one argument:
/**
* Practical examples
*/
// Open Desktop directory on any platform
// Option 1
openPath(OS.Constants.Path.desktopDir);
// Option 2
openPath(Services.dirsvc.get("Desk", Ci.nsIFile));
// Open Home directory on any platform
// Option 1
openPath(OS.Constants.Path.homeDir);
// Option 2
openPath(Services.dirsvc.get("Home", Ci.nsIFile));
// Execute a new instace of Firefox with profile selector.
// Short version
openPath(OS.Path.join(OS.Constants.Path.libDir, "firefox.exe"), ["-no-remote", "-p"]);
// or long version...
let profDir = Services.dirsvc.get("CurProcD", Ci.nsIFile);
profDir.append("firefox.exe");
openPath(profDir, ["-no-remote", "-p"]);
// Execute a new instace of SeaMonkey with profile selector.
// Short version
openPath(OS.Path.join(OS.Constants.Path.libDir, "seamonkey.exe"), ["-no-remote", "-p"]);
// or long version...
let profDir = Services.dirsvc.get("CurProcD", Ci.nsIFile);
profDir.append("seamonkey.exe");
openPath(profDir, ["-no-remote", "-p"]);
// Execute Notepad in Windows.
openPath("C:\\Windows\\notepad.exe");
// Execute KWrite in Linux.
openPath("/usr/bin/kwrite");
// Open a Firefox profile called "default" in Linux.
openPath("/usr/bin/firefox", ["-no-remote", "-p", "default"]);
Examples of different functions to work with files(read/write/create) and launch programs
File creation function
function addfile(parentpath, filename) {
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(parentpath);
file.append(filename);
if (!file.exists() || !file.isFile()) { // if it doesn't exist, create
file.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
}
}
Folder add function
function adddir(parentpath, newdir) {
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(parentpath);
file.append(newdir);
if (!file.exists() || !file.isDirectory()) { // if it doesn't exist, create
file.create(Ci.nsIFile.DIRECTORY_TYPE, 0777);
}
}
Profile address
var currProfD = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties).get("ProfD", Ci.nsIFile);
var profileDir = currProfD.path;
Doubling slashes in the path.
function slashdouble(path) {
var path = path.replace(/\\/g, "\\")
return (path)
}
Function of reading from file
function readfile(parentdir, filename, fileout) {
var filefullpath = parentdir + "\\" + filename;
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(filefullpath);
Cu.import("resource://gre/modules/NetUtil.jsm");
NetUtil.asyncFetch(file, function (inputStream, status) {
if (!Components.isSuccessCode(status)) {
data = "An error occured"; // To notify Interval func on error
return;
}
data = NetUtil.readInputStreamToString(inputStream, inputStream.available());
if (!data) {
data = "File contains no data";
} // To notify Interval func on empty file
});
}
readfile(feedsdir, "myfeeds.txt");
var xInterval = setInterval(function () {
if (typeof(data) == "undefined") {
return;
} else {
alert(data);
clearInterval(xInterval);
// Parser code here, data is valid
}
}, 1101);
Open folder
var Dir = "C:\\windows\\Media"; // the path to a folder, do not forget about the double slashes in the path
var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", "nsILocalFile", "initWithPath");
new nsLocalFile(Dir).reveal();
Save the file with a choice
MyFile = "test"; //the contents of the file
MyFilename = "test.txt"; // the file name
var nsIFilePicker = Ci.nsIFilePicker;
var fp = Cc["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, "", fp.modeSave);
fp.defaultString = MyFilename;
fp.appendFilters(fp.filterHTML);
fp.appendFilters(fp.filterAll);
if (fp.show() == fp.returnCancel)
return;
var stream = Cc['@mozilla.org/network/file-output-stream;1']
.createInstance(Ci.nsIFileOutputStream);
stream.init(fp.file, 0x02 | 0x20 | 0x08, 0666, 0);
stream.write(MyFile, MyFile.length);
stream.close();
Converting strings to unicode
var mytext = "Text"
var uc = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
uc.charset = "utf-8";
unicodetext = uc.ConvertFromUnicode(mytext);
To create a new resource resource:rootc
//icon
// data:image/png;base64,CODE
Cu.import("resource://gre/modules/FileUtils.jsm");
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath("C:\\");
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var rph = ios.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
var uri = ios.newFileURI(file);
rph.setSubstitution("rootc", uri);
alert("resource:rootc")
getBrowser().selectedTab = getBrowser().addTab("resource:rootc");
Start external program with arguments
var prgpath = "C:\\windows\\ping.exe"; // the path to the executable file, do not forget about the double slashes in the path
var args = ['-n', '6', 'google.com']; // arguments are separated by a space. i.e. string bla.exe -open "c:\program files\ololo\ololo.txt" will have arguments var args = ['-open','"c:\program', 'files\ololo\ololo.txt"'];
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(prgpath);
var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
process.init(file);
process.run(false, args, args.length);
Function writes to the file, overwriting
function data2fileoverwrite(filepath, data) {
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(filepath);
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
var ostream = FileUtils.openSafeFileOutputStream(file)
var converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var istream = converter.convertToInputStream(data);
// The last argument (the callback) is optional.
NetUtil.asyncCopy(istream, ostream, function (status) {
if (!Components.isSuccessCode(status)) {
// Handle error!
return;
}
// Data has been written to the file.
});
};
Feature writing to a file by adding at the end
function append2file(filepath, text) {
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
file.initWithPath(filepath);
var stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
var converter = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
stream.init(file, 0x02 | 0x10, 0664, 0);
converter.init(stream, "UTF-8", 0, 0x1010);
converter.writeString("\u101D\u101A"); //If you want to add a new row
converter.writeString(text);
converter.close();
stream.close();
}
append2file("C:\\testfile.txt", "ololololololo!");
Select the file and getting his path
const nsIFilePicker = Ci.nsIFilePicker;
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
fp.init(window, "Select any file!", nsIFilePicker.modeOpen);
fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText);
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
var file = fp.file;
// Get the path as string. Note that you usually won't
// need to work with the string paths.
var path = fp.file.path;
alert("You have chosen a file:\n" + path);
// work with returned nsILocalFile...
}
Working with clipboard, text data, etc
Using Clipboards
/*Code*/
// copy string to system clipboard
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
clipboard.copyString("test");
/*Code*/
// internal clipboard - uppercase write, read, clear
gClipboard.Write(document.location.href);
alert(gClipboard.Read());
gClipboard.Clear();
alert(gClipboard.Read());
/*Code*/
// system clipboard - lowercase write, read, clear
gClipboard.write(content.document.location.href);
alert(gClipboard.read());
gClipboard.clear();
alert(gClipboard.read());
Export Commands to Clipboard
/*Code*/
var commands = document.getElementsByTagName("command");
var out = new Array();
var info = Cc["@mozilla.org/xre/app-info;1"].
getService(Ci.nsIXULAppInfo);
out.push(info.name + " " + info.version, "");
out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '"', "");
for (var i = 0; i < commands.length; i++) {
var id = commands[i].getAttribute("id");
var oncommand = commands[i].getAttribute("oncommand");
if (id && oncommand)
out.push(id);
}
var req = new XMLHttpRequest();
req.open("GET", "chrome://global/content/platformHTMLBindings.xml", false);
req.send(null);
var doc = req.responseXML;
var handlers = doc.getElementsByTagName("handler");
for (var i = 0; i < handlers.length; i++) {
var command = handlers[i].getAttribute("command");
if (command && out.indexOf(command) == -1)
out.push(command);
}
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
clipboard.copyString(out.join("\r\n"));
Using Special Files
/*Code*/
var file = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties).
get("Home", Ci.nsIFile);
alert(file.path);
var uri = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService).
newFileURI(file);
alert(uri.spec);
var localFile = file.QueryInterface(Ci.nsILocalFile);
localFile.reveal();
Export Special Files to Clipboard
/*Code*/
var ds = Cc["@mozilla.org/file/directory_service;1"].
getService(Ci.nsIProperties);
var nsDirectoryServiceDefs = ["AppData", "ApplMenu", "Buckt", "CmDeskP", "CmPrgs", "CmStrt",
"CntlPnl", "Cntls", "CookD", "CurProcD", "CurWorkD", "Desk", "DeskP", "DeskV", "DfltDwnld",
"Docs", "Drivs", "DrvD", "Exts", "Favs", "Fnts", "GreD", "Home", "IntrntSts", "ISrch", "LibD",
"LocalAppData", "LocApp", "LocDocs", "LocDsk", "LocFrmwrks", "Locl", "LoclIntrntPlgn", "LocPrfs",
"Mov", "Music", "netH", "NetW", "OS2Dir", "Pct", "Pers", "Prfs", "PrntHd", "Prnts", "ProgF",
"Progs", "Rcnt", "Shdwn", "SndTo", "Strt", "SysD", "TmpD", "Tmpls","Trsh", "ULibDir", "UsrApp",
"UsrDocs", "UsrDsk", "UsrFrmwrks", "UsrIntrntPlgn", "UsrPrfs", "WinD", "XCurProcD", "XDGDesk",
"XDGDocs", "XDGDwnld", "XDGMusic", "XDGPict", "XDGPubSh", "XDGTempl", "XDGVids", "XpcomLib"];
var nsAppDirectoryServiceDefs = ["AChrom", "AChromDL", "APluginsDL", "APlugns", "AppRegD",
"AppRegF", "ARes", "BMarks", "cachePDir", "DefProfLRt", "DefProfRt", "DefRt", "DLoads",
"ExtPrefDL", "LclSt", "PrefD", "PrefDL", "PrefDOverride", "PrefF", "PrfDef", "ProfD", "profDef",
"ProfDefNoLoc", "ProfLD", "SHARED", "SrchF", "SrchPluginsDL", "SrchPlugns", "UChrm", "UHist",
"UMimTyp", "UPnls", "UsrSrchPlugns", "UStor", "XPIClnupD"];
var nsBrowserDirectoryServiceDefs = ["ExistingPrefOverride"];
var nsXULAppAPI = ["ProfDS", "ProfLDS", "UAppData", "XREAppDist", "XREExeF", "XREExtDL",
"XRESysLExtPD", "XRESysSExtPD", "XREUSysExt"];
var props = new Array();
var out = new Array();
props = props.concat(nsDirectoryServiceDefs);
props = props.concat(nsAppDirectoryServiceDefs);
props = props.concat(nsBrowserDirectoryServiceDefs);
props = props.concat(nsXULAppAPI);
for (var i = 0; i < props.length; i++) {
if (ds.has(props[i])) {
var file = ds.get(props[i], Ci.nsIFile);
if (file && file.path) {
out.push([props[i], file.path]);
}
}
}
out.sort(function (a, b) {
return a[1] > b[1]
});
var width = out.reduce(function (a, b) {
return a[0].length > b[0].length ? a : b
})[0].length;
for (var i = 0; i < out.length; i++) {
out[i] = out[i][0] + Array(width + 2 - out[i][0].length).join(" ") + out[i][1];
}
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
clipboard.copyString(out.join("\r\n"));
The clipboard, change the conversion getting different values, and so forth
Obtain the value from the Clipboard
var text = custombuttonsUtils.gClipboard.read();
Write the value to the Clipboard
var text = "This text will be placed into the Clipboard";
const gClipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
gClipboardHelper.copyString(text);
Attention!! If you add one of the components of the string (for example, if you enter through the prompt):
Add it with a numeric variable is like adding rows to it around, use the following option:
var a = prompt("Enter the number of:");
var b = 5;
var n = a + b;
var m = (+a) + (+b);
alert("a=" + a + "\nb=5\na+b=" + n + "\n(+a)+(+b)=" + m);
// do not forget about this feature of javascript
Break a line into pieces at a delimiter
var stroka = "123=43*44o=lol*=rm8658oo*=uenrnk7n*=4upa6m";
var chkpoint = "*="; // This separator
var arrayOfStrings = stroka.split(chkpoint);
pervyi_element = arrayOfStrings[0]; //is 123 = 43 * 44o = lol
vtoroi_element = arrayOfStrings[1]; //equal to rm8658oo
//etc
The length of the string
var stroka = "envosnvrohnorhnsonhoisd";
alert(stroka + "=" + stroka.length + " characters");
Get a piece of string
var stroka = "1234567890";
alert(stroka.substring(4, 7)); // 567
alert(stroka.substring(5)); // 67890
Converting strings to unicode
var mytext = "sdlgsdlgsdlvnlsfndn";
var uc = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
uc.charset = "utf-8";
unicodetext = uc.ConvertFromUnicode(mytext);
URL decoding with (unescape)
var nn = unescape('%64%6f%63%75%6d%65%6e');
alert(nn);
Insert text into the text area on page option 1.
var text = "Pasted text";
var cmd = "cmd_insertText";
var controller = document.commandDispatcher.getControllerForCommand(cmd);
if (controller && controller.isCommandEnabled(cmd)) {
controller = controller.QueryInterface(Ci.nsICommandController);
var params = Cc["@mozilla.org/embedcomp/command-params;1"]
.createInstance(Ci.nsICommandParams);
params.setStringValue("state_data", text);
controller.doCommandWithParams(cmd, params);
}
Insert text into the text field on page option 2.
var intext = "The pasted text";
var theBox = document.commandDispatcher.focusedElement;
var pos = theBox.selectionStart;
var text = theBox.value.substring(0, pos) + intext + theBox.value.substring(pos, theBox.value.length);
theBox.value = text;
theBox.setSelectionRange(pos, pos + intext.length);
Paste the code into the current page version 1.
vnachalo = "< b>This bold text and a line at the top of the page< b>< hr>";
vkonec = "< br>< u>The underlined text and picture < img src='http://www.mozilla.org/favicon.ico'> at the end of the page</ u>";
content.document.body.innerHTML = vnachalo + content.document.body.innerHTML + vkonec; // remove spaces from HTML tags for it to work
Paste the code into the current page version 2.
var begin = "< b>This bold text and a line at the top of the page< b>< hr>";
var end = "< br >< u >The underlined text and picture < img src='http://www.mozilla.org/favicon.ico'> at the end of the page< / u >";
var doc = content.document; // remove spaces from HTML tags for it to work
var body = doc.body || doc.documentElement;
body.insertBefore(createDocumentFragment(begin), body.firstChild);
body.appendChild(createDocumentFragment(end));
function createDocumentFragment(html) {
var tmp = doc.createElementNS("http://www.w3.org/1999/xhtml", "div");
tmp.innerHTML = html;
var df = doc.createDocumentFragment();
while (tmp.hasChildNodes())
df.appendChild(tmp.firstChild);
return df;
}
Paste the code into the current page option 3.
var begin = "< b >This bold text and a line at the top of the page< b >< hr >";
var end = "< br >< u >The underlined text and picture < img src='http://www.mozilla.org/favicon.ico'> at the end of the page</ u >";
var doc = content.document; // remove spaces from HTML tags for it to work
var body = doc.body || doc.documentElement;
body.insertBefore(createDiv(begin), body.firstChild);
body.appendChild(createDiv(end));
function createDiv(html) {
var div = doc.createElementNS("http://www.w3.org/1999/xhtml", "div");
div.innerHTML = html;
return div;
}
Getting the date 1.
var t=new Date();
var y=1900+t.getYear();
var min=t.getMinutes(); if (min<10){min="0"+min};
var h=t.getHours();
var m=t.getMonth();switch(m){case 0: m="Jan";break;case 1: m="Feb";break;case 2: m="Mar";break;case 3: m="Apr";break;case 4: m="May";break;case 5: m="Jun";break;case 6: m="Jul";break;case 7: m="Aug";break;case 8: m="Sep";break;case 9: m="Oct";break;case 10: m="Nov";break;default: m="Dec";}
var d=t.getDate();
var curdate=y+"-"+d+"-"+m+"_"+h+":"+min;
alert(curdate)
Getting the date 2.
var t=new Date();
var y=1900+t.getYear();
var min=t.getMinutes(); if (min<10){min="0"+min};
var h=t.getHours();
var m = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][t.getMonth()];
var d=t.getDate();
var curdate=y+"-"+d+"-"+m+"_"+h+":"+min;
alert(curdate)
Working with URLs, tabs, UI elements and so on
Open Pages - Firefox and SeaMonkey
/*Code*/
// open page in the current tab
loadURI("http://www.google.com/");
/*Code*/
// open page in a new tab in the background
gBrowser.addTab("http://www.google.com/");
/*Code*/
// open page in a new tab in the foreground
gBrowser.selectedTab = gBrowser.addTab("http://www.google.com/");
/*Code*/
// open page in a new window
window.open("http://www.google.com/");
Open Sidebar - Firefox
/*Code*/
// open page in the side panel
openWebPanel("Firefox", "about:logo");
/*Code*/
// open and close a page in the side panel
if (document.getElementById("sidebar-title").value) {
toggleSidebar();
} else {
openWebPanel("Firefox", "about:logo");
}
Using Bookmarklets - Firefox and SeaMonkey
javascript:(function(){alert('test');})();
/*Code*/
loadURI("javascript:(function(){alert('test');})();");
javascript:(function(){alert("test");})();
/*Code*/
loadURI('javascript:(function(){alert("test");})();');
/*Code*/
// google "greasemonkey location hack" for more information
content.document.location.href = "javascript:(" + function() {
alert("test");
} + ")()";
Select Tabs - Firefox and SeaMonkey
/*Code*/
// next tab
gBrowser.tabContainer.advanceSelectedTab(1, true);
/*Code*/
// previous tab
gBrowser.tabContainer.advanceSelectedTab(-1, true);
Move Tabs - Firefox and SeaMonkey
/*Code*/
// move tab forward
if (gBrowser.selectedTab.nextSibling) gBrowser.moveTabForward();
else gBrowser.moveTabToStart();
/*Code*/
// move tab backward
if (gBrowser.selectedTab.previousSibling) gBrowser.moveTabBackward();
else gBrowser.moveTabToEnd();
Reload Tabs - Firefox and SeaMonkey
/*Code*/
gBrowser.reloadTab(gBrowser.selectedTab);
/*Code*/
gBrowser.reloadAllTabs();
Remove Tabs - Firefox and SeaMonkey
/*Code*/
gBrowser.removeTab(gBrowser.selectedTab);
/*Code*/
gBrowser.removeAllTabsBut(gBrowser.selectedTab);
Navigate History - Firefox and SeaMonkey
/*Code*/
// go back to the first page
gBrowser.webNavigation.gotoIndex(0);
/*Code*/
// go forward to the last page
gBrowser.webNavigation.gotoIndex(gBrowser.webNavigation.sessionHistory.count - 1);
Toggle Toolbars - Firefox
/*Code*/
var toolbar = document.getElementById("toolbar-menubar");
var visibility = toolbar.getAttribute("autohide") == "true";
setToolbarVisibility(toolbar, visibility);
/*Code*/
var toolbar = document.getElementById("nav-bar");
var visibility = toolbar.collapsed;
setToolbarVisibility(toolbar, visibility);
/*Code*/
var toolbar = document.getElementById("PersonalToolbar");
var visibility = toolbar.collapsed;
setToolbarVisibility(toolbar, visibility);
/*Code*/
var toolbar = document.getElementById("addon-bar");
var visibility = toolbar.collapsed;
setToolbarVisibility(toolbar, visibility);
Toggle Find Bar - Firefox, SeaMonkey and Thunderbird
/*Code*/
var toolbar = document.getElementById("FindToolbar");
toolbar.hidden ? toolbar.onFindCommand() : toolbar.close();
Toggle Tab Strip - Firefox and SeaMonkey
/*Code*/
gBrowser.setStripVisibilityTo(!gBrowser.getStripVisibility());
Execute Menu Item Command
/*Code*/
document.getElementsByAttribute("label", "Troubleshooting Information")[0].doCommand();
/*Code*/
// unicode hexadecimal 2026 - horizontal ellipsis character
document.getElementsByAttribute("label", "Add new button\u2026")[0].doCommand();
Observe Attribute Example - Firefox, SeaMonkey and Thunderbird
/*Initialization code*/
// toggle attribute in customize toolbar window
var info = Cc["@mozilla.org/xre/app-info;1"].
getService(Ci.nsIXULAppInfo);
var toolbox;
if (info.name == "Firefox" || info.name == "SeaMonkey") {
toolbox = document.getElementById("navigator-toolbox");
}
if (info.name == "Thunderbird") {
toolbox = document.getElementById("mail-toolbox");
}
var ob = <observes
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
element={toolbox.id}
attribute="iconsize"
onbroadcast={"document.getElementById('" + this.id + "').change()"}/>;
this.appendChild(custombuttonsUtils.makeXML(ob));
this.change = function() {
if (toolbox.getAttribute("iconsize") == "small") {
this.image = "chrome://global/skin/icons/information-16.png";
alert('attribute for the "Use Small Icons" option is checked');
}
if (toolbox.getAttribute("iconsize") == "large") {
this.image = "chrome://global/skin/icons/information-24.png";
alert('attribute for the "Use Small Icons" option is not checked');
}
}
this.change();
Various examples of the addresses-tabs-windows-and other things
Management of the browser window.
window.restore(); // Restore
window.maximize(); // Expand
window.minimize() // Collapse
window.close(); // Close
goQuitApplication();// Close all windows
window.moveTo(0,0);// Move the window to the specified coordinates (upper left corner)
window.resizeTo(1024,738);// Resize the window
OPEN a new window size half the screen with the address or arbitrary html code.
var urla = "http://custombuttons.mozdev.org/"//---set the address or write code as in the line below
var urlb = "data:text/html,ololo!"; //just text ololo!
// 2 lines below to clear 1-HTML code of the page 2-collect the entire address
var pagecode='<html><head><title>The title of the page</title><meta http-equiv="content-type" content="text /html; charset=UTF-8"></head><body><hr><font size=+2 color=#ff1010><b>TEST</b></font><hr> </body></html>';
var urlc = "data:text/html,"+pagecode;
var sizex = screen.width/2; //------screen width/2
var sizey = screen.height/2; //-----screen height/2
Setup window: resizable - changing dimensions scrollbars - Show scroll bars menubar - the menu bar toolbar - browser panel location - Panel with the address bar personalbar - custom panels status - status bar
var winfeatures='resizable=yes,scrollbars=yes,menubar=yes,toolbar=yes,location=yes,personalbar=yes,status=yes,width=' + sizex + ',height=' +sizey;
var wnd = window.open(url, this.name,winfeatures ); // actually open the window with the address url and settings winfeatures
if (wnd.focus) wnd.focus();
Add the current page to a specified folder in bookmarks
var folderName = "test";
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
var menuFolder = bmsvc. bookmarksMenuFolder;
var f = bmsvc. getChildFolder (menuFolder, folderName);
if (f == 0){ bmsvc. createFolder (menuFolder, folderName, bmsvc. DEFAULT_INDEX);
f = bmsvc. getChildFolder (menuFolder, folderName);}
PlacesCommandHook. bookmarkCurrentPage (false, f);
Open the url in a new tab without validation
var url="http://custombuttons.mozdev.org/";
getBrowser (). selectedTab = getBrowser (). addTab (url);
Open the url in a new tab if it is not empty, if empty then the current
var url="http://custombuttons.mozdev.org/";
if (getBrowser().currentURI.spec == "about:blank") loadURI (url);
else{ getBrowser (). selectedTab = getBrowser (). addTab (url);
Open the url in a new tab if it is not empty, if empty then the current option 2. for FF 4+
var url = "http://custombuttons.mozdev.org/";
if (
(
gBrowser.currentURI.spec == "about:blank"
|| gBrowser.currentURI.spec == cbu.getPrefs("browser.newtab.url")
)
&& !gBrowser.selectedBrowser.webProgress.isLoadingDocument
)
loadURI(url);
else
gBrowser.selectedTab = gBrowser.addTab(url);
Open a url in the current tab
var url="http://custombuttons.mozdev.org/";
loadURI (url);
Get the address of the current page
var url=getBrowser().currentURI.spec;
Listener to load the page.
var appcontent = document.getElementById("appcontent");
appcontent.removeEventListener("DOMContentLoaded", pageloadedok, true);
appcontent.addEventListener("DOMContentLoaded", pageloadedok, true);
function pageloadedok(){custombuttons.alertSlide("Page loaded","Page loaded")}
Listener values change URL bar
var myExt_urlBarListener = {
QueryInterface: function (aIID)
{
if (aIID.equals(Ci.nsIWebProgressListener) ||
aIID.equals(Ci.nsISupportsWeakReference) ||
aIID.equals(Ci.nsISupports))
return this;
throw Cr.NS_NOINTERFACE;
},
onLocationChange: function (aProgress, aRequest, aURI)
{
setTimeout(urlbarvaluechanged, 300);
},
onStateChange: function (a, b, c, d) {},
onProgressChange: function (a, b, c, d, e, f) {},
onStatusChange: function (a, b, c, d) {},
onSecurityChange: function (a, b, c) {}
};
gBrowser.addProgressListener(myExt_urlBarListener,Ci.nsIWebProgress.NOTIFY_LOCATION);
function urlbarvaluechanged(){custombuttons.alertSlide("urlbar value changed", "on "+gURLBar.value);}
Getting the current IP with duplicate in case the first server is unavailable.
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://ip.xss.ru/', true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
var ip = xmlhttp.responseText;
ipok = ip. match (/\d?\d?\d\.\d?\d?\d\.\d?\d?\d\.\d?\d?\d/) [0];
alert("1="+ipok);
return ipok;
} else { getipalt(); }
}
};
xmlhttp.send(null);
function getipalt(){
xmlhttp.open('GET', 'http://www.myip.ru/ru-RU/index.php', true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
var ip = xmlhttp.responseText;
ipok = ip. match (/\d?\d?\d\.\d?\d?\d\.\d?\d?\d\.\d?\d?\d/) [0];
alert("2="+ipok);
return ipok;
}
}
};
xmlhttp.send(null);
}
Working with preferences (about:config)
Open Config Manager
/*Code*/
toOpenWindowByType("Preferences:ConfigManager", "chrome://global/content/config.xul");
Using Preferences
Test preference existence
Custom Buttons' built-in
/*Code*/
// test whether a preference exists
alert(custombuttons.isPref("dom.disable_open_during_load"));
// Will alert "true" if the preference exists or "false" if it doesn't.
Native code - Using "Services" module
var prefType = Services.prefs.getPrefType("preference.name");
if (prefType === 0) // Inexistent
alert("Preference doesn't exists.");
else if (prefType === 32) // String
alert("Preference type is 'string'.");
else if (prefType === 64) // Integer
alert("Preference type is 'integer'.");
else if (prefType === 128) // Boolean
alert("Preference type is 'boolean'.");
h3#nav_f-2-pref-get-value Get preference value
h4 Custom Buttons' built-in
/*Code*/
// get preference
alert(custombuttons.getPrefs("dom.disable_open_during_load"));
Native code - Using "Services" module
Services.prefs.getBoolPref("preference.name"); // Get "boolean" type preference
Services.prefs.getIntPref("preference.name"); // Get "integer" type preference
Services.prefs.getCharPref("preference.name"); // Get "string" type preference
Services.prefs.getComplexValue("preference.name",
Ci.nsISupportsString).data; // Get "string" type preference with UNICODE support
Given a "string" type preference with the value C:\Folder\папка\フォルダ\夹 (It's a Windows path with words in Russian, Japanese and Chinese).
Using getCharPref
will output...
And using getComplexValue
will output...
Set preference value
Custom Buttons' built-in
/*Code*/
// set preference
custombuttons.setPrefs("dom.disable_open_during_load", false);
/*Code*/
// toggle preference
var s = "dom.disable_open_during_load";
custombuttons.setPrefs(s, !custombuttons.getPrefs(s));
Native code - Using "Services" module
Services.prefs.setBoolPref("preference.name", true); // Set "boolean" type preference
Services.prefs.setBoolPref("preference.name",
!Services.prefs.getBoolPref("preference.name")); // Toggle "boolean" type preference
Services.prefs.setIntPref("preference.name", 100); // Set "integer" type preference
Services.prefs.setCharPref("preference.name", "Preference Value"); // Set "string" type preference
// Set "string" type preference with UNICODE support
var str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
str.data = "Preference 值";
Services.prefs.setComplexValue("preference.name", Ci.nsISupportsString, str);
Other methods for handling preferences
Clear preference - Custom Buttons' built-in
/*Code*/
// clear preference
custombuttons.clearPrefs("dom.disable_open_during_load");
Clear preference - Native code using "Services" module
Called to clear a user set value from a specific preference. This will, in effect, reset the value to the default value. If no default value exists the preference will cease to exist.
Services.prefs.clearUserPref("preference.name");
Observe Preferences - Firefox, SeaMonkey and Thunderbird
/*Initialization code*/
// toggle preference in about:config
var prefs = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefBranch);
var pref = "dom.disable_open_during_load";
this.change = function () {
var s = "test 1\n"; // increment to test observer
if (prefs.getBoolPref(pref))
alert(s + 'preference for the "Block pop-up windows" option is true');
else
alert(s + 'preference for the "Block pop-up windows" option is false');
};
this.obj = new Object();
this.obj.observe = this.change.bind(this);
// comment out the next line to disable observer
prefs.addObserver(pref, this.obj, false);
this.onDestroy = function (reason) {
if (reason == "update") {
prefs.removeObserver(pref, this.obj);
}
if (reason == "delete") {
prefs.removeObserver(pref, this.obj);
alert("observer unregistered");
}
};
deleteBranch
Called to remove all of the preferences referenced by this branch.
var prefBranch = Services.prefs.getBranch("");
prefBranch.deleteBranch("extensions.custombuttons."); // Will DELETE ALL preferences from this branch
getChildList
Returns an array of strings representing the child preferences of the root of this branch.
var customButtonsBranch = Services.prefs.getChildList("extensions.custombuttons.", {});
// Log to console all preferences from "extensions.custombuttons." branch
LOG(customButtonsBranch.join("\n"));
lockPref
Called to lock a specific preference. Locking a preference will cause the preference service to always return the default value regardless of whether there is a user set value or not.
Services.prefs.lockPref("preference.name");
prefIsLocked
Called to check if a specific preference is locked. If a preference is locked calling its Get method will always return the default value.
alert(Services.prefs.prefIsLocked("preference.name"));
// Will alert "true" if preference is locked or "false" if it's not locked.
unlockPref
Called to unlock a specific preference. Unlocking a previously locked preference allows the preference service to once again return the user set value of the preference.
Services.prefs.unlockPref("preference.name");
prefHasUserValue
Called to check if a specific preference has a user value associated to it.
alert(Services.prefs.prefHasUserValue("preference.name"));
// Will alert "true" if preference has a user set value or "false" if it doesn't.
Thunderbird/SeaMonkey specifics
Open Pages - Thunderbird
/*Code*/
// open page in a new tab in the foreground
openContentTab("http://www.google.com/");
/*Code*/
// open page in a new tab in the background
var tabmail = document.getElementById("tabmail");
if (!tabmail) {
var win = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator)
.getMostRecentWindow("mail:3pane");
if (win) {
tabmail = win.document.getElementById("tabmail");
win.focus();
}
}
if (tabmail) {
tabmail.openTab("contentTab", {
contentPage : "http://www.google.com/",
background : true
});
} else {
window.openDialog("chrome://messenger/content/", "_blank", "chrome,dialog=no,all", null, {
tabType : "contentTab",
tabParams : {
contentPage : "http://www.google.com/",
background : true
}
});
}
/*Code*/
// open page in an external application e.g. Firefox
var eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"]
.getService(Ci.nsIExternalProtocolService);
var ios = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
eps.loadURI(ios.newURI("http://www.google.com/", null, null));
Toggle Message Pane - Thunderbird and SeaMonkey
/*Code*/
// use a boolean parameter with SeaMonkey
// true - toggle message pane
// false - show message pane splitter
MsgToggleMessagePane();
Toggle Headers - Thunderbird and SeaMonkey
/*Code*/
var prefBranch = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefBranch);
var intPref = prefBranch.getIntPref("mail.show_headers");
intPref == 1 ? MsgViewAllHeaders() : MsgViewNormalHeaders();
Toggle Message Body As - Thunderbird and SeaMonkey
/*Code*/
var prefBranch = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefBranch);
var boolPref = prefBranch.getBoolPref("mailnews.display.prefer_plaintext");
boolPref == true ? MsgBodyAllowHTML() : MsgBodyAsPlaintext();
Toggle Mail Views - Thunderbird and SeaMonkey
/*Code*/
var customView = "Last 5 Days";
if (document.getElementById("viewPicker").label == customView) {
if ("ViewChangeByValue" in window)
ViewChangeByValue(0);
else
ViewChange(0);
} else {
for (var i = 0; i < gMailViewList.mailViewCount; i++) {
var viewInfo = gMailViewList.getMailViewAt(i);
if (viewInfo.prettyName == customView) {
if ("ViewChangeByValue" in window)
ViewChangeByValue(kViewItemFirstCustom + i);
else
ViewChange(kViewItemFirstCustom + i);
break;
}
}
}
Next Message - Thunderbird and SeaMonkey
/*Code*/
var rowCount = gDBView.rowCount;
var viewIndex = gDBView.currentlyDisplayedMessage;
if (rowCount - viewIndex != 1) {
goDoCommand("cmd_nextMsg");
} else {
var wintype = document.documentElement.getAttribute("windowtype");
var tabmail = document.getElementById("tabmail");
if (wintype == "mail:3pane" && tabmail.tabContainer.selectedIndex > 0) {
tabmail.removeCurrentTab();
}
if (wintype == "mail:messageWindow") {
window.close();
}
}
Show Folder - Thunderbird and SeaMonkey
/*Code*/
alert(GetFirstSelectedMsgFolder().URI);
Select Folder - Thunderbird and SeaMonkey
/*Code*/
SelectFolder("mailbox://nobody@Local%20Folders/Unsent%20Messages"); // Outbox
Copy Message - Thunderbird and SeaMonkey
/*Code*/
var targetUri = "mailbox://nobody@Local%20Folders/Trash";
var targetFolder = document.getElementById(targetUri) || GetMsgFolderFromUri(targetUri);
MsgCopyMessage(targetFolder);
Move Message - Thunderbird and SeaMonkey
/*Code*/
var targetUri = "mailbox://nobody@Local%20Folders/Trash";
var targetFolder = document.getElementById(targetUri) || GetMsgFolderFromUri(targetUri);
MsgMoveMessage(targetFolder);
Compose Message - Thunderbird and SeaMonkey
/*Code*/
var mcService = Cc["@mozilla.org/messengercompose;1"]
.getService(Ci.nsIMsgComposeService);
var mcFields = Cc["@mozilla.org/messengercompose/composefields;1"]
.createInstance(Ci.nsIMsgCompFields);
var mcParams = Cc["@mozilla.org/messengercompose/composeparams;1"]
.createInstance(Ci.nsIMsgComposeParams);
mcFields.to = "nobody <test@example.com>";
mcFields.subject = "alpha beta";
mcFields.body = "gamma\ndelta\nepsilon";
mcParams.type = Ci.nsIMsgCompType.New;
mcParams.format = Ci.nsIMsgCompFormat.Default;
mcParams.composeFields = mcFields;
mcService.OpenComposeWindowWithParams(null, mcParams);
Insert Text - Thunderbird and SeaMonkey
/*Code*/
GetCurrentEditor().insertText("Mozilla");
Insert HTML - Thunderbird and SeaMonkey
/*Code*/
GetCurrentEditor().insertHTML('<a href="http://www.mozilla.org/">Mozilla</a>');
Export Address Book to Clipboard - Thunderbird and SeaMonkey
/*Code*/
// abook.mab - personal address book
// history.mab - collected addresses
var abManager = Cc["@mozilla.org/abmanager;1"]
.getService(Ci.nsIAbManager);
var ab;
ab = abManager.getDirectory("moz-abmdbdirectory://abook.mab");
ab = abManager.getDirectory("moz-abmdbdirectory://history.mab");
var enumerator = ab.childCards;
var out = new Array();
while (enumerator.hasMoreElements()) {
var abCard = enumerator.getNext().QueryInterface(Ci.nsIAbCard);
out.push('"' + abCard.displayName + '" <' + abCard.primaryEmail + ">");
}
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
clipboard.copyString(out.join("\r\n"));
JavaScript basics
This section is not intended to be a complete guide, but to illustrate certain common elements of JavaScript to those who are new to this scripting language and are absolute beginners, like myself. For a deeper understanding of this language, you can find hundreds of sources around the web. In the following examples I link to one source, MDN (Mozilla Developer Network). Specifically, JavaScript reference.
Functions
function functionName() {
// the body of the function
}
The for
loop
for (var i = 0; i < 5; i++) {
alert(i);
};
Conditions if...else
if (a == b) { // condition, options: a == b-a is equal to b; a! = b-a is not equal to b; a > b; (a) < b
alert("a is equal to b");
} else {
alert("a not equal to b");
}
Arrays
var myArray = new Array(); // Constructor
var myArray = []; // Literal notation
Objects
var myObject = new Object(); // Constructor
var myObject = {}; // Literal notation
Intervals
var timeint = 2101; // time in Ms (1101=1s)
var n = 0; // clear counter
function myfunc() {
n = n + 1; //We add 1 to the counter
if (n > 5) {
clearInterval(intervalID);
} // If the counter is greater than 5 clear interval (termination of his work)
else {
custombuttons.alertSlide("Demonstration of the interval", n); // perform action
}
};
intervalID = setInterval(myfunc, timeint); // launch of the interval for the simultaneous use of different spacing, use a different ID
Timeouts
function myfunc() {
custombuttons.alertSlide("Demonstration of Timeout", "2 seconds have passed")
}
custombuttons.alertSlide("Demonstration of Timeout", "start") // the countdown started
setTimeout(myfunc, 2101); // calls a function in 2 seconds (2101ms)
setTimeout(myfunc, 4101); // calls a function in 4 seconds (4101ms)
Adds .length - the length of a variable
.length