home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February / PCWorld_2008-02_cd.bin / temacd / songbird / Songbird_0.4_windows-i686.exe / components / sbBundle.js < prev    next >
Text File  |  2007-12-21  |  11KB  |  343 lines

  1. /**
  2. //
  3. // BEGIN SONGBIRD GPL
  4. // 
  5. // This file is part of the Songbird web player.
  6. //
  7. // Copyright(c) 2005-2008 POTI, Inc.
  8. // http://songbirdnest.com
  9. // 
  10. // This file may be licensed under the terms of of the
  11. // GNU General Public License Version 2 (the "GPL").
  12. // 
  13. // Software distributed under the License is distributed 
  14. // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either 
  15. // express or implied. See the GPL for the specific language 
  16. // governing rights and limitations.
  17. //
  18. // You should have received a copy of the GPL along with this 
  19. // program. If not, go to http://www.gnu.org/licenses/gpl.html
  20. // or write to the Free Software Foundation, Inc., 
  21. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. // 
  23. // END SONGBIRD GPL
  24. //
  25.  */
  26. Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
  27.  
  28. const SONGBIRD_BUNDLE_IID = Components.interfaces.sbIBundle;
  29.  
  30. const SONGBIRD_GETBUNDLE_PREFKEY = "songbird.url.bundles";
  31.  
  32. function Bundle() {
  33.   this._datalisteners = new Array();
  34.   this._installlisteners = new Array();
  35.  
  36.   var obs = Components.classes["@mozilla.org/observer-service;1"]
  37.                       .getService(Components.interfaces.nsIObserverService);
  38.   obs.addObserver(this, "quit-application", false);
  39. }
  40.  
  41. Bundle.prototype.constructor = Bundle;
  42.  
  43. Bundle.prototype = {
  44.   classDescription: "Songbird Bundle Service Interface",
  45.   classID:          Components.ID("{ff29ec35-1294-42ae-a341-63d0303df969}"),
  46.   contractID:       "@songbirdnest.com/Songbird/Bundle;1",
  47.  
  48.   _bundleid: null,
  49.   _req: null,
  50.   _datalisteners: null,
  51.   _installlisteners: null,
  52.   _status: 0,
  53.   _extlist: null,
  54.   _browser: null,
  55.   _downloadListener: null,
  56.   _url: null,
  57.   _file: null,
  58.   _filename: null,
  59.   _needrestart: false,
  60.   _bundleversion: 0,
  61.   _simulate_lots_of_entries: false,
  62.   _init: false,
  63.   _onload: null,
  64.   _onerror: null,
  65.   _installresult: -1,
  66.   _timer: null,
  67.  
  68.   LOG: function(str) {
  69.     var consoleService = Components.classes['@mozilla.org/consoleservice;1']
  70.                             .getService(Components.interfaces.nsIConsoleService);
  71.     consoleService.logStringMessage(str);
  72.   },
  73.   
  74.   
  75.   get bundleId() {
  76.     return this._bundleid;
  77.   },
  78.  
  79.   set bundleId(aStringValue) {
  80.     // Make sure there is a string object to pass.
  81.     if (aStringValue == null)
  82.       aStringValue = "";
  83.     this._bundleid = aStringValue;
  84.   },
  85.   
  86.   retrieveBundleData: function(aTimeout) {
  87.   
  88.     if (this._init && this._req) {
  89.       this._req.abort();
  90.       var httpReq = this._req.QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
  91.       httpReq.removeEventListener("load", this._onload, false);
  92.       httpReq.removeEventListener("error", this._onerror, false);
  93.       this._req = null;
  94.       this._status = SONGBIRD_BUNDLE_IID.BUNDLE_DATA_STATUS_DOWNLOADING;
  95.     }
  96.     
  97.     this._onload = { 
  98.       _that: null, 
  99.       handleEvent: function( event ) { this._that.onLoad(); } 
  100.     }; this._onload._that = this;
  101.     
  102.     this._onerror = { 
  103.       _that: null, 
  104.       handleEvent: function( event ) { this._that.onError(); } 
  105.     }; this._onerror._that = this;
  106.     
  107.     this._req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Components.interfaces.nsIXMLHttpRequest); 
  108.     var httpReq = this._req.QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
  109.     httpReq.addEventListener("load", this._onload, false);
  110.     httpReq.addEventListener("error", this._onerror, false);
  111.     
  112.     var prefsService =
  113.         Components.classes["@mozilla.org/preferences-service;1"].
  114.         getService(Components.interfaces.nsIPrefBranch);
  115.  
  116.     var baseURL = prefsService.getCharPref(SONGBIRD_GETBUNDLE_PREFKEY);
  117.     var url = baseURL + this._bundleid;
  118.  
  119.     this._req.open('GET', url + this._getRandomParameter(), true); 
  120.     this._req.send(null);
  121.     this._init = true;
  122.  
  123.     // If specified, set up a callback to enforce request timeout
  124.     if (aTimeout > 0) {
  125.       this._timer = Components.classes["@mozilla.org/timer;1"]
  126.                               .createInstance(Components.interfaces.nsITimer);
  127.       this._timer.initWithCallback(this, aTimeout,
  128.                                    Components.interfaces.nsITimer.TYPE_ONE_SHOT);
  129.     }
  130.   },
  131.  
  132.   get bundleDataDocument() {
  133.     return this._req ? this._req.responseXML : null;
  134.   },
  135.  
  136.   get bundleDataText() {
  137.     return this._req ? this._req.responseText : "";
  138.   },
  139.   
  140.   addBundleDataListener: function(aListener) {
  141.     this._datalisteners.push(aListener);
  142.   },
  143.   
  144.   removeBundleDataListener: function (aListener) {
  145.     var r = this.getDataListenerIndex(aListener);
  146.     if (r != -1) this._datalisteners.splice(r, 1);
  147.   },
  148.   
  149.   getNumDataListeners: function() {
  150.     return this._datalisteners.length;
  151.   },
  152.   
  153.   getDataListener: function(aIndex) {
  154.     return this._datalisteners[aIndex];
  155.   },
  156.  
  157.   getDataListenerIndex: function(aListener) {
  158.     return this._datalisteners.indexOf(aListener);
  159.   },
  160.  
  161.   addBundleInstallListener: function(aListener) {
  162.     this._installlisteners.push(aListener);
  163.   },
  164.   
  165.   removeBundleInstallListener: function (aListener) {
  166.     var r = this.getInstallListenerIndex(aListener);
  167.     if (r != -1) this._installlisteners.splice(r, 1);
  168.   },
  169.   
  170.   get installListenerCount() {
  171.     return this._installlisteners.length;
  172.   },
  173.   
  174.   getInstallListener: function(aIndex) {
  175.     return this._installlisteners[aIndex];
  176.   },
  177.   
  178.   getInstallaListenerIndex: function(aListener) {
  179.     for (var i=0;i<this._installlisteners.length;i++) if (this._datalisteners[i] == aListener) return i;
  180.     return -1;
  181.   },
  182.   
  183.   get bundleDataStatus() {
  184.     return this._status;
  185.   },
  186.   
  187.   onLoad: function() {
  188.     this._status = SONGBIRD_BUNDLE_IID.BUNDLE_DATA_STATUS_SUCCESS;
  189.     this.getExtensionList();
  190.     for (var i=0;i<this._datalisteners.length;i++) this._datalisteners[i].onDownloadComplete(this);
  191.   },
  192.  
  193.   onError: function() {
  194.     this._status = SONGBIRD_BUNDLE_IID.BUNDLE_DATA_STATUS_ERROR;
  195.     for (var i=0;i<this._datalisteners.length;i++) this._datalisteners[i].onError(this);
  196.   },
  197.   
  198.   getDataNodes: function(bundledocument) {
  199.     if (!bundledocument) return null;
  200.     var datablocknodes = bundledocument.childNodes;
  201.     
  202.     for (var i=0;i<datablocknodes.length;i++) {
  203.       if (datablocknodes[i].tagName == "SongbirdInstallBundle") {
  204.         this._bundleversion = datablocknodes[i].getAttribute("version")
  205. /*
  206.         // Sample code to generate some elements for testing.
  207.         for ( var j = 0; j < 10; j++ ) {
  208.           var testElement = bundledocument.createElement("XPI");
  209.           testElement.setAttribute("name", "TEST ELEMENT #" + (j+1) );
  210.           testElement.setAttribute("url", "");
  211.           datablocknodes[i].appendChild( testElement );
  212.         }
  213. */
  214.         return datablocknodes[i].childNodes;
  215.       }
  216.     }
  217.     return null;
  218.   },
  219.  
  220.   installFlaggedExtensions: function(aWindow) {
  221.     var windowWatcherService = Components.classes['@mozilla.org/embedcomp/window-watcher;1']
  222.                             .getService(Components.interfaces.nsIWindowWatcher);
  223.                             
  224.     // TODO: do the install !
  225.     this._installresult = "";
  226.     windowWatcherService.openWindow(aWindow, "chrome://songbird/content/xul/setupProgress.xul", "_blank", "chrome,dialog=yes,centerscreen,alwaysRaised,close=no,modal", this);
  227.     return this._installresult;
  228.   },
  229.   
  230.   setInstallResult: function(aResult) {
  231.     this._installresult = aResult;
  232.   },
  233.   
  234.   getExtensionList: function() {
  235.     this._extlist = new Array();
  236.     if (this._status == SONGBIRD_BUNDLE_IID.BUNDLE_DATA_STATUS_SUCCESS) {
  237.       var bundledocument = this.bundleDataDocument;
  238.       if (bundledocument) {
  239.         var nodes = this.getDataNodes(bundledocument);
  240.         if (nodes) {
  241.           for (var i=0;i<nodes.length;i++) {
  242.             if (nodes[i].tagName == "XPI") {
  243.               var inst = nodes[i].getAttribute("default");
  244.               this._extlist.push(Array(nodes[i], (inst=="true" || inst=="1")));
  245.             }
  246.           }
  247.         }
  248.       }
  249.     }
  250.   },
  251.   
  252.   get bundleExtensionCount() {
  253.     if (this._status == SONGBIRD_BUNDLE_IID.BUNDLE_DATA_STATUS_SUCCESS) {
  254.       if (this._simulate_lots_of_entries) return this._extlist.length * 20;
  255.       return this._extlist.length;
  256.     }
  257.     return 0;
  258.   },
  259.   
  260.   getExtensionAttribute: function(aIndex, aAttributeName) {
  261.     if (!this._extlist) return "";
  262.     if (this._extlist.length != 0 && this._simulate_lots_of_entries) 
  263.       aIndex = aIndex % this._extlist.length;
  264.     if (this._status == SONGBIRD_BUNDLE_IID.BUNDLE_DATA_STATUS_SUCCESS && aIndex < this.bundleExtensionCount) 
  265.       return this._extlist[aIndex][0].getAttribute(aAttributeName);
  266.     return "";
  267.   },
  268.       
  269.   getExtensionInstallFlag: function(aIndex) {
  270.     if (!this._extlist) return false;
  271.     if (this._extlist.length != 0 && this._simulate_lots_of_entries) 
  272.       aIndex = aIndex % this._extlist.length;
  273.     if (this._status == SONGBIRD_BUNDLE_IID.BUNDLE_DATA_STATUS_SUCCESS && aIndex < this.bundleExtensionCount) 
  274.       return this._extlist[aIndex][1];
  275.     return false;
  276.   },
  277.   
  278.   setExtensionInstallFlag: function(aIndex, aInstallFlag) {
  279.     if (!this._extlist) return;
  280.     if (this._extlist.length != 0 && this._simulate_lots_of_entries) 
  281.       aIndex = aIndex % this._extlist.length;
  282.     if (this._status == SONGBIRD_BUNDLE_IID.BUNDLE_DATA_STATUS_SUCCESS && aIndex < this.bundleExtensionCount) 
  283.       this._extlist[aIndex][1] = aInstallFlag;
  284.   },
  285.   
  286.   _getRandomParameter: function() {
  287.     var aUUIDGenerator = (Components.classes["@mozilla.org/uuid-generator;1"]).createInstance();
  288.     aUUIDGenerator = aUUIDGenerator.QueryInterface(Components.interfaces.nsIUUIDGenerator);
  289.     var aUUID = aUUIDGenerator.generateUUID();
  290.     return "?randomguid=" + escape(aUUID);
  291.   },
  292.   
  293.   setNeedRestart: function(aRequired) {
  294.     this._needrestart = aRequired;
  295.   },
  296.  
  297.   get restartRequired() {
  298.     return this._needrestart;
  299.   },
  300.  
  301.   get bundleDataVersion() {
  302.     return this._bundleversion;
  303.   },
  304.   
  305.   // nsITimerCallback
  306.   notify: function(timer)
  307.   {
  308.     if(this._req.readyState != 4) { // 4 = COMPLETED
  309.       // abort() stops the http request so the normal event listeners are never
  310.       // called so we need to call onError() manually.
  311.       this._req.abort();
  312.       this.onError();
  313.     }
  314.     this._timer.cancel();
  315.     this._timer = null;
  316.   },
  317.  
  318.   // nsIObserver
  319.   observe: function(aSubject, aTopic, aData) {
  320.     if (aTopic == "quit-application") {
  321.       if (this._timer) {
  322.         this._timer.cancel();
  323.         this._timer = null;
  324.       }
  325.     }
  326.   },
  327.  
  328.   /**
  329.    * See nsISupports.idl
  330.    */
  331.   QueryInterface:
  332.     XPCOMUtils.generateQI([SONGBIRD_BUNDLE_IID,
  333.                            Components.interfaces.sbPIBundle,
  334.                            Components.interfaces.nsIWebProgressListener,
  335.                            Components.interfaces.nsISupportsWeakReference,
  336.                            Components.interfaces.nsIObserver])
  337. }; // Bundle.prototype
  338.  
  339. function NSGetModule(compMgr, fileSpec) {
  340.   return XPCOMUtils.generateModule([Bundle]);
  341. }
  342.  
  343.