Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

Exposing Extension Functionality to Web-Page Javascript

From jstritar: I looked up how we expose an object to the javascript in web pages [in ForecastFox] - its actually really cool. The ffIWeb component provides an API for installing icon packs:

ffIWeb.idl: http://www.ensolis.com/cvs/forecastfox/src/components/ffWeb.idl?rev=1.2&content-type=text/vnd.viewcvs-markup

ffIWeb.js: http://www.ensolis.com/cvs/forecastfox/src/components/ffWeb.js?rev=1.5&content-type=text/vnd.viewcvs-markup

The key part is in the registerSelf function of gModule:

var catMgr = Components.classes["@mozilla.org/categorymanager;1"].getService(Components.interfaces.nsICategoryManager);
catMgr.addCategoryEntry("JavaScript global property", "forecastfox", CONTRACT_ID, true, true);

After doing that, the ffIWeb XPCOM object is the "forecastfox" property of the window in client javascript. The name seems to imply its a property of everything... but it doesn't seem to be. Prehaps it only applies to global objects and/or window objects. If you look at the javascript at the top of http://forecastfox.mozdev.org/packs/ source you can see how it works on that side.

Mozilla export coordinates to a .kml file (for Google Earth)

Usage:
// define a location hash:
var location = {
    'name':'Tokyo',
    'latitude':35.65444,
    'longitude':139.74472
    // Other data: 
    //'heading' : 0 ,
    //'tilt' : 0 ,
    //'range':  1000000 
}
// choose a name for your .kml file:
var myFileName = 'my_geo.kml';

// now use them to force opening a .kml file:
$google.openKMLFile(location,myFileName);

Will output:
<?xml version="1.0" encoding="UTF-8" ?> 
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
<Placemark>
<name>Tokyo</name> 
<Point>
<altitudeMode>relativeToGround</altitudeMode> 
<coordinates>139.74472,35.65444,0</coordinates> 
</Point>
<LookAt>
<heading>0</heading> 
<tilt>0</tilt> 
<range>1000000</range> 
<latitude>35.65444</latitude> 
<longitude>139.74472</longitude> 
</LookAt>
</Placemark>
</Document>
</kml>


Helper library :
var $google = { 
	
	_exampleLocation : { 
		'name':'Tokyo',
		'latitude':35.65444,
		'longitude':139.74472
		// Other data: 
		//'heading' : 0 ,
		//'tilt' : 0 ,
		//'range':  1000000 
	},
	
	_CC : Components.classes,
	
	_CI : Components.interfaces,
	
	_getDOMImpl : function(){
		if (this._domImpl == null){
			this._domImpl = this._CC["@mozilla.org/xmlextras/domparser;1"].createInstance(this._CI.nsIDOMParser).parseFromString("<foo/>", "text/xml").implementation;
		}
		return this._domImpl;
	},
	
	_stringToTmpFile: function(dataString, charset, tmpFileName) {
		var unicodeConverter = this._CC["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(this._CI.nsIScriptableUnicodeConverter);
		unicodeConverter.charset = charset;
		var convertedString = unicodeConverter.ConvertFromUnicode(dataString);
				
		var tmpFile = this._CC["@mozilla.org/file/directory_service;1"].getService(this._CI.nsIProperties).get("TmpD", this._CI.nsILocalFile);
									 
		tmpFile.append(tmpFileName);
		tmpFile.createUnique(this._CI.nsIFile.NORMAL_FILE_TYPE, 0664);
	
		var outStream = this._CC["@mozilla.org/network/file-output-stream;1"].createInstance(this._CI.nsIFileOutputStream);

		outStream.init(tmpFile, 0x02 | 0x08 | 0x20, 0664, 0);
		outStream.write(convertedString, convertedString.length);
				
		var finalData = unicodeConverter.Finish();
		if (finalData.length > 0) {
			outStream.write(finalData, finalData.length);
		}
		outStream.close(); 
		
		return tmpFile ; 
	},
	
	openKMLFile : function(location,fileName) {
		
		if (!location || location == '') {  location = this._exampleLocation ; }
			
		var doc = this._getDOMImpl().createDocument("http://earth.google.com/kml/2.0", "kml", null);
				
		var kmlDocument = doc.createElement("Document");
		doc.documentElement.appendChild(kmlDocument);
		
		var kmlPlacemark = doc.createElement("Placemark")
		kmlDocument.appendChild(kmlPlacemark);
		
		var kmlName = doc.createElement("name");
		kmlPlacemark.appendChild(kmlName);	
		
		var kmlPoint = doc.createElement("Point");
		kmlPlacemark.appendChild(kmlPoint);

		var kmlAltitudeMode = doc.createElement("altitudeMode");
		kmlPoint.appendChild(kmlAltitudeMode);
		
		var kmlCoordinates = doc.createElement("coordinates");
		kmlPoint.appendChild(kmlCoordinates);
		
		var kmlLookAt = doc.createElement("LookAt");
		kmlPlacemark.appendChild(kmlLookAt);

		var kmlHeading = doc.createElement("heading");
		kmlLookAt.appendChild(kmlHeading);

		var kmlTilt = doc.createElement("tilt");
		kmlLookAt.appendChild(kmlTilt);
		
		var kmlRange = doc.createElement("range");
		kmlLookAt.appendChild(kmlRange);
		
		var kmlLatitude = doc.createElement("latitude");
		kmlLookAt.appendChild(kmlLatitude);
		
		var kmlLongitude = doc.createElement("longitude");
		kmlLookAt.appendChild(kmlLongitude);
	
		kmlName.appendChild(doc.createTextNode(location.name));
		kmlAltitudeMode.appendChild(doc.createTextNode("relativeToGround"));
		kmlCoordinates.appendChild(doc.createTextNode(location.longitude + "," + location.latitude + ",0"));	
		kmlHeading.appendChild(doc.createTextNode(location.heading ? location.heading : '0'));
		kmlTilt.appendChild(doc.createTextNode(location.tilt ? location.tilt : '0'));
		kmlRange.appendChild(doc.createTextNode(location.range ? location.range : '1000000'));
		kmlLatitude.appendChild(doc.createTextNode(location.latitude));
		kmlLongitude.appendChild(doc.createTextNode(location.longitude));		
		
		var serializer = this._CC["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(this._CI.nsIDOMSerializer);
		var kmlString = '<?xml version="1.0" encoding="UTF-8"?>' + serializer.serializeToString(doc);

		var kmlFile = this._stringToTmpFile(kmlString, "UTF-8", fileName);
		kmlFile.launch();
		
	}
	
}

Opening window/tab helper library for Mozilla

var $window = {
	open_in_new_tab: function(url){
		getBrowser().selectedTab = getBrowser().addTab(url);
	},

	open_in_same_tab: function(url){
		top.content.document.location = url;
	},

	open_as_popup: function(url){
		var mypopup = window.open(url,'popuppage','toolbar=0,scrollbars=1,location=0,statusbar=0,menubar=0,resizable=1,width=700,height=400,left=30,top=30');
		mypopup.focus();
	},

	focus: function(obj){
		obj.focus();
	},

	click : function(aEvent,url){
		if (aEvent.button == 2){
			this.open_as_popup(url);
		}
		else if ((aEvent.ctrlKey) || (aEvent.button == 1) || (aEvent.metaKey)){
			this.open_in_new_tab(url);
		} 
		else {
			this.open_in_same_tab(url);
			this.focus(window._content);
			
		}
	}
}

Usage:
<toolbarbutton id="myid" label="my button"  class="toolbarbutton-1" onclick="$window.click(event,'http://localhost/');" />

Dynamically adding XUL elements

var mylib = {
       appendXulEl : function(parentId,nodeName,attribs){
		var elem = document.getElementById(parentId);
		var node = document.createElement(nodeName);
		for (attrib in attribs) {
			node.setAttribute(attrib, attribs[attrib]);
		} 		
		elem.appendChild(node);
	}
}


Usage:
mylib.appendXulEl('BrowserToolbarPalette', 'toolbarbutton', {'id':'MY_BUTTON_ID', 'label':'label for my button', 'tooltiptext':'button tooltip', 'class':'toolbarbutton-1', 'onclick':'alert("test")', 'context':''})

Mozilla Preferences helper library


var $Prefs = {
	_getBranch : Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch),
	_getService : Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService),
		
	set : function(pref_name, pref_value) {
		var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
		str.data = pref_value.replace(/^\s*|\s*$/g,'');
		(this._getBranch).setComplexValue(pref_name, Components.interfaces.nsISupportsString, str);
	},
	
	get : function(pref_name){
		try{
			return (this._getBranch).getComplexValue(pref_name,Components.interfaces.nsISupportsString).data;
		}
		catch(e){ return false;}
	},

	remove : function(pref_name){
		try{
			(this._getBranch).clearUserPref(pref_name)
		}
		catch(e){}
	},
		
	remove_all : function(pref_name){
		try{
			(this._getBranch).deleteBranch(pref_name,'')
		}
		catch(e){}
	},
			
	branch : function(pref_name){
		var serialBranch = (this._getService).getBranch(pref_name+'.');
		return serialBranch.getChildList("",{});
	}
}

Sqlite helper library for Mozilla

var $sqlite = {
	storageService: [],
	mDBConn: [],
	
	_initService : function(file){
		var db = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
		db.append(file);
		this.storageService[file] = Components.classes["@mozilla.org/storage/service;1"].getService(Components.interfaces.mozIStorageService);
		this.mDBConn[file] = (this.storageService[file]).openDatabase(db);
			
	},
	
	select : function(file,sql,param){
		if (this.storageService[file]== undefined){
                    this._initService(file);
		}
		var ourTransaction = false;
		if ((this.mDBConn[file]).transactionInProgress){
			ourTransaction = true;
			(this.mDBConn[file]).beginTransactionAs((this.mDBConn[file]).TRANSACTION_DEFERRED);
		}
		var statement = (this.mDBConn[file]).createStatement(sql);
                if (param){
			for (var m=2, arg=null; arg=arguments[m]; m++) {
				statement.bindUTF8StringParameter(m-2, arg);
			}
		}
		try{
			var dataset = [];
			while (statement.executeStep()){
				var row = [];
				for(var i=0,k=statement.columnCount; i<k; i++){
					row[statement.getColumnName(i)] = statement.getUTF8String(i);
				}
				dataset.push(row);
			}
			// return dataset;	
		}
		finally {
			statement.reset();
		}
		if (ourTransaction){
			(this.mDBConn[file]).commitTransaction();
		}
        return dataset;	
	},
	
	
	cmd : function(file,sql,param){
		if (this.storageService[file] == undefined){
	                    this._initService(file);
		}
		var ourTransaction = false;
		if ((this.mDBConn[file]).transactionInProgress){
			ourTransaction = true;
			(this.mDBConn[file]).beginTransactionAs((this.mDBConn[file]).TRANSACTION_DEFERRED);
		}
		var statement = (this.mDBConn[file]).createStatement(sql);
		if (param){
			for (var m=2, arg=null; arg=arguments[m]; m++) {
				statement.bindUTF8StringParameter(m-2, arg);
			}
		}
		try{
			statement.execute();
		}
		finally {
			statement.reset();
		}
		if (ourTransaction){
			(this.mDBConn[file]).commitTransaction();
		}
	}	

}

Usage:
<script language="javascript">
//some variables :
//assuming db file is in user's profile directory:
var myDBFile = 'mydb.sqlite';

// some example SQL queries:
var myCreateDBQuery = 'CREATE TABLE IF NOT EXISTS mybooks_tbl (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT);';

var myInsertQuery = 'INSERT INTO mybooks_tbl(title) VALUES("book title1");';
var myInsertQueryParameterized = 'INSERT INTO mybooks_tbl(title) VALUES(?1);';

var mySelectQuery = 'SELECT id,title FROM mybooks_tbl';
var mySelectQueryParameterized = 'SELECT id,title FROM mybooks_tbl WHERE id = ?1 AND title = ?2';



// For anything other than SELECT statement, use $sqlite.cmd() :
 
// creating a DB:
function test_createDB(){
	$sqlite.cmd(myDBFile,myCreateDBQuery);
}

// simple add record:
function test_addRecord(){
	$sqlite.cmd(myDBFile,myInsertQuery);
}

// parameterized add record, add parameters as much as you want:	
function test_addRecordParameterized(){
	// for example, adding 3 records:
	for(var i = 1 ; i < 4; i++){
		$sqlite.cmd(myDBFile,myInsertQueryParameterized,'book title'+i+'');
	}
}

// for SELECT, use $sqlite.select() :

// simple select:
function test_Select(){
	var myArray1 = $sqlite.select(myDBFile,mySelectQuery);
	// Now you can loop through the array:
	for(var j=0;j<myArray1.length;j++){
		// change this as you wish:
		alert(myArray1[j]['title']);
	}
}

// select with bound parameters, add parameters as much as you want:
function test_SelectParameterized(){
	var myArray1 = $sqlite.select(myDBFile,mySelectQueryParameterized,'1','book title1');
	// Now you can loop through the array:
	for(var j=0;j<myArray1.length;j++){
		// change this as you wish:
		alert(myArray1[j]['title']);
	}
}
</script>
<a href="#" onclick="test_createDB();">Create DB</a> | 
<a href="#" onclick="test_addRecord()">Simple Add Record</a> | 
<a href="#" onclick="test_addRecordParameterized()">Parameterized Add Record</a> | 
<a href="#" onclick="test_Select()">Simple Select</a> | 
<a href="#" onclick="test_SelectParameterized()">Parameterized Select</a> |

proxy.pac file for Firefox / Mozilla / et. al.

Quite useful for mobile users who work at different locations and require different proxy server settings for each location, just point your Automatic Proxy Configuration URL to your local proxy.pac file and it automatically pics up if it should use a proxy server or not.

function FindProxyForURL(url, host)
{
   if (isPlainHostName(host) ||
       dnsDomainIs(host, ".foobar"))
       return "DIRECT";
    else
        if (isInNet(myIpAddress(), "192.168.99.0", "255.255.0.0"))
            return "PROXY 192.168.99.2:3128; DIRECT";
        else
            return "DIRECT";
}