功能類似 Extension List DumperListZilla 兩個套件,把附加元件清單匯出成檔案。
輸出格式可用樣板(是我參考 Ext JS 寫的陽春版)方式調整,但要改原始碼、比較麻煩就是了。

Bookmarklet 在這裡 → 匯出附加元件列表(僅支援 Firefox 3 系列)


使用說明:

  1. 先將 Bookmarklet 加入書籤。
  2. 在 Firefox 網址列輸入 chrome://mozapps/content/extensions/extensions.xul 並開啟。
    (可見動作是在 Chrome URL 執行的,小提醒:別讓壞人的 bookmarklet 這麼做)
  3. 要匯出擴充套件的話,就先點選「擴充套件」分頁;
    同理,佈景主題和外掛程式也是可以匯出的。
  4. 執行 bookmarklet,順利的話會跑出如下訊息:

    按「確定」繼續

    接下來照著訊息指示進行,便能完成匯出了。

改造說明:(有點囉唆,看不懂原始碼再參考吧)

為了調整輸出格式,需要修改原始碼;可自製幾支不同的樣板,存成不同的 bookmarklet 備用(不會壓製 bookmarklet 的話可參考前文)。原始碼附在文末,重要部分如下:

  • 樣板部分(template-prefix 等)

    樣板由 template_prefixtemplate_itemtemplate_suffix 組成,輸出時會把頭(_prefix)接上一連串的項目(_item)再接上尾(_suffix)。

    樣板字串中 ${foo} 型式的元素,會被代換成實際值,例如 ${name} 會變成套件名稱。
    ※要注意的是 _prefix、_suffix 和 _item 能用的 ${foo} 不同。預設 _prefix、_suffix 專用的是 ${date}${total},其他則是 _item 專用。

  • 過濾不要的資料(data = data.filter)

    清單資料會儲存在 data 陣列裡面,要過濾的話得在
    data = data.filter(function(item, idx, arr){
    內處理。例如 return item['hidden']!='true'; 會把隱藏的項目拿掉。

  • helpers(var helpers = )

    樣板字串可以用 ${foo:helper} 這樣的元素來修改資料,例如 ${isDisabled:isTrue( 「已停用」,)} 會在套件停用時顯示「已停用」。

    相應原始碼在 var helpers = { 裡面有幾個函數,傳回值就是要輸出的字串。
    template_item 可用的函數,基本型為:
    函數名稱 : function( item, value[, 參數1, 參數2, …] ){}

    • item 為目前的 template_item,就是 data 陣列中的一項。
    • value${foo:helper} 之中 foo 的實際值,例如 ${name:helper} 傳回的是套件名稱。
    • 其餘參數,在樣板中是以 ${foo:helper(參數1,參數2)} 型式傳進來的。

原始碼:

  1. var leqExtDumper = {  
  2.   
  3. dump: function(){  
  4.   if(typeof(gExtensionsView)=='undefined'return(alert('出了點狀況,無法繼續;\n\n請在 Firefox 3 的\nchrome://mozapps/content/extensions/extensions.xul\n執行這支 bookmarklet.'));  
  5.     
  6.   var txt = '';  
  7.   var data = [];  
  8.     
  9.   // 樣板  
  10.   var template_prefix = '附加元件列表 (${total}) - ${date}\n<ul>';  
  11.   var template_item   = '<li>\n'  
  12.                       + '${homepageURL:addLink} - ${version} - <small>${optionsURL}</small>'  
  13.                       + '${isDisabled:isTrue( (已停用),)} ${compatible:isFalse( (與應用程式不相容),)}'  
  14.                       + '  
  15. \n'  
  16.                       + '適用於: Firefox ${min} - ${max}\n'  
  17.                       + '<p>${description}</p>\n'  
  18.                       + '</li>\n';  
  19.   var template_suffix = '</ul>';  
  20.     
  21.   var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);  
  22.   var charset = "UTF-8";  
  23.   var os = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream);  
  24.   var fos = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);  
  25.   
  26.   fp.init(window, null, fp.modeSave);  
  27.   fp.defaultExtension='txt';  
  28.   fp.defaultString='附加元件列表';  
  29.   fp.appendFilters(fp.filterText | fp.filterHTML);  
  30.     
  31.   gExtensionsView.children.forEach(  
  32.     function(i){  
  33.       var item = gExtensionManager.getItemForID(getIDFromResourceURI(i.getAttribute('id')));  
  34.       data.push({  
  35.         name        : i.getAttribute('name'),         // 套件名稱  
  36.         id          : i.getAttribute('id'),           // 套件 id  
  37.         min         : item ? item.minAppVersion : ''// 支援的最低 Firefox 版本  
  38.         max         : item ? item.maxAppVersion : ''// 支援的最高 Firefox 版本  
  39.         iconURL     : i.getAttribute('iconURL'),      // 套件的圖示位址  
  40.         version     : i.getAttribute('version'),      // 套件版本  
  41.         description : i.getAttribute('description'),  // 套件的敘述  
  42.         homepageURL : i.getAttribute('homepageURL'),  // 套件首頁  
  43.         optionsURL  : i.getAttribute('optionsURL'),   // 套件的選項位址  
  44.         hidden      : i.getAttribute('hidden'),       // 是否為隱藏套件  
  45.         isDisabled  : i.getAttribute('isDisabled'),   // 是否已停用  
  46.         compatible  : i.getAttribute('compatible')    // 是否與目前 Firefox 版本相容  
  47.       });  
  48.     }, this  
  49.   );  
  50.     
  51.   // 過濾不要列出的項目 (return false 的資料會被排除)  
  52.   data = data.filter(function(item, idx, arr){  
  53.     return item['hidden']!='true';  
  54.   });  
  55.   
  56.   var helpers = {  
  57.     isTrue  : function(item, value, strTrue, strFalse){  
  58.       return value=='true' ? strTrue : strFalse;  
  59.     },  
  60.     isFalse : function(item, value, strTrue, strFalse){  
  61.       return value=='false' ? strTrue : strFalse;  
  62.     },  
  63.     addLink : function(item, value){  
  64.       return value=='' ? item['name'] : '<a href="' + value + '">' + item['name'] + '</a>';  
  65.     },  
  66.     // 以下僅適用於 template_prefix 與 template_suffix  
  67.     date    : function(){  
  68.       return (new Date()).toLocaleString();  
  69.     },  
  70.     total   : function(){  
  71.       return data.length;  
  72.     }  
  73.   };  
  74.     
  75.   // template_prefix  
  76.   // 取代 ${key} 形式的字串  
  77.   txt = template_prefix.replace( /\$\{([\w-]+)\}/g, function(m, key){ return helpers[key].apply(this); } );  
  78.   
  79.   data.forEach(  
  80.     function(i){  
  81.       // template_item  
  82.       // 取代 ${key:format(args)} 形式的字串 - 參考自 Ext.Template library - http://www.extjs.com  
  83.       txt += template_item.replace( /\$\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, function(m, key, format, args){  
  84.         if(format){  
  85.           args = [i, i[key]].concat(args.split(','));  
  86.           return helpers[format].apply(this, args);  
  87.         }  
  88.         else {  
  89.           return i[key] !== undefined ? i[key] : "";  
  90.         }  
  91.       });  
  92.     }, this  
  93.   );  
  94.   // template_suffix  
  95.   txt += template_suffix.replace( /\$\{([\w-]+)\}/g, function(m, key){ return helpers[key].apply(this); } );  
  96.   
  97.     
  98.   if(!confirm('請選擇匯出檔案的位置:')) return;  
  99.     
  100.   if (fp.show() != fp.returnCancel) {  
  101.     if (fp.file.exists()) fp.file.remove(true);  
  102.     fos.init(fp.file, 0x02 | 0x08 | 0x20, 0666, 0);  
  103.     os.init(fos, charset, 0, 0x0000);  
  104.     os.writeString(txt);  
  105.     os.close();  
  106.     fos.close();  
  107.     alert('資料已匯出至 ' + fp.file.path);  
  108.   }  
  109.   
  110. }  
  111.   
  112. };  
  113.   
  114. leqExtDumper.dump();