也不必再打主控密碼了(輸入過的話)

這是 Firefox chrome url 用的 bookmarklet。

我註冊都沒在記密碼的。自動登入失靈的時候,只好打開 Firefox 的「已存密碼」然後找個地方(例如搜尋列)把密碼抄一遍,再複製、貼上表單登入。

要是哪天我被盜帳號,原因就是螢幕擷圖給別人,恰好密碼就在搜尋列吧。為甚麼這麼麻煩,都是「已存密碼」不能右鍵複製的緣故啊。

  1. 於是,把這支 bookmarklet 加入書籤 → 複製已存密碼(右鍵選單)
  2. 打開「已存密碼」(chrome://passwordmgr/content/passwordManager.xul)
  3. 點剛剛加入的書籤。
  4. 就可以開右鍵選單,複製或顯示密碼了。多選也有效。

原始碼拆開如下:

// 應於 chrome://passwordmgr/content/passwordManager.xul 執行
if( ! netscape.security.PrivilegeManager.isPrivilegeEnabled('UniversalXPConnect') || ! document.getElementById('signonsTree') ) {
 alert('操作失敗:\n\n請於下述 URL 執行這支 bookmarklet:\nchrome://passwordmgr/content/passwordManager.xul\n\n');
 return;
}

window.leqPasswordPicker = {

 clipboardHelper: Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper),

 init: function(){

   if( ! document.getElementById("leqPasswordPicker_menupopup") ) {

     var popupset = document.createElement("popupset");

       var menupopup = document.createElement("menupopup");
       menupopup.setAttribute('id', 'leqPasswordPicker_menupopup');

         var menuitem = document.createElement("menuitem");
         menuitem.setAttribute('oncommand', 'leqPasswordPicker.show();');
         menuitem.setAttribute('label', '顯示密碼');

         var menuitem2 = document.createElement("menuitem");
         menuitem2.setAttribute('oncommand', 'leqPasswordPicker.copy();');
         menuitem2.setAttribute('label', '複製密碼');

     menupopup.appendChild(menuitem);
     menupopup.appendChild(menuitem2);
     popupset.appendChild(menupopup);

     document.getElementById('signonsTree').getElementsByTagName('treechildren')[0].setAttribute('context', 'leqPasswordPicker_menupopup');
     document.getElementById('SignonViewerDialog').appendChild(popupset);
   }

 },

 show: function(){
   var selections = GetTreeSelections(signonsTree);
   if (selections.length > 0) {
     var txt = [];
     for (var s = 0 ; s < selections.length ; s++) {
       var i = selections[s];
       txt.push(
           '網 站:' + signonsTreeView.getCellText(i,signonsTree.columns[0])
         + '\n使用者:' + signonsTreeView.getCellText(i,signonsTree.columns[1])
         + '\n密 碼:\n\t' + signonsTreeView.getCellText(i,signonsTree.columns[2]) + '\n'
       );
     }
     alert( txt.join('\n') );
   }
 },

 copy: function(){
   var selections = GetTreeSelections(signonsTree);

   if (selections.length > 0) {
     var txt = [];
     for (var s = 0 ; s < selections.length ; s++) {
       var i = selections[s];
       txt.push( signonsTreeView.getCellText(i,signonsTree.columns[2]) );
     }
     this.clipboardHelper.copyString( txt.join('\n') );

     // 送一個 copy 事件,這段可以不用
     var evt = document.createEvent("HTMLEvents");
     evt.initEvent('copy', true, true);
     document.getElementById('signonsTree').getElementsByTagName('treechildren')[0].dispatchEvent(evt);
   }
 }

};

leqPasswordPicker.init();