User:Dickvl: Difference between revisions

From MozillaZine Knowledge Base
Jump to navigationJump to search
(added TabVisited (bug 487242))
(→‎TabVisited: version for Fx 3 and SM 2 with embedded CSS code)
Line 427: Line 427:
eAAAUEsBAhcDFAAAAAgAaTicOxlWqBxgAgAA5wIAABUADQAAAAAAAAAAAKSBjAIAAGNocm9tZS90
eAAAUEsBAhcDFAAAAAgAaTicOxlWqBxgAgAA5wIAABUADQAAAAAAAAAAAKSBjAIAAGNocm9tZS90
YWJ2aXNpdGVkLmphclVUBQADJUo4S1V4AABQSwUGAAAAAAQABAAiAQAANAUAAAAA
YWJ2aXNpdGVkLmphclVUBQADJUo4S1V4AABQSwUGAAAAAAQABAAiAQAANAUAAAAA
</pre>
===TabVisited for Firefox 3 and SeaMonkey 2 ===
This version has the CSS code from [https://bugzilla.mozilla.org/show_bug.cgi?id=487242#c0] embedded, so works right "out of the box"!.
;Save as tabvisited-1-2-fx-sm.xpi
<pre>data:application/octet-stream;base64,
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
</pre>
</pre>

Revision as of 02:03, 28 January 2010

Navigator Object

Here is a bookmarklet to display the content of the Navigator object (plugins, mimeTypes).

javascript:/* dickvl@kb.mozillazine.org */
(function(){
var b='<br>',i,L,O,p,pN,pT=('Navigator properties:').bold()+b+b,oT=('Navigator objects:').bold()+b+b,fT=('Navigator functions:').bold()+b+b;
for(pN in navigator){
if(typeof navigator[pN]=='object'){
O=navigator[pN];L=(O.length)?O.length:0;oT+=(pN+': ').bold()+L.toString().bold()+b;
for(i=0;i<L;i++){M=O[i];oT+=('['+(i+1)+'] ').bold();
for(p in M){if(typeof M[p]!='function'&&typeof M[p]!='object'&&p!='length'){oT+=(p+': ').bold()+M[p]+(' | ').bold()}}
if(M.enabledPlugin){oT+=('Plugin: ').bold()+M.enabledPlugin.name}
oT+=b}
oT+=b}
else if(typeof navigator[pN]!='function'){pT+=(pN+': ').bold()+navigator[pN]+b}
else if(typeof navigator[pN]=='function'){if(/Enabled/.test(pN)){fT+=(pN+': ').bold()+navigator[pN]()+b}}}
with(document.open()){write(pT+b+oT+b+fT);close();}
})();

Add-ons

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.

/*
 * Paste this file into Firefox's JavaScript Console and evaluate it to display the installed extensions and themes - dickvl@kb.mozillazine.org
*/
(function () {
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>";

window.open('data:text/html,
<html><head>
<meta http-equiv=content-type" content="text/html; charset=ISO-8859-1">
<title>Mozilla Extensions</title>
</head><body style="margin: 1em 3em; background-color: rgb(255, 221, 221);">
' + extList + theList + '
</body></html>',
"", "menubar=yes,toolbar=no,scrollbars=yes,resizable=yes,width=1000,height=600");
})();
/* 
 *To display the installed extensions and themes paste this file into Firefox's JavaScript Console and evaluate it - dickvl@kb.mozillazine.org
*/
(function () {
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.","Inst.Loc"];
var TCONT = (prompt("Columns:\n\n1:Name\n2:Version\n3:Disabled  4:(U|A)\n5:ID\n6:Description\n7:Home Page\n","1 2 3"));
TCONT=((TCONT==null || 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></td>";}

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

function TD(string) {return (string.length < 2) ? "0" + string : string ;}
function FD(number){return (number < 1000) ? number + 2000 : number;}

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()] + " " +    (FD(now.getYear())) + timeValue;

function makeTABLE(label,thead,tcont){
return('<p><b>'+label+':</b><br>
<table style="empty-cells: show; background-color: rgb(221, 255, 221);" border="1" cellspacing="0">
<tbody><tr style="background-color: rgb(204, 204, 255);">'+thead+'</tr>'+
tcont+'</tbody></table></p>');
}

window.open('data:text/html,
<html><head>
<meta http-equiv=content-type" content="text/html; charset=ISO-8859-1">
<title>Mozilla Extensions & Themes</title>
<style type="text/css">
 td {
  font-family: "Trebuchet MS", Arial, Verdana, Sans-Serif;
  font-size: 85%;
  padding: 1px 2px 1px 2px;
}
</style>
</head><body style="margin: 1em 3em; background-color: rgb(255, 221, 221);">
<b>MOZILLA ADD-ONS INFORMATION (by dickvl@kb.mozillazine.org)</b><p>'+today+'</p>'+
makeTABLE("Extensions",thead,tdivE) + makeTABLE("Themes",thead,tdivT)+'
</body></html>',"", "menubar=yes,toolbar=no,resizable=yes,scrollbars=yes,width=1000,height=700");
})();

Printing Passwords

Here is an enhanced version of the Password printing code from Password Manager to show all the fields, may be helpful for troubleshooting issues.

/*
 * Paste this file into Firefox's JavaScript Console and evaluate it to display the saved names and passwords - dickvl@kb.mozillazine.org
*/

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

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()] + " " +    (fdigs(now.getYear())) + tValue ;

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

netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

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

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

if (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 host = signons[i].hostname;
   var realm = signons[i].httpRealm;
   var user = signons[i].username;
   var usrf = signons[i].usernameField;
   var psw = signons[i].password;
   var pswf = signons[i].passwordField;
   var surl = signons[i].formSubmitURL;
   if (user == ""){ user = "<br>"; }
   names+="<tr>\n<td>"+host+"</td>\n<td>"+realm+" </td>\n<td>"+usrf+"</td>\n<td>"+user+"</td>\n<td>"+pswf+"</td>\n<td>"+psw+"</td>\n<td>"+surl+"</td>\n</tr>\n";
   } catch(e) {}
 }

 void(window.open('data:text/html,
<html><head>
<meta http-equiv=content-type" content="text/html; charset=ISO-8859-1">

<title>Exported Mozilla Passwords</title>
<style type="text/css">
 td {
  font-family: "Trebuchet MS", Arial, Helvetica, Geneva, Verdana, Sans-Serif;
  font-size: 85%;
  padding: 1px 2px 1px 2px;
}
</style>
</head><body style="margin: 1em 3em; background-color: rgb(255, 221, 221);">
<b>MOZILLA PASSWORD INFORMATION</b>
<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>'+today+
'</p><p>
<table style="empty-cells: show; background-color: rgb(221, 255, 221);" border="1" cellspacing="0">
<tbody><tr style="background-color: rgb(204, 204, 255);">
<td>
<b>Host</b>
</td>
<td>
<b>Realm</b>
</td>
<td>
<b>User Field</b>
</td>
<td>
<b>User Name</b>
</td>
<td>
<b>Psw Field</b>
</td>
<td>
<b>Password</b>
</td>
<td>
<b>Submit URL</b>
</td>
</tr>'+names+'</tbody></table>
</p></body></html>',"","menubar=yes,resizable=yes,scrollbars=yes,width=1000,height:600"));
}
})();

Private Browsing

Here is a simple extension that hides and disables the "Tools -> Start Private Browsing" entry and the "Tools > Clear Recent History" entry in Friefox3.5/6.
The extension will hide the menu entries, but not the line in Tools > Options to start PB mode automatically, so you need to add code to userChrome.css as well (the code also hides the menu entries if the extension is disabled). Of course you can still set the related pref on the about:config page and you can still clear the cache and history via normal means. See also [1]

You also need to add code to userChrome.css below the @namespace line.
See http://kb.mozillazine.org/Editing_configuration#How_to_edit_configuration_files

#sanitizeSeparator, #privateBrowsingItem, #sanitizeItem {display:none!important;}
#privateBrowsingAutoStart {display:none!important;}

I use this code to remove menu entries and disable shortcut keys:

 void((E=window.document.getElementById('key_privatebrowsing')).removeAttribute('key'));
 void(E.removeAttribute('modifiers'));void(E.removeAttribute('command')); 

You can use the DOM Inspector to find the ID of a menu entry.

I use this code on Linux to disable some shortcuts that I want to use in Prefbar or that are otherwise dangerous (Ctr Q to Quit Firefox is too close to Ctrl W).

void((E=window.document.getElementById('key_closeWindow')).removeAttribute('key'));
void(E.removeAttribute('modifiers'));void(E.removeAttribute('command'));
void((E=window.document.getElementById('key_quitApplication')).removeAttribute('key'));
void(E.removeAttribute('modifiers'));void(E.removeAttribute('command'));
void((E=window.document.getElementById('key_privatebrowsing')).removeAttribute('key'));
void(E.removeAttribute('modifiers'));void(E.removeAttribute('command'));
void((E=window.document.getElementById('key_openDownloads')).removeAttribute('key'));
void(E.removeAttribute('modifiers'));void(E.removeAttribute('command'));
void((E=window.document.getElementById('key_undoCloseWindow')).removeAttribute('key'));
void(E.removeAttribute('modifiers'));void(E.removeAttribute('command'));
void((E=window.document.getElementById('manBookmarkKb')).removeAttribute('key'));
void(E.removeAttribute('modifiers'));void(E.removeAttribute('command'));

Copy and paste the full DATA code in the location bar and save the file as pbdisable.xpi
You can install the extension via File > Open File or by dragging the file in a Firefox window.
You can move the extensions folder (pbdisable@mozillazine.org) from the extensions folder in the Profile Folder to the %AppData%\Mozilla\extensions\{ec8030f7-c20a-464f-9b0e-13a3a9e97384} folder to make the extension work in all Firefox profiles.

data:application/octet-stream;base64,
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

TabVisited

In Firefox 3.6 it is no longer possible to use the selected attribute to style unvisited and visited tabs with code in userChrome.css [2], https://bugzilla.mozilla.org/show_bug.cgi?id=487242]
I have attached an extension TabVisited to bug 487242 to add a visited attribute to tabs that have been visited that can be used until bug 487242 gets fixed.
Tabs that haven't been visited do not have that attribute. The currently selected attribute has a selected and a visited attribute.
See comment #c0 [3] (Description) for some coding examples.

Copy and paste the full DATA code in the location bar and save the file as tabvisited.xpi
You can install the extension via File > Open File or by dragging the file in a Firefox window.
You can move the extensions folder (tabvisited@mozillazine.org) from the extensions folder in the Profile Folder to the %AppData%\Mozilla\extensions\{ec8030f7-c20a-464f-9b0e-13a3a9e97384} folder to make the extension work in all Firefox profiles (that includes nightly Minefield and Namoroka builds). The maxVersion is set to 4.*.

data:application/octet-stream;base64,
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

TabVisited for Firefox 3 and SeaMonkey 2

This version has the CSS code from [4] embedded, so works right "out of the box"!.

Save as tabvisited-1-2-fx-sm.xpi
data:application/octet-stream;base64,
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