sbFaceplateManager.js
Go to the documentation of this file.
1 
33 const Cc = Components.classes;
34 const Ci = Components.interfaces;
35 const Cr = Components.results;
36 const Ce = Components.Exception;
37 
38 const URL_BINDING_DEFAULT_PANE = "chrome://songbird/content/bindings/facePlate.xml#default-pane";
39 const URL_BINDING_DASHBOARD_PANE = "chrome://songbird/content/bindings/facePlate.xml#playback-pane";
40 
41 const DATAREMOTE_PLAYBACK = "faceplate.playing";
42 
43 
44 
50 {
51  this.data = array;
52 }
53 ArrayEnumerator.prototype = {
54 
55  index: 0,
56 
57  getNext: function() {
58  return this.data[this.index++];
59  },
60 
65  hasMoreElements: function() {
66  if (this.index < this.data.length)
67  return true;
68  else
69  return false;
70  },
71  hasMore: function () {
72  return this.hasMoreElements();
73  },
74 
75  QueryInterface: function(iid)
76  {
77  if (!iid.equals(Ci.nsISimpleEnumerator) &&
78  !iid.equals(Ci.nsIStringEnumerator) &&
79  !iid.equals(Ci.nsISupports))
80  throw Components.results.NS_ERROR_NO_INTERFACE;
81  return this;
82  }
83 }
84 
85 
86 
87 
88 
89 
96 function FaceplatePane(aID, aName, aBindingURL)
97 {
98  this._id = aID;
99  this._name = aName;
100  this._bindingURL = aBindingURL;
101  this._data = {};
102  this._observers = [];
103 }
104 FaceplatePane.prototype = {
105 
106  _id: null,
107  _name: null,
108  _bindingURL: null,
109 
110  _data: null,
111 
112  _observers: null,
113 
114  get id() { return this._id; },
115  get name() { return this._name; },
116  get bindingURL() { return this._bindingURL; },
117 
122  setData: function FaceplatePane_setData(aKey, aValue) {
123  if (!aKey) {
124  throw Components.results.NS_ERROR_INVALID_ARG;
125  }
126 
127  this._data[aKey] = aValue;
128  this._notify(aKey);
129  },
130 
131  getData: function FaceplatePane_getData(aKey) {
132  return this._data[aKey];
133  },
134 
135  getKeys: function FaceplatePane_getKeys() {
136  // Copy all the data keys into an array, and then return an enumerator
137  return new ArrayEnumerator( [key for (key in this._data)] );
138  },
139 
140  addObserver: function FaceplatePane_addObserver(aObserver) {
141  if (! (aObserver instanceof Ci.nsIObserver)) {
142  throw Components.results.NS_ERROR_INVALID_ARG;
143  }
144  if (this._observers.indexOf(aObserver) == -1) {
145  this._observers.push(aObserver);
146  }
147  },
148 
149  removeObserver: function FaceplatePane_removeObserver(aObserver) {
150  var index = this._observers.indexOf(aObserver);
151  if (index > -1) {
152  this._observers.splice(index,1);
153  }
154  },
155 
156  _notify: function FaceplatePane_notify(topic) {
157  var thisPane = this.QueryInterface(Ci.sbIFaceplatePane);
158  this._observers.forEach( function (observer) {
159  observer.observe(thisPane, topic, null);
160  });
161  },
162 
163  QueryInterface: function(iid)
164  {
165  if (!iid.equals(Components.interfaces.sbIFaceplatePane) &&
166  !iid.equals(Components.interfaces.nsISupports))
167  throw Components.results.NS_ERROR_NO_INTERFACE;
168  return this;
169  }
170 }
171 
172 
173 
174 
175 
176 
182 function FaceplateManager() {
183 
184  var os = Components.classes["@mozilla.org/observer-service;1"]
185  .getService(Components.interfaces.nsIObserverService);
186 
187  // We want to wait till profile-after-change to initialize
188  os.addObserver(this, 'songbird-library-manager-ready', false);
189 
190  // We need to unhook things on shutdown
191  os.addObserver(this, "songbird-library-manager-before-shutdown", false);
192 
193  this._listeners = [];
194  this._panes = {};
195 
196 };
197 FaceplateManager.prototype = {
198  constructor: FaceplateManager,
199 
200  _listeners: null,
201  _paneCount: 0,
202 
203  // Map of pane IDs to sbIFaceplatePanes
204  _panes: null,
205 
206  // Most recently shown pane ID
207  _defaultPaneID: null,
208 
213  _init: function init() {
214 
215  // Come up with some localized names for the default panes.
216  var strings = Cc["@mozilla.org/intl/stringbundle;1"]
217  .getService(Ci.nsIStringBundleService)
218  .createBundle("chrome://songbird/locale/songbird.properties");
219  var getString = function(aStringId, aDefault) {
220  try {
221  return strings.GetStringFromName(aStringId);
222  } catch (e) {
223  return aDefault;
224  }
225  }
226  var introName = getString("faceplate.pane.intro.name", "Intro");
227  var dashboardName = getString("faceplate.pane.dashboard.name", "Dashboard");
228 
229  // Create the panes
230  this.createPane("songbird-intro", introName, URL_BINDING_DEFAULT_PANE);
231  this.createPane("songbird-dashboard", dashboardName, URL_BINDING_DASHBOARD_PANE);
232 
233  // Set up a dataremote to show the dashboard on first playback.
234  var createDataRemote = new Components.Constructor(
235  "@songbirdnest.com/Songbird/DataRemote;1",
236  Components.interfaces.sbIDataRemote, "init");
237 
238  this._playbackDataRemote = createDataRemote(DATAREMOTE_PLAYBACK, null);
239  this._playbackDataRemote.bindObserver(this, true);
240  },
241 
245  _deinit: function deinit() {
246  this._listeners = null;
247  this._panes = null;
248  if (this._playbackDataRemote) {
249  this._playbackDataRemote.unbind();
250  this._playbackDataRemote = null;
251  }
252  },
253 
254 
259  get paneCount() {
260  return this._paneCount;
261  },
262 
263  createPane: function FaceplateManager_createPane(aID, aName, aBindingURL) {
264  if (!aID || !aName || !aBindingURL) {
265  throw Components.results.NS_ERROR_INVALID_ARG;
266  }
267  if (this._panes[aID]) {
268  throw Components.results.NS_ERROR_FAILURE;
269  }
270 
271  var pane = new FaceplatePane(aID, aName, aBindingURL);
272  this._panes[aID] = pane;
273  this._paneCount++;
274 
275  // Announce this faceplate to the world. All listening faceplate
276  // widgets should receive this message and then instantiate
277  // the requested binding
278  this._onCreate(pane);
279 
280  return pane;
281  },
282 
283  showPane: function FaceplateManager_showPane(aPane) {
284  if (!aPane || !aPane.id || !this._panes[aPane.id]) {
285  throw Components.results.NS_ERROR_INVALID_ARG;
286  }
287  this._defaultPaneID = aPane.id;
288  this._onShow(this._panes[aPane.id]);
289  },
290 
291  destroyPane: function FaceplateManager_destroyPane(aPane) {
292  if (!aPane || !aPane.id || !this._panes[aPane.id]) {
293  throw Components.results.NS_ERROR_INVALID_ARG;
294  }
295  var pane = this._panes[aPane.id];
296  delete this._panes[pane.id];
297  this._paneCount--;
298  this._onDestroy(pane);
299  },
300 
301  getPane: function FaceplateManager_getPane(aID) {
302  return this._panes[aID];
303  },
304 
305  getPanes: function FaceplateManager_getPanes() {
306  // Copy all the faceplates into an array, and then return an enumerator
307  return new ArrayEnumerator( [this._panes[key] for (key in this._panes)] );
308  },
309 
310  getDefaultPane: function FaceplateManager_getDefaultPane() {
311  var pane = this.getPane(this._defaultPaneID);
312  if (!pane) {
313  pane = this.getPane("songbird-intro");
314  }
315  return pane;
316  },
317 
318  addListener: function FaceplateManager_addListener(aListener) {
319  if (! (aListener instanceof Ci.sbIFaceplateManagerListener)) {
320  throw Components.results.NS_ERROR_INVALID_ARG;
321  }
322  if (this._listeners.indexOf(aListener) == -1) {
323  this._listeners.push(aListener);
324  }
325  },
326 
327  removeListener: function FaceplateManager_removeListener(aListener) {
328  var index = this._listeners.indexOf(aListener);
329  if (index > -1) {
330  this._listeners.splice(index,1);
331  }
332  },
333 
334 
338  _onCreate: function FaceplateManager__onCreate(aFaceplatePane) {
339  aFaceplatePane = aFaceplatePane.QueryInterface(Ci.sbIFaceplatePane);
340  this._listeners.forEach( function (listener) {
341  listener.onCreatePane(aFaceplatePane);
342  });
343  },
344 
348  _onShow: function FaceplateManager__onShow(aFaceplatePane) {
349  aFaceplatePane = aFaceplatePane.QueryInterface(Ci.sbIFaceplatePane);
350  this._listeners.forEach( function (listener) {
351  listener.onShowPane(aFaceplatePane);
352  });
353  },
354 
358  _onDestroy: function FaceplateManager__onDestroy(aFaceplatePane) {
359  aFaceplatePane = aFaceplatePane.QueryInterface(Ci.sbIFaceplatePane);
360  this._listeners.forEach( function (listener) {
361  listener.onDestroyPane(aFaceplatePane);
362  });
363  },
364 
365 
371  _showDashboardPane: function FaceplateManager__showDashboardPane() {
372  var pane = this.getPane("songbird-dashboard");
373  if (pane) {
374  this.showPane(pane);
375  } else {
376  dump("FaceplateManager__showDashboardPane: dashboard not found\n");
377  }
378  },
379 
380 
384  observe: function(subject, topic, data) {
385  var os = Components.classes["@mozilla.org/observer-service;1"]
386  .getService(Components.interfaces.nsIObserverService);
387 
388  switch (topic) {
389  case "songbird-library-manager-ready":
390  os.removeObserver(this, "songbird-library-manager-ready");
391  this._init();
392  break;
393  case "songbird-library-manager-before-shutdown":
394  os.removeObserver(this, "songbird-library-manager-before-shutdown");
395  this._deinit();
396  break;
397  // When playback begins for the first time, jump
398  // to the playback dashboard
399  case DATAREMOTE_PLAYBACK:
400  if (this._playbackDataRemote.boolValue) {
401  this._playbackDataRemote.unbind();
402  this._playbackDataRemote = null;
403  this._showDashboardPane();
404  }
405  }
406  },
407 
411  QueryInterface: function(iid) {
412  if (!iid.equals(Components.interfaces.sbIFaceplateManager) &&
413  !iid.equals(Components.interfaces.nsIObserver) &&
414  !iid.equals(Components.interfaces.nsISupports))
415  throw Components.results.NS_ERROR_NO_INTERFACE;
416  return this;
417  }
418 }; // FaceplateManager.prototype
419 
420 
421 
422 
423 
424 
428 function makeGetModule(CONSTRUCTOR, CID, CLASSNAME, CONTRACTID, CATEGORIES) {
429  return function (comMgr, fileSpec) {
430  return {
431  registerSelf : function (compMgr, fileSpec, location, type) {
432  compMgr.QueryInterface(Ci.nsIComponentRegistrar);
433  compMgr.registerFactoryLocation(CID,
434  CLASSNAME,
435  CONTRACTID,
436  fileSpec,
437  location,
438  type);
439  if (CATEGORIES && CATEGORIES.length) {
440  var catman = Cc["@mozilla.org/categorymanager;1"]
441  .getService(Ci.nsICategoryManager);
442  for (var i=0; i<CATEGORIES.length; i++) {
443  var e = CATEGORIES[i];
444  catman.addCategoryEntry(e.category, e.entry, e.value,
445  true, true);
446  }
447  }
448  },
449 
450  getClassObject : function (compMgr, cid, iid) {
451  if (!cid.equals(CID)) {
452  throw Cr.NS_ERROR_NO_INTERFACE;
453  }
454 
455  if (!iid.equals(Ci.nsIFactory)) {
456  throw Cr.NS_ERROR_NOT_IMPLEMENTED;
457  }
458 
459  return this._factory;
460  },
461 
462  _factory : {
463  createInstance : function (outer, iid) {
464  if (outer != null) {
465  throw Cr.NS_ERROR_NO_AGGREGATION;
466  }
467  return (new CONSTRUCTOR()).QueryInterface(iid);
468  }
469  },
470 
471  unregisterSelf : function (compMgr, location, type) {
472  compMgr.QueryInterface(Ci.nsIComponentRegistrar);
473  compMgr.unregisterFactoryLocation(CID, location);
474  if (CATEGORIES && CATEGORIES.length) {
475  var catman = Cc["@mozilla.org/categorymanager;1"]
476  .getService(Ci.nsICategoryManager);
477  for (var i=0; i<CATEGORIES.length; i++) {
478  var e = CATEGORIES[i];
479  catman.deleteCategoryEntry(e.category, e.entry, true);
480  }
481  }
482  },
483 
484  canUnload : function (compMgr) {
485  return true;
486  },
487 
488  QueryInterface : function (iid) {
489  if ( !iid.equals(Ci.nsIModule) ||
490  !iid.equals(Ci.nsISupports) )
491  throw Cr.NS_ERROR_NO_INTERFACE;
492  return this;
493  }
494 
495  };
496  }
497 }
498 
500  FaceplateManager,
501  Components.ID("{eb5c665a-bfe2-49f0-a747-cd3554e55606}"),
502  "Songbird Faceplate Pane Manager Service",
503  "@songbirdnest.com/faceplate/manager;1",
504  [{
505  category: 'app-startup',
506  entry: 'faceplate-pane-manager',
507  value: 'service,@songbirdnest.com/faceplate/manager;1'
508  }]);
const DATAREMOTE_PLAYBACK
classDescription entry
Definition: FeedWriter.js:1427
function ArrayEnumerator(array)
const URL_BINDING_DASHBOARD_PANE
prefs removeObserver(PREF_SELECTED_ACTION, this)
menuItem id
Definition: FeedWriter.js:971
onPageChanged aValue
Definition: FeedWriter.js:1395
SafebrowsingApplicationMod prototype registerSelf
inArray array
Wraps a js array in an nsISimpleEnumerator.
const Cr
sidebarFactory createInstance
Definition: nsSidebar.js:351
sbOSDControlService prototype QueryInterface
const CLASSNAME
var strings
Definition: Info.js:46
const CID
_window init
Definition: FeedWriter.js:1144
SafebrowsingApplicationMod prototype getClassObject
const URL_BINDING_DEFAULT_PANE
const CONTRACTID
const Ce
const Ci
DataRemote prototype constructor
historySvc addObserver(this, false)
var createDataRemote
return null
Definition: FeedWriter.js:1143
var os
SimpleArrayEnumerator prototype hasMoreElements
_updateCookies aName
StringArrayEnumerator prototype hasMore
countRef value
Definition: FeedWriter.js:1423
observe topic
Definition: FeedWriter.js:1326
function makeGetModule(CONSTRUCTOR, CID, CLASSNAME, CONTRACTID, CATEGORIES)
XPCOM initialization code.
const Cc
observe data
Definition: FeedWriter.js:1329
window addListener("unload", function(){window.removeListener("unload", arguments.callee);document.purge();if(Browser.Engine.trident){CollectGarbage();}})
_getSelectedPageStyle s i
var NSGetModule
let observer
sbDeviceFirmwareAutoCheckForUpdate prototype observe