FeedConverter.js
Go to the documentation of this file.
1 # -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 # ***** BEGIN LICENSE BLOCK *****
3 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 #
5 # The contents of this file are subject to the Mozilla Public License Version
6 # 1.1 (the "License"); you may not use this file except in compliance with
7 # the License. You may obtain a copy of the License at
8 # http://www.mozilla.org/MPL/
9 #
10 # Software distributed under the License is distributed on an "AS IS" basis,
11 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # for the specific language governing rights and limitations under the
13 # License.
14 #
15 # The Original Code is the Feed Stream Converter.
16 #
17 # The Initial Developer of the Original Code is Google Inc.
18 # Portions created by the Initial Developer are Copyright (C) 2006
19 # the Initial Developer. All Rights Reserved.
20 #
21 # Contributor(s):
22 # Ben Goodger <beng@google.com>
23 # Jeff Walden <jwalden+code@mit.edu>
24 # Will Guaraldi <will.guaraldi@pculture.org>
25 #
26 # Alternatively, the contents of this file may be used under the terms of
27 # either the GNU General Public License Version 2 or later (the "GPL"), or
28 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 # in which case the provisions of the GPL or the LGPL are applicable instead
30 # of those above. If you wish to allow use of your version of this file only
31 # under the terms of either the GPL or the LGPL, and not to allow others to
32 # use your version of this file under the terms of the MPL, indicate your
33 # decision by deleting the provisions above and replace them with the notice
34 # and other provisions required by the GPL or the LGPL. If you do not delete
35 # the provisions above, a recipient may use your version of this file under
36 # the terms of any one of the MPL, the GPL or the LGPL.
37 #
38 # ***** END LICENSE BLOCK ***** */
39 
40 const Cc = Components.classes;
41 const Ci = Components.interfaces;
42 const Cr = Components.results;
43 
44 function LOG(str) {
45  dump("*** " + str + "\n");
46 }
47 
48 const FC_CLASSID = Components.ID("{229fa115-9412-4d32-baf3-2fc407f76fb1}");
49 const FC_CLASSNAME = "Feed Stream Converter";
50 const FS_CLASSID = Components.ID("{2376201c-bbc6-472f-9b62-7548040a61c6}");
51 const FS_CLASSNAME = "Feed Result Service";
52 const FS_CONTRACTID = "@mozilla.org/browser/feeds/result-service;1";
53 const FPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=feed";
54 const FPH_CLASSID = Components.ID("{4f91ef2e-57ba-472e-ab7a-b4999e42d6c0}");
55 const FPH_CLASSNAME = "Feed Protocol Handler";
56 const PCPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=pcast";
57 const PCPH_CLASSID = Components.ID("{1c31ed79-accd-4b94-b517-06e0c81999d5}");
58 const PCPH_CLASSNAME = "Podcast Protocol Handler";
59 
60 const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
61 const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
62 const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
63 const TYPE_ANY = "*/*";
64 
65 const FEEDHANDLER_URI = "about:feeds";
66 
67 const PREF_SELECTED_APP = "browser.feeds.handlers.application";
68 const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
69 const PREF_SELECTED_ACTION = "browser.feeds.handler";
70 const PREF_SELECTED_READER = "browser.feeds.handler.default";
71 
72 const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
73 const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
74 const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
75 const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
76 
77 const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
78 const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
79 const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
80 const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
81 
82 function getPrefAppForType(t) {
83  switch (t) {
84  case Ci.nsIFeed.TYPE_VIDEO:
86 
87  case Ci.nsIFeed.TYPE_AUDIO:
89 
90  default:
91  return PREF_SELECTED_APP;
92  }
93 }
94 
95 function getPrefWebForType(t) {
96  switch (t) {
97  case Ci.nsIFeed.TYPE_VIDEO:
99 
100  case Ci.nsIFeed.TYPE_AUDIO:
102 
103  default:
104  return PREF_SELECTED_WEB;
105  }
106 }
107 
109  switch (t) {
110  case Ci.nsIFeed.TYPE_VIDEO:
112 
113  case Ci.nsIFeed.TYPE_AUDIO:
115 
116  default:
117  return PREF_SELECTED_ACTION;
118  }
119 }
120 
122  switch (t) {
123  case Ci.nsIFeed.TYPE_VIDEO:
125 
126  case Ci.nsIFeed.TYPE_AUDIO:
128 
129  default:
130  return PREF_SELECTED_READER;
131  }
132 }
133 
134 function safeGetCharPref(pref, defaultValue) {
135  var prefs =
136  Cc["@mozilla.org/preferences-service;1"].
137  getService(Ci.nsIPrefBranch);
138  try {
139  return prefs.getCharPref(pref);
140  }
141  catch (e) {
142  }
143  return defaultValue;
144 }
145 
146 function FeedConverter() {
147 }
148 FeedConverter.prototype = {
152  _data: null,
153 
158  _listener: null,
159 
163  _sniffed: false,
164 
168  convert: function FC_convert(sourceStream, sourceType, destinationType,
169  context) {
170  throw Cr.NS_ERROR_NOT_IMPLEMENTED;
171  },
172 
176  asyncConvertData: function FC_asyncConvertData(sourceType, destinationType,
177  listener, context) {
178  this._listener = listener;
179  },
180 
184  _forcePreviewPage: false,
185 
189  _releaseHandles: function FC__releaseHandles() {
190  this._listener = null;
191  this._request = null;
192  this._processor = null;
193  },
194 
198  handleResult: function FC_handleResult(result) {
199  // Feeds come in various content types, which our feed sniffer coerces to
200  // the maybe.feed type. However, feeds are used as a transport for
201  // different data types, e.g. news/blogs (traditional feed), video/audio
202  // (podcasts) and photos (photocasts, photostreams). Each of these is
203  // different in that there's a different class of application suitable for
204  // handling feeds of that type, but without a content-type differentiation
205  // it is difficult for us to disambiguate.
206  //
207  // The other problem is that if the user specifies an auto-action handler
208  // for one feed application, the fact that the content type is shared means
209  // that all other applications will auto-load with that handler too,
210  // regardless of the content-type.
211  //
212  // This means that content-type alone is not enough to determine whether
213  // or not a feed should be auto-handled. This means that for feeds we need
214  // to always use this stream converter, even when an auto-action is
215  // specified, not the basic one provided by WebContentConverter. This
216  // converter needs to consume all of the data and parse it, and based on
217  // that determination make a judgement about type.
218  //
219  // Since there are no content types for this content, and I'm not going to
220  // invent any, the upshot is that while a user can set an auto-handler for
221  // generic feed content, the system will prevent them from setting an auto-
222  // handler for other stream types. In those cases, the user will always see
223  // the preview page and have to select a handler. We can guess and show
224  // a client handler, but will not be able to show web handlers for those
225  // types.
226  //
227  // If this is just a feed, not some kind of specialized application, then
228  // auto-handlers can be set and we should obey them.
229  try {
230  var feedService =
231  Cc["@mozilla.org/browser/feeds/result-service;1"].
232  getService(Ci.nsIFeedResultService);
233  if (!this._forcePreviewPage && result.doc) {
234  var feed = result.doc.QueryInterface(Ci.nsIFeed);
235  var handler = safeGetCharPref(getPrefActionForType(feed.type), "ask");
236 
237  if (handler != "ask") {
238  if (handler == "reader")
239  handler = safeGetCharPref(getPrefReaderForType(feed.type), "bookmarks");
240  switch (handler) {
241  case "web":
242  var wccr =
243  Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
244  getService(Ci.nsIWebContentConverterService);
245  if ((feed.type == Ci.nsIFeed.TYPE_FEED &&
246  wccr.getAutoHandler(TYPE_MAYBE_FEED)) ||
247  (feed.type == Ci.nsIFeed.TYPE_VIDEO &&
248  wccr.getAutoHandler(TYPE_MAYBE_VIDEO_FEED)) ||
249  (feed.type == Ci.nsIFeed.TYPE_AUDIO &&
250  wccr.getAutoHandler(TYPE_MAYBE_AUDIO_FEED))) {
251  wccr.loadPreferredHandler(this._request);
252  return;
253  }
254  break;
255 
256  default:
257  LOG("unexpected handler: " + handler);
258  // fall through -- let feed service handle error
259  case "bookmarks":
260  case "client":
261  try {
262  var title = feed.title ? feed.title.plainText() : "";
263  var desc = feed.subtitle ? feed.subtitle.plainText() : "";
264  feedService.addToClientReader(result.uri.spec, title, desc, feed.type);
265  return;
266  } catch(ex) { /* fallback to preview mode */ }
267  }
268  }
269  }
270 
271  var ios =
272  Cc["@mozilla.org/network/io-service;1"].
273  getService(Ci.nsIIOService);
274  var chromeChannel;
275 
276  // If there was no automatic handler, or this was a podcast,
277  // photostream or some other kind of application, show the preview page
278  // if the parser returned a document.
279  if (result.doc) {
280 
281  // Store the result in the result service so that the display
282  // page can access it.
283  feedService.addFeedResult(result);
284 
285  // Now load the actual XUL document.
286  var chromeURI = ios.newURI(FEEDHANDLER_URI, null, null);
287  chromeChannel = ios.newChannelFromURI(chromeURI, null);
288  chromeChannel.originalURI = result.uri;
289  }
290  else
291  chromeChannel = ios.newChannelFromURI(result.uri, null);
292 
293  chromeChannel.loadGroup = this._request.loadGroup;
294  chromeChannel.asyncOpen(this._listener, null);
295  }
296  finally {
297  this._releaseHandles();
298  }
299  },
300 
304  onDataAvailable: function FC_onDataAvailable(request, context, inputStream,
305  sourceOffset, count) {
306  if (this._processor)
307  this._processor.onDataAvailable(request, context, inputStream,
308  sourceOffset, count);
309  },
310 
314  onStartRequest: function FC_onStartRequest(request, context) {
315  var channel = request.QueryInterface(Ci.nsIChannel);
316 
317  // Check for a header that tells us there was no sniffing
318  // The value doesn't matter.
319  try {
320  var httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
321  var noSniff = httpChannel.getResponseHeader("X-Moz-Is-Feed");
322  }
323  catch (ex) {
324  this._sniffed = true;
325  }
326 
327  this._request = request;
328 
329  // Save and reset the forced state bit early, in case there's some kind of
330  // error.
331  var feedService =
332  Cc["@mozilla.org/browser/feeds/result-service;1"].
333  getService(Ci.nsIFeedResultService);
334  this._forcePreviewPage = feedService.forcePreviewPage;
335  feedService.forcePreviewPage = false;
336 
337  // Parse feed data as it comes in
338  this._processor =
339  Cc["@mozilla.org/feed-processor;1"].
340  createInstance(Ci.nsIFeedProcessor);
341  this._processor.listener = this;
342  this._processor.parseAsync(null, channel.URI);
343 
344  this._processor.onStartRequest(request, context);
345  },
346 
350  onStopRequest: function FC_onStopRequest(request, context, status) {
351  if (this._processor)
352  this._processor.onStopRequest(request, context, status);
353  },
354 
358  QueryInterface: function FC_QueryInterface(iid) {
359  if (iid.equals(Ci.nsIFeedResultListener) ||
360  iid.equals(Ci.nsIStreamConverter) ||
361  iid.equals(Ci.nsIStreamListener) ||
362  iid.equals(Ci.nsIRequestObserver)||
363  iid.equals(Ci.nsISupports))
364  return this;
365  throw Cr.NS_ERROR_NO_INTERFACE;
366  },
367 };
368 
370  createInstance: function FS_createInstance(outer, iid) {
371  if (outer != null)
372  throw Cr.NS_ERROR_NO_AGGREGATION;
373  return new FeedConverter().QueryInterface(iid);
374  },
375 
376  QueryInterface: function FS_QueryInterface(iid) {
377  if (iid.equals(Ci.nsIFactory) ||
378  iid.equals(Ci.nsISupports))
379  return this;
380  throw Cr.NS_ERROR_NO_INTERFACE;
381  },
382 };
383 
389 
394  _results: { },
395 
399  forcePreviewPage: false,
400 
404  addToClientReader: function FRS_addToClientReader(spec, title, subtitle, feedType) {
405  var prefs =
406  Cc["@mozilla.org/preferences-service;1"].
407  getService(Ci.nsIPrefBranch);
408 
410  if (handler == "ask" || handler == "reader")
411  handler = safeGetCharPref(getPrefReaderForType(feedType), "bookmarks");
412 
413  switch (handler) {
414  case "client":
415  var clientApp = prefs.getComplexValue(getPrefAppForType(feedType), Ci.nsILocalFile);
416 
417  // For the benefit of applications that might know how to deal with more
418  // URLs than just feeds, send feed: URLs in the following format:
419  //
420  // http urls: replace scheme with feed, e.g.
421  // http://foo.com/index.rdf -> feed://foo.com/index.rdf
422  // other urls: prepend feed: scheme, e.g.
423  // https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
424  var ios =
425  Cc["@mozilla.org/network/io-service;1"].
426  getService(Ci.nsIIOService);
427  var feedURI = ios.newURI(spec, null, null);
428  if (feedURI.schemeIs("http")) {
429  feedURI.scheme = "feed";
430  spec = feedURI.spec;
431  }
432  else
433  spec = "feed:" + spec;
434 
435  // Retrieving the shell service might fail on some systems, most
436  // notably systems where GNOME is not installed.
437  try {
438  var ss =
439  Cc["@mozilla.org/browser/shell-service;1"].
440  getService(Ci.nsIShellService);
441  ss.openApplicationWithURI(clientApp, spec);
442  } catch(e) {
443  // If we couldn't use the shell service, fallback to using a
444  // nsIProcess instance
445  var p =
446  Cc["@mozilla.org/process/util;1"].
447  createInstance(Ci.nsIProcess);
448  p.init(clientApp);
449  p.run(false, [spec], 1);
450  }
451  break;
452 
453  default:
454  // "web" should have been handled elsewhere
455  LOG("unexpected handler: " + handler);
456  // fall through
457  case "bookmarks":
458  var wm =
459  Cc["@mozilla.org/appshell/window-mediator;1"].
460  getService(Ci.nsIWindowMediator);
461  var topWindow = wm.getMostRecentWindow("navigator:browser");
462  topWindow.PlacesCommandHook.addLiveBookmark(spec, title, subtitle);
463  break;
464  }
465  },
466 
470  addFeedResult: function FRS_addFeedResult(feedResult) {
471  NS_ASSERT(feedResult.uri != null, "null URI!");
472  NS_ASSERT(feedResult.uri != null, "null feedResult!");
473  var spec = feedResult.uri.spec;
474  if(!this._results[spec])
475  this._results[spec] = [];
476  this._results[spec].push(feedResult);
477  },
478 
482  getFeedResult: function RFS_getFeedResult(uri) {
483  NS_ASSERT(uri != null, "null URI!");
484  var resultList = this._results[uri.spec];
485  for (var i in resultList) {
486  if (resultList[i].uri == uri)
487  return resultList[i];
488  }
489  return null;
490  },
491 
495  removeFeedResult: function FRS_removeFeedResult(uri) {
496  NS_ASSERT(uri != null, "null URI!");
497  var resultList = this._results[uri.spec];
498  if (!resultList)
499  return;
500  var deletions = 0;
501  for (var i = 0; i < resultList.length; ++i) {
502  if (resultList[i].uri == uri) {
503  delete resultList[i];
504  ++deletions;
505  }
506  }
507 
508  // send the holes to the end
509  resultList.sort();
510  // and trim the list
511  resultList.splice(resultList.length - deletions, deletions);
512  if (resultList.length == 0)
513  delete this._results[uri.spec];
514  },
515 
516  createInstance: function FRS_createInstance(outer, iid) {
517  if (outer != null)
518  throw Cr.NS_ERROR_NO_AGGREGATION;
519  return this.QueryInterface(iid);
520  },
521 
522  QueryInterface: function FRS_QueryInterface(iid) {
523  if (iid.equals(Ci.nsIFeedResultService) ||
524  iid.equals(Ci.nsIFactory) ||
525  iid.equals(Ci.nsISupports))
526  return this;
527  throw Cr.NS_ERROR_NOT_IMPLEMENTED;
528  },
529 };
530 
535 function FeedProtocolHandler(scheme) {
536  this._scheme = scheme;
537  var ios =
538  Cc["@mozilla.org/network/io-service;1"].
539  getService(Ci.nsIIOService);
540  this._http = ios.getProtocolHandler("http");
541 }
542 FeedProtocolHandler.prototype = {
543  _scheme: "",
544  get scheme() {
545  return this._scheme;
546  },
547 
548  get protocolFlags() {
549  return this._http.protocolFlags;
550  },
551 
552  get defaultPort() {
553  return this._http.defaultPort;
554  },
555 
556  allowPort: function FPH_allowPort(port, scheme) {
557  return this._http.allowPort(port, scheme);
558  },
559 
560  newURI: function FPH_newURI(spec, originalCharset, baseURI) {
561  // See bug 408599 - feed URIs can be either standard URLs of the form
562  // feed://example.com, in which case the real protocol is http, or nested
563  // URIs of the form feed:realscheme:. When realscheme is either http or
564  // https, we deal with the way that creates a standard URL with the
565  // realscheme as the host by unmangling in newChannel; for others, we fail
566  // rather than let it wind up loading something like www.realscheme.com//foo
567 
568  const feedSlashes = "feed://";
569  const feedHttpSlashes = "feed:http://";
570  const feedHttpsSlashes = "feed:https://";
571  const NS_ERROR_MALFORMED_URI = 0x804B000A;
572 
573  if (spec.substr(0, feedSlashes.length) != feedSlashes &&
574  spec.substr(0, feedHttpSlashes.length) != feedHttpSlashes &&
575  spec.substr(0, feedHttpsSlashes.length) != feedHttpsSlashes)
577 
578  var uri =
579  Cc["@mozilla.org/network/standard-url;1"].
580  createInstance(Ci.nsIStandardURL);
581  uri.init(Ci.nsIStandardURL.URLTYPE_STANDARD, 80, spec, originalCharset,
582  baseURI);
583  return uri;
584  },
585 
586  newChannel: function FPH_newChannel(aUri) {
587  var ios =
588  Cc["@mozilla.org/network/io-service;1"].
589  getService(Ci.nsIIOService);
590  // feed: URIs either start feed://, in which case the real scheme is http:
591  // or feed:http(s)://, (which by now we've changed to feed://realscheme//)
592  var feedSpec = aUri.spec;
593  const httpsChunk = "feed://https//";
594  const httpChunk = "feed://http//";
595  if (feedSpec.substr(0, httpsChunk.length) == httpsChunk)
596  feedSpec = "https://" + feedSpec.substr(httpsChunk.length);
597  else if (feedSpec.substr(0, httpChunk.length) == httpChunk)
598  feedSpec = "http://" + feedSpec.substr(httpChunk.length);
599  else
600  feedSpec = feedSpec.replace(/^feed/, "http");
601 
602  var uri = ios.newURI(feedSpec, aUri.originCharset, null);
603  var channel =
604  ios.newChannelFromURI(uri, null).QueryInterface(Ci.nsIHttpChannel);
605  // Set this so we know this is supposed to be a feed
606  channel.setRequestHeader("X-Moz-Is-Feed", "1", false);
607  channel.originalURI = aUri;
608  return channel;
609  },
610 
611  QueryInterface: function FPH_QueryInterface(iid) {
612  if (iid.equals(Ci.nsIProtocolHandler) ||
613  iid.equals(Ci.nsISupports))
614  return this;
615  throw Cr.NS_ERROR_NO_INTERFACE;
616  }
617 };
618 
619 var Module = {
620  QueryInterface: function M_QueryInterface(iid) {
621  if (iid.equals(Ci.nsIModule) ||
622  iid.equals(Ci.nsISupports))
623  return this;
624  throw Cr.NS_ERROR_NO_INTERFACE;
625  },
626 
627  getClassObject: function M_getClassObject(cm, cid, iid) {
628  if (!iid.equals(Ci.nsIFactory))
629  throw Cr.NS_ERROR_NOT_IMPLEMENTED;
630 
631  if (cid.equals(FS_CLASSID))
632  return FeedResultService;
633  if (cid.equals(FPH_CLASSID))
634  return new GenericComponentFactory(FeedProtocolHandler, "feed");
635  if (cid.equals(PCPH_CLASSID))
636  return new GenericComponentFactory(FeedProtocolHandler, "pcast");
637  if (cid.equals(FC_CLASSID))
639 
640  throw Cr.NS_ERROR_NO_INTERFACE;
641  },
642 
643  registerSelf: function M_registerSelf(cm, file, location, type) {
644  var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
645 
646  cr.registerFactoryLocation(FS_CLASSID, FS_CLASSNAME, FS_CONTRACTID,
647  file, location, type);
648  cr.registerFactoryLocation(FPH_CLASSID, FPH_CLASSNAME, FPH_CONTRACTID,
649  file, location, type);
650  cr.registerFactoryLocation(PCPH_CLASSID, PCPH_CLASSNAME, PCPH_CONTRACTID,
651  file, location, type);
652 
653  // The feed converter is always attached, since parsing must be done to
654  // determine whether or not auto-handling can occur.
655  const converterPrefix = "@mozilla.org/streamconv;1?from=";
656  var converterContractID =
657  converterPrefix + TYPE_MAYBE_FEED + "&to=" + TYPE_ANY;
658  cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
659  file, location, type);
660 
661  converterContractID =
662  converterPrefix + TYPE_MAYBE_VIDEO_FEED + "&to=" + TYPE_ANY;
663  cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
664  file, location, type);
665 
666  converterContractID =
667  converterPrefix + TYPE_MAYBE_AUDIO_FEED + "&to=" + TYPE_ANY;
668  cr.registerFactoryLocation(FC_CLASSID, FC_CLASSNAME, converterContractID,
669  file, location, type);
670  },
671 
672  unregisterSelf: function M_unregisterSelf(cm, location, type) {
673  var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
674  cr.unregisterFactoryLocation(FPH_CLASSID, location);
675  cr.unregisterFactoryLocation(PCPH_CLASSID, location);
676  },
677 
678  canUnload: function M_canUnload(cm) {
679  return true;
680  }
681 };
682 
683 function NSGetModule(cm, file) {
684  return Module;
685 }
686 
687 #include ../../../../toolkit/content/debug.js
688 #include GenericFactory.js
feedService removeFeedResult(this._feedURI)
const TYPE_MAYBE_VIDEO_FEED
const FC_CLASSID
function getPrefAppForType(t)
const PREF_SELECTED_READER
const FS_CLASSID
var wccr
Definition: FeedWriter.js:1042
const TYPE_MAYBE_AUDIO_FEED
const FS_CONTRACTID
function getPrefActionForType(t)
function FeedProtocolHandler(scheme)
SafebrowsingApplicationMod prototype registerSelf
const PREF_SELECTED_APP
var FeedResultService
var pref
Definition: openLocation.js:44
const PREF_VIDEO_SELECTED_ACTION
const Cr
const PREF_AUDIO_SELECTED_READER
var Module
const FPH_CLASSID
const TYPE_ANY
function LOG(str)
const FPH_CLASSNAME
const PREF_AUDIO_SELECTED_WEB
sidebarFactory createInstance
Definition: nsSidebar.js:351
sbOSDControlService prototype QueryInterface
const NS_ERROR_MALFORMED_URI
Definition: test_355473.js:1
feedService addToClientReader(this._window.location.href, feedTitle, feedSubtitle, feedType)
function safeGetCharPref(pref, defaultValue)
const PCPH_CONTRACTID
function GenericComponentFactory(ctor, params)
function getPrefReaderForType(t)
getService(Ci.sbIFaceplateManager)
const PREF_SELECTED_ACTION
SafebrowsingApplicationMod prototype getClassObject
var t
var count
Definition: test_bug7406.js:32
const PREF_AUDIO_SELECTED_APP
const Cc
const PREF_VIDEO_SELECTED_READER
function NSGetModule(cm, file)
const Ci
const FPH_CONTRACTID
return null
Definition: FeedWriter.js:1143
const PREF_SELECTED_WEB
function newURI(aURLString)
var feedType
Definition: FeedWriter.js:949
function NS_ASSERT(cond, msg)
Definition: httpd.js:70
var uri
Definition: FeedWriter.js:1135
const FS_CLASSNAME
var prefs
Definition: FeedWriter.js:1169
const TYPE_MAYBE_FEED
function getPrefWebForType(t)
const FC_CLASSNAME
var cr
if(DEBUG_DATAREMOTES)
const PCPH_CLASSID
const FEEDHANDLER_URI
const PCPH_CLASSNAME
var ios
Definition: head_feeds.js:5
var FeedConverterFactory
_getSelectedPageStyle s i
GstMessage gpointer data sbGStreamerMessageHandler * handler
function FeedConverter()
const PREF_AUDIO_SELECTED_ACTION
const PREF_VIDEO_SELECTED_APP
var cm
var file
const PREF_VIDEO_SELECTED_WEB