這是 Firefox chrome url 用的 bookmarklet。
我註冊都沒在記密碼的。自動登入失靈的時候,只好打開 Firefox 的「已存密碼」然後找個地方(例如搜尋列)把密碼抄一遍,再複製、貼上表單登入。
要是哪天我被盜帳號,原因就是螢幕擷圖給別人,恰好密碼就在搜尋列吧。為甚麼這麼麻煩,都是「已存密碼」不能右鍵複製的緣故啊。
- 於是,把這支 bookmarklet 加入書籤 → 複製已存密碼(右鍵選單)
- 打開「已存密碼」(chrome://passwordmgr/content/passwordManager.xul)
- 點剛剛加入的書籤。
- 就可以開右鍵選單,複製或顯示密碼了。多選也有效。
原始碼拆開如下:
// 應於 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();