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

這是 Firefox chrome url 用的 bookmarklet。

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

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

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

原始碼拆開如下:

  1. // 應於 chrome://passwordmgr/content/passwordManager.xul 執行  
  2. if( ! netscape.security.PrivilegeManager.isPrivilegeEnabled('UniversalXPConnect') || ! document.getElementById('signonsTree') ) {  
  3.  alert('操作失敗:\n\n請於下述 URL 執行這支 bookmarklet:\nchrome://passwordmgr/content/passwordManager.xul\n\n');  
  4.  return;  
  5. }  
  6.   
  7. window.leqPasswordPicker = {  
  8.   
  9.  clipboardHelper: Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper),  
  10.   
  11.  init: function(){  
  12.   
  13.    if( ! document.getElementById("leqPasswordPicker_menupopup") ) {  
  14.   
  15.      var popupset = document.createElement("popupset");  
  16.   
  17.        var menupopup = document.createElement("menupopup");  
  18.        menupopup.setAttribute('id''leqPasswordPicker_menupopup');  
  19.   
  20.          var menuitem = document.createElement("menuitem");  
  21.          menuitem.setAttribute('oncommand''leqPasswordPicker.show();');  
  22.          menuitem.setAttribute('label''顯示密碼');  
  23.   
  24.          var menuitem2 = document.createElement("menuitem");  
  25.          menuitem2.setAttribute('oncommand''leqPasswordPicker.copy();');  
  26.          menuitem2.setAttribute('label''複製密碼');  
  27.   
  28.      menupopup.appendChild(menuitem);  
  29.      menupopup.appendChild(menuitem2);  
  30.      popupset.appendChild(menupopup);  
  31.   
  32.      document.getElementById('signonsTree').getElementsByTagName('treechildren')[0].setAttribute('context''leqPasswordPicker_menupopup');  
  33.      document.getElementById('SignonViewerDialog').appendChild(popupset);  
  34.    }  
  35.   
  36.  },  
  37.   
  38.  show: function(){  
  39.    var selections = GetTreeSelections(signonsTree);  
  40.    if (selections.length > 0) {  
  41.      var txt = [];  
  42.      for (var s = 0 ; s < selections.length ; s++) {  
  43.        var i = selections[s];  
  44.        txt.push(  
  45.            '網 站:' + signonsTreeView.getCellText(i,signonsTree.columns[0])  
  46.          + '\n使用者:' + signonsTreeView.getCellText(i,signonsTree.columns[1])  
  47.          + '\n密 碼:\n\t' + signonsTreeView.getCellText(i,signonsTree.columns[2]) + '\n'  
  48.        );  
  49.      }  
  50.      alert( txt.join('\n') );  
  51.    }  
  52.  },  
  53.   
  54.  copy: function(){  
  55.    var selections = GetTreeSelections(signonsTree);  
  56.   
  57.    if (selections.length > 0) {  
  58.      var txt = [];  
  59.      for (var s = 0 ; s < selections.length ; s++) {  
  60.        var i = selections[s];  
  61.        txt.push( signonsTreeView.getCellText(i,signonsTree.columns[2]) );  
  62.      }  
  63.      this.clipboardHelper.copyString( txt.join('\n') );  
  64.   
  65.      // 送一個 copy 事件,這段可以不用  
  66.      var evt = document.createEvent("HTMLEvents");  
  67.      evt.initEvent('copy'truetrue);  
  68.      document.getElementById('signonsTree').getElementsByTagName('treechildren')[0].dispatchEvent(evt);  
  69.    }  
  70.  }  
  71.   
  72. };  
  73.   
  74. leqPasswordPicker.init();