30 const Cc = Components.classes;
31 const Ci = Components.interfaces;
32 const Cr = Components.results;
34 Components.utils.import(
"resource://gre/modules/XPCOMUtils.jsm");
36 Components.utils.import(
"resource://app/jsmodules/sbProperties.jsm");
37 Components.utils.import(
"resource://app/jsmodules/sbLibraryUtils.jsm");
38 Components.utils.import(
"resource://app/jsmodules/ArrayConverter.jsm");
39 Components.utils.import(
"resource://app/jsmodules/DropHelper.jsm");
40 Components.utils.import(
"resource://app/jsmodules/StringUtils.jsm");
41 Components.utils.import(
"resource://app/jsmodules/WindowUtils.jsm");
43 const CONTRACTID =
"@songbirdnest.com/servicepane/library;1";
45 const URN_PREFIX_ITEM =
'urn:item:';
46 const URN_PREFIX_LIBRARY =
'urn:library:';
48 const LSP =
'http://songbirdnest.com/rdf/library-servicepane#';
49 const SP=
'http://songbirdnest.com/rdf/servicepane#';
52 const TYPE_X_SB_TRANSFER_MEDIA_ITEM =
"application/x-sb-transfer-media-item";
55 const TYPE_X_SB_TRANSFER_DISABLE_DOWNLOAD =
"application/x-sb-transfer-disable-download";
63 dump(parentArgs.callee.name +
"(");
64 for (var
i = 0;
i < parentArgs.length;
i++) {
66 if (
i < parentArgs.length - 1) {
73 const DEBUG_MODE =
false;
86 function sbLibraryServicePane() {
87 this._servicePane =
null;
89 this._lastShortcuts =
null;
90 this._lastMenuitems =
null;
93 this.stringbundle =
null;
96 this._refreshPending =
false;
106 sbLibraryServicePane.prototype.QueryInterface =
107 XPCOMUtils.generateQI([
Ci.nsIObserver,
108 Ci.sbIServicePaneModule,
109 Ci.sbILibraryServicePaneService,
110 Ci.sbILibraryManagerListener,
111 Ci.sbIMediaListListener]);
113 sbLibraryServicePane.prototype.classID =
114 Components.ID(
"{64ec2154-3733-4862-af3f-9f2335b14821}");
115 sbLibraryServicePane.prototype.classDescription =
116 "Songbird Library Service Pane Service";
117 sbLibraryServicePane.prototype.contractID =
119 sbLibraryServicePane.prototype._xpcom_categories = [{
120 category:
'service-pane',
128 sbLibraryServicePane.prototype.servicePaneInit =
129 function sbLibraryServicePane_servicePaneInit(sps) {
133 this._servicePane = sps;
136 this._initLibraryManager();
139 sbLibraryServicePane.prototype.shutdown =
140 function sbLibraryServicePane_shutdown() {}
142 sbLibraryServicePane.prototype.fillContextMenu =
143 function sbLibraryServicePane_fillContextMenu(aNode, aContextMenu, aParentWindow) {
144 var libraryMgr =
Cc[
"@songbirdnest.com/Songbird/library/Manager;1"]
145 .getService(
Ci.sbILibraryManager);
148 if (aNode.id ==
'SB:Playlists' ||
149 this._getLibraryGUIDForURN(aNode.id) == libraryMgr.mainLibrary.guid ||
150 aNode.getAttributeNS(
LSP,
'ListCustomType') ==
'local') {
151 this.fillNewItemMenu(aNode, aContextMenu, aParentWindow);
154 var list = this.getLibraryResourceForNode(aNode);
156 this._appendCommands(aContextMenu, list, aParentWindow);
159 if (list instanceof
Ci.sbILocalDatabaseSmartMediaList) {
160 if (list.userEditable) {
161 this._appendMenuItem(aContextMenu,
SBString(
"command.smartpl.properties"),
function(
event) {
162 var watcher =
Cc[
"@mozilla.org/embedcomp/window-watcher;1"]
163 .getService(
Ci.nsIWindowWatcher);
164 watcher.openWindow(aParentWindow,
165 "chrome://songbird/content/xul/smartPlaylist.xul",
167 "chrome,dialog=yes,centerscreen,modal,titlebar=no",
173 var appPrefs =
Cc[
"@mozilla.org/fuel/application;1"]
174 .getService(
Ci.fuelIApplication).prefs;
175 if (appPrefs.getValue(
"songbird.library_exporter.export_tracks",
false)) {
177 if (list == libraryMgr.mainLibrary) {
178 var exportService =
Cc[
"@songbirdnest.com/media-export-service;1"]
179 .getService(
Ci.sbIMediaExportService);
181 var item = aContextMenu.ownerDocument.createElement(
"menuitem");
182 item.setAttribute(
"label",
SBString(
"command.libraryexport"));
183 item.addEventListener(
186 var exportService =
Cc[
"@songbirdnest.com/media-export-service;1"]
187 .getService(
Ci.sbIMediaExportService);
188 exportService.exportSongbirdData();
193 if (!exportService.hasPendingChanges) {
194 item.setAttribute(
"disabled",
"true");
197 aContextMenu.appendChild(item);
202 if (list.getProperty(
"http://songbirdnest.com/data/1.0#isSubscription") ==
"1") {
203 this._appendMenuItem(aContextMenu,
SBString(
"command.subscription.properties"),
function(
event) {
204 var params =
Cc[
"@songbirdnest.com/moz/xpcom/threadsafe-array;1"].createInstance(
Ci.nsIMutableArray);
205 params.appendElement(list,
false);
207 WindowUtils.openModalDialog(
null,
208 "chrome://songbird/content/xul/subscribe.xul",
210 "chrome,modal=yes,centerscreen",
214 this._appendMenuItem(aContextMenu,
"Update",
function(
event) {
215 var dps =
Cc[
"@songbirdnest.com/Songbird/Library/DynamicPlaylistService;1"]
216 .getService(
Ci.sbIDynamicPlaylistService);
223 sbLibraryServicePane.prototype.fillNewItemMenu =
224 function sbLibraryServicePane_fillNewItemMenu(aNode, aContextMenu, aParentWindow) {
225 var sbSvc =
Cc[
"@mozilla.org/intl/stringbundle;1"].getService(
Ci.nsIStringBundleService);
226 var stringBundle = sbSvc.createBundle(
"chrome://songbird/locale/songbird.properties");
228 function add(
id,
label, accesskey, oncommand, modifiers) {
229 var menuitem = aContextMenu.ownerDocument.createElement(
'menuitem');
230 menuitem.setAttribute(
'id',
id);
231 menuitem.setAttribute(
'class',
'menuitem-iconic');
232 menuitem.setAttribute(
'label', stringBundle.GetStringFromName(
label));
233 menuitem.setAttribute(
'accesskey', stringBundle.GetStringFromName(accesskey));
234 menuitem.setAttribute(
'oncommand', oncommand);
235 if (typeof(modifiers) !=
"undefined") {
236 menuitem.setAttribute(
'modifiers', modifiers);
238 aContextMenu.appendChild(menuitem);
241 add(
'menuitem_file_new',
242 'menu.servicepane.file.new',
243 'menu.servicepane.file.new.accesskey',
244 'doMenu("menuitem_file_new", event)');
246 'menu.servicepane.file.smart',
247 'menu.servicepane.file.smart.accesskey',
248 'doMenu("menuitem_file_smart")',
252 sbLibraryServicePane.prototype.onSelectionChanged =
253 function sbLibraryServicePane_onSelectionChanged(aNode, aContainer, aParentWindow) {
254 this._destroyShortcuts(aContainer, aParentWindow);
256 if (aNode) list = this.getLibraryResourceForNode(aNode);
257 if (list) this._createShortcuts(list, aContainer, aParentWindow);
260 sbLibraryServicePane.prototype._createShortcuts =
261 function sbLibraryServicePane__createShortcuts(aList, aContainer, aWindow) {
262 var shortcuts = aWindow.document.createElement(
"sb-commands-shortcuts");
263 shortcuts.setAttribute(
"id",
"playlist-commands-shortcuts");
264 shortcuts.setAttribute(
"commandtype",
"medialist");
265 shortcuts.setAttribute(
"bind", aList.library.guid +
';' + aList.guid);
266 aContainer.appendChild(shortcuts);
267 this._lastShortcuts = shortcuts;
270 sbLibraryServicePane.prototype._destroyShortcuts =
271 function sbLibraryServicePane__destroyShortcuts(aContainer, aWindow) {
272 if (this._lastShortcuts) {
273 this._lastShortcuts.destroy();
274 aContainer.removeChild(this._lastShortcuts);
275 this._lastShortcuts =
null;
279 sbLibraryServicePane.prototype._canDownloadDrop =
280 function sbLibraryServicePane__canDownloadDrop(aDragSession) {
284 if (!InternalDropHandler.isSupported(aDragSession))
287 var IOS =
Cc[
"@mozilla.org/network/io-service;1"]
288 .getService(
Ci.nsIIOService);
290 function canDownload(aMediaItem) {
291 var contentSpec = aMediaItem.getProperty(SBProperties.contentURL);
292 var contentURL = IOS.newURI(contentSpec,
null,
null);
293 switch(contentURL.scheme) {
305 getInternalTransferDataForFlavour(aDragSession,
307 Ci.sbIMediaItemsTransferContext);
308 var items = context.items;
312 var downloadable =
true;
313 while (items.hasMoreElements() && downloadable) {
314 downloadable = canDownload(items.getNext());
319 if (count == 0) { downloadable =
false; }
326 Components.utils.reportError(
"_getMediaListForDrop should have returned null");
331 sbLibraryServicePane.prototype._getMediaListForDrop =
332 function sbLibraryServicePane__getMediaListForDrop(aNode, aDragSession, aOrientation) {
337 if (!InternalDropHandler.isSupported(aDragSession)&&
338 !ExternalDropHandler.isSupported(aDragSession)) {
346 var targetNode = aNode;
348 if (aOrientation != 0) {
353 var targetResource = this.getLibraryResourceForNode(targetNode);
361 var targetIsLibrary = (targetResource instanceof
Ci.sbILibrary);
374 return targetResource;
380 if (!targetIsLibrary) {
389 getInternalTransferDataForFlavour(aDragSession,
391 Ci.sbIMediaListTransferContext);
392 if (targetResource == draggedList.list.library) {
398 return targetResource;
410 if (targetNode.parentNode.id ==
"SB:Root") {
423 getInternalTransferDataForFlavour(aDragSession,
425 Ci.sbIMediaListTransferContext);
426 var fromResource = draggedList.library;
428 var toResource =
null;
439 var parentNode = targetNode.parentNode;
441 toResource = this.getLibraryResourceForNode(parentNode);
450 var siblingNode = targetNode.previousSibling;
452 toResource = this.getLibraryResourceForNode(siblingNode);
456 var siblingNode = targetNode.nextSibling;
458 toResource = this.getLibraryResourceForNode(siblingNode);
467 toResource = toResource.library;
474 if (toResource == fromResource)
481 if (targetIsLibrary && aOrientation == 1)
495 sbLibraryServicePane.prototype._canDropReorder =
496 function sbLibraryServicePane__canDropReorder(aNode, aDragSession, aOrientation) {
499 if (aOrientation == 0) {
501 if (aNode.dndAcceptIn) {
502 types = aNode.dndAcceptIn.split(
',');
506 if (aNode.dndAcceptNear) {
507 types = aNode.dndAcceptNear.split(
',');
510 for each (let type
in types) {
511 if (aDragSession.isDataFlavorSupported(type)) {
519 sbLibraryServicePane.prototype.canDrop =
520 function sbLibraryServicePane_canDrop(aNode, aDragSession, aOrientation, aWindow) {
522 if (this._canDropReorder(aNode, aDragSession, aOrientation)) {
526 if (aNode.getAttributeNS(
LSP,
"ReadOnly") ==
"true")
531 if (aDragSession.isDataFlavorSupported(TYPE_X_SB_TRANSFER_DISABLE_DOWNLOAD)) {
535 var list = this._getMediaListForDrop(aNode, aDragSession, aOrientation);
539 if (!list.library.userEditable ||
540 !list.library.userEditableContent) {
546 if (!list.userEditable ||
547 !list.userEditableContent) {
555 var customType = list.getProperty(SBProperties.customType);
556 if (customType ==
"download") {
557 return this._canDownloadDrop(aDragSession);
560 return InternalDropHandler.isSupported(aDragSession) ||
561 ExternalDropHandler.isSupported(aDragSession);
567 sbLibraryServicePane.prototype.onDrop =
568 function sbLibraryServicePane_onDrop(aNode, aDragSession, aOrientation, aWindow) {
570 let type = this._canDropReorder(aNode, aDragSession, aOrientation);
576 let transferable =
Cc[
"@mozilla.org/widget/transferable;1"]
577 .createInstance(
Ci.nsITransferable);
579 transferable.addDataFlavor(type);
581 aDragSession.getData(transferable, 0);
584 transferable.getTransferData(type, data, {});
586 data = data.value.QueryInterface(
Ci.nsISupportsString).data;
589 let droppedNode = this._servicePane.getNode(data);
592 if (!droppedNode || aNode == droppedNode) {
596 if (aOrientation == 0) {
598 aNode.appendChild(droppedNode);
599 }
else if (aOrientation > 0) {
601 aNode.parentNode.insertBefore(droppedNode, aNode.nextSibling);
604 aNode.parentNode.insertBefore(droppedNode, aNode);
607 var medialist = this.getLibraryResourceForNode(aNode);
609 this._saveListsOrder(medialist.library, aNode.parentNode);
614 if (aNode.getAttributeNS(
LSP,
"ReadOnly") ==
"true")
618 var targetList = this._getMediaListForDrop(aNode, aDragSession, aOrientation);
627 var isLastSibling = (aNode.nextSibling ==
null);
629 var dropHandlerListener = {
631 onDropComplete:
function(aTargetList,
634 aInsertedInMediaList,
635 aOtherDropsHandled) {
639 onFirstMediaItem:
function(aTargetList, aFirstMediaItem) {},
640 onCopyMediaList:
function(aSourceList, aNewList) {
643 this.libSPS._servicePane.getNode(this.libSPS._itemURN(aNewList));
645 switch (aOrientation) {
647 aNode.parentNode.insertBefore(newnode, aNode);
651 aNode.parentNode.insertBefore(newnode, aNode.nextSibling);
659 if (InternalDropHandler.isSupported(aDragSession)) {
661 InternalDropHandler.dropOnList(aWindow,
665 dropHandlerListener);
667 }
else if (ExternalDropHandler.isSupported(aDragSession)) {
670 ExternalDropHandler.dropOnList(aWindow,
674 dropHandlerListener);
678 sbLibraryServicePane.prototype._saveListsOrder =
679 function sbLibraryServicePane__saveListsOrder(library, nodesParent) {
681 var children = nodesParent.childNodes;
682 while (children.hasMoreElements()) {
683 var child = children.getNext();
684 var resource = this.getLibraryResourceForNode(child);
685 if (resource instanceof Components.interfaces.sbIMediaList) {
688 str += resource.guid;
691 var appPrefs =
Cc[
"@mozilla.org/fuel/application;1"]
692 .getService(
Ci.fuelIApplication).prefs;
693 appPrefs.setValue(
"songbird.library_listorder." + library.guid, str);
696 sbLibraryServicePane.prototype._nodeIsLibrary =
697 function sbLibraryServicePane__nodeIsLibrary(aNode) {
698 return aNode.getAttributeNS(
LSP,
"LibraryGUID") ==
699 aNode.getAttributeNS(
LSP,
"ListGUID");
701 sbLibraryServicePane.prototype.onDragGesture =
702 function sbLibraryServicePane_onDragGesture(aNode, aDataTransfer) {
703 if (this._nodeIsLibrary(aNode)) {
709 var list = this._getItemForURN(aNode.id);
711 source: list.library,
718 var dnd = Components.classes[
'@songbirdnest.com/Songbird/DndSourceTracker;1']
719 .getService(Components.interfaces.sbIDndSourceTracker);
721 var
handle = dnd.registerSource(context);
733 sbLibraryServicePane.prototype.onBeforeRename =
734 function sbLibraryServicePane_onBeforeRename(aNode) {
740 sbLibraryServicePane.prototype.onRename =
741 function sbLibraryServicePane_onRename(aNode, aNewName) {
743 if (aNode && aNewName) {
744 var libraryResource = this.getLibraryResourceForNode(aNode);
745 libraryResource.name = aNewName;
746 aNode.name = aNewName;
763 sbLibraryServicePane.prototype.suggestLibraryForNewList =
764 function sbLibraryServicePane_suggestLibraryForNewList(aMediaListType, aNode) {
768 if (!aMediaListType) {
769 throw Components.results.NS_ERROR_INVALID_ARG;
774 throw Components.results.NS_ERROR_NOT_INITIALIZED;
781 function checkNode(aNode, aLibServicePane) {
784 if (aNode.contractid ==
CONTRACTID && !aNode.hidden) {
788 var mediaItem = aLibServicePane._getItemForURN(aNode.id);
789 if (mediaItem && mediaItem instanceof
Ci.sbIMediaList &&
790 aLibServicePane._doesLibrarySupportListType(mediaItem.library, aMediaListType))
792 return mediaItem.library;
797 var library = aLibServicePane._getLibraryForURN(aNode.id);
798 if (library && library instanceof
Ci.sbILibrary &&
799 aLibServicePane._doesLibrarySupportListType(library, aMediaListType))
809 var lib = checkNode(aNode,
this);
814 for (var child = aNode.firstChild; child; child = child.nextSibling) {
815 lib = checkNode(child,
this);
822 aNode = aNode.parentNode;
823 while (aNode && aNode != this._servicePane.root) {
825 lib = checkNode(aNode,
this);
830 aNode = aNode.parentNode;
849 sbLibraryServicePane.prototype.suggestNameForNewPlaylist =
850 function sbLibraryServicePane_suggestNameForNewPlaylist(aLibrary) {
854 var length = name.length;
856 if(aLibrary instanceof
Ci.sbILibrary) {
859 let mediaLists = aLibrary.getItemsByProperty(SBProperties.isList,
"1");
860 for (let
i = 0;
i < mediaLists.length; ++
i) {
861 let mediaListName = mediaLists.queryElementAt(
i,
Ci.sbIMediaList).name;
862 if (mediaListName && mediaListName.substr(0, length) ==
name) {
863 if (mediaListName.length == length) {
866 else if (mediaListName.length > length + 1) {
867 listIDs.push(parseInt(mediaListName.substr(length + 1)));
875 if (listIDs.indexOf(
id) == -1)
888 sbLibraryServicePane.prototype.createNodeForLibrary =
889 function sbLibraryServicePane_createNodeForLibrary(aLibrary) {
890 if(aLibrary instanceof
Ci.sbILibrary) {
891 return this._libraryAdded(aLibrary);
902 sbLibraryServicePane.prototype._getURNForLibraryResource =
903 function sbLibraryServicePane_getURNForLibraryResource(aResource) {
908 throw Components.results.NS_ERROR_NOT_INITIALIZED;
912 if (aResource instanceof
Ci.sbILibrary) {
913 return this._libraryURN(aResource);
916 }
else if (aResource instanceof
Ci.sbIMediaItem) {
918 var outerListGuid = aResource.getProperty(SBProperties.outerGUID);
920 var library = aResource.library;
921 var outerList = library.getMediaItem(outerListGuid);
923 aResource = outerList;
927 return this._itemURN(aResource);
932 throw Components.results.NS_ERROR_INVALID_ARG;
946 sbLibraryServicePane.prototype.getNodeForLibraryResource =
947 function sbLibraryServicePane_getNodeForLibraryResource(aResource, aType) {
950 var urn = this._getURNForLibraryResource(aResource);
952 if (aResource instanceof
Ci.sbILibrary) {
955 var types = aType ? [aType] : [
"audio",
"video",
"podcast"];
956 for each (let type
in types) {
957 let constrainedURN = urn +
":constraint(" + type +
")";
958 let
node = this._servicePane.getNode(constrainedURN);
959 if (node && !node.hidden) {
967 return this._servicePane.getNode(urn);
979 sbLibraryServicePane.prototype.getNodesForLibraryResource =
980 function sbLibraryServicePane_getNodesForLibraryResource(aResource) {
982 let urn = this._getURNForLibraryResource(aResource);
983 let node = this._servicePane.getNode(urn);
986 if (aResource instanceof
Ci.sbILibrary) {
987 for each (let type
in [
"audio",
"video",
"podcast"]) {
988 let constrainedURN = urn +
":constraint(" + type +
")";
989 node = this._servicePane.getNode(constrainedURN);
995 return ArrayConverter.nsIArray(nodeList);
1004 sbLibraryServicePane.prototype.getNodeFromMediaListView =
1005 function sbLibraryServicePane_getNodeFromMediaListView(aMediaListView) {
1009 var urn = this._getURNForLibraryResource(aMediaListView.mediaList);
1011 var values = this._getConstraintsValueArrayFromMediaListView(aMediaListView);
1012 for (let
i = 0;
i < values.length; ++
i) {
1013 urn +=
":constraint(" + values[
i] +
")";
1016 return this._servicePane.getNode(urn);
1028 sbLibraryServicePane.prototype.getNodeContentTypeFromMediaListView =
1029 function sbLibraryServicePane_getNodeContentTypeFromMediaListView(
1031 var values = this._getConstraintsValueArrayFromMediaListView(aMediaListView);
1033 const K_TYPES = [
"audio",
"video",
"podcast"];
1035 for (let
i = 0;
i < values.length; ++
i) {
1036 if (K_TYPES.indexOf(values[
i]) > -1)
1051 sbLibraryServicePane.prototype.getLibraryResourceForNode =
1052 function sbLibraryServicePane_getLibraryResourceForNode(aNode) {
1056 if (!(aNode instanceof
Ci.sbIServicePaneNode)) {
1057 throw Components.results.NS_ERROR_INVALID_ARG;
1061 throw Components.results.NS_ERROR_NOT_INITIALIZED;
1071 var resource = this._getItemForURN(aNode.id);
1073 resource = this._getLibraryForURN(aNode.id);
1085 sbLibraryServicePane.prototype.setNodeReadOnly =
1086 function sbLibraryServicePane_setNodeReadOnly(aNode, aReadOnly) {
1088 aNode.editable =
false;
1089 aNode.setAttributeNS(
LSP,
"ReadOnly",
"true");
1091 aNode.editable =
true;
1092 aNode.setAttributeNS(
LSP,
"ReadOnly",
"false");
1101 sbLibraryServicePane.prototype._getConstraintsValueArrayFromMediaListView =
1102 function sbLibraryServicePane__getConstraintsValueArrayFromMediaListView(
1106 if ((aMediaListView instanceof
Ci.sbIFilterableMediaListView) &&
1107 aMediaListView.filterConstraint)
1111 var standardConstraintProperties = {};
1112 const standardConstraint =
LibraryUtils.standardFilterConstraint;
1113 for (let
group in ArrayConverter.JSEnum(standardConstraint.groups)) {
1114 group.QueryInterface(
Ci.sbILibraryConstraintGroup);
1115 for (let prop in ArrayConverter.JSEnum(
group.properties)) {
1116 standardConstraintProperties[prop] =
true;
1120 for (let
group in ArrayConverter.JSEnum(aMediaListView.filterConstraint.groups)) {
1121 group.QueryInterface(
Ci.sbILibraryConstraintGroup);
1122 for (let prop in ArrayConverter.JSEnum(
group.properties)) {
1123 if (prop in standardConstraintProperties) {
1126 for (let
value in ArrayConverter.JSEnum(
group.getValues(prop))) {
1140 sbLibraryServicePane.prototype._doesDeviceSupportPlaylist =
1141 function sbLibraryServicePane__doesDeviceSupportPlaylist(aDevice) {
1145 var capabilities = aDevice.capabilities;
1146 var sbIDC =
Ci.sbIDeviceCapabilities;
1148 if (capabilities.supportsContent(sbIDC.FUNCTION_DEVICE,
1149 sbIDC.CONTENT_PLAYLIST) ||
1150 capabilities.supportsContent(sbIDC.FUNCTION_AUDIO_PLAYBACK,
1151 sbIDC.CONTENT_PLAYLIST)) {
1165 sbLibraryServicePane.prototype._doesLibrarySupportListType =
1166 function sbLibraryServicePane__doesLibrarySupportListType(aLibrary, aListType) {
1173 device = aLibrary.device;
1179 if (device && !this._doesDeviceSupportPlaylist(device)) {
1188 var transferPolicy = aLibrary.getProperty(SBProperties.transferPolicy);
1189 if (transferPolicy && transferPolicy.match(/readOnlyMediaLists/)) {
1199 var types = aLibrary.mediaListTypes;
1200 while (types.hasMore()) {
1201 if(aListType == types.getNext()) {
1212 sbLibraryServicePane.prototype._addAllLibraries =
1213 function sbLibraryServicePane__addAllLibraries() {
1216 while (libraries.hasMoreElements()) {
1217 var library = libraries.getNext();
1218 this._libraryAdded(library);
1225 sbLibraryServicePane.prototype._processListsInLibrary =
1226 function sbLibraryServicePane__processListsInLibrary(aLibrary) {
1232 onEnumerationBegin:
function() { },
1233 onEnumerationEnd:
function() { },
1234 onEnumeratedItem:
function(list, item) {
1235 this.items.push(item);
1240 aLibrary.enumerateItemsByProperty(SBProperties.isList,
"1",
1244 var remaining = listener.items.slice(0);
1249 var appPrefs =
Cc[
"@mozilla.org/fuel/application;1"]
1250 .getService(
Ci.fuelIApplication).prefs;
1251 var saved = appPrefs.getValue(
"songbird.library_listorder." + aLibrary.guid,
"");
1252 var savedArray = saved.split(
",");
1253 for each (var listguid
in savedArray) {
1254 for (var
i in remaining) {
1255 if (remaining[
i].guid == listguid) {
1256 this._ensureMediaListNodeExists(remaining[
i],
true);
1257 remaining.slice(
i, 1);
1265 for (var
i = 0;
i < remaining.length;
i++) {
1266 this._ensureMediaListNodeExists(remaining[
i],
false);
1274 sbLibraryServicePane.prototype._libraryAdded =
1275 function sbLibraryServicePane__libraryAdded(aLibrary) {
1277 var node = this._ensureLibraryNodeExists(aLibrary);
1280 var
filter = SBProperties.createArray([[SBProperties.hidden,
null],
1281 [SBProperties.mediaListName,
null]]);
1282 aLibrary.addListener(
this,
1284 Ci.sbIMediaList.LISTENER_FLAGS_ALL,
1286 this._libraries.push(aLibrary);
1288 this._processListsInLibrary(aLibrary);
1299 sbLibraryServicePane.prototype._libraryRemoved =
1300 function sbLibraryServicePane__libraryRemoved(aLibrary) {
1304 var libraryItemNodeList = this._servicePane.getNodesByAttributeNS
1310 var libraryItemNodeEnum = libraryItemNodeList.enumerate();
1311 while (libraryItemNodeEnum.hasMoreElements()) {
1313 var libraryItemNode =
1314 libraryItemNodeEnum.getNext().QueryInterface(
Ci.sbIServicePaneNode);
1315 libraryItemNode.hidden =
true;
1318 aLibrary.removeListener(
this);
1319 this._libraries.splice(this._libraries.indexOf(aLibrary), 1);
1322 sbLibraryServicePane.prototype._refreshLibraryNodes =
1323 function sbLibraryServicePane__refreshLibraryNodes(aLibrary) {
1324 var
id = this._libraryURN(aLibrary);
1325 var node = this._servicePane.getNode(
id);
1326 this._scanForRemovedItems(aLibrary);
1327 this._ensureLibraryNodeExists(aLibrary);
1328 this._processListsInLibrary(aLibrary);
1334 sbLibraryServicePane.prototype._playlistAdded =
1335 function sbLibraryServicePane__playlistAdded(aMediaList) {
1337 this._ensureMediaListNodeExists(aMediaList);
1345 sbLibraryServicePane.prototype._playlistRemoved =
1346 function sbLibraryServicePane__playlistRemoved(aMediaList) {
1349 var
id = this._itemURN(aMediaList);
1350 var node = this._servicePane.getNode(
id);
1352 node.parentNode.removeChild(node);
1361 sbLibraryServicePane.prototype._mediaListUpdated =
1362 function sbLibraryServicePane__mediaListUpdated(aMediaList) {
1364 if (aMediaList instanceof
Ci.sbILibrary) {
1365 this._ensureLibraryNodeExists(aMediaList);
1366 }
else if (aMediaList instanceof
Ci.sbIMediaList) {
1367 this._ensureMediaListNodeExists(aMediaList);
1375 sbLibraryServicePane.prototype._itemURN =
1376 function sbLibraryServicePane__itemURN(aMediaItem) {
1377 return URN_PREFIX_ITEM + aMediaItem.guid;
1384 sbLibraryServicePane.prototype._libraryURN =
1385 function sbLibraryServicePane__libraryURN(aLibrary) {
1386 return URN_PREFIX_LIBRARY + aLibrary.guid;
1393 sbLibraryServicePane.prototype._getItemGUIDForURN =
1394 function sbLibraryServicePane__getItemGUIDForURN(aID) {
1396 var index = aID.indexOf(URN_PREFIX_ITEM);
1398 return aID.slice(URN_PREFIX_ITEM.length);
1407 sbLibraryServicePane.prototype._getLibraryGUIDForURN =
1408 function sbLibraryServicePane__getLibraryGUIDForURN(aID) {
1410 if (aID.substring(0, URN_PREFIX_LIBRARY.length) != URN_PREFIX_LIBRARY) {
1413 var
id = aID.slice(URN_PREFIX_LIBRARY.length);
1414 id =
id.replace(/:constraint\(.*?\)/g,
'');
1423 sbLibraryServicePane.prototype._getItemForURN =
1424 function sbLibraryServicePane__getItemForURN(aID) {
1426 var guid = this._getItemGUIDForURN(aID);
1428 var node = this._servicePane.getNode(aID);
1429 var libraryGUID = node.getAttributeNS(
LSP,
"LibraryGUID");
1433 return library.getMediaItem(guid);
1435 LOG(
"sbLibraryServicePane__getItemForURN: error trying to get medialist " +
1436 guid +
" from library " + libraryGUID);
1442 LOG(
"sbLibraryServicePane__getItemForURN: could not find a mediaItem " +
1443 "for URN " + aID +
". The service pane must be out of sync with " +
1454 sbLibraryServicePane.prototype._getLibraryForURN =
1455 function sbLibraryServicePane__getLibraryForURN(aID) {
1457 var guid = this._getLibraryGUIDForURN(aID);
1463 LOG(
"sbLibraryServicePane__getLibraryForURN: error trying to get " +
1476 sbLibraryServicePane.prototype._ensureLibraryNodeExists =
1477 function sbLibraryServicePane__ensureLibraryNodeExists(aLibrary) {
1489 function makeNodeFromLibrary(aLibrary, aConstraintType, aParentNode) {
1490 var
id =
self._libraryURN(aLibrary);
1491 if (aConstraintType) {
1493 id +=
":constraint(" + aConstraintType +
")";
1495 var node =
self._servicePane.getNode(
id);
1498 node =
self._servicePane.createNode();
1501 node.editable =
false;
1504 self._addClassNames(node,
1506 "libraryguid-" + aLibrary.guid,
1510 node.setAttributeNS(
LSP,
"ListType", aLibrary.type)
1512 node.setAttributeNS(
LSP,
"LibraryGUID", aLibrary.guid);
1514 node.setAttributeNS(
LSP,
"ListGUID", aLibrary.guid);
1516 node.setAttributeNS(
LSP,
"ListCustomType", customType);
1518 node.setAttributeNS(
LSP,
"LibraryCustomType", customType);
1520 if (aConstraintType) {
1521 self._addClassNames(node, [aConstraintType]);
1522 var builder =
Cc[
"@songbirdnest.com/Songbird/Library/ConstraintBuilder;1"]
1523 .createInstance(
Ci.sbILibraryConstraintBuilder);
1524 builder.includeConstraint(
LibraryUtils.standardFilterConstraint);
1525 builder.intersect();
1526 builder.include(SBProperties.contentType, aConstraintType);
1527 node.setAttributeNS(
SP,
1528 "mediaListViewConstraints",
1532 var customType = aLibrary.getProperty(SBProperties.customType);
1536 let name = (aConstraintType ?
'&servicesource.library.' + aConstraintType :
1538 if (node.name != name) {
1541 var
hidden = (aLibrary.getProperty(SBProperties.hidden) ==
"1");
1544 if (aParentNode && !node.parentNode) {
1546 aParentNode.insertBefore(node, aParentNode.firstChild);
1551 var customType = aLibrary.getProperty(SBProperties.customType);
1553 if (customType ==
'web') {
1556 let node = makeNodeFromLibrary(aLibrary,
null,
null);
1559 node.setAttributeNS(
SP,
'Weight', 5);
1562 if (!node.parentNode)
1563 this._servicePane.root.appendChild(node);
1569 var
id =
self._libraryURN(aLibrary);
1570 var parentNode =
self._servicePane.getNode(
id);
1573 parentNode = this._servicePane.createNode();
1575 parentNode.editable =
false;
1576 parentNode.setAttributeNS(
SP,
'Weight', -4);
1585 const K_PARENT_PROPS = [
"folder",
"library-container"];
1587 self._addClassNames(parentNode, K_PARENT_PROPS);
1591 parentNode.hidden =
true;
1597 if (parentNode.name != aLibrary.name) {
1598 parentNode.name = aLibrary.name;
1602 for each (let type
in [
"video",
"audio"]) {
1603 let node = makeNodeFromLibrary(aLibrary, type, parentNode);
1607 this._ensurePlaylistFolderExists();
1608 this._ensurePodcastFolderExists();
1611 var fnode = this._servicePane.getNode(
'SB:iTunes');
1613 fnode.hidden =
false;
1616 for each (let type
in [
"video",
"audio"]) {
1617 let node = makeNodeFromLibrary(aLibrary, type, parentNode);
1623 if (node.getAttributeNS(
SP,
'dndCustomAccept') !=
'true')
1624 node.dndAcceptIn =
'text/x-sb-playlist-'+aLibrary.guid;
1628 if (!parentNode.parentNode) {
1630 this._servicePane.root.appendChild(parentNode);
1641 sbLibraryServicePane.prototype._ensureMediaListNodeExists =
1642 function sbLibraryServicePane__ensureMediaListNodeExists(aMediaList, aAppend) {
1645 var
id = this._itemURN(aMediaList);
1646 var node = this._servicePane.getNode(
id);
1648 var customType = aMediaList.getProperty(SBProperties.customType);
1649 var libCustomType = aMediaList.library.getProperty(SBProperties.customType);
1654 node = this._servicePane.createNode();
1658 if (customType ==
'download') {
1660 node.editable =
false;
1662 node.setAttributeNS(
SP,
'Weight', 999);
1665 node.editable = aMediaList.userEditable;
1669 if (aMediaList.getProperty(SBProperties.isSubscription) ==
"1") {
1670 this._addClassNames(node, [
"medialist",
"medialisttype-dynamic"]);
1671 node.setAttributeNS(
LSP,
"ListSubscription",
"1");
1673 this._addClassNames(node, [
"medialist medialisttype-" + aMediaList.type]);
1674 node.setAttributeNS(
LSP,
"ListSubscription",
"0");
1677 this._addClassNames(node, [customType]);
1679 node.setAttributeNS(
LSP,
"ListType", aMediaList.type);
1681 node.setAttributeNS(
LSP,
"LibraryGUID", aMediaList.library.guid);
1683 node.setAttributeNS(
LSP,
"ListGUID", aMediaList.guid);
1685 node.setAttributeNS(
LSP,
"LibraryCustomType", libCustomType);
1687 node.setAttributeNS(
LSP,
"ListCustomType", customType);
1690 if (node.getAttributeNS(
SP,
'dndCustomAccept') !=
'true') {
1691 if (aMediaList.library ==
this._libraryManager.mainLibrary) {
1694 if (customType !=
'download') {
1695 node.dndDragTypes =
'text/x-sb-playlist';
1696 node.dndAcceptNear =
'text/x-sb-playlist';
1700 node.dndDragTypes =
'text/x-sb-playlist-'+aMediaList.library.guid;
1701 node.dndAcceptNear =
'text/x-sb-playlist-'+aMediaList.library.guid;
1708 if (node.name != aMediaList.name) {
1709 node.name = aMediaList.name;
1713 var hidden = (aMediaList.getProperty(SBProperties.hidden) ==
"1");
1716 if (!node.parentNode) {
1718 this._insertMediaListNode(node, aMediaList, aAppend);
1728 sbLibraryServicePane.prototype._ensurePlaylistFolderExists =
1729 function sbLibraryServicePane__ensurePlaylistFolderExists() {
1730 let fnode = this._servicePane.getNode(
"SB:Playlists");
1733 fnode = this._servicePane.createNode();
1734 fnode.id =
"SB:Playlists";
1735 fnode.name =
'&servicesource.playlists';
1736 this._addClassNames(fnode, [
"folder", this._makeCSSProperty(fnode.name)]);
1738 fnode.dndAcceptIn =
'text/x-sb-playlist';
1739 fnode.editable =
false;
1740 fnode.setAttributeNS(
SP,
'Weight', 3);
1741 this._servicePane.root.appendChild(fnode);
1751 sbLibraryServicePane.prototype._ensurePodcastFolderExists =
1752 function sbLibraryServicePane__ensurePodcastFolderExists() {
1757 let fnode = this._servicePane.getNode(
"SB:Podcasts");
1760 fnode = this._servicePane.createNode();
1761 fnode.id =
"SB:Podcasts";
1762 fnode.name =
"&servicesource.podcasts";
1763 this._addClassNames(fnode, [
"folder", this._makeCSSProperty(fnode.name)]);
1765 fnode.editable =
false;
1766 fnode.setAttributeNS(
SP,
"Weight", 2);
1767 this._servicePane.root.appendChild(fnode);
1776 sbLibraryServicePane.prototype._ensureiTunesFolderExists =
1777 function sbLibraryServicePane__ensureiTunesFolderExists() {
1778 let fnode = this._servicePane.getNode(
"SB:iTunes");
1781 fnode = this._servicePane.createNode();
1782 fnode.id =
"SB:iTunes";
1783 fnode.name =
'&servicesource.itunes';
1784 this._addClassNames(fnode, [
"folder", this._makeCSSProperty(fnode.name)]);
1786 fnode.editable =
false;
1787 fnode.setAttributeNS(
SP,
'Weight', 3);
1788 this._servicePane.root.appendChild(fnode);
1793 sbLibraryServicePane.prototype._scanForRemovedItems =
1794 function sbLibraryServicePane__scanForRemovedItems(aLibrary) {
1796 var libraryItemNodeList = this._servicePane.getNodesByAttributeNS
1802 var libraryItemNodeEnum = libraryItemNodeList.enumerate();
1803 while (libraryItemNodeEnum.hasMoreElements()) {
1805 var libraryItemNode =
1806 libraryItemNodeEnum.getNext().QueryInterface(
Ci.sbIServicePaneNode);
1809 if (this._nodeIsLibrary(libraryItemNode))
1813 var mediaItem = this._getItemForURN(libraryItemNode.id);
1815 libraryItemNode.parentNode.removeChild(libraryItemNode);
1823 sbLibraryServicePane.prototype._insertMediaListNode =
1824 function sbLibraryServicePane__insertMediaListNode(aNode, aMediaList, aAppend) {
1830 if (aMediaList.library ==
this._libraryManager.mainLibrary)
1833 if (aNode.getAttributeNS(
LSP,
'ListCustomType') ==
'download') {
1835 var libraryNode = this.getNodeForLibraryResource(aMediaList.library);
1839 if (libraryNode.parentNode !=
this._servicePane.root)
1840 libraryNode = libraryNode.parentNode;
1842 libraryNode.appendChild(aNode);
1847 if (aMediaList.getProperty(SBProperties.iTunesGUID) !=
null) {
1848 folder = this._ensureiTunesFolderExists();
1849 }
else if (aMediaList.getProperty(SBProperties.customType) ==
"podcast") {
1850 folder = this._ensurePodcastFolderExists();
1852 folder = this._ensurePlaylistFolderExists();
1856 folder.appendChild(aNode);
1858 this._insertByNodeType(aNode, folder);
1866 var parentLibraryNode = this.getNodeForLibraryResource(aMediaList.library);
1870 if (parentLibraryNode && parentLibraryNode.parentNode !=
this._servicePane.root)
1871 parentLibraryNode = parentLibraryNode.parentNode;
1874 if (parentLibraryNode) {
1876 parentLibraryNode.appendChild(aNode);
1878 this._insertByNodeType(aNode, parentLibraryNode);
1880 LOG(
"sbLibraryServicePane__insertMediaListNode: could not add media list to parent library");
1881 this._servicePane.root.appendChild(aNode);
1893 sbLibraryServicePane.prototype._insertByNodeType =
1894 function sbLibraryServicePane__insertByNodeType(aNode, aParent) {
1897 function getNodeType(aNode) {
1898 let type = aNode.getAttributeNS(
LSP,
"ListType");
1899 if (type ==
"simple" && aNode.getAttributeNS(
LSP,
"ListSubscription") ==
"1")
1900 return "subscription";
1908 let nodeTypes = {
"smart": 1,
"simple": 2,
"subscription": 3 };
1909 let nodePriority = nodeTypes[getNodeType(aNode)];
1910 let insertAfter =
null;
1911 let insertAfterPriority = 0;
1912 for (let child = aParent.lastChild; child; child = child.previousSibling) {
1913 if (child.hidden || child.contractid !=
CONTRACTID)
1916 let childNodePriority = nodeTypes[getNodeType(child)];
1917 if (childNodePriority > insertAfterPriority &&
1918 childNodePriority <= nodePriority) {
1919 insertAfter = child;
1920 insertAfterPriority = childNodePriority;
1923 if (insertAfterPriority == nodePriority)
1929 aParent.insertBefore(aNode, insertAfter.nextSibling);
1931 aParent.insertBefore(aNode, aParent.firstChild);
1934 for (let parent = aParent; parent; parent = parent.parentNode)
1936 parent.isOpen =
true;
1939 sbLibraryServicePane.prototype._appendMenuItem =
1940 function sbLibraryServicePane__appendMenuItem(aContextMenu, aLabel, aCallback) {
1941 var item = aContextMenu.ownerDocument.createElement(
"menuitem");
1942 item.setAttribute(
"label", aLabel);
1943 item.addEventListener(
"command", aCallback,
false);
1944 aContextMenu.appendChild(item);
1947 sbLibraryServicePane.prototype._appendCommands =
1948 function sbLibraryServicePane__appendCommands(aContextMenu, aList, aParentWindow) {
1949 if (this._lastMenuitems && this._lastMenuitems.destroy) {
1950 var pnode = this._lastMenuitems.parentNode;
1951 this._lastMenuitems.destroy();
1952 this._lastMenuitems =
null;
1954 var itemBuilder = aContextMenu.ownerDocument.createElement(
"sb-commands-menuitems");
1955 itemBuilder.setAttribute(
"id",
"playlist-commands");
1956 itemBuilder.setAttribute(
"commandtype",
"medialist");
1957 itemBuilder.setAttribute(
"bind", aList.library.guid +
';' + aList.guid);
1958 aContextMenu.appendChild(itemBuilder);
1959 this._lastMenuitems = itemBuilder;
1966 sbLibraryServicePane.prototype._removeListNodesForLibrary =
1967 function sbLibraryServicePane__removeListNodesForLibrary(aStartNode, aLibraryGUID) {
1969 var node = aStartNode.firstChild;
1973 this._removeListNodesForLibrary(node, aLibraryGUID);
1975 var nextSibling = node.nextSibling;
1977 if (this._getItemGUIDForURN(node.id)) {
1978 var nodeLibraryGUID = node.getAttributeNS(
LSP,
"LibraryGUID");
1979 if (nodeLibraryGUID == aLibraryGUID) {
1980 node.parentNode.removeChild(node);
1988 sbLibraryServicePane.prototype._addClassNames =
1989 function sbLibraryServicePane__addClassNames(aNode, aList) {
1992 for each (let name
in className.split(
" "))
1993 existing[name] =
true;
1995 for each (let name
in aList)
1996 if (!existing.hasOwnProperty(name))
1997 className += (className ?
" " :
"") +
name;
2006 sbLibraryServicePane.prototype._makeCSSProperty =
2007 function sbLibraryServicePane__makeCSSProperty(aString) {
2008 if ( aString[0] ==
"&" ) {
2009 aString = aString.substr(1, aString.length);
2010 aString = aString.replace(/\./g,
"-");
2019 sbLibraryServicePane.prototype.onLibraryRegistered =
2020 function sbLibraryServicePane_onLibraryRegistered(aLibrary) {
2022 this._libraryAdded(aLibrary);
2024 sbLibraryServicePane.prototype.onLibraryUnregistered =
2025 function sbLibraryServicePane_onLibraryUnregistered(aLibrary) {
2027 this._libraryRemoved(aLibrary);
2034 sbLibraryServicePane.prototype.onItemAdded =
2035 function sbLibraryServicePane_onItemAdded(aMediaList, aMediaItem, aIndex) {
2037 if (this._batch[aMediaList.guid] &&
this._batch[aMediaList.guid].isActive()) {
2040 this._refreshPending =
true;
2044 var isList = aMediaItem instanceof
Ci.sbIMediaList;
2046 this._playlistAdded(aMediaItem);
2051 sbLibraryServicePane.prototype.onBeforeItemRemoved =
2052 function sbLibraryServicePane_onBeforeItemRemoved(aMediaList, aMediaItem, aIndex) {
2055 sbLibraryServicePane.prototype.onAfterItemRemoved =
2056 function sbLibraryServicePane_onAfterItemRemoved(aMediaList, aMediaItem, aIndex) {
2058 if (this._batch[aMediaList.guid] &&
this._batch[aMediaList.guid].isActive()) {
2061 this._refreshPending =
true;
2065 var isList = aMediaItem instanceof
Ci.sbIMediaList;
2067 this._playlistRemoved(aMediaItem);
2072 sbLibraryServicePane.prototype.onItemUpdated =
2073 function sbLibraryServicePane_onItemUpdated(aMediaList,
2076 if (this._batch[aMediaList.guid] &&
this._batch[aMediaList.guid].isActive()) {
2079 this._refreshPending =
true;
2083 var isList = aMediaItem instanceof
Ci.sbIMediaList;
2085 this._mediaListUpdated(aMediaItem);
2090 sbLibraryServicePane.prototype.onItemMoved =
2091 function sbLibraryServicePane_onItemMoved(aMediaList,
2096 sbLibraryServicePane.prototype.onBeforeListCleared =
2097 function sbLibraryServicePane_onBeforeListCleared(aMediaList,
2101 sbLibraryServicePane.prototype.onListCleared =
2102 function sbLibraryServicePane_onListCleared(aMediaList,
2104 if (this._batch[aMediaList.guid] &&
this._batch[aMediaList.guid].isActive()) {
2107 this._refreshPending =
true;
2111 if (aMediaList instanceof
Ci.sbILibrary) {
2112 var libraryGUID = aMediaList.guid;
2114 var node = this._servicePane.root;
2115 this._removeListNodesForLibrary(node, libraryGUID);
2120 sbLibraryServicePane.prototype.onBatchBegin =
2121 function sbLibraryServicePane_onBatchBegin(aMediaList) {
2123 if (!this._batch[aMediaList.guid]) {
2124 this._batch[aMediaList.guid] =
new LibraryUtils.BatchHelper();
2126 this._batch[aMediaList.guid].begin();
2128 sbLibraryServicePane.prototype.onBatchEnd =
2129 function sbLibraryServicePane_onBatchEnd(aMediaList) {
2131 if (!this._batch[aMediaList.guid]) {
2135 this._batch[aMediaList.guid].end();
2136 if (!this._batch[aMediaList.guid].isActive() && this._refreshPending) {
2137 this._refreshLibraryNodes(aMediaList);
2138 this._refreshPending =
false;
2143 sbLibraryServicePane.prototype._initLibraryManager =
2144 function sbLibraryServicePane__initLibraryManager() {
2147 .getService(
Ci.sbILibraryManager);
2154 var obs =
Cc[
"@mozilla.org/observer-service;1"].
2156 obs.addObserver(
this,
"songbird-library-manager-before-shutdown",
false);
2158 this._addAllLibraries();
2165 sbLibraryServicePane.prototype.observe =
2166 function sbLibraryServicePane_observe(subject,
topic, data) {
2168 var obs =
Cc[
"@mozilla.org/observer-service;1"]
2169 .getService(
Ci.nsIObserverService);
2171 if (
topic ==
"songbird-library-manager-before-shutdown") {
2172 obs.removeObserver(
this,
"songbird-library-manager-before-shutdown");
2175 .getService(
Ci.sbILibraryManager);
2176 libraryManager.removeListener(
this);
2177 for each (let lib
in this._libraries) {
2178 lib.removeListener(
this);
2187 var
NSGetModule = XPCOMUtils.generateNSGetModule([sbLibraryServicePane]);
function SBFormattedString(aKey, aParams, aDefault, aStringBundle)
function logcall(parentArgs)
sbOSDControlService prototype className
sbOSDControlService prototype QueryInterface
const TYPE_X_SB_TRANSFER_MEDIA_ITEMS
ui plugin add("draggable","cursor",{start:function(e, ui){var t=$('body');if(t.css("cursor")) ui.options._cursor=t.css("cursor");t.css("cursor", ui.options.cursor);}, stop:function(e, ui){if(ui.options._cursor)$('body').css("cursor", ui.options._cursor);}})
function handle(request, response)
getService(Ci.sbIFaceplateManager)
function SBString(aKey, aDefault, aStringBundle)
const TYPE_X_SB_TRANSFER_MEDIA_LIST
this _contentSandbox label
sbAutoDownloader prototype _libraryManager
Javascript wrappers for common library tasks.
_getSelectedPageStyle s i
Array filter(tab.attributes, function(aAttr){return(_this.xulAttributes.indexOf(aAttr.name) >-1);}).forEach(tab.removeAttribute