25 const Cc = Components.classes;
26 const Ci = Components.interfaces;
27 const Cu = Components.utils;
30 Cu.import(
"resource://gre/modules/XPCOMUtils.jsm");
31 Cu.import(
"resource://app/jsmodules/ArrayConverter.jsm");
32 Cu.import(
"resource://app/jsmodules/RDFHelper.jsm");
33 Cu.import(
"resource://app/jsmodules/StringUtils.jsm");
42 requiredProperties: [
"contentUrl",
45 "suggestedContentGroups",
48 optionalProperties: [
"showOnInstall" ],
52 for (var
i = 0;
i < this.requiredProperties.length;
i++) {
53 var
property = this.requiredProperties[
i];
54 if (! (typeof(
this[property]) ==
'string'
55 &&
this[property].length > 0))
57 errorList.push(
"Invalid description. '" + property +
"' is a required property.");
61 this.defaultWidth = parseInt(this.defaultWidth);
62 this.defaultHeight = parseInt(this.defaultHeight);
63 this.showOnInstall = this.showOnInstall ==
"true";
65 errorList.push(e.toString());
80 this._manager =
Cc[
"@songbirdnest.com/Songbird/DisplayPane/Manager;1"]
81 .getService(
Ci.sbIDisplayPaneManager);
89 loadPanes:
function loadPanes() {
91 var addons =
RDFHelper.help(
"rdf:addon-metadata",
"urn:songbird:addon:root",
RDFHelper.DEFAULT_RDF_NAMESPACES);
93 for (var
i = 0;
i < addons.length;
i++) {
96 if (addons[
i].displayPanes) {
99 "DisplayPanes: Use of the <displayPanes> element in install.rdf " +
100 "is deprecated. Remove that element and leave the contents as-is."
102 panes = addons[
i].displayPanes[0].displayPane;
105 panes = addons[
i].displayPane;
114 for (var j = 0; j < panes.length; j++) {
115 this._registerDisplayPane(addons[
i], panes[j])
118 this._reportErrors(
"", [
"An error occurred while processing " +
119 "extension " + addons[
i].Value +
". Exception: " + e ]);
127 _registerDisplayPane:
function _registerDisplayPane(addon, pane) {
130 for (property in pane) {
132 info[property] = pane[property][0];
134 var errorList = info.verify();
138 if (errorList.length > 0) {
140 "Ignoring display pane addon in the install.rdf of extension " +
141 addon.Value +
" due to these error(s):\n", errorList);
148 var contentTitle =
SBString(
"displaypanes.contenttitle.unnamed");
149 var split = info.contentTitle.split(
"#", 2);
150 if (split.length == 2) {
152 contentTitle = bundle.get(split[1], contentTitle);
154 info.contentTitle = contentTitle;
158 this._manager.registerContent( info.contentUrl,
163 info.suggestedContentGroups,
164 info.showOnInstall );
177 _reportErrors:
function _reportErrors(contextMessage, errorList) {
178 var consoleService =
Cc[
"@mozilla.org/consoleservice;1"]
179 .getService(
Ci.nsIConsoleService);
180 for (var
i = 0;
i < errorList.length;
i++) {
181 consoleService.logStringMessage(
"Display Pane Metadata Reader: "
182 + contextMessage + errorList[
i]);
183 dump(
"DisplayPaneMetadataReader: " + contextMessage + errorList[i] +
"\n");
196 function DisplayPaneManager() {
201 var catMgr =
Cc[
"@mozilla.org/categorymanager;1"]
202 .getService(
Ci.nsICategoryManager);
203 var entries = catMgr.enumerateCategory(
"display-pane-provider");
204 while (entries.hasMoreElements()) {
205 var
entry = entries.getNext().QueryInterface(
Ci.nsISupportsCString).data;
206 this._registerContentFromCategoryEntry(entry, catMgr);
209 this._initialized =
true;
212 DisplayPaneManager.prototype = {
214 classID: Components.ID(
"{6aef120f-d7ad-414d-a93d-3ac945e64301}"),
215 contractID:
"@songbirdnest.com/Songbird/DisplayPane/Manager;1",
219 var consoleService =
Cc[
'@mozilla.org/consoleservice;1']
220 .getService(
Ci.nsIConsoleService);
221 consoleService.logStringMessage(
str);
225 _instantiatorsList: [],
226 _delayedInstantiations: [],
230 _addonMetadataLoaded:
false,
232 _getString:
function(
aName, aDefault) {
233 if (!this._stringbundle) {
234 var src =
"chrome://branding/locale/brand.properties";
235 var stringBundleService =
Cc[
"@mozilla.org/intl/stringbundle;1"]
236 .getService(
Ci.nsIStringBundleService);
237 this._stringbundle = stringBundleService.createBundle(src);
241 return this._stringbundle.GetStringFromName(
aName);
249 _defaultPaneInfo:
null,
251 _cleanupInstantiatorsList:
function DPM_cleanupInstantiatorsList() {
252 for (var
i = this._instantiatorsList.length - 1;
i >= 0; --
i) {
253 if (!(this._instantiatorsList[
i] instanceof
254 Ci.sbIDisplayPaneInstantiator)) {
255 Cu.reportError(
"Warning: found bad instantiator; "+
256 "possibly via removal from DOM");
257 this._instantiatorsList.splice(
i, 1);
262 get defaultPaneInfo() {
263 if (!this._defaultPaneInfo) {
265 contentUrl: this._getString(
"displaypane.default.url",
"chrome://songbird/content/xul/defaultDisplayPane.xul"),
267 contentIcon: this._getString(
"displaypane.default.icon",
"chrome://branding/content/branding.ico"),
268 defaultWidth: this._getString(
"displaypane.default.width",
"150"),
269 defaultHeight: this._getString(
"displaypane.default.height",
"75"),
270 suggestedContentGroups: this._getString(
"displaypane.default.groups",
"")
272 this._defaultPaneInfo = paneInfo;
274 return this._defaultPaneInfo;
281 ensureAddonMetadataLoaded:
function() {
282 if (!this._initialized || this._addonMetadataLoaded) {
285 this._addonMetadataLoaded =
true;
289 metadataReader.loadPanes();
296 makePaneInfo:
function(aContentUrl,
299 aSuggestedContentGroups,
303 paneInfo.contentUrl = aContentUrl;
304 paneInfo.contentTitle = aContentTitle;
305 paneInfo.contentIcon = aContentIcon;
306 paneInfo.suggestedContentGroups = aSuggestedContentGroups;
307 paneInfo.defaultWidth = aDefaultWidth;
308 paneInfo.defaultHeight = aDefaultHeight;
316 getPaneInfo:
function(aContentUrl) {
317 this.ensureAddonMetadataLoaded();
319 for each (var pane
in this._contentList) {
321 if (pane.contentUrl == aContentUrl)
330 getInstantiatorForWindow:
331 function sbDisplayPaneMgr_getInstantiatorForWindow(aWindow) {
332 this._cleanupInstantiatorsList();
333 for each (var instantiator
in this._instantiatorsList) {
334 if (instantiator.contentWindow === aWindow) {
345 this.ensureAddonMetadataLoaded();
346 return ArrayConverter.enumerator(this._contentList);
352 get instantiatorsList() {
353 this._cleanupInstantiatorsList();
354 return ArrayConverter.enumerator(this._instantiatorsList);
360 registerContent:
function(aContentUrl,
365 aSuggestedContentGroups,
370 var info = this.getPaneInfo(aContentUrl);
372 throw Components.results.NS_ERROR_ALREADY_INITIALIZED;
374 info = this.makePaneInfo(aContentUrl,
377 aSuggestedContentGroups,
380 this._contentList.push(info);
381 for each (var
listener in this._listenersList) {
382 listener.onRegisterContent(info);
385 var
SB_NewDataRemote = Components.Constructor(
"@songbirdnest.com/Songbird/DataRemote;1",
389 if (!known.boolValue) {
391 if (!this.tryInstantiation(info)) {
392 this._delayedInstantiations.push(info);
396 known.boolValue =
true;
403 unregisterContent:
function(aContentUrl) {
404 for (var contentIndex = 0; contentIndex < this._contentList.length; contentIndex++) {
405 if (this._contentList[contentIndex].contentUrl != aContentUrl) {
410 for each (var instantiator
in this._instantiatorsList) {
411 if (instantiator.contentUrl == aContentUrl) {
416 for (instantiatorIndex = this._delayedInstantiations.length - 1; instantiatorIndex >= 0; --instantiatorIndex) {
417 if (this._delayedInstantiations[instantiatorIndex].contentUrl == aContentUrl) {
418 this._delayedInstantiations.splice(instantiatorIndex, 1);
422 var [info] = this._contentList.splice(contentIndex, 1);
424 for each (var listener
in this._listenersList) {
425 listener.onUnregisterContent(info);
434 registerInstantiator:
function(aInstantiator) {
435 this.ensureAddonMetadataLoaded();
437 if (this._instantiatorsList.indexOf(aInstantiator) > -1) {
438 Cu.reportError(
"Attempt to re-register instantiator ignored\n" +
439 (
new Error()).stack);
442 this._instantiatorsList.push(aInstantiator);
443 for each (var listener
in this._listenersList) {
444 listener.onRegisterInstantiator(aInstantiator);
446 this.processDelayedInstantiations();
452 unregisterInstantiator:
function(aInstantiator) {
453 var index = this._instantiatorsList.indexOf(aInstantiator);
458 this._instantiatorsList.splice(index, 1);
459 for each (var listener
in this._listenersList) {
460 listener.onUnregisterInstantiator(aInstantiator);
469 getFirstInstantiatorForGroupList:
function(aContentGroupList) {
470 var groups = aContentGroupList.toUpperCase().split(
";");
471 for each (var
group in groups) {
472 for each (var instantiator
in this._instantiatorsList) {
473 if (instantiator.contentGroup.toUpperCase() ==
group) {
481 processDelayedInstantiations:
function() {
483 for each (var info
in this._delayedInstantiations) {
484 if (!this.isValidPane(info) || this.tryInstantiation(info)) {
489 this._delayedInstantiations = table;
492 tryInstantiation:
function(info) {
493 var instantiator = this.getFirstInstantiatorForGroupList(info.suggestedContentGroups);
495 instantiator.loadContent(info);
501 isValidPane:
function(aPane) {
502 this.ensureAddonMetadataLoaded();
503 for each (var pane
in this._contentList) {
504 if (pane == aPane)
return true;
509 showPane:
function(aContentUrl) {
510 for each (var instantiator
in this._instantiatorsList) {
511 if (instantiator.contentUrl == aContentUrl) {
513 instantiator.collapsed =
false;
517 var info = this.getPaneInfo(aContentUrl);
519 if (!this.tryInstantiation(info)) {
520 this._delayedInstantiations.push(info);
523 throw new Error(
"Content URL was not found in list of registered panes");
528 this._listenersList.push(aListener);
531 removeListener:
function(aListener) {
532 var index = this._listenersList.indexOf(aListener);
534 this._listenersList.splice(index, 1);
537 updateContentInfo:
function(aContentUrl, aNewContentTitle, aNewContentIcon) {
538 var info = this.getPaneInfo(aContentUrl);
540 throw Components.results.NS_ERROR_NOT_INITIALIZED;
543 info.contentTitle = aNewContentTitle;
544 info.contentIcon = aNewContentIcon;
547 for each (var instantiator
in this._instantiatorsList) {
548 if (instantiator.contentUrl == aContentUrl) {
549 instantiator.contentTitle = aNewContentTitle;
550 instantiator.contentIcon = aNewContentIcon;
553 for each (var listener
in this._listenersList) {
554 listener.onPaneInfoChanged(info);
558 _registerContentFromCategoryEntry:
function(aEntry, aCatMgr) {
559 var catMgr = aCatMgr ||
Cc[
"@mozilla.org/categorymanager;1"]
560 .getService(
Ci.nsICategoryManager);
561 var contractId = catMgr.getCategoryEntry(
"display-pane-provider", aEntry);
562 var contentInfo =
Cc[contractId]
563 .createInstance(
Ci.sbIDisplayPaneContentInfo);
564 this.registerContent(contentInfo.contentUrl,
565 contentInfo.contentTitle,
566 contentInfo.contentIcon,
567 contentInfo.defaultWidth,
568 contentInfo.defaultHeight,
569 contentInfo.suggestedContentGroups);
576 XPCOMUtils.generateQI([
Ci.sbIDisplayPaneManager])
580 return XPCOMUtils.generateModule([DisplayPaneManager]);
sbDeviceFirmwareAutoCheckForUpdate prototype contractID
sbOSDControlService prototype QueryInterface
sbDeviceFirmwareAutoCheckForUpdate prototype classDescription
function NSGetModule(compMgr, fileSpec)
function SBString(aKey, aDefault, aStringBundle)
function RDFHelper(aRdf, aDatasource, aResource, aNamespaces)
DataRemote prototype constructor
function SBStringBundle(aBundle)
function DisplayPaneMetadataReader()
sbDeviceFirmwareAutoCheckForUpdate prototype classID
_getSelectedPageStyle s i