26 Components.utils.import(
"resource://app/jsmodules/sbProperties.jsm");
 
   27 Components.utils.import(
"resource://app/jsmodules/sbColumnSpecParser.jsm");
 
   31 const Cc = Components.classes;
 
   32 const Ci = Components.interfaces;
 
   33 const Cr = Components.results;
 
   42     var manager = 
Cc[
"@songbirdnest.com/Songbird/library/Manager;1"].
 
   54     return this.manager.mainLibrary;
 
   58     var webLibraryGUID = 
Cc[
"@mozilla.org/preferences-service;1"].
 
   60                          getCharPref(
"songbird.library.web");
 
   61     var webLibrary = this.manager.getLibrary(webLibraryGUID);
 
   62     delete webLibraryGUID;
 
   74   getMediaListByGUID: 
function(aLibraryGUID, aMediaListGUID) {
 
   75     var mediaList = (aLibraryGUID instanceof 
Ci.sbILibrary) ?
 
   77                     this.manager.getLibrary( aLibraryGUID );
 
   80     if (aMediaListGUID && aLibraryGUID != aMediaListGUID) {
 
   81       mediaList = mediaList.getMediaItem( aMediaListGUID );
 
   86   _standardFilterConstraint: 
null,
 
   87   get standardFilterConstraint() {
 
   88     if (!this._standardFilterConstraint) {
 
   89       this._standardFilterConstraint = this.createConstraint([
 
   91           [SBProperties.isList, [
"0"]]
 
   94           [SBProperties.hidden, [
"0"]]
 
   98     return this._standardFilterConstraint;
 
  101   createConstraint: 
function(aObject) {
 
  102     var builder = 
Cc[
"@songbirdnest.com/Songbird/Library/ConstraintBuilder;1"]
 
  103                     .createInstance(
Ci.sbILibraryConstraintBuilder);
 
  104     aObject.forEach(
function(aGroup, aIndex) {
 
  105       aGroup.forEach(
function(aPair) {
 
  106         var 
property = aPair[0];
 
  107         var values = aPair[1];
 
  112             return this.
i < this.a.length;
 
  114           getNext: 
function() {
 
  115             return this.a[this.
i++];
 
  118         builder.includeList(property, enumerator);
 
  120       if (aIndex < aObject.length - 1) {
 
  124     return builder.get();
 
  127   createStandardSearchConstraint: 
function(aSearchString) {
 
  128     if (aSearchString == 
"" || !aSearchString)
 
  130     var builder = 
Cc[
"@songbirdnest.com/Songbird/Library/ConstraintBuilder;1"]
 
  131                     .createInstance(
Ci.sbILibraryConstraintBuilder);
 
  132     var a = aSearchString.split(
" ");
 
  134     for (var 
i = 0; 
i < a.length; 
i++) {
 
  135       if (a[
i] && a[
i] != 
"") {
 
  139         builder.include(SBProperties.artistName, a[
i]);
 
  140         builder.include(SBProperties.albumName, a[i]);
 
  141         builder.include(SBProperties.trackName, a[i]);
 
  145     return builder.get();
 
  166   createStandardMediaListView: 
function(aMediaList, aSearchString) {
 
  167     var mediaList = aMediaList.QueryInterface(
Ci.sbIMediaList);
 
  168     var mediaListView = mediaList.createView();
 
  173     var parser = 
new ColumnSpecParser(aMediaList, 
null);
 
  176         Cc[
"@songbirdnest.com/Songbird/Properties/MutablePropertyArray;1"].
 
  178       propertyArray.strict = 
false;
 
  179       propertyArray.appendProperty(parser.sortID,
 
  180           (parser.sortIsAscending ? 
"a" : 
"d"));
 
  181       mediaListView.setSort(propertyArray);
 
  186     mediaListView.filterConstraint = LibraryUtils.standardFilterConstraint;
 
  190     var 
filter = mediaListView.cascadeFilterSet;
 
  191     filter.appendSearch([
"*"], 1);
 
  195       var searchArray = aSearchString.split(
" ");
 
  196       filter.set(0, searchArray, searchArray.length);
 
  199       filter.set(0, [], 0);
 
  202     return mediaListView;
 
  205   createConstrainedMediaListView: 
function(aMediaList, 
aConstraint,
 
  207     var mediaListView = this.createStandardMediaListView(aMediaList,
 
  212     var constraintBuilder =
 
  213           Cc[
"@songbirdnest.com/Songbird/Library/ConstraintBuilder;1"]
 
  214             .createInstance(
Ci.sbILibraryConstraintBuilder);
 
  215     constraintBuilder.includeConstraint(mediaListView.filterConstraint);
 
  216     constraintBuilder.intersect();
 
  217     constraintBuilder.include(aConstraint[0], aConstraint[1]);
 
  218     mediaListView.filterConstraint = constraintBuilder.get();
 
  220     return mediaListView;
 
  229   isMediaTabURL: 
function(aURL, 
aBrowser) {
 
  231       return Components.results.NS_ERROR_INVALID_ARG;
 
  238     if (aURL instanceof Components.interfaces.nsIURI) {
 
  247     const Application = 
Cc[
"@mozilla.org/fuel/application;1"].getService();
 
  249     if (
url == firstRunURL) {
 
  254       Components.classes[
'@songbirdnest.com/servicepane/service;1']
 
  255       .getService(Components.interfaces.sbIServicePaneService);
 
  256     var 
node = service.getNodeForURL(
url,
 
  257                                      Ci.sbIServicePaneService.URL_MATCH_PREFIX);
 
  258     if (!node) 
return false;
 
  272     var originGUID = aMediaItem.getProperty(SBProperties.originItemGuid);
 
  277       var 
foundItem = this.mainLibrary.getMediaItem(originGUID);
 
  295 LibraryUtils.BatchHelper = 
function() {
 
  299 LibraryUtils.BatchHelper.prototype.begin =
 
  300 function BatchHelper_begin()
 
  305 LibraryUtils.BatchHelper.prototype.end =
 
  306 function BatchHelper_end()
 
  309   if (this._depth < 0) {
 
  310     throw new Error(
"Invalid batch depth!");
 
  314 LibraryUtils.BatchHelper.prototype.depth =
 
  315 function BatchHelper_depth()
 
  320 LibraryUtils.BatchHelper.prototype.isActive =
 
  321 function BatchHelper_isActive()
 
  323   return this._depth > 0;
 
  333 LibraryUtils.MultiBatchHelper = 
function() {
 
  334   this._libraries = {};
 
  337 LibraryUtils.MultiBatchHelper.prototype.get =
 
  338 function MultiBatchHelper_get(aLibrary)
 
  340   var batch = this._libraries[aLibrary.guid];
 
  342     batch = 
new LibraryUtils.BatchHelper();
 
  343     this._libraries[aLibrary.guid] = batch;
 
  348 LibraryUtils.MultiBatchHelper.prototype.begin =
 
  349 function MultiBatchHelper_begin(aLibrary)
 
  351   var batch = this.
get(aLibrary);
 
  355 LibraryUtils.MultiBatchHelper.prototype.end =
 
  356 function MultiBatchHelper_end(aLibrary)
 
  358   var batch = this.
get(aLibrary);
 
  362 LibraryUtils.MultiBatchHelper.prototype.depth =
 
  363 function MultiBatchHelper_depth(aLibrary)
 
  365   var batch = this.
get(aLibrary);
 
  366   return batch.depth();
 
  369 LibraryUtils.MultiBatchHelper.prototype.isActive =
 
  370 function MultiBatchHelper_isActive(aLibrary)
 
  372   var batch = this.
get(aLibrary);
 
  373   return batch.isActive();
 
  384 LibraryUtils.RemovalMonitor = 
function(aCallback) {
 
  387   if (!aCallback || !aCallback.onMediaListRemoved) {
 
  388     throw new Error(
"RemovalMonitor() requires a callback object");
 
  391   this._callback = aCallback;
 
  394 LibraryUtils.RemovalMonitor.prototype = {
 
  410   _removedInBatch: 
false,
 
  417   setMediaList:  
function RemovalMonitor_setMediaList(aMediaList) {
 
  419     this._removedInBatch = 
false;
 
  422     if (aMediaList instanceof 
Ci.sbIMediaList) {
 
  425       if (aMediaList.library != 
this._library) {
 
  435         if (!(aMediaList instanceof 
Ci.sbILibrary)) {
 
  436           this._batchHelper = 
new LibraryUtils.BatchHelper();
 
  438           var 
flags = 
Ci.sbIMediaList.LISTENER_FLAGS_BATCHBEGIN |
 
  439                       Ci.sbIMediaList.LISTENER_FLAGS_BATCHEND |
 
  440                       Ci.sbIMediaList.LISTENER_FLAGS_BEFOREITEMREMOVED |
 
  441                       Ci.sbIMediaList.LISTENER_FLAGS_AFTERITEMREMOVED |
 
  442                       Ci.sbIMediaList.LISTENER_FLAGS_LISTCLEARED;
 
  450                                 .getService(
Ci.sbILibraryManager);
 
  455       this._targetGUID = aMediaList.guid;
 
  469       this._batchHelper = 
null;
 
  470       this._targetGUID = 
null;
 
  478   _onBeforeMediaListRemoved: 
function RemovalMonitor_onBeforeMediaListRemoved()
 
  481     this._callback.onBeforeMediaListRemoved();
 
  489   _onMediaListRemoved: 
function RemovalMonitor_onMediaListRemoved() {
 
  493     this.setMediaList(
null);
 
  496     this._callback.onMediaListRemoved();
 
  503   onItemAdded: 
function(aMediaList, aMediaItem, aIndex) { 
return true; },
 
  504   onItemUpdated: 
function(aMediaList, aMediaItem, aProperties) { 
return true },
 
  505   onItemMoved: 
function(aMediaList, aFromIndex, aToIndex) { 
return true },
 
  506   onBeforeItemRemoved: 
function (aMediaList, aMediaItem, aIndex) {
 
  508     if (this._batchHelper.isActive()) {
 
  509       if (aMediaItem.guid == 
this._targetGUID) {
 
  510         this._removedInBatch = 
true;
 
  516     if (aMediaItem.guid == 
this._targetGUID) {
 
  517       this._onBeforeMediaListRemoved();
 
  522   onAfterItemRemoved: 
function RemovalMonitor_onAfterItemRemoved(aMediaList,
 
  529     if (this._batchHelper.isActive()) {
 
  530       if (aMediaItem.guid == 
this._targetGUID) {
 
  531         this._removedInBatch = 
true;
 
  537     if (aMediaItem.guid == 
this._targetGUID) {
 
  538       this._onMediaListRemoved();
 
  543   onBeforeListCleared: 
function RemovalMonitor_onBeforeListCleared
 
  551   onListCleared: 
function RemovalMonitor_onListCleared(aMediaList,
 
  557     if (this._batchHelper.isActive()) {
 
  558       this._removedInBatch = 
true;
 
  563     this._onMediaListRemoved();
 
  568   onBatchBegin: 
function RemovalMonitor_onBatchBegin(aMediaList)
 
  570     this._batchHelper.begin();
 
  572   onBatchEnd: 
function RemovalMonitor_onBatchEnd(aMediaList)
 
  576     this._batchHelper.end();
 
  578     if (this._batchHelper.isActive()) {
 
  585     if (this._removedInBatch) {
 
  589     } 
else if (this._targetGUID != this.
_library.guid) {
 
  593         this.
_library.getMediaItem(this._targetGUID);
 
  599     this._removedInBatch = 
false;
 
  602       this._onMediaListRemoved();
 
  609   onLibraryRegistered: 
function(aLibrary) {},
 
  610   onLibraryUnregistered: 
function RemovalMonitor_onLibraryUnregistered(aLibrary)
 
  615       this._onMediaListRemoved();
 
  624     if (!aIID.equals(Components.interfaces.nsISupports) &&
 
  625         !aIID.equals(Components.interfaces.sbILibraryManagerListener) &&
 
  626         !aIID.equals(Components.interfaces.sbIMediaListListener)) {
 
  627       throw Components.results.NS_ERROR_NO_INTERFACE;
 
  637 LibraryUtils.MediaListEnumeratorToArray = 
function() {
 
  640 LibraryUtils.MediaListEnumeratorToArray.prototype = {
 
  658   onEnumerationBegin: 
function DSW_MLEAL_onEnumerationBegin(aMediaList) {
 
  661     return Ci.sbIMediaListEnumerationListener.CONTINUE;
 
  674   onEnumeratedItem: 
function DSW_MLEAL_onEnumeratedItem(aMediaList,
 
  677     this.
array.push(aMediaItem);
 
  678     return Ci.sbIMediaListEnumerationListener.CONTINUE;
 
  689   onEnumerationEnd: 
function DSW_MLEAL_onEnumerationEnd(aMediaList,
 
  704 LibraryUtils.GlobalMediaListListener = 
function(aListener,
 
  709   if (aFlags === undefined) {
 
  710     aFlags = Components.interfaces.sbIMediaList.LISTENER_FLAGS_ALL;
 
  714   this.ownsWeak = aOwnsWeak;
 
  715   this.propFilter = aPropFilter;
 
  716   this.listenerFlags = aFlags;
 
  719     Cc[
"@songbirdnest.com/Songbird/library/Manager;1"]
 
  720       .getService(
Ci.sbILibraryManager);
 
  722   this.listListener = {
 
  724     onitemadded_skipbatch : 
false,
 
  725     onitemadded_stack     : [],
 
  726     onafteritemremoved_skipbatch : 
false,
 
  727     onafteritemremoved_stack     : [],
 
  729     onItemAdded: 
function(aMediaList, aMediaItem, aIndex) {
 
  730       if (aMediaItem instanceof 
Ci.sbIMediaList)
 
  731         this.cb.addMediaListListener(aMediaItem);
 
  732       if (this.batchcount > 0 && this.onitemadded_skipbatch)
 
  733         return Ci.sbIMediaListEnumerationListener.CONTINUE;
 
  734       if (this.cb.listener.onItemAdded(aMediaList, aMediaItem, aIndex) !=
 
  735           Ci.sbIMediaListEnumerationListener.CONTINUE) {
 
  736         this.onitemadded_skipbatch = 
true;
 
  738       return Ci.sbIMediaListEnumerationListener.CONTINUE;
 
  740     onBeforeItemRemoved: 
function(aMediaList, aMediaItem, aIndex) {
 
  741       return this.cb.listener.onBeforeItemRemoved(aMediaList, aMediaItem, aIndex);
 
  743     onAfterItemRemoved: 
function(aMediaList, aMediaItem, aIndex) {
 
  744       if (aMediaItem instanceof 
Ci.sbIMediaList)
 
  745         this.cb.removeMediaListListener(aMediaItem);
 
  746       if (this.onafteritemremoved_skipbatch)
 
  747         return Ci.sbIMediaListEnumerationListener.CONTINUE;
 
  748       if (this.cb.listener.onAfterItemRemoved(aMediaList, aMediaItem, aIndex) !=
 
  749         Ci.sbIMediaListEnumerationListener.CONTINUE) {
 
  750         this.onafteritemremoved_skipbatch = 
true;
 
  752       return Ci.sbIMediaListEnumerationListener.CONTINUE;
 
  754     onItemUpdated: 
function(aMediaList, aMediaItem, aProperties) {
 
  755       return this.cb.listener.onItemUpdated(aMediaList, aMediaItem, aProperties);
 
  757     onItemMoved: 
function(aMediaList, aFromIndex, aToIndex) {
 
  758       return this.cb.listener.onItemMoved(aMediaList, aFromIndex, aToIndex);
 
  760     onBeforeListCleared: 
function(aMediaList, aExcludeLists) {
 
  761       return this.cb.listener.onBeforeListCleared(aMediaList, aExcludeLists);
 
  763     onListCleared: 
function(aMediaList, aExcludeLists) {
 
  764       return this.cb.listener.onListCleared(aMediaList, aExcludeLists);
 
  766     onBatchBegin: 
function(aMediaList) {
 
  768       this.onitemadded_stack.push(this.onitemadded_skipbatch);
 
  769       this.onitemadded_skipbatch = 
false;
 
  770       this.onafteritemremoved_stack.push(this.onafteritemremoved_skipbatch);
 
  771       this.onafteritemremoved_skipbatch = 
false;
 
  772       return this.cb.listener.onBatchBegin(aMediaList);
 
  774     onBatchEnd: 
function(aMediaList) {
 
  776       this.onitemadded_skipbatch = this.onitemadded_stack.pop();
 
  777       this.onafteritemremoved_skipbatch = this.onafteritemremoved_stack.pop();
 
  778       return this.cb.listener.onBatchEnd(aMediaList);
 
  781       if (iid.equals(Components.interfaces.sbIMediaListListener) ||
 
  782           iid.equals(Components.interfaces.nsISupports))
 
  784       throw Components.results.NS_ERROR_NO_INTERFACE;
 
  791     onEnumerationBegin: 
function(aMediaList) { },
 
  792     onEnumerationEnd: 
function(aMediaList) { },
 
  793     onEnumeratedItem: 
function(aMediaList, aMediaItem) {
 
  794       this.cb.addMediaListListener(aMediaItem);
 
  795       return Components.interfaces.sbIMediaListEnumerationListener.CONTINUE;
 
  798       if (iid.equals(Components.interfaces.sbIMediaListEnumerationListener) ||
 
  799           iid.equals(Components.interfaces.nsISupports))
 
  801       throw Components.results.NS_ERROR_NO_INTERFACE;
 
  806   while (libs.hasMoreElements()) {
 
  807     var library = libs.getNext();
 
  808     if (aOnlyThisLibrary &&
 
  809         library != aOnlyThisLibrary)
 
  811     enumListener.onEnumeratedItem(library, library);
 
  813       enumerateItemsByProperty(
 
  817         Components.interfaces.sbIMediaList.ENUMERATIONTYPE_LOCKING);
 
  820   if (!aOnlyThisLibrary) {
 
  821     this.managerListener = {
 
  823       onLibraryRegistered: 
function(aLibrary) {
 
  824         this.cb.addMediaListListener(aLibrary);
 
  825         this.cb.listener.onItemAdded(
null, aLibrary, 0);
 
  827       onLibraryUnregistered: 
function(aLibrary) {
 
  828         this.cb.listener.onBeforeItemRemoved(
null, aLibrary, 0);
 
  829         this.cb.removeMediaListListener(aLibrary);
 
  830         this.cb.listener.onAfterItemRemoved(
null, aLibrary, 0);
 
  833         if (iid.equals(Components.interfaces.sbILibraryManagerListener) ||
 
  834             iid.equals(Components.interfaces.nsISupports))
 
  836         throw Components.results.NS_ERROR_NO_INTERFACE;
 
  844 LibraryUtils.GlobalMediaListListener.prototype = {
 
  847   managerListener : 
null,
 
  854     for (var 
i=0;
i<this.listento.length;
i++)
 
  855       this.listento[
i].removeListener(this.listListener);
 
  858     this.listListener = 
null;
 
  861     this.propFilter = 
null;
 
  863     if (this.managerListener)
 
  865     this.managerListener = 
null;
 
  870   addMediaListListener: 
function(aList) {
 
  871     if (this.listento.indexOf(aList) >= 0)
 
  873     aList.addListener(this.listListener,
 
  877     this.listento.push(aList);
 
  880   removeMediaListListener: 
function(aList) {
 
  881     aList.removeListener(this.listListener);
 
  882     var 
p = this.listento.indexOf(aList);
 
  883     if (p >= 0) this.listento.splice(p, 1);
 
  896 LibraryUtils.canEditMetadata = 
function (aItem) {
 
  897   var editable = aItem.userEditable;
 
  900       var contentSrc = aItem.contentSrc;
 
  901       if (contentSrc.scheme == 
"x-mtp")
 
sbDeviceFirmwareAutoCheckForUpdate prototype flags
sbOSDControlService prototype QueryInterface
sbDownloadDeviceServicePaneModule prototype shutdown
getService(Ci.sbIFaceplateManager)
StringArrayEnumerator prototype hasMore
_updateTextAndScrollDataForTab aBrowser
sbAutoDownloader prototype _libraryManager
Javascript wrappers for common library tasks. 
__defineGetter__("Application", function(){delete this.Application;return this.Application=Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication);})
_getSelectedPageStyle s i
Array filter(tab.attributes, function(aAttr){return(_this.xulAttributes.indexOf(aAttr.name) >-1);}).forEach(tab.removeAttribute
sbAutoDownloader prototype _library
var getMainLibraryOriginItem
Find an item in the main library whose guid matches the originItemGuid of the param aMediaItem and re...