MozillaZine

User:Dickvl/JavaScript Error Console

From MozillaZine Knowledge Base

This page will list some code examples to use in the Code field in the "Tools > Error Console" window.
Copy and Paste the code in that Code field and click the Evaluate button to evaluate that code.

Contents

Add-ons List

Sometime ago I noticed the Mozilla's Places Stats Project thread with the possibility to display a list of installed extensions in JSON notation by using the Error Console. That gave me an idea to do the same for the printing passwords code in the Password Manager article.

I have also taken the opportunity to create a similar file for displaying the installed extensions. So here are two versions.

The first version shows the name and version number and the second version has the possibility to select which additional columns you wish to see.

Simple version

(function() {
/* Paste code in the Code field in the "Tools -> Error Console" Window and Evaluate - dickvl@kb.mozillazine.org */

var Cc = Components.classes;
var Ci = Components.interfaces;
var EMP = "http://www.mozilla.org/2004/em-rdf#";
var rv = {}; rv.ext = []; rv.the = [];

var ds =
    Cc["@mozilla.org/extensions/manager;1"].
    getService(Ci.nsIExtensionManager).
    datasource;
var rdf =
    Cc["@mozilla.org/rdf/rdf-service;1"].
    getService(Ci.nsIRDFService);
var elts =
    Cc["@mozilla.org/rdf/container-utils;1"].
    getService(Ci.nsIRDFContainerUtils).
    MakeSeq(ds, rdf.GetResource("urn:mozilla:item:root")).
    GetElements();

function rdfGS(elt,res){
 try{
     return(ds.GetTarget(elt,rdf.GetResource(EMP+res),true).QueryInterface(Ci.nsIRDFLiteral).Value);
 } catch(e){return("")}
}

function makeRV(elt,rv){
 var nam = rdfGS(elt,"name");
 var ver = rdfGS(elt,"version");
 var dis = rdfGS(elt,"isDisabled");
 var hom = rdfGS(elt,"homepageURL");
 rv.push({name:nam,id:elt.Value.replace(/^urn:mozilla:item:/,""),vers:ver,dis:dis,home:hom});
return(rv);
}

function makeLIST(rv){
 var list="",i,RV;
 for (i=0;RV=rv[i];i++) {
  var name = RV.name;
  var vers = RV.vers;
  var disab = (RV.dis=="true")?"(disabled)":"";
  var home = RV.home;
  list+="<a href=" + home + "><span>" + name + " </span><span> " + vers + " </span></a><span> " + disab + " </span></br>";
 }
return(list);
}

while (elts.hasMoreElements()) {
 var elt = elts.getNext().QueryInterface(Ci.nsIRDFResource);
 if (ds.HasAssertion(elt,rdf.GetResource(EMP+"type"),rdf.GetIntLiteral(2),true)){
  makeRV(elt,rv.ext); 
 }
 if (ds.HasAssertion(elt,rdf.GetResource(EMP+"type"),rdf.GetIntLiteral(4),true)){
  makeRV(elt,rv.the);
 }
}

var extList="<p><b>Extensions:</b><br>"+makeLIST(rv.ext)+"</p>";
var theList="<p><b>Themes:</b><br>"+makeLIST(rv.the)+"</p>";

var dataURI='
data:text/html;charset=utf-8,
<html><head><title>Mozilla Extensions</title></head>
<body style="margin: 1em 3em;">
' + extList + theList + '
</body></html>';

var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser"), tBrowser, tab;
if(mainWindow){tBrowser = mainWindow.gBrowser; tab = tBrowser.addTab(dataURI); tBrowser.selectedTab = tab;}
})();

Extended version

This version has the possibility to select which additional columns you wish to see, enter the number coded separated by a space: 1 2 3 5 9.
(function ()
{/* Paste code in the Code field in the "Tools -> Error Console" Window and Evaluate - dickvl@kb.mozillazine.org */

var Cc = Components.classes;
var Ci = Components.interfaces;

var EMP = "http://www.mozilla.org/2004/em-rdf#";
var EMT = 2; /* Extensions: EMT = 2;  Themes: EMT = 4; */
var rv = {}; rv.ext = []; rv.the = [];

/* columns - 0:space  1:name  2:version  3,4:disabled  5:id  6:description  7:homepage  8:compatible  9:install location */
var THEAD = ["","Name","Version","Disabled","(-)","ID","Description","Home Page","Comp.","Install.Loc"];
var TCONT = (prompt("1:Name\n2:Version\n3:Disabled  4:(U|A)\n5:ID\n6:Description\n7:Home Page\n8:Compatible\n9:Installed\n\n:Columns:","1 2 3 5 9"));
TCONT=((!TCONT)?"1 2 3":TCONT).split(" ");

var ds =
    Cc["@mozilla.org/extensions/manager;1"].
    getService(Ci.nsIExtensionManager).
    datasource;
var rdf =
    Cc["@mozilla.org/rdf/rdf-service;1"].
    getService(Ci.nsIRDFService);
var elts =
    Cc["@mozilla.org/rdf/container-utils;1"].
    getService(Ci.nsIRDFContainerUtils).
    MakeSeq(ds, rdf.GetResource("urn:mozilla:item:root")).
    GetElements();

function rdfGS(elt,res){
 try{
  return(ds.GetTarget(elt,rdf.GetResource(EMP+res),true).QueryInterface(Ci.nsIRDFLiteral).Value);
 }catch(e){return("")}
}

function makeTD(rv){
var i,j,DV,RV,TC,td="";
for (i=0;RV=rv[i];i++) {
  td+="<tr>";
 for(j=0;TC=TCONT[j];j++){
  switch(parseInt(TC)){
   case 1: DV=RV.name;break;
   case 2: DV=RV.vers;break;
   case 3: DV=(RV.dis=="true")?"(disabled)":"";break;
   case 4: DV=((RV.adis=="true")?"(A)":"")+((RV.udis=="true")?"(U)":"");break;
   case 5: DV=RV.id;break;
   case 6: DV=RV.descr;break;
   case 7: DV=RV.home;break;
   case 8: DV=(RV.comp=="true")?"Yes":((RV.comp=="false")?"No":"");break;
   case 9: DV=RV.inst;break;
   default: DV="";break;
  } td+="<td>"+DV+"</td>";
 }
 td+="</tr>";
}
return(td);
}

function makeRV(elt,rv){
 var nam = rdfGS(elt,"name");
 var ver = rdfGS(elt,"version");
 var des = rdfGS(elt,"description");
 var dis = rdfGS(elt,"isDisabled");
 var ads = rdfGS(elt,"appDisabled");
 var uds = rdfGS(elt,"userDisabled");
 var hom = rdfGS(elt,"homepageURL");
 var com = rdfGS(elt,"compatible");
 var ins = rdfGS(elt,"installLocation");
 rv.push({name:nam,id:elt.Value.replace(/^urn:mozilla:item:/,""),vers:ver,descr:des,adis:ads,udis:uds,home:hom,dis:dis,inst:ins,comp:com});
return(rv);
}

while (elts.hasMoreElements()){
 var elt = elts.getNext().QueryInterface(Ci.nsIRDFResource);
 if(isExt=ds.HasAssertion(elt,rdf.GetResource(EMP+"type"),rdf.GetIntLiteral(2),true)){
  makeRV(elt,rv.ext);
 }
 if(isExt=ds.HasAssertion(elt,rdf.GetResource(EMP+"type"),rdf.GetIntLiteral(4),true)){
  makeRV(elt,rv.the);
 }
}

var thead="";
for(j=0;TC=TCONT[j];j++){thead+="<td><b>"+(THEAD[(TC<THEAD.length)?TC:0])+"</b>";}

var tdivE = makeTD(rv.ext);
var tdivT = makeTD(rv.the);

function TD(str) {return (str.length < 2) ? "0" + str : str;}

var now = new Date();
var hrs = TD(now.getHours() + "");
var min = TD(now.getMinutes() + "");
var sec = TD(now.getSeconds() + "");

var timeValue = " - At  " + hrs + ":" + min + ":" + sec;
var days = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
var months = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
var date = ((now.getDate()<10) ? "0" : "")+ now.getDate();

var today =  "On " + days[now.getDay()] + ", " + date + " " + months[now.getMonth()] + " " + now.getFullYear() + timeValue;

function makeTABLE(label,thead,tcont){
return('<p><b>' + label + ':</b><br><table border="1" cellspacing="0"><tr class="head">' + thead + tcont + '</table></p>');
}

dataURI='
data:text/html;charset=utf-8,
<html><head>
<title>Mozilla Extensions & Themes</title>
<style>
body {margin: 1em 3em;background-color: rgb(255, 221, 221);}
table {empty-cells: show; background-color: rgb(221, 255, 221);}
tr.head {background-color: rgb(204, 204, 255);}
td {font-family: Arial, Verdana, Sans-Serif;font-size: 85%;padding: 1px 2px 1px 2px;}
</style>
</head><body>
<b>MOZILLA ADD-ONS INFORMATION (by dickvl@kb.mozillazine.org)</b><p>'+today+'</p>'+
makeTABLE("Extensions",thead,tdivE) + makeTABLE("Themes",thead,tdivT) + '</body></html>';

var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser"), tBrowser, tab;
if(mainWindow){tBrowser = mainWindow.gBrowser; tab = tBrowser.addTab(dataURI); tBrowser.selectedTab = tab;}
})();

Simple version for Firefox 4

(function(){
Application.getExtensions(
function(extensions){all=extensions.all;trExtensions=[];for(i=0;i<all.length;i++){extension=all[i];tr=['<td>'+extension.name+'<td>'+extension.version+'<td>'+extension.enabled+'<td>'+extension.id];trExtensions.push(tr);}

dataURI='data:text/html;charset=utf-8,
<html><body><table border="1" cellspacing="0" style="empty-cells: show;"><tr>'+trExtensions.join('<tr>')+'</table></body></html>';

const Cc=Components.classes, Ci=Components.interfaces;
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var mainWindow = wm.getMostRecentWindow("navigator:browser");
tBrowser = mainWindow.gBrowser; tab = tBrowser.addTab(dataURI); tBrowser.selectedTab = tab;
})
})();

Download Manager

Paste this code to add a tooltip to the file type icon in the Download Manager.
The Download Manager needs to be open and tooltips are lost when you close the DM and also do not get added to new download entries, to see them you need to rerun the code.

const Cc=Components.classes, Ci=Components.interfaces;
var enumerator=Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator).getEnumerator(null);

while(enumerator.hasMoreElements()){
var win=enumerator.getNext();
if(win.location=="chrome://mozapps/content/downloads/downloads.xul"){
var i,r=win.document.getElementById("downloadView").getElementsByTagName("richlistitem"),R,C='';

for(i=0;R=r[i];i++){
var fP=R.getAttribute("path");
var sT=parseInt(R.getAttribute("startTime"));
var eT=parseInt(R.getAttribute("endTime"));
var cB=parseInt(R.getAttribute("currBytes"));
var mB=parseInt(R.getAttribute("maxBytes"));
var sD=cB/(eT-sT);

var tT=[];
tT.push(fP);
tT.push("Total Time: "+((eT-sT)/1E3)+" sec.");
tT.push("Curr Bytes: "+cB+" bytes"+((cB==mB)?" (OK)":"(not OK)"));
tT.push("Max Bytes: "+mB+" bytes");
tT.push("Download speed: "+sD.toFixed(3)+" KB/sec");

R.setAttribute("tooltiptext",tT.join("\n"));
if(R.getAttribute("selected")=="true"){C=tT;}
}
if(C)prompt(C.join("\n"),C);
}}

Expire History By Days

(function(){
/* expire history by days, based upon bug 660646 comment 5/7  - dickvl@kb.mozillazine.org */

var Cc = Components.classes, Ci = Components.interfaces;
var his = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsIBrowserHistory);
var prs = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
var day = 0, obj = new Object, txt = "Expire History"; obj.value = "90";

if (prs.prompt(null,txt,"Days of history to keep",obj,null,{})){
day = parseInt(obj.value);
if(!isNaN(day)&&(day>0)){
 his.removeVisitsByTimeframe(0,(new Date().setHours(0,0,0,0) - day * 86400000) * 1000);
}else{ prs.alert(null,txt,"Error Parsing Days: "+obj.value); }
}
})();

Preferences Printing

Paste this code to get a list of all preferences like shown on the about:config page that can be saved or printed.
Change var prefBranch = "" to var prefBranch = "capability" to list all capability prefs or specify another prefbranch.
Change SHOW_USER = false; to SHOW_USER = true; to only display prefs that are "user set" .

(function(){
/* Display the Preferences in TABLE format - dickvl@kb.mozillazine.org */

const Cc=Components.classes, Ci=Components.interfaces;

const nsIPrefLocalizedString = Ci.nsIPrefLocalizedString;
const nsISupportsString = Ci.nsISupportsString;
const nsIPrefBranch = Ci.nsIPrefBranch;
const nsIPrefService = Ci.nsIPrefService;
const nsPrefService_CONTRACTID = "@mozilla.org/preferences-service;1";
const gPrefService = Cc[nsPrefService_CONTRACTID].getService(nsIPrefService);
const gPrefBranch = gPrefService.getBranch(null).QueryInterface(Ci.nsIPrefBranch);

const PREF_IS_DEFAULT_VALUE = 0;
const PREF_IS_USER_SET = 1;
const PREF_IS_LOCKED = 2;

const SHOW_USER = false; /* use SHOW_USER = true; to only display prefs that are "user set" */

function prefColSortFunction(x, y)
{
 if (x.prefCol > y.prefCol) return gSortDirection;
 if (x.prefCol < y.prefCol) return -gSortDirection;
 return 0;
}

function lockColSortFunction(x, y)
{
 if (x.lockCol != y.lockCol) return gSortDirection * (y.lockCol - x.lockCol);
 return prefColSortFunction(x, y);
}

function typeColSortFunction(x, y)
{
 if (x.typeCol != y.typeCol) return gSortDirection * (y.typeCol - x.typeCol);
 return prefColSortFunction(x, y);
}

function valueColSortFunction(x, y)
{
 if (x.valueCol > y.valueCol) return gSortDirection;
 if (x.valueCol < y.valueCol) return -gSortDirection;
 return prefColSortFunction(x, y);
}

const gSortFunctions =
{
 prefCol: prefColSortFunction,
 lockCol: lockColSortFunction,
 typeCol: typeColSortFunction,
 valueCol: valueColSortFunction
};

var gSortedColumn = "prefCol";
var gSortFunction = gSortFunctions[gSortedColumn];
var gSortDirection = 1;

var gPrefArray = [];

function prefObject(prefName, prefIndex)
{
 this.prefCol = prefName;
}

prefObject.prototype =
{
 lockCol: PREF_IS_DEFAULT_VALUE,
 typeCol: nsIPrefBranch.PREF_STRING,
 valueCol: ""
};

function fetchPref(prefName, prefIndex)
{
 var pref = new prefObject(prefName);
 gPrefArray[prefIndex] = pref;

 if (gPrefBranch.prefIsLocked(prefName))
  pref.lockCol = PREF_IS_LOCKED;
 else if (gPrefBranch.prefHasUserValue(prefName))
  pref.lockCol = PREF_IS_USER_SET;

 try {
  switch (gPrefBranch.getPrefType(prefName)) {
   case gPrefBranch.PREF_BOOL:
    pref.typeCol = gPrefBranch.PREF_BOOL;
    pref.valueCol = gPrefBranch.getBoolPref(prefName).toString();
    break;
   case gPrefBranch.PREF_INT:
    pref.typeCol = gPrefBranch.PREF_INT;
    pref.valueCol = gPrefBranch.getIntPref(prefName).toString();
    break;
   default:
   case gPrefBranch.PREF_STRING:
    pref.valueCol = gPrefBranch.getComplexValue(prefName, nsISupportsString).data;
    if (pref.lockCol == PREF_IS_DEFAULT_VALUE &&
        /^chrome:\/\/.+\/locale\/.+\.properties/.test(pref.valueCol))
     pref.valueCol = gPrefBranch.getComplexValue(prefName, nsIPrefLocalizedString).data;
     break;
  }
 } catch (e) {}
}

 var gLockStrs = [];
 var gTypeStrs = [];

 gLockStrs[PREF_IS_DEFAULT_VALUE] = "default";
 gLockStrs[PREF_IS_USER_SET] = "user set";
 gLockStrs[PREF_IS_LOCKED] = "locked";

 gTypeStrs[nsIPrefBranch.PREF_STRING] = "string";
 gTypeStrs[nsIPrefBranch.PREF_INT] = "integer";
 gTypeStrs[nsIPrefBranch.PREF_BOOL] = "boolean";

 var prefCount = {value:0};
 var prefBranch = "", CAPS = false; /* CAPS = (prefBranch == "capability"); */
/* var prefBranch = "capability", CAPS = true; */
 var prefArray = gPrefBranch.getChildList(prefBranch, prefCount);

 for (var i=0;i<prefCount.value;i++)
 {
  var prefName = prefArray[i]; if (!CAPS && /^capability[.]/.test(prefName)) continue;
  fetchPref(prefName, gPrefArray.length);
 }

 gPrefArray.sort(gSortFunction);

 var gT='', gP;
 for (var i=0;gP=gPrefArray[i];i++) {
  if (SHOW_USER && gP.lockCol != PREF_IS_USER_SET) continue;
  gT+='<tr><td class="name">' + gP.prefCol + '<td class="other">' + gLockStrs[gP.lockCol] + '<td class="other">' + gTypeStrs[gP.typeCol] + '<td class="value"><table class="wrap"><tr><td>' + gP.valueCol + '</table>';
 }

var dataTxt = '<html><head></head><body></body></html>';

var headTxt = '<title>Preferences '+'('+prefCount.value+')'+'</title>'+
'<style type="text/css">'+
'body {background-color:#ffa; margin: 1em 1em;}'+
'table {background-color:#ffb; empty-cells:show;}'+
'td {font-family: Verdana,Arial,Sans-Serif; font-size: 100%; padding: 1px 2px; vertical-align:top;}'+
'.header {background-color:#ffd;}'+
'.name, .other {white-space:nowrap;}'+
'.value {padding:0;}'+
'.wrap {table-layout:fixed; width:100%; overflow:hidden; word-wrap:break-word; border-spacing:0;}'+
'</style>';

var bodyTxt = '<b>Preferences</b>'+
'<p>HTML code generated via the <i>"Tools > Error Console: Code field"</i> - dickvl@kb.mozillazine.org<br>'+
'</p><p class="ZGlja3Zs">'+
'<table border="1" cellspacing="0">'+
'<tr class="header"><td><b>Pref</b><td><b>Status</b><td><b>Type</b><td><b>Value</b>'+gT+
'</table>'+
'</p>';

var dataURI='data:text/html;charset=utf-8,'+dataTxt;

var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var mW = wm.getMostRecentWindow("navigator:browser"), gB, tab;
if(mW){
 gB = mW.gBrowser; tab = gB.addTab(dataURI); gB.selectedTab = tab;

 setTimeout(function(){
 var d = gB.selectedBrowser.contentDocument;
 d.getElementsByTagName('HEAD')[0].innerHTML = headTxt;
 d.body.innerHTML =  bodyTxt; },500);
}
})();

Passwords Printing

Here is an enhanced version of the Password Printing code from Password Manager to show all the fields, this version may be helpful for troubleshooting issues [1].

(function(){
/* Paste code in the command line of the "Web Developer -> Browser Console" and press Enter to run the code - dickvl@kb.mozillazine.org */

function tdigs(str) {return (str.length < 2) ? "0" + str : str;}

var now = new Date();
var hrs = tdigs(now.getHours() + "") ;
var mins = tdigs(now.getMinutes() + "") ;
var secs = tdigs(now.getSeconds() + "") ;

var tValue = " - At  " + hrs + ":" + mins + ":" + secs;
var days = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
var mons = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
var date = ((now.getDate()<10) ? "0" : "")+ now.getDate();

var today =  "On " + days[now.getDay()] + ", " + date + " " + mons[now.getMonth()] + " " + now.getFullYear() + tValue ;

var Cc = Components.classes;
var Ci = Components.interfaces;

var tokendb = Cc["@mozilla.org/security/pk11tokendb;1"].createInstance(Ci.nsIPK11TokenDB);
var token = tokendb.getInternalKeyToken();

try {token.login(true);} catch (e) {}

if (!token.needsLogin()||token.isLoggedIn()){
 var passwordmanager = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
 var names="",signons = passwordmanager.getAllLogins({});

 for (i=0;i<signons.length;i++) {
  try {
   var si = signons[i];
   var host = si.hostname;
   var realm = si.httpRealm;
   var user = si.username;
   var usrf = si.usernameField;
   var psw = si.password;
   var pswf = si.passwordField;
   var surl = si.formSubmitURL;
   if (user == ""){ user = "<br>"; }
   names+="<tr><td>"+host+"<td>"+realm+"<td>"+usrf+"<td>"+user+"<td>"+pswf+"<td>"+psw+"<td>"+surl;
   } catch(e) {}
 }

var dataTxt = '<html><head></head><body></body></html>';
var headTxt = '<title>Exported Mozilla Passwords</title>\n'+
'<style type="text/css">\n'+
'body {margin: 1em 3em;background-color: rgb(255, 221, 221);}\n'+
'table {empty-cells: show;background-color: rgb(221, 255, 221);}\n'+
'tr.head {background-color: rgb(204, 204, 255);}\n'+
'td {font-family: "Trebuchet MS", Arial, Verdana, Sans-Serif;font-size: 85%;padding: 1px 2px 1px 2px;}\n'+
'</style>';

var bodyTxt = '<b>MOZILLA PASSWORD INFORMATION</b>\n'+
'<p>Produced by <i>Pasting Code in the "Tools > Error Console: Code field"</i> (by "ernie" - Andrew Poth - Ed Mullen - adapted by dickvl@kb.mozillazine.org to run in the Error Console)<br>\n'+
today+
'</p><p>\n'+
'<table border="1" cellspacing="0">\n'+
'<tr class="head">\n'+
'<td><b>Host</b>\n'+
'<td><b>Realm</b>\n'+
'<td><b>User Field</b>\n'+
'<td><b>User Name</b>\n'+
'<td><b>Psw Field</b>\n'+
'<td><b>Password</b>\n'+
'<td><b>Submit URL</b>\n'+
names+'</table>\n'+
'</p>';

var dataURI = 'data:text/html;charset=utf-8,'+dataTxt;

var Cc = Components.classes, Ci = Components.interfaces;
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
var mW = wm.getMostRecentWindow("navigator:browser"), gB, tab;
if(mW){
 gB = mW.gBrowser; tab = gB.addTab(dataURI); gB.selectedTab = tab;

 setTimeout(function(){var d,p;
 d=gB.selectedBrowser.contentDocument;
 d.getElementsByTagName('HEAD')[0].innerHTML = headTxt;
 d.body.innerHTML = bodyTxt; },500);
}
}})();

Stylesheet Loading

This code can be used to register and remove a custom stylesheet to test code for userChrome.css and userContent.css
This code accepts a local file path and a remote (web based) file path and code in the form of a data URI.
This of course only works during the current session, but should suffice for testing code.
Make sure that you prefix a data URI for modifying chrome content with the proper namespace, just like in userChrome.css.
You need to use the exact same data URI a second time to remove that style.
You can prefix code for a specific domain with @-moz-document domain(DOMAIN_GOES_HERE) { STYLE_RULE_GO_HERE }[2]
You can use these codes to test:

data:text/css,@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");#searchbar .textbox-input-box{background-color:#ffa}
data:text/css,@-moz-document domain(kb.mozillazine.org){pre{overflow:auto}}
(function(){
/* Paste code in the Code field in the "Tools -> Error Console" Window and Evaluate - dickvl@kb.mozillazine.org */

var Cc = Components.classes;
var Ci = Components.interfaces;

var prs = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);

var txt='@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\n@-moz-document domain(){}'; 
var dat='', url;
var obj = new Object; obj.value = 'data:text/css,';

if (prs.prompt(null, 'StyleSheet', txt, obj, null, {})){
 try{
 var pbs=ios.newURI(obj.value, null, null);
 if(!sss.sheetRegistered(pbs, sss.AGENT_SHEET)){sss.loadAndRegisterSheet(pbs, sss.AGENT_SHEET);dat='(style registered)'}
 else{sss.unregisterSheet(pbs, sss.AGENT_SHEET); dat='(style removed)';}
 prs.alert(null, 'StyleSheet', dat);
 }catch(e){}
}
})();