Bug 1477670 - remove content handler code from browser/, r=florian,jkt
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Tue, 24 Jul 2018 17:54:40 +0100
changeset 823627 3abafc9e0915bf426db04fe6224661126e034a4e
parent 823626 04ce1d287d583bef07b29a9b9c055ee3a2e94d87
child 823628 452156f0fc6d79738b09f2763a1908ef80dab09c
push id117745
push userbmo:wcosta@mozilla.com
push dateFri, 27 Jul 2018 17:51:32 +0000
reviewersflorian, jkt
bugs1477670
milestone63.0a1
Bug 1477670 - remove content handler code from browser/, r=florian,jkt MozReview-Commit-ID: 3kS7yPdkjGs
browser/base/content/browser-feeds.js
browser/base/content/test/performance/browser_startup.js
browser/components/feeds/BrowserFeeds.manifest
browser/components/feeds/FeedConverter.js
browser/components/feeds/FeedWriter.js
browser/components/feeds/WebContentConverter.js
browser/components/feeds/moz.build
browser/components/feeds/nsIWebContentConverterRegistrar.idl
browser/components/nsBrowserGlue.js
browser/components/preferences/applicationManager.js
browser/components/preferences/in-content/main.js
browser/modules/Feeds.jsm
dom/interfaces/sidebar/nsIWebContentHandlerRegistrar.idl
--- a/browser/base/content/browser-feeds.js
+++ b/browser/base/content/browser-feeds.js
@@ -8,52 +8,46 @@ ChromeUtils.defineModuleGetter(this, "De
 
 const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
 const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
 const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
 
 const PREF_SHOW_FIRST_RUN_UI = "browser.feeds.showFirstRunUI";
 
 const PREF_SELECTED_APP = "browser.feeds.handlers.application";
-const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
 const PREF_SELECTED_ACTION = "browser.feeds.handler";
 const PREF_SELECTED_READER = "browser.feeds.handler.default";
 
 const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
-const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
 const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
 const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
 
 const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
-const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
 const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
 const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
 
 const PREF_UPDATE_DELAY = 2000;
 
 const SETTABLE_PREFS = new Set([
   PREF_VIDEO_SELECTED_ACTION,
   PREF_AUDIO_SELECTED_ACTION,
   PREF_SELECTED_ACTION,
   PREF_VIDEO_SELECTED_READER,
   PREF_AUDIO_SELECTED_READER,
-  PREF_SELECTED_READER,
-  PREF_VIDEO_SELECTED_WEB,
-  PREF_AUDIO_SELECTED_WEB,
-  PREF_SELECTED_WEB
+  PREF_SELECTED_READER
 ]);
 
 const EXECUTABLE_PREFS = new Set([
   PREF_SELECTED_APP,
   PREF_VIDEO_SELECTED_APP,
   PREF_AUDIO_SELECTED_APP
 ]);
 
 const VALID_ACTIONS = new Set(["ask", "reader", "bookmarks"]);
-const VALID_READERS = new Set(["web", "client", "default", "bookmarks"]);
+const VALID_READERS = new Set(["client", "default", "bookmarks"]);
 
 XPCOMUtils.defineLazyPreferenceGetter(this, "SHOULD_LOG",
                                       "feeds.log", false);
 
 function LOG(str) {
   if (SHOULD_LOG)
     dump("*** Feeds: " + str + "\n");
 }
@@ -79,29 +73,16 @@ function getPrefReaderForType(t) {
     case Ci.nsIFeed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_READER;
 
     default:
       return PREF_SELECTED_READER;
   }
 }
 
-function getPrefWebForType(t) {
-  switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
-      return PREF_VIDEO_SELECTED_WEB;
-
-    case Ci.nsIFeed.TYPE_AUDIO:
-      return PREF_AUDIO_SELECTED_WEB;
-
-    default:
-      return PREF_SELECTED_WEB;
-  }
-}
-
 function getPrefAppForType(t) {
   switch (t) {
     case Ci.nsIFeed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_APP;
 
     case Ci.nsIFeed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_APP;
 
@@ -422,23 +403,20 @@ var FeedHandler = {
     window.messageManager.addMessageListener("FeedWriter:SetFeedPrefsAndSubscribe", this);
     window.messageManager.addMessageListener("FeedWriter:ShownFirstRun", this);
 
     Services.ppmm.addMessageListener("FeedConverter:ExecuteClientApp", this);
 
     const prefs = Services.prefs;
     prefs.addObserver(PREF_SELECTED_ACTION, this, true);
     prefs.addObserver(PREF_SELECTED_READER, this, true);
-    prefs.addObserver(PREF_SELECTED_WEB, this, true);
     prefs.addObserver(PREF_VIDEO_SELECTED_ACTION, this, true);
     prefs.addObserver(PREF_VIDEO_SELECTED_READER, this, true);
-    prefs.addObserver(PREF_VIDEO_SELECTED_WEB, this, true);
     prefs.addObserver(PREF_AUDIO_SELECTED_ACTION, this, true);
     prefs.addObserver(PREF_AUDIO_SELECTED_READER, this, true);
-    prefs.addObserver(PREF_AUDIO_SELECTED_WEB, this, true);
   },
 
   uninit() {
     Services.ppmm.removeMessageListener("FeedConverter:ExecuteClientApp", this);
 
     this._prefChangeCallback = null;
   },
 
@@ -459,53 +437,35 @@ var FeedHandler = {
   },
 
   _prefChanged(prefName) {
     // Don't observe for PREF_*SELECTED_APP as user likely just picked one
     // That is also handled by SetApplicationLauncherMenuItem call
     // Rather than the others which happen on subscription
     switch (prefName) {
       case PREF_SELECTED_READER:
-      case PREF_SELECTED_WEB:
       case PREF_VIDEO_SELECTED_READER:
-      case PREF_VIDEO_SELECTED_WEB:
       case PREF_AUDIO_SELECTED_READER:
-      case PREF_AUDIO_SELECTED_WEB:
       case PREF_SELECTED_ACTION:
       case PREF_VIDEO_SELECTED_ACTION:
       case PREF_AUDIO_SELECTED_ACTION:
         const response = {
          default: this._getReaderForType(Ci.nsIFeed.TYPE_FEED),
          [Ci.nsIFeed.TYPE_AUDIO]: this._getReaderForType(Ci.nsIFeed.TYPE_AUDIO),
          [Ci.nsIFeed.TYPE_VIDEO]: this._getReaderForType(Ci.nsIFeed.TYPE_VIDEO)
         };
         Services.mm.broadcastAsyncMessage("FeedWriter:PreferenceUpdated",
                                           response);
         break;
     }
   },
 
   _initSubscriptionUIResponse(feedType) {
-    const wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-               getService(Ci.nsIWebContentConverterService);
-    const handlersRaw = wccr.getContentHandlers(getMimeTypeForFeedType(feedType));
-    const handlers = [];
-    for (let handler of handlersRaw) {
-      LOG(`Handler found: ${handler}`);
-      handlers.push({
-        name: handler.name,
-        uri: handler.uri
-      });
-    }
-    let showFirstRunUI = true;
-    // eslint-disable-next-line mozilla/use-default-preference-values
-    try {
-      showFirstRunUI = Services.prefs.getBoolPref(PREF_SHOW_FIRST_RUN_UI);
-    } catch (ex) { }
-    const response = { handlers, showFirstRunUI };
+    let showFirstRunUI = Services.prefs.getBoolPref(PREF_SHOW_FIRST_RUN_UI, true);
+    const response = { showFirstRunUI };
     let selectedClientApp;
     const feedTypePref = getPrefAppForType(feedType);
     try {
       selectedClientApp = Services.prefs.getComplexValue(feedTypePref, Ci.nsIFile);
     } catch (ex) {
       // Just do nothing, then we won't bother populating
     }
 
@@ -540,46 +500,30 @@ var FeedHandler = {
         Services.prefs.setCharPref(aPrefName, aPrefValue);
       }
     } else {
       LOG(`FeedWriter._setPref ${aPrefName} not allowed`);
     }
   },
 
   _getReaderForType(feedType) {
-    let prefs = Services.prefs;
-    let handler = "bookmarks";
-    let url;
-    // eslint-disable-next-line mozilla/use-default-preference-values
-    try {
-      handler = prefs.getCharPref(getPrefReaderForType(feedType));
-    } catch (ex) { }
-
-    if (handler === "web") {
-      try {
-        url = prefs.getStringPref(getPrefWebForType(feedType));
-      } catch (ex) {
-        LOG("FeedWriter._setSelectedHandler: invalid or no handler in prefs");
-        url = null;
-      }
-    }
+    let handler = Services.prefs.getCharPref(getPrefReaderForType(feedType), "bookmarks");
     const alwaysUse = this._getAlwaysUseState(feedType);
-    const action = prefs.getCharPref(getPrefActionForType(feedType));
-    return { handler, url, alwaysUse, action };
+    const action = Services.prefs.getCharPref(getPrefActionForType(feedType));
+    return { handler, alwaysUse, action };
   },
 
   _getAlwaysUseState(feedType) {
     try {
       return Services.prefs.getCharPref(getPrefActionForType(feedType)) != "ask";
     } catch (ex) { }
     return false;
   },
 
   receiveMessage(msg) {
-    let handler;
     switch (msg.name) {
       case "FeedWriter:GetSubscriptionUI":
         const response = this._initSubscriptionUIResponse(msg.data.feedType);
         msg.target.messageManager
            .sendAsyncMessage("FeedWriter:GetSubscriptionUIResponse",
                             response);
         break;
       case "FeedWriter:ChooseClientApp":
@@ -600,50 +544,26 @@ var FeedHandler = {
         }
 
         Services.telemetry.scalarAdd("browser.feeds.feed_subscribed", 1);
 
         const actionPref = getPrefActionForType(settings.feedType);
         this._setPref(actionPref, settings.action);
         const readerPref = getPrefReaderForType(settings.feedType);
         this._setPref(readerPref, settings.reader);
-        handler = null;
+
+        const feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
+                            getService(Ci.nsIFeedResultService);
 
-        switch (settings.reader) {
-          case "web":
-            // This is a web set URI by content using window.registerContentHandler()
-            // Lets make sure we know about it before setting it
-            const webPref = getPrefWebForType(settings.feedType);
-            let wccr = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                       getService(Ci.nsIWebContentConverterService);
-            // If the user provided an invalid web URL this function won't give us a reference
-            handler = wccr.getWebContentHandlerByURI(getMimeTypeForFeedType(settings.feedType), settings.uri);
-            if (handler) {
-              this._setPref(webPref, settings.uri, true);
-              if (settings.useAsDefault) {
-                wccr.setAutoHandler(getMimeTypeForFeedType(settings.feedType), handler);
-              }
-              msg.target.messageManager
-                 .sendAsyncMessage("FeedWriter:SetFeedPrefsAndSubscribeResponse",
-                                  { redirect: handler.getHandlerURI(settings.feedLocation) });
-            } else {
-              LOG(`No handler found for web ${settings.feedType} ${settings.uri}`);
-            }
-            break;
-          default:
-            const feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
-                                getService(Ci.nsIFeedResultService);
-
-            feedService.addToClientReader(settings.feedLocation,
-                                          settings.feedTitle,
-                                          settings.feedSubtitle,
-                                          settings.feedType,
-                                          settings.reader);
-         }
-         break;
+        feedService.addToClientReader(settings.feedLocation,
+                                      settings.feedTitle,
+                                      settings.feedSubtitle,
+                                      settings.feedType,
+                                      settings.reader);
+        break;
       case "FeedConverter:ExecuteClientApp":
         // Always check feedHandler is from a set array of executable prefs
         if (EXECUTABLE_PREFS.has(msg.data.feedHandler)) {
           this.executeClientApp(msg.data.spec, msg.data.title,
                                 msg.data.subtitle, msg.data.feedHandler);
         } else {
           LOG(`FeedConverter:ExecuteClientApp - Will not exec ${msg.data.feedHandler}`);
         }
--- a/browser/base/content/test/performance/browser_startup.js
+++ b/browser/base/content/test/performance/browser_startup.js
@@ -26,17 +26,16 @@ const startupPhases = {
   // Consider loading your code after first paint instead,
   // eg. from nsBrowserGlue.js' _onFirstWindowLoaded method).
   "before profile selection": {whitelist: {
     components: new Set([
       "nsBrowserGlue.js",
       "MainProcessSingleton.js",
 
       // Bugs to fix: The following components shouldn't be initialized that early.
-      "WebContentConverter.js", // bug 1369443
       "nsSessionStartup.js", // bug 1369456
       "PushComponents.js", // bug 1369436
     ]),
     modules: new Set([
       "resource://gre/modules/AppConstants.jsm",
       "resource://gre/modules/XPCOMUtils.jsm",
       "resource://gre/modules/Services.jsm",
     ])
--- a/browser/components/feeds/BrowserFeeds.manifest
+++ b/browser/components/feeds/BrowserFeeds.manifest
@@ -1,18 +1,10 @@
-# This component must restrict its registration for the app-startup category
-# to the specific list of apps that use it so it doesn't get loaded in xpcshell.
-# Thus we restrict it to these apps:
-#
-#   browser:        {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
-#   mobile/android: {aa3c5121-dab2-40e2-81ca-7ea25febc110}
-
 component {229fa115-9412-4d32-baf3-2fc407f76fb1} FeedConverter.js
 contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
 contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.video.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
 contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.audio.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
 component {2376201c-bbc6-472f-9b62-7548040a61c6} FeedConverter.js
 contract @mozilla.org/browser/feeds/result-service;1 {2376201c-bbc6-472f-9b62-7548040a61c6}
 component {49bb6593-3aff-4eb3-a068-2712c28bd58e} FeedWriter.js
 contract @mozilla.org/browser/feeds/result-writer;1 {49bb6593-3aff-4eb3-a068-2712c28bd58e}
 component {792a7e82-06a0-437c-af63-b2d12e808acc} WebContentConverter.js
 contract @mozilla.org/embeddor.implemented/web-content-handler-registrar;1 {792a7e82-06a0-437c-af63-b2d12e808acc}
-category app-startup WebContentConverter service,@mozilla.org/embeddor.implemented/web-content-handler-registrar;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={aa3c5121-dab2-40e2-81ca-7ea25febc110}
--- a/browser/components/feeds/FeedConverter.js
+++ b/browser/components/feeds/FeedConverter.js
@@ -15,56 +15,40 @@ const FPH_CONTRACTID = "@mozilla.org/net
 const PCPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=pcast";
 
 const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
 const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
 const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
 const TYPE_ANY = "*/*";
 
 const PREF_SELECTED_APP = "browser.feeds.handlers.application";
-const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
 const PREF_SELECTED_ACTION = "browser.feeds.handler";
 const PREF_SELECTED_READER = "browser.feeds.handler.default";
 
 const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
-const PREF_VIDEO_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
 const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
 const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
 
 const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
-const PREF_AUDIO_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
 const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
 const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
 
 function getPrefAppForType(t) {
   switch (t) {
     case Ci.nsIFeed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_APP;
 
     case Ci.nsIFeed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_APP;
 
     default:
       return PREF_SELECTED_APP;
   }
 }
 
-function getPrefWebForType(t) {
-  switch (t) {
-    case Ci.nsIFeed.TYPE_VIDEO:
-      return PREF_VIDEO_SELECTED_WEB;
-
-    case Ci.nsIFeed.TYPE_AUDIO:
-      return PREF_AUDIO_SELECTED_WEB;
-
-    default:
-      return PREF_SELECTED_WEB;
-  }
-}
-
 function getPrefActionForType(t) {
   switch (t) {
     case Ci.nsIFeed.TYPE_VIDEO:
       return PREF_VIDEO_SELECTED_ACTION;
 
     case Ci.nsIFeed.TYPE_AUDIO:
       return PREF_AUDIO_SELECTED_ACTION;
 
@@ -165,61 +149,37 @@ FeedConverter.prototype = {
     // converter needs to consume all of the data and parse it, and based on
     // that determination make a judgment about type.
     //
     // Since there are no content types for this content, and I'm not going to
     // invent any, the upshot is that while a user can set an auto-handler for
     // generic feed content, the system will prevent them from setting an auto-
     // handler for other stream types. In those cases, the user will always see
     // the preview page and have to select a handler. We can guess and show
-    // a client handler, but will not be able to show web handlers for those
-    // types.
+    // a client handler.
     //
     // If this is just a feed, not some kind of specialized application, then
     // auto-handlers can be set and we should obey them.
     try {
       let feedService =
           Cc["@mozilla.org/browser/feeds/result-service;1"].
           getService(Ci.nsIFeedResultService);
       if (!this._forcePreviewPage && result.doc) {
         let feed = result.doc.QueryInterface(Ci.nsIFeed);
         let handler = Services.prefs.getCharPref(getPrefActionForType(feed.type), "ask");
 
         if (handler != "ask") {
           if (handler == "reader")
             handler = Services.prefs.getCharPref(getPrefReaderForType(feed.type), "bookmarks");
-          switch (handler) {
-            case "web":
-              let wccr =
-                  Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                  getService(Ci.nsIWebContentConverterService);
-              if ((feed.type == Ci.nsIFeed.TYPE_FEED &&
-                   wccr.getAutoHandler(TYPE_MAYBE_FEED)) ||
-                  (feed.type == Ci.nsIFeed.TYPE_VIDEO &&
-                   wccr.getAutoHandler(TYPE_MAYBE_VIDEO_FEED)) ||
-                  (feed.type == Ci.nsIFeed.TYPE_AUDIO &&
-                   wccr.getAutoHandler(TYPE_MAYBE_AUDIO_FEED))) {
-                wccr.loadPreferredHandler(this._request);
-                return;
-              }
-              break;
-
-            default:
-              LOG("unexpected handler: " + handler);
-              // fall through -- let feed service handle error
-            case "bookmarks":
-            case "client":
-            case "default":
-              try {
-                let title = feed.title ? feed.title.plainText() : "";
-                let desc = feed.subtitle ? feed.subtitle.plainText() : "";
-                feedService.addToClientReader(result.uri.spec, title, desc, feed.type, handler);
-                return;
-              } catch (ex) { /* fallback to preview mode */ }
-          }
+          try {
+            let title = feed.title ? feed.title.plainText() : "";
+            let desc = feed.subtitle ? feed.subtitle.plainText() : "";
+            feedService.addToClientReader(result.uri.spec, title, desc, feed.type, handler);
+            return;
+          } catch (ex) { /* fallback to preview mode */ }
         }
       }
 
       let chromeChannel;
 
       // handling a redirect, hence forwarding the loadInfo from the old channel
       // to the newchannel.
       let oldChannel = this._request.QueryInterface(Ci.nsIChannel);
@@ -377,18 +337,16 @@ FeedResultService.prototype = {
       // Default system feed reader
       Services.cpmm.sendAsyncMessage("FeedConverter:ExecuteClientApp",
                                      { spec,
                                        title,
                                        subtitle,
                                        feedHandler: "default" });
       break;
     default:
-      // "web" should have been handled elsewhere
-      LOG("unexpected handler: " + handler);
       // fall through
     case "bookmarks":
       Services.cpmm.sendAsyncMessage("FeedConverter:addLiveBookmark",
                                      { spec, title });
       break;
     }
   },
 
--- a/browser/components/feeds/FeedWriter.js
+++ b/browser/components/feeds/FeedWriter.js
@@ -570,36 +570,19 @@ FeedWriter.prototype = {
           });
         } else {
           this._setAlwaysUseLabel();
         }
         break;
     }
   },
 
-  _getWebHandlerElementsForURL(aURL) {
-    return this._handlersList.querySelectorAll('[webhandlerurl="' + aURL + '"]');
-  },
-
-  _setSelectedHandlerResponse(handler, url) {
-    LOG(`Selecting handler response ${handler} ${url}`);
+  _setSelectedHandlerResponse(handler) {
+    LOG(`Selecting handler response ${handler}`);
     switch (handler) {
-      case "web": {
-        if (this._handlersList) {
-          let handlers =
-            this._getWebHandlerElementsForURL(url);
-          if (handlers.length == 0) {
-            LOG(`Selected web handler isn't in the menulist ${url}`);
-            return;
-          }
-
-          handlers[0].selected = true;
-        }
-        break;
-      }
       case "client":
       case "default":
         // do nothing, these are handled by the onchange event
         break;
       case "bookmarks":
       default: {
         let liveBookmarksMenuItem = this._document.getElementById("liveBookmarksMenuItem");
         if (liveBookmarksMenuItem)
@@ -658,36 +641,17 @@ FeedWriter.prototype = {
     // "Choose Application..." menuitem
     menuItem = liveBookmarksMenuItem.cloneNode(false);
     menuItem.removeAttribute("selected");
     menuItem.setAttribute("id", "chooseApplicationMenuItem");
     menuItem.textContent = this._getString("chooseApplicationMenuItem");
 
     this._handlersList.appendChild(menuItem);
 
-    // separator
-    let chooseAppSep = liveBookmarksMenuItem.nextElementSibling.cloneNode(false);
-    chooseAppSep.textContent = liveBookmarksMenuItem.nextElementSibling.textContent;
-    this._handlersList.appendChild(chooseAppSep);
-
-    for (let handler of setupMessage.handlers) {
-      if (!handler.uri) {
-        LOG("Handler with name " + handler.name + " has no URI!? Skipping...");
-        continue;
-      }
-      menuItem = liveBookmarksMenuItem.cloneNode(false);
-      menuItem.removeAttribute("selected");
-      menuItem.className = "menuitem-iconic";
-      menuItem.textContent = handler.name;
-      menuItem.setAttribute("handlerType", "web");
-      menuItem.setAttribute("webhandlerurl", handler.uri);
-      this._handlersList.appendChild(menuItem);
-    }
-
-    this._setSelectedHandlerResponse(setupMessage.reader.handler, setupMessage.reader.url);
+    this._setSelectedHandlerResponse(setupMessage.reader.handler);
 
     if (setupMessage.defaultMenuItem) {
       LOG(`Setting default menu item ${setupMessage.defaultMenuItem}`);
       this._setApplicationLauncherMenuItem(this._defaultHandlerMenuItem, setupMessage.defaultMenuItem);
     }
     if (setupMessage.selectedMenuItem) {
       LOG(`Setting selected menu item ${setupMessage.selectedMenuItem}`);
       this._setApplicationLauncherMenuItem(this._selectedAppMenuItem, setupMessage.selectedMenuItem);
@@ -795,17 +759,16 @@ FeedWriter.prototype = {
     this._feedPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(this._feedURI, {});
 
     LOG("Subscribe Preview: feed uri = " + this._window.location.href);
 
 
     this._mm.addMessageListener("FeedWriter:PreferenceUpdated", this);
     this._mm.addMessageListener("FeedWriter:SetApplicationLauncherMenuItem", this);
     this._mm.addMessageListener("FeedWriter:GetSubscriptionUIResponse", this);
-    this._mm.addMessageListener("FeedWriter:SetFeedPrefsAndSubscribeResponse", this);
 
     const feedType = this._getFeedType();
     this._mm.sendAsyncMessage("FeedWriter:GetSubscriptionUI",
                               { feedType });
   },
 
   receiveMessage(msg) {
     if (!this._window) {
@@ -825,23 +788,19 @@ FeedWriter.prototype = {
         const feedType = this._getFeedType();
         LOG(`Got prefChange! ${JSON.stringify(msg.data)} current type: ${feedType}`);
         let feedTypePref = msg.data.default;
         if (feedType in msg.data) {
           feedTypePref = msg.data[feedType];
         }
         LOG(`Got pref ${JSON.stringify(feedTypePref)}`);
         this._setCheckboxCheckedState(feedTypePref.alwaysUse);
-        this._setSelectedHandlerResponse(feedTypePref.handler, feedTypePref.url);
+        this._setSelectedHandlerResponse(feedTypePref.handler);
         this._setAlwaysUseLabel();
         break;
-      case "FeedWriter:SetFeedPrefsAndSubscribeResponse":
-        LOG(`FeedWriter:SetFeedPrefsAndSubscribeResponse - Redirecting ${msg.data.redirect}`);
-        this._window.location.href = msg.data.redirect;
-        break;
       case "FeedWriter:GetSubscriptionUIResponse":
         // Set up the subscription UI
         this._initSubscriptionUI(msg.data);
         break;
       case "FeedWriter:SetApplicationLauncherMenuItem":
         LOG(`FeedWriter:SetApplicationLauncherMenuItem - picked ${msg.data.name}`);
         this._setApplicationLauncherMenuItem(this._selectedAppMenuItem, msg.data.name);
         // Potentially a bit racy, but I don't think we can get into a state where this callback is set and
@@ -928,37 +887,32 @@ FeedWriter.prototype = {
       let settings = {
         feedType,
         useAsDefault,
         // Pull the title and subtitle out of the document
         feedTitle: this._document.getElementById(TITLE_ID).textContent,
         feedSubtitle: this._document.getElementById(SUBTITLE_ID).textContent,
         feedLocation: this._window.location.href
       };
-      if (selectedItem.hasAttribute("webhandlerurl")) {
-        feedReader = "web";
-        settings.uri = selectedItem.getAttribute("webhandlerurl");
-      } else {
-        switch (selectedItem.id) {
-          case "selectedAppMenuItem":
-            feedReader = "client";
-            break;
-          case "defaultHandlerMenuItem":
-            feedReader = "default";
-            break;
-          case "liveBookmarksMenuItem":
-            defaultHandler = "bookmarks";
-            feedReader = "bookmarks";
-            break;
-        }
+      switch (selectedItem.id) {
+        case "selectedAppMenuItem":
+          feedReader = "client";
+          break;
+        case "defaultHandlerMenuItem":
+          feedReader = "default";
+          break;
+        case "liveBookmarksMenuItem":
+          defaultHandler = "bookmarks";
+          feedReader = "bookmarks";
+          break;
       }
       settings.reader = feedReader;
 
       // If "Always use..." is checked, we should set PREF_*SELECTED_ACTION
-      // to either "reader" (If a web reader or if an application is selected),
+      // to either "reader" (If an application is selected),
       // or to "bookmarks" (if the live bookmarks option is selected).
       // Otherwise, we should set it to "ask"
       if (!useAsDefault) {
         defaultHandler = "ask";
       }
       settings.action = defaultHandler;
       LOG(`FeedWriter:SetFeedPrefsAndSubscribe - ${JSON.stringify(settings)}`);
       this._mm.sendAsyncMessage("FeedWriter:SetFeedPrefsAndSubscribe",
--- a/browser/components/feeds/WebContentConverter.js
+++ b/browser/components/feeds/WebContentConverter.js
@@ -7,118 +7,28 @@ ChromeUtils.import("resource://gre/modul
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "PrivateBrowsingUtils",
   "resource://gre/modules/PrivateBrowsingUtils.jsm");
 
 function LOG(str) {
   // dump("*** " + str + "\n");
 }
 
-const WCCR_CONTRACTID = "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1";
 const WCCR_CLASSID = Components.ID("{792a7e82-06a0-437c-af63-b2d12e808acc}");
 
 const WCC_CLASSID = Components.ID("{db7ebf28-cc40-415f-8a51-1b111851df1e}");
 const WCC_CLASSNAME = "Web Service Handler";
 
-const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
-const TYPE_ANY = "*/*";
-
-const PREF_CONTENTHANDLERS_AUTO = "browser.contentHandlers.auto.";
-const PREF_CONTENTHANDLERS_BRANCH = "browser.contentHandlers.types.";
-const PREF_SELECTED_WEB = "browser.feeds.handlers.webservice";
-const PREF_SELECTED_ACTION = "browser.feeds.handler";
-const PREF_SELECTED_READER = "browser.feeds.handler.default";
 const PREF_HANDLER_EXTERNAL_PREFIX = "network.protocol-handler.external";
 
 const STRING_BUNDLE_URI = "chrome://browser/locale/feeds/subscribe.properties";
 
 const NS_ERROR_MODULE_DOM = 2152923136;
 const NS_ERROR_DOM_SYNTAX_ERR = NS_ERROR_MODULE_DOM + 12;
 
-function WebContentConverter() {
-}
-WebContentConverter.prototype = {
-  convert() { },
-  asyncConvertData() { },
-  onDataAvailable() { },
-  onStopRequest() { },
-
-  onStartRequest(request, context) {
-    let wccr =
-        Cc[WCCR_CONTRACTID].
-        getService(Ci.nsIWebContentConverterService);
-    wccr.loadPreferredHandler(request);
-  },
-
-  QueryInterface: ChromeUtils.generateQI(["nsIStreamConverter",
-                                          "nsIStreamListener"]),
-};
-
-let WebContentConverterFactory = {
-  createInstance(outer, iid) {
-    if (outer != null)
-      throw Cr.NS_ERROR_NO_AGGREGATION;
-    return new WebContentConverter().QueryInterface(iid);
-  },
-
-  QueryInterface: ChromeUtils.generateQI(["nsIFactory"]),
-};
-
-function ServiceInfo(contentType, uri, name) {
-  this._contentType = contentType;
-  this._uri = uri;
-  this._name = name;
-}
-ServiceInfo.prototype = {
-  /**
-   * See nsIHandlerApp
-   */
-  get name() {
-    return this._name;
-  },
-
-  /**
-   * See nsIHandlerApp
-   */
-  equals(aHandlerApp) {
-    if (!aHandlerApp)
-      throw Cr.NS_ERROR_NULL_POINTER;
-
-    if (aHandlerApp instanceof Ci.nsIWebContentHandlerInfo &&
-        aHandlerApp.contentType == this.contentType &&
-        aHandlerApp.uri == this.uri)
-      return true;
-
-    return false;
-  },
-
-  /**
-   * See nsIWebContentHandlerInfo
-   */
-  get contentType() {
-    return this._contentType;
-  },
-
-  /**
-   * See nsIWebContentHandlerInfo
-   */
-  get uri() {
-    return this._uri;
-  },
-
-  /**
-   * See nsIWebContentHandlerInfo
-   */
-  getHandlerURI(uri) {
-    return this._uri.replace(/%s/gi, encodeURIComponent(uri));
-  },
-
-  QueryInterface: ChromeUtils.generateQI(["nsIWebContentHandlerInfo"]),
-};
-
 const Utils = {
   makeURI(aURL, aOriginCharset, aBaseURI) {
     return Services.io.newURI(aURL, aOriginCharset, aBaseURI);
   },
 
   checkAndGetURI(aURIString, aContentWindow) {
     let uri;
     try {
@@ -217,35 +127,19 @@ const Utils = {
   // better.
   getSecurityError(errorString, aWindowOrNull) {
     if (!aWindowOrNull) {
       return errorString;
     }
 
     return new aWindowOrNull.DOMException(errorString, "SecurityError");
   },
-
-  /**
-   * Mappings from known feed types to our internal content type.
-   */
-  _mappings: {
-    "application/rss+xml": TYPE_MAYBE_FEED,
-    "application/atom+xml": TYPE_MAYBE_FEED,
-  },
-
-  resolveContentType(aContentType) {
-    if (aContentType in this._mappings)
-      return this._mappings[aContentType];
-    return aContentType;
-  }
 };
 
 function WebContentConverterRegistrar() {
-  this._contentTypes = {};
-  this._autoHandleContentTypes = {};
 }
 
 WebContentConverterRegistrar.prototype = {
   get stringBundle() {
     let sb = Services.strings.createBundle(STRING_BUNDLE_URI);
     delete WebContentConverterRegistrar.prototype.stringBundle;
     return WebContentConverterRegistrar.prototype.stringBundle = sb;
   },
@@ -254,87 +148,17 @@ WebContentConverterRegistrar.prototype =
     return this.stringBundle.formatStringFromName(key, params, params.length);
   },
 
   _getString(key) {
     return this.stringBundle.GetStringFromName(key);
   },
 
   /**
-   * See nsIWebContentConverterService
-   */
-  getAutoHandler(contentType) {
-    contentType = Utils.resolveContentType(contentType);
-    if (contentType in this._autoHandleContentTypes)
-      return this._autoHandleContentTypes[contentType];
-    return null;
-  },
-
-  /**
-   * See nsIWebContentConverterService
-   */
-  setAutoHandler(contentType, handler) {
-    if (handler && !this._typeIsRegistered(contentType, handler.uri))
-      throw Cr.NS_ERROR_NOT_AVAILABLE;
-
-    contentType = Utils.resolveContentType(contentType);
-    this._setAutoHandler(contentType, handler);
-
-    let ps = Services.prefs;
-    let autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
-    if (handler)
-      autoBranch.setCharPref(contentType, handler.uri);
-    else if (autoBranch.prefHasUserValue(contentType))
-      autoBranch.clearUserPref(contentType);
-
-    ps.savePrefFile(null);
-  },
-
-  /**
-   * Update the internal data structure (not persistent)
-   */
-  _setAutoHandler(contentType, handler) {
-    if (handler)
-      this._autoHandleContentTypes[contentType] = handler;
-    else if (contentType in this._autoHandleContentTypes)
-      delete this._autoHandleContentTypes[contentType];
-  },
-
-  /**
-   * See nsIWebContentConverterService
-   */
-  getWebContentHandlerByURI(contentType, uri) {
-    return this.getContentHandlers(contentType)
-               .find(e => e.uri == uri) || null;
-  },
-
-  /**
-   * See nsIWebContentConverterService
-   */
-  loadPreferredHandler(request) {
-    let channel = request.QueryInterface(Ci.nsIChannel);
-    let contentType = Utils.resolveContentType(channel.contentType);
-    let handler = this.getAutoHandler(contentType);
-    if (handler) {
-      request.cancel(Cr.NS_ERROR_FAILURE);
-
-      let triggeringPrincipal = channel.loadInfo
-        ? channel.loadInfo.triggeringPrincipal
-        : Services.scriptSecurityManager.getSystemPrincipal();
-
-      let webNavigation =
-          channel.notificationCallbacks.getInterface(Ci.nsIWebNavigation);
-      webNavigation.loadURI(handler.getHandlerURI(channel.URI.spec),
-                            Ci.nsIWebNavigation.LOAD_FLAGS_NONE,
-                            null, null, null, triggeringPrincipal);
-    }
-  },
-
-  /**
-   * See nsIWebContentConverterService
+   * See nsIWebContentHandlerRegistrar
    */
   removeProtocolHandler(aProtocol, aURITemplate) {
     let eps = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
               getService(Ci.nsIExternalProtocolService);
     let handlerInfo = eps.getProtocolHandlerInfo(aProtocol);
     let handlers =  handlerInfo.possibleApplicationHandlers;
     for (let i = 0; i < handlers.length; i++) {
       try { // We only want to test web handlers
@@ -346,39 +170,16 @@ WebContentConverterRegistrar.prototype =
           hs.store(handlerInfo);
           return;
         }
       } catch (e) { /* it wasn't a web handler */ }
     }
   },
 
   /**
-   * See nsIWebContentConverterService
-   */
-  removeContentHandler(contentType, uri) {
-    function notURI(serviceInfo) {
-      return serviceInfo.uri != uri;
-    }
-
-    if (contentType in this._contentTypes) {
-      this._contentTypes[contentType] =
-        this._contentTypes[contentType].filter(notURI);
-    }
-  },
-
-  /**
-   * These are types for which there is a separate content converter aside
-   * from our built in generic one. We should not automatically register
-   * a factory for creating a converter for these types.
-   */
-  _blockedTypes: {
-    "application/vnd.mozilla.maybe.feed": true,
-  },
-
-  /**
    * Determines if a web handler is already registered.
    *
    * @param aProtocol
    *        The scheme of the web handler we are checking for.
    * @param aURITemplate
    *        The URI template that the handler uses to handle the protocol.
    * @return true if it is already registered, false otherwise.
    */
@@ -478,61 +279,16 @@ WebContentConverterRegistrar.prototype =
     notificationBox.appendNotification(message,
                                        notificationValue,
                                        notificationIcon,
                                        notificationBox.PRIORITY_INFO_LOW,
                                        [addButton]);
   },
 
   /**
-   * See nsIWebContentHandlerRegistrar
-   * If a DOM window is provided, then the request came from content, so we
-   * prompt the user to confirm the registration.
-   */
-  registerContentHandler(aContentType, aURIString, aTitle, aWindowOrBrowser) {
-    LOG("registerContentHandler(" + aContentType + "," + aURIString + "," + aTitle + ")");
-
-    // Make sure to do our URL checks up front, before our content type check,
-    // just like the WebContentConverterRegistrarContent does.
-    let haveWindow = aWindowOrBrowser &&
-                     (aWindowOrBrowser instanceof Ci.nsIDOMWindow);
-    let uri;
-    if (haveWindow) {
-      uri = Utils.checkAndGetURI(aURIString, aWindowOrBrowser);
-    } else if (aWindowOrBrowser) {
-      // uri was vetted in the content process.
-      uri = Utils.makeURI(aURIString, null);
-    }
-
-    // We only support feed types at present.
-    let contentType = Utils.resolveContentType(aContentType);
-    // XXX We should be throwing a Utils.getSecurityError() here in at least
-    // some cases.  See bug 1266492.
-    if (contentType != TYPE_MAYBE_FEED) {
-      return;
-    }
-
-    if (aWindowOrBrowser) {
-      let notificationBox;
-      if (haveWindow) {
-        let browserWindow = this._getBrowserWindowForContentWindow(aWindowOrBrowser);
-        let browserElement = this._getBrowserForContentWindow(browserWindow, aWindowOrBrowser);
-        notificationBox = browserElement.getTabBrowser().getNotificationBox(browserElement);
-      } else {
-        notificationBox = aWindowOrBrowser.getTabBrowser()
-                                          .getNotificationBox(aWindowOrBrowser);
-      }
-
-      this._appendFeedReaderNotification(uri, aTitle, notificationBox);
-    } else {
-      this._registerContentHandler(contentType, aURIString, aTitle);
-    }
-  },
-
-  /**
    * Returns the browser chrome window in which the content window is in
    */
   _getBrowserWindowForContentWindow(aContentWindow) {
     return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                          .getInterface(Ci.nsIWebNavigation)
                          .QueryInterface(Ci.nsIDocShellTreeItem)
                          .rootTreeItem
                          .QueryInterface(Ci.nsIInterfaceRequestor)
@@ -553,493 +309,43 @@ WebContentConverterRegistrar.prototype =
   _getBrowserForContentWindow(aBrowserWindow, aContentWindow) {
     // This depends on pseudo APIs of browser.js and tabbrowser.xml
     aContentWindow = aContentWindow.top;
     return aBrowserWindow.gBrowser.browsers.find((browser) =>
       browser.contentWindow == aContentWindow);
   },
 
   /**
-   * Appends a notifcation for the given feed reader details.
-   *
-   * The notification could be either a pseudo-dialog which lets
-   * the user to add the feed reader:
-   * [ [icon] Add %feed-reader-name% (%feed-reader-host%) as a Feed Reader?  (Add) [x] ]
-   *
-   * or a simple message for the case where the feed reader is already registered:
-   * [ [icon] %feed-reader-name% is already registered as a Feed Reader             [x] ]
-   *
-   * A new notification isn't appended if the given notificationbox has a
-   * notification for the same feed reader.
-   *
-   * @param aURI
-   *        The url of the feed reader as a nsIURI object
-   * @param aName
-   *        The feed reader name as it was passed to registerContentHandler
-   * @param aNotificationBox
-   *        The notification box to which a notification might be appended
-   * @return true if a notification has been appended, false otherwise.
-   */
-  _appendFeedReaderNotification(aURI, aName, aNotificationBox) {
-    let uriSpec = aURI.spec;
-    let notificationValue = "feed reader notification: " + uriSpec;
-    let notificationIcon = aURI.prePath + "/favicon.ico";
-
-    // Don't append a new notification if the notificationbox
-    // has a notification for the given feed reader already
-    if (aNotificationBox.getNotificationWithValue(notificationValue))
-      return false;
-
-    let buttons;
-    let message;
-    if (this.getWebContentHandlerByURI(TYPE_MAYBE_FEED, uriSpec))
-      message = this._getFormattedString("handlerRegistered", [aName]);
-    else {
-      message = this._getFormattedString("addHandler", [aName, aURI.host]);
-      let self = this;
-      let addButton = {
-        _outer: self,
-        label: self._getString("addHandlerAddButton"),
-        accessKey: self._getString("addHandlerAddButtonAccesskey"),
-        feedReaderInfo: { uri: uriSpec, name: aName },
-
-        /* static */
-        callback(aNotification, aButtonInfo) {
-          let uri = aButtonInfo.feedReaderInfo.uri;
-          let name = aButtonInfo.feedReaderInfo.name;
-          let outer = aButtonInfo._outer;
-
-          // The reader could have been added from another window mean while
-          if (!outer.getWebContentHandlerByURI(TYPE_MAYBE_FEED, uri))
-            outer._registerContentHandler(TYPE_MAYBE_FEED, uri, name);
-
-          // avoid reference cycles
-          aButtonInfo._outer = null;
-
-          return false;
-        }
-      };
-      buttons = [addButton];
-    }
-
-    aNotificationBox.appendNotification(message,
-                                        notificationValue,
-                                        notificationIcon,
-                                        aNotificationBox.PRIORITY_INFO_LOW,
-                                        buttons);
-    return true;
-  },
-
-  /**
-   * Save Web Content Handler metadata to persistent preferences.
-   * @param   contentType
-   *          The content Type being handled
-   * @param   uri
-   *          The uri of the web service
-   * @param   title
-   *          The human readable name of the web service
-   *
-   * This data is stored under:
-   *
-   *    browser.contentHandlers.type0 = content/type
-   *    browser.contentHandlers.uri0 = http://www.foo.com/q=%s
-   *    browser.contentHandlers.title0 = Foo 2.0alphr
-   */
-  _saveContentHandlerToPrefs(contentType, uri, title) {
-    let ps = Services.prefs;
-    let i = 0;
-    let typeBranch = null;
-    while (true) {
-      typeBranch =
-        ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + i + ".");
-      try {
-        typeBranch.getCharPref("type");
-        ++i;
-      } catch (e) {
-        // No more handlers
-        break;
-      }
-    }
-    if (typeBranch) {
-      typeBranch.setCharPref("type", contentType);
-      let pls =
-          Cc["@mozilla.org/pref-localizedstring;1"].
-          createInstance(Ci.nsIPrefLocalizedString);
-      pls.data = uri;
-      typeBranch.setComplexValue("uri", Ci.nsIPrefLocalizedString, pls);
-      pls.data = title;
-      typeBranch.setComplexValue("title", Ci.nsIPrefLocalizedString, pls);
-
-      ps.savePrefFile(null);
-    }
-  },
-
-  /**
-   * Determines if there is a type with a particular uri registered for the
-   * specified content type already.
-   * @param   contentType
-   *          The content type that the uri handles
-   * @param   uri
-   *          The uri of the content type
-   */
-  _typeIsRegistered(contentType, uri) {
-    if (!(contentType in this._contentTypes))
-      return false;
-
-    return this._contentTypes[contentType]
-               .some(t => t.uri == uri);
-  },
-
-  /**
-   * Gets a stream converter contract id for the specified content type.
-   * @param   contentType
-   *          The source content type for the conversion.
-   * @returns A contract id to construct a converter to convert between the
-   *          contentType and *\/*.
-   */
-  _getConverterContractID(contentType) {
-    const template = "@mozilla.org/streamconv;1?from=%s&to=*/*";
-    return template.replace(/%s/, contentType);
-  },
-
-  /**
-   * Register a web service handler for a content type.
-   *
-   * @param   contentType
-   *          the content type being handled
-   * @param   uri
-   *          the URI of the web service
-   * @param   title
-   *          the human readable name of the web service
-   */
-  _registerContentHandler(contentType, uri, title) {
-    this._updateContentTypeHandlerMap(contentType, uri, title);
-    this._saveContentHandlerToPrefs(contentType, uri, title);
-
-    if (contentType == TYPE_MAYBE_FEED) {
-      // Make the new handler the last-selected reader in the preview page
-      // and make sure the preview page is shown the next time a feed is visited
-      let pb = Services.prefs.getBranch(null);
-      pb.setCharPref(PREF_SELECTED_READER, "web");
-
-      pb.setStringPref(PREF_SELECTED_WEB, uri);
-      pb.setCharPref(PREF_SELECTED_ACTION, "ask");
-      this._setAutoHandler(TYPE_MAYBE_FEED, null);
-    }
-  },
-
-  /**
-   * Update the content type -> handler map. This mapping is not persisted, use
-   * registerContentHandler or _saveContentHandlerToPrefs for that purpose.
-   * @param   contentType
-   *          The content Type being handled
-   * @param   uri
-   *          The uri of the web service
-   * @param   title
-   *          The human readable name of the web service
-   */
-  _updateContentTypeHandlerMap(contentType, uri, title) {
-    if (!(contentType in this._contentTypes))
-      this._contentTypes[contentType] = [];
-
-    // Avoid adding duplicates
-    if (this._typeIsRegistered(contentType, uri))
-      return;
-
-    this._contentTypes[contentType].push(new ServiceInfo(contentType, uri, title));
-
-    if (!(contentType in this._blockedTypes)) {
-      let converterContractID = this._getConverterContractID(contentType);
-      let cr = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-      cr.registerFactory(WCC_CLASSID, WCC_CLASSNAME, converterContractID,
-                         WebContentConverterFactory);
-    }
-  },
-
-  /**
-   * See nsIWebContentConverterService
-   */
-  getContentHandlers(contentType, countRef) {
-    if (countRef) {
-      countRef.value = 0;
-    }
-    if (!(contentType in this._contentTypes))
-      return [];
-
-    let handlers = this._contentTypes[contentType];
-    if (countRef) {
-      countRef.value = handlers.length;
-    }
-    return handlers;
-  },
-
-  /**
-   * See nsIWebContentConverterService
-   */
-  resetHandlersForType(contentType) {
-    // currently unused within the tree, so only useful for extensions; previous
-    // impl. was buggy (and even infinite-looped!), so I argue that this is a
-    // definite improvement
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  /**
-   * Registers a handler from the settings on a preferences branch.
-   *
-   * Since we support up to six predefined readers, we need to handle gaps
-   * better, since the first branch with user-added values will be .6
-   *
-   * How we deal with that is to check to see if there's no prefs in the
-   * branch and stop cycling once that's true.  This doesn't fix the case
-   * where a user manually removes a reader, but that's not supported yet!
-   *
-   * @param branch
-   *        an nsIPrefBranch containing "type", "uri", and "title" preferences
-   *        corresponding to the content handler to be registered
-   */
-  _registerContentHandlerHavingBranch(branch) {
-    let vals = branch.getChildList("");
-    if (vals.length == 0)
-      return;
-
-    let type = branch.getCharPref("type");
-    let uri = branch.getComplexValue("uri", Ci.nsIPrefLocalizedString).data;
-    let title = branch.getComplexValue("title",
-                                       Ci.nsIPrefLocalizedString).data;
-    this._updateContentTypeHandlerMap(type, uri, title);
-  },
-
-  /**
-   * Load the auto handler, content handler and protocol tables from
-   * preferences.
-   */
-  _init() {
-    let ps = Services.prefs;
-
-    let children = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH)
-                     .getChildList("");
-
-    // first get the numbers of the providers by getting all ###.uri prefs
-    let nums = children.map((child) => {
-      let match = /^(\d+)\.uri$/.exec(child);
-      return match ? match[1] : "";
-    }).filter(child => !!child)
-      .sort();
-
-
-    // now register them
-    for (let num of nums) {
-      let branch = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + num + ".");
-      try {
-        this._registerContentHandlerHavingBranch(branch);
-      } catch (ex) {
-        // do nothing, the next branch might have values
-      }
-    }
-
-    // We need to do this _after_ registering all of the available handlers,
-    // so that getWebContentHandlerByURI can return successfully.
-    let autoBranch;
-    try {
-      autoBranch = ps.getBranch(PREF_CONTENTHANDLERS_AUTO);
-    } catch (e) {
-      // No auto branch yet, that's fine
-      // LOG("WCCR.init: There is no auto branch, benign");
-    }
-
-    if (autoBranch) {
-      for (let type of autoBranch.getChildList("")) {
-        let uri = autoBranch.getCharPref(type);
-        if (uri) {
-          let handler = this.getWebContentHandlerByURI(type, uri);
-          if (handler) {
-            this._setAutoHandler(type, handler);
-          }
-        }
-      }
-    }
-  },
-
-  /**
-   * See nsIObserver
-   */
-  observe(subject, topic, data) {
-    let os = Services.obs;
-    switch (topic) {
-    case "app-startup":
-      os.addObserver(this, "browser-ui-startup-complete");
-      break;
-    case "browser-ui-startup-complete":
-      os.removeObserver(this, "browser-ui-startup-complete");
-      this._init();
-      break;
-    }
-  },
-
-  /**
    * See nsIFactory
    */
   createInstance(outer, iid) {
     if (outer != null)
       throw Cr.NS_ERROR_NO_AGGREGATION;
     return this.QueryInterface(iid);
   },
 
   classID: WCCR_CLASSID,
 
   /**
    * See nsISupports
    */
   QueryInterface: ChromeUtils.generateQI(
-     [Ci.nsIWebContentConverterService,
-      Ci.nsIWebContentHandlerRegistrar,
-      Ci.nsIObserver,
+     [Ci.nsIWebContentHandlerRegistrar,
       Ci.nsIFactory]),
 
   _xpcom_categories: [{
     category: "app-startup",
     service: true
   }]
 };
 
 function WebContentConverterRegistrarContent() {
-  this._contentTypes = {};
 }
 
 WebContentConverterRegistrarContent.prototype = {
-
-  /**
-   * Load the auto handler, content handler and protocol tables from
-   * preferences.
-   */
-  _init() {
-    let ps = Services.prefs;
-
-    let children = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH)
-                     .getChildList("");
-
-    // first get the numbers of the providers by getting all ###.uri prefs
-    let nums = children.map((child) => {
-      let match = /^(\d+)\.uri$/.exec(child);
-      return match ? match[1] : "";
-    }).filter(child => !!child)
-      .sort();
-
-    // now register them
-    for (let num of nums) {
-      let branch = ps.getBranch(PREF_CONTENTHANDLERS_BRANCH + num + ".");
-      try {
-        this._registerContentHandlerHavingBranch(branch);
-      } catch (ex) {
-        // do nothing, the next branch might have values
-      }
-    }
-  },
-
-  _typeIsRegistered(contentType, uri) {
-    return this._contentTypes[contentType]
-               .some(e => e.uri == uri);
-  },
-
-  /**
-   * Since we support up to six predefined readers, we need to handle gaps
-   * better, since the first branch with user-added values will be .6
-   *
-   * How we deal with that is to check to see if there's no prefs in the
-   * branch and stop cycling once that's true.  This doesn't fix the case
-   * where a user manually removes a reader, but that's not supported yet!
-   *
-   * @param   branch
-   *          The pref branch to register the content handler under
-   *
-   */
-  _registerContentHandlerHavingBranch(branch) {
-    let vals = branch.getChildList("");
-    if (vals.length == 0)
-      return;
-
-    let type = branch.getCharPref("type");
-    let uri = branch.getComplexValue("uri", Ci.nsIPrefLocalizedString).data;
-    let title = branch.getComplexValue("title",
-                                       Ci.nsIPrefLocalizedString).data;
-    this._updateContentTypeHandlerMap(type, uri, title);
-  },
-
-  _updateContentTypeHandlerMap(contentType, uri, title) {
-    if (!(contentType in this._contentTypes))
-      this._contentTypes[contentType] = [];
-
-    // Avoid adding duplicates
-    if (this._typeIsRegistered(contentType, uri))
-      return;
-
-    this._contentTypes[contentType].push(new ServiceInfo(contentType, uri, title));
-
-    if (!(contentType in this._blockedTypes)) {
-      let converterContractID = this._getConverterContractID(contentType);
-      let cr = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
-      cr.registerFactory(WCC_CLASSID, WCC_CLASSNAME, converterContractID,
-                         WebContentConverterFactory);
-    }
-  },
-
-  /**
-   * See nsIWebContentConverterService
-   */
-  getContentHandlers(contentType, countRef) {
-    this._init();
-    if (countRef) {
-      countRef.value = 0;
-    }
-
-    if (!(contentType in this._contentTypes))
-      return [];
-
-    let handlers = this._contentTypes[contentType];
-    if (countRef) {
-      countRef.value = handlers.length;
-    }
-    return handlers;
-  },
-
-  setAutoHandler(contentType, handler) {
-    Services.cpmm.sendAsyncMessage("WCCR:setAutoHandler",
-                                   { contentType, handler });
-  },
-
-  getWebContentHandlerByURI(contentType, uri) {
-    return this.getContentHandlers(contentType)
-               .find(e => e.uri == uri) || null;
-  },
-
-  /**
-   * See nsIWebContentHandlerRegistrar
-   */
-  registerContentHandler(aContentType, aURIString, aTitle, aBrowserOrWindow) {
-    // aBrowserOrWindow must be a window.
-    let messageManager = aBrowserOrWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                                         .getInterface(Ci.nsIWebNavigation)
-                                         .QueryInterface(Ci.nsIDocShell)
-                                         .QueryInterface(Ci.nsIInterfaceRequestor)
-                                         .getInterface(Ci.nsITabChild)
-                                         .messageManager;
-
-    let uri = Utils.checkAndGetURI(aURIString, aBrowserOrWindow);
-    // XXX We should be throwing a Utils.getSecurityError() here in at least
-    // some cases.  See bug 1266492.
-    if (Utils.resolveContentType(aContentType) != TYPE_MAYBE_FEED) {
-      return;
-    }
-
-    messageManager.sendAsyncMessage("WCCR:registerContentHandler",
-                                    { contentType: aContentType,
-                                      uri: uri.spec,
-                                      title: aTitle });
-  },
-
   registerProtocolHandler(aProtocol, aURIString, aTitle, aBrowserOrWindow) {
     aProtocol = (aProtocol || "").toLowerCase();
     // aBrowserOrWindow must be a window.
     let messageManager = aBrowserOrWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                                          .getInterface(Ci.nsIWebNavigation)
                                          .QueryInterface(Ci.nsIDocShell)
                                          .QueryInterface(Ci.nsIInterfaceRequestor)
                                          .getInterface(Ci.nsITabChild)
@@ -1065,16 +371,15 @@ WebContentConverterRegistrarContent.prot
 
   classID: WCCR_CLASSID,
 
   /**
    * See nsISupports
    */
   QueryInterface: ChromeUtils.generateQI(
                      [Ci.nsIWebContentHandlerRegistrar,
-                      Ci.nsIWebContentConverterService,
                       Ci.nsIFactory])
 };
 
 this.NSGetFactory =
   (Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_CONTENT) ?
     XPCOMUtils.generateNSGetFactory([WebContentConverterRegistrarContent]) :
     XPCOMUtils.generateNSGetFactory([WebContentConverterRegistrar]);
--- a/browser/components/feeds/moz.build
+++ b/browser/components/feeds/moz.build
@@ -7,17 +7,16 @@
 MOCHITEST_CHROME_MANIFESTS += ['test/chrome/chrome.ini']
 MOCHITEST_MANIFESTS += ['test/mochitest.ini']
 BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
 
 JAR_MANIFESTS += ['jar.mn']
 
 XPIDL_SOURCES += [
     'nsIFeedResultService.idl',
-    'nsIWebContentConverterRegistrar.idl',
 ]
 
 XPIDL_MODULE = 'browser-feeds'
 
 SOURCES += [
     'nsFeedSniffer.cpp',
 ]
 
deleted file mode 100644
--- a/browser/components/feeds/nsIWebContentConverterRegistrar.idl
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "nsIMIMEInfo.idl"
-#include "nsIWebContentHandlerRegistrar.idl"
-
-interface nsIRequest;
-
-[scriptable, uuid(eb361098-5158-4b21-8f98-50b445f1f0b2)]
-interface nsIWebContentHandlerInfo : nsIHandlerApp
-{
-  /**
-   * The content type handled by the handler
-   */
-  readonly attribute AString contentType;
-
-  /**
-   * The uri of the handler, with an embedded %s where the URI of the loaded
-   * document will be encoded.
-   */
-  readonly attribute AString uri;
-
-  /** 
-   * Gets the service URL Spec, with the loading document URI encoded in it.
-   * @param   uri
-   *          The URI of the document being loaded
-   * @returns The URI of the service with the loading document URI encoded in 
-   *          it.
-   */
-  AString getHandlerURI(in AString uri);
-};
-
-[scriptable, uuid(de7cc06e-e778-45cb-b7db-7a114e1e75b1)]
-interface nsIWebContentConverterService : nsIWebContentHandlerRegistrar
-{
-  /**
-   * Specifies the handler to be used to automatically handle all links of a
-   * certain content type from now on. 
-   * @param   contentType
-   *          The content type to automatically load with the specified handler
-   * @param   handler
-   *          A web service handler. If this is null, no automatic action is
-   *          performed and the user must choose.
-   * @throws  NS_ERROR_NOT_AVAILABLE if the service refered to by |handler| is 
-   *          not already registered.
-   */
-  void setAutoHandler(in AString contentType, in nsIWebContentHandlerInfo handler);
-
-  /**
-   * Gets the auto handler specified for a particular content type
-   * @param   contentType
-   *          The content type to look up an auto handler for.
-   * @returns The web service handler that will automatically handle all 
-   *          documents of the specified type. null if there is no automatic
-   *          handler. (Handlers may be registered, just none of them specified
-   *          as "automatic").
-   */
-  nsIWebContentHandlerInfo getAutoHandler(in AString contentType);
-
-  /**
-   * Gets a web handler for the specified service URI
-   * @param   contentType
-   *          The content type of the service being located
-   * @param   uri
-   *          The service URI of the handler to locate.
-   * @returns A web service handler that uses the specified uri.
-   */
-  nsIWebContentHandlerInfo getWebContentHandlerByURI(in AString contentType, 
-                                                     in AString uri);
-
-  /**
-   * Loads the preferred handler when content of a registered type is about
-   * to be loaded.
-   * @param   request
-   *          The nsIRequest for the load of the content
-   */
-  void loadPreferredHandler(in nsIRequest request);
-
-  /**
-   * Removes a registered protocol handler
-   * @param   protocol
-   *          The protocol scheme to remove a service handler for
-   * @param   uri
-   *          The uri of the service handler to remove
-   */
-  void removeProtocolHandler(in AString protocol, in AString uri);
-
-  /**
-   * Removes a registered content handler
-   * @param   contentType
-   *          The content type to remove a service handler for
-   * @param   uri
-   *          The uri of the service handler to remove
-   */
-  void removeContentHandler(in AString contentType, in AString uri);
-
-  /**
-   * Gets the list of content handlers for a particular type.
-   * @param   contentType
-   *          The content type to get handlers for
-   * @returns An array of nsIWebContentHandlerInfo objects
-   */
-  void getContentHandlers(in AString contentType,
-                          [optional] out unsigned long count,
-                          [retval,array,size_is(count)] out nsIWebContentHandlerInfo handlers);
-
-  /**
-   * Resets the list of available content handlers to the default set from
-   * the distribution.
-   * @param   contentType
-   *          The content type to reset handlers for
-   */
-  void resetHandlersForType(in AString contentType);
-};
-
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -202,17 +202,16 @@ const listeners = {
     // PLEASE KEEP THIS LIST IN SYNC WITH THE LISTENERS ADDED IN ContentPrefServiceParent.init
 
     // PLEASE KEEP THIS LIST IN SYNC WITH THE LISTENERS ADDED IN AsyncPrefs.init
     "AsyncPrefs:SetPref": ["AsyncPrefs"],
     "AsyncPrefs:ResetPref": ["AsyncPrefs"],
     // PLEASE KEEP THIS LIST IN SYNC WITH THE LISTENERS ADDED IN AsyncPrefs.init
 
     "FeedConverter:addLiveBookmark": ["Feeds"],
-    "WCCR:setAutoHandler": ["Feeds"],
     "webrtc:UpdateGlobalIndicators": ["webrtcUI"],
     "webrtc:UpdatingIndicators": ["webrtcUI"],
   },
 
   mm: {
     "Content:Click": ["ContentClick"],
     "ContentSearch": ["ContentSearch"],
     "FormValidation:ShowPopup": ["FormValidationHandler"],
@@ -227,17 +226,16 @@ const listeners = {
     "RemoteLogins:autoCompleteLogins": ["LoginManagerParent"],
     "RemoteLogins:removeLogin": ["LoginManagerParent"],
     "RemoteLogins:insecureLoginFormPresent": ["LoginManagerParent"],
     // For Savant Shield study, bug 1465685. Study on desktop only.
     "LoginStats:LoginFillSuccessful": ["LoginManagerParent"],
     "LoginStats:LoginEncountered": ["LoginManagerParent"],
     // PLEASE KEEP THIS LIST IN SYNC WITH THE MOBILE LISTENERS IN BrowserCLH.js
     "WCCR:registerProtocolHandler": ["Feeds"],
-    "WCCR:registerContentHandler": ["Feeds"],
     "rtcpeer:CancelRequest": ["webrtcUI"],
     "rtcpeer:Request": ["webrtcUI"],
     "webrtc:CancelRequest": ["webrtcUI"],
     "webrtc:Request": ["webrtcUI"],
     "webrtc:StopRecording": ["webrtcUI"],
     "webrtc:UpdateBrowserIndicators": ["webrtcUI"],
   },
 
--- a/browser/components/preferences/applicationManager.js
+++ b/browser/components/preferences/applicationManager.js
@@ -107,17 +107,15 @@ var gAppManagerDialog = {
     }
     document.getElementById("remove").disabled = false;
     var app = list.selectedItem.app;
     var address = "";
     if (app instanceof Ci.nsILocalHandlerApp)
       address = app.executable.path;
     else if (app instanceof Ci.nsIWebHandlerApp)
       address = app.uriTemplate;
-    else if (app instanceof Ci.nsIWebContentHandlerInfo)
-      address = app.uri;
     document.getElementById("appLocation").value = address;
     const l10nId = app instanceof Ci.nsILocalHandlerApp ? "app-manager-local-app-info"
                                                         : "app-manager-web-app-info";
     const appTypeElem = document.getElementById("appType");
     document.l10n.setAttributes(appTypeElem, l10nId);
   }
 };
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -16,17 +16,16 @@ ChromeUtils.import("resource://gre/modul
 ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm");
 ChromeUtils.defineModuleGetter(this, "CloudStorage",
   "resource://gre/modules/CloudStorage.jsm");
 
 XPCOMUtils.defineLazyServiceGetters(this, {
   gCategoryManager: ["@mozilla.org/categorymanager;1", "nsICategoryManager"],
   gHandlerService: ["@mozilla.org/uriloader/handler-service;1", "nsIHandlerService"],
   gMIMEService: ["@mozilla.org/mime;1", "nsIMIMEService"],
-  gWebContentContentConverterService: ["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1", "nsIWebContentConverterService"],
 });
 
 // Constants & Enumeration Values
 const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
 const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
 const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
 const TYPE_PDF = "application/pdf";
 
@@ -51,41 +50,35 @@ const CONTAINERS_KEY = "privacy.containe
  *
  * browser.feeds.handler
  * - "bookmarks", "reader" (clarified further using the .default preference),
  *   or "ask" -- indicates the default handler being used to process feeds;
  *   "bookmarks" is obsolete; to specify that the handler is bookmarks,
  *   set browser.feeds.handler.default to "bookmarks";
  *
  * browser.feeds.handler.default
- * - "bookmarks", "client" or "web" -- indicates the chosen feed reader used
+ * - "bookmarks" or "client" -- indicates the chosen feed reader used
  *   to display feeds, either transiently (i.e., when the "use as default"
  *   checkbox is unchecked, corresponds to when browser.feeds.handler=="ask")
  *   or more permanently (i.e., the item displayed in the dropdown in Feeds
  *   preferences)
  *
- * browser.feeds.handler.webservice
- * - the URL of the currently selected web service used to read feeds
- *
  * browser.feeds.handlers.application
  * - nsIFile, stores the current client-side feed reading app if one has
  *   been chosen
  */
 const PREF_FEED_SELECTED_APP = "browser.feeds.handlers.application";
-const PREF_FEED_SELECTED_WEB = "browser.feeds.handlers.webservice";
 const PREF_FEED_SELECTED_ACTION = "browser.feeds.handler";
 const PREF_FEED_SELECTED_READER = "browser.feeds.handler.default";
 
 const PREF_VIDEO_FEED_SELECTED_APP = "browser.videoFeeds.handlers.application";
-const PREF_VIDEO_FEED_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
 const PREF_VIDEO_FEED_SELECTED_ACTION = "browser.videoFeeds.handler";
 const PREF_VIDEO_FEED_SELECTED_READER = "browser.videoFeeds.handler.default";
 
 const PREF_AUDIO_FEED_SELECTED_APP = "browser.audioFeeds.handlers.application";
-const PREF_AUDIO_FEED_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
 const PREF_AUDIO_FEED_SELECTED_ACTION = "browser.audioFeeds.handler";
 const PREF_AUDIO_FEED_SELECTED_READER = "browser.audioFeeds.handler.default";
 
 // The nsHandlerInfoAction enumeration values in nsIHandlerInfo identify
 // the actions the application can take with content of various types.
 // But since nsIHandlerInfo doesn't support plugins, there's no value
 // identifying the "use plugin" action, so we use this constant instead.
 const kActionUsePlugin = 5;
@@ -183,27 +176,24 @@ Preferences.addAll([
   { id: "dom.ipc.processCount", type: "int" },
   { id: "dom.ipc.processCount.web", type: "int" },
   { id: "layers.acceleration.disabled", type: "bool", inverted: true },
 
   // Files and Applications
   { id: "browser.feeds.handler", type: "string" },
   { id: "browser.feeds.handler.default", type: "string" },
   { id: "browser.feeds.handlers.application", type: "file" },
-  { id: "browser.feeds.handlers.webservice", type: "string" },
 
   { id: "browser.videoFeeds.handler", type: "string" },
   { id: "browser.videoFeeds.handler.default", type: "string" },
   { id: "browser.videoFeeds.handlers.application", type: "file" },
-  { id: "browser.videoFeeds.handlers.webservice", type: "string" },
 
   { id: "browser.audioFeeds.handler", type: "string" },
   { id: "browser.audioFeeds.handler.default", type: "string" },
   { id: "browser.audioFeeds.handlers.application", type: "file" },
-  { id: "browser.audioFeeds.handlers.webservice", type: "string" },
 
   { id: "pref.downloads.disable_button.edit_actions", type: "bool" },
 
   // DRM content
   { id: "media.eme.enabled", type: "bool" },
 
   // Update
   { id: "browser.preferences.advanced.selectedTabIndex", type: "int" },
@@ -534,27 +524,24 @@ var gMainPane = {
 
     // Initilize Application section.
 
     // Observe preferences that influence what we display so we can rebuild
     // the view when they change.
     Services.prefs.addObserver(PREF_SHOW_PLUGINS_IN_LIST, this);
     Services.prefs.addObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this);
     Services.prefs.addObserver(PREF_FEED_SELECTED_APP, this);
-    Services.prefs.addObserver(PREF_FEED_SELECTED_WEB, this);
     Services.prefs.addObserver(PREF_FEED_SELECTED_ACTION, this);
     Services.prefs.addObserver(PREF_FEED_SELECTED_READER, this);
 
     Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_APP, this);
-    Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_WEB, this);
     Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_ACTION, this);
     Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_READER, this);
 
     Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_APP, this);
-    Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_WEB, this);
     Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_ACTION, this);
     Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_READER, this);
 
     setEventListener("filter", "command", gMainPane.filter);
     setEventListener("typeColumn", "click", gMainPane.sort);
     setEventListener("actionColumn", "click", gMainPane.sort);
     setEventListener("chooseFolder", "command", gMainPane.chooseFolder);
     setEventListener("saveWhere", "command", gMainPane.handleSaveToCommand);
@@ -1199,27 +1186,24 @@ var gMainPane = {
     gSubDialog.open("chrome://mozapps/content/update/history.xul");
   },
 
   destroy() {
     window.removeEventListener("unload", this);
     Services.prefs.removeObserver(PREF_SHOW_PLUGINS_IN_LIST, this);
     Services.prefs.removeObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this);
     Services.prefs.removeObserver(PREF_FEED_SELECTED_APP, this);
-    Services.prefs.removeObserver(PREF_FEED_SELECTED_WEB, this);
     Services.prefs.removeObserver(PREF_FEED_SELECTED_ACTION, this);
     Services.prefs.removeObserver(PREF_FEED_SELECTED_READER, this);
 
     Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_APP, this);
-    Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_WEB, this);
     Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_ACTION, this);
     Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_READER, this);
 
     Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_APP, this);
-    Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_WEB, this);
     Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_ACTION, this);
     Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_READER, this);
 
     Services.prefs.removeObserver(PREF_CONTAINERS_EXTENSION, this);
   },
 
 
   // nsISupports
@@ -1483,19 +1467,16 @@ var gMainPane = {
       return false;
 
     if (aHandlerApp instanceof Ci.nsILocalHandlerApp)
       return this._isValidHandlerExecutable(aHandlerApp.executable);
 
     if (aHandlerApp instanceof Ci.nsIWebHandlerApp)
       return aHandlerApp.uriTemplate;
 
-    if (aHandlerApp instanceof Ci.nsIWebContentHandlerInfo)
-      return aHandlerApp.uri;
-
     if (aHandlerApp instanceof Ci.nsIGIOMimeApp)
       return aHandlerApp.command;
 
     return false;
   },
 
   _isValidHandlerExecutable(aExecutable) {
     let leafName;
@@ -1987,19 +1968,16 @@ var gMainPane = {
 
   _getIconURLForHandlerApp(aHandlerApp) {
     if (aHandlerApp instanceof Ci.nsILocalHandlerApp)
       return this._getIconURLForFile(aHandlerApp.executable);
 
     if (aHandlerApp instanceof Ci.nsIWebHandlerApp)
       return this._getIconURLForWebApp(aHandlerApp.uriTemplate);
 
-    if (aHandlerApp instanceof Ci.nsIWebContentHandlerInfo)
-      return this._getIconURLForWebApp(aHandlerApp.uri);
-
     // We know nothing about other kinds of handler apps.
     return "";
   },
 
   _getIconURLForFile(aFile) {
     var fph = Services.io.getProtocolHandler("file").
       QueryInterface(Ci.nsIFileProtocolHandler);
     var urlSpec = fph.getURLSpecFromFile(aFile);
@@ -2866,45 +2844,29 @@ class FeedHandlerInfo extends HandlerInf
     switch (Preferences.get(this._prefSelectedReader).value) {
       case "client":
         var file = Preferences.get(this._prefSelectedApp).value;
         if (file)
           return getLocalHandlerApp(file);
 
         return null;
 
-      case "web":
-        var uri = Preferences.get(this._prefSelectedWeb).value;
-        if (!uri)
-          return null;
-        return gWebContentContentConverterService.getWebContentHandlerByURI(this.type, uri);
-
       case "bookmarks":
       default:
         // When the pref is set to bookmarks, we handle feeds internally,
         // we don't forward them to a local or web handler app, so there is
         // no preferred handler.
         return null;
     }
   }
 
   set preferredApplicationHandler(aNewValue) {
     if (aNewValue instanceof Ci.nsILocalHandlerApp) {
       Preferences.get(this._prefSelectedApp).value = aNewValue.executable;
       Preferences.get(this._prefSelectedReader).value = "client";
-    } else if (aNewValue instanceof Ci.nsIWebContentHandlerInfo) {
-      Preferences.get(this._prefSelectedWeb).value = aNewValue.uri;
-      Preferences.get(this._prefSelectedReader).value = "web";
-      // Make the web handler be the new "auto handler" for feeds.
-      // Note: we don't have to unregister the auto handler when the user picks
-      // a non-web handler (local app, Live Bookmarks, etc.) because the service
-      // only uses the "auto handler" when the selected reader is a web handler.
-      // We also don't have to unregister it when the user turns on "always ask"
-      // (i.e. preview in browser), since that also overrides the auto handler.
-      gWebContentContentConverterService.setAutoHandler(this.type, aNewValue);
     }
   }
 
   get possibleApplicationHandlers() {
     if (this._possibleApplicationHandlers)
       return this._possibleApplicationHandlers;
 
     // A minimal implementation of nsIMutableArray.  It only supports the two
@@ -2946,21 +2908,16 @@ class FeedHandlerInfo extends HandlerInf
     var preferredAppFile = Preferences.get(this._prefSelectedApp).value;
     if (preferredAppFile) {
       let preferredApp = getLocalHandlerApp(preferredAppFile);
       let defaultApp = this._defaultApplicationHandler;
       if (!defaultApp || !defaultApp.equals(preferredApp))
         this._possibleApplicationHandlers.appendElement(preferredApp);
     }
 
-    // Add the registered web handlers.  There can be any number of these.
-    var webHandlers = gWebContentContentConverterService.getContentHandlers(this.type);
-    for (let webHandler of webHandlers)
-      this._possibleApplicationHandlers.appendElement(webHandler);
-
     return this._possibleApplicationHandlers;
   }
 
   get _defaultApplicationHandler() {
     if (typeof this.__defaultApplicationHandler != "undefined")
       return this.__defaultApplicationHandler;
 
     var defaultFeedReader = null;
@@ -3089,51 +3046,44 @@ class FeedHandlerInfo extends HandlerInf
       if (app instanceof Ci.nsILocalHandlerApp) {
         let pref = Preferences.get(PREF_FEED_SELECTED_APP);
         var preferredAppFile = pref.value;
         if (preferredAppFile) {
           let preferredApp = getLocalHandlerApp(preferredAppFile);
           if (app.equals(preferredApp))
             pref.reset();
         }
-      } else {
-        app.QueryInterface(Ci.nsIWebContentHandlerInfo);
-        gWebContentContentConverterService.removeContentHandler(app.contentType,
-                                                                app.uri);
       }
     }
     this._possibleApplicationHandlers._removed = [];
   }
 
   get smallIcon() {
     return this._smallIcon;
   }
 }
 
 var feedHandlerInfo = new FeedHandlerInfo(TYPE_MAYBE_FEED, {
   _prefSelectedApp: PREF_FEED_SELECTED_APP,
-  _prefSelectedWeb: PREF_FEED_SELECTED_WEB,
   _prefSelectedAction: PREF_FEED_SELECTED_ACTION,
   _prefSelectedReader: PREF_FEED_SELECTED_READER,
   _smallIcon: "chrome://browser/skin/feeds/feedIcon16.png",
   _appPrefLabel: "webFeed"
 });
 
 var videoFeedHandlerInfo = new FeedHandlerInfo(TYPE_MAYBE_VIDEO_FEED, {
   _prefSelectedApp: PREF_VIDEO_FEED_SELECTED_APP,
-  _prefSelectedWeb: PREF_VIDEO_FEED_SELECTED_WEB,
   _prefSelectedAction: PREF_VIDEO_FEED_SELECTED_ACTION,
   _prefSelectedReader: PREF_VIDEO_FEED_SELECTED_READER,
   _smallIcon: "chrome://browser/skin/feeds/videoFeedIcon16.png",
   _appPrefLabel: "videoPodcastFeed"
 });
 
 var audioFeedHandlerInfo = new FeedHandlerInfo(TYPE_MAYBE_AUDIO_FEED, {
   _prefSelectedApp: PREF_AUDIO_FEED_SELECTED_APP,
-  _prefSelectedWeb: PREF_AUDIO_FEED_SELECTED_WEB,
   _prefSelectedAction: PREF_AUDIO_FEED_SELECTED_ACTION,
   _prefSelectedReader: PREF_AUDIO_FEED_SELECTED_READER,
   _smallIcon: "chrome://browser/skin/feeds/audioFeedIcon16.png",
   _appPrefLabel: "audioPodcastFeed"
 });
 
 /**
  * InternalHandlerInfoWrapper provides a basic mechanism to create an internal
--- a/browser/modules/Feeds.jsm
+++ b/browser/modules/Feeds.jsm
@@ -21,31 +21,16 @@ var Feeds = {
       case "WCCR:registerProtocolHandler": {
         let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
                           getService(Ci.nsIWebContentHandlerRegistrar);
         registrar.registerProtocolHandler(data.protocol, data.uri, data.title,
                                           aMessage.target);
         break;
       }
 
-      case "WCCR:registerContentHandler": {
-        let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                          getService(Ci.nsIWebContentHandlerRegistrar);
-        registrar.registerContentHandler(data.contentType, data.uri, data.title,
-                                         aMessage.target);
-        break;
-      }
-
-      case "WCCR:setAutoHandler": {
-        let registrar = Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"].
-                          getService(Ci.nsIWebContentConverterService);
-        registrar.setAutoHandler(data.contentType, data.handler);
-        break;
-      }
-
       case "FeedConverter:addLiveBookmark": {
         let topWindow = BrowserWindowTracker.getTopWindow();
         topWindow.PlacesCommandHook.addLiveBookmark(data.spec, data.title)
                                    .catch(Cu.reportError);
         break;
       }
     }
   },
--- a/dom/interfaces/sidebar/nsIWebContentHandlerRegistrar.idl
+++ b/dom/interfaces/sidebar/nsIWebContentHandlerRegistrar.idl
@@ -17,25 +17,32 @@
  * can invoke it. 
  */
 
 [scriptable, uuid(65a3fafd-0e4a-4b06-8b4e-6a611da63d98)]
 interface nsIWebContentHandlerRegistrar : nsISupports
 {
   /**
    * See documentation in Navigator.webidl
-   * The additional contentWindow param for both methods represents the dom
+   * The additional contentWindow param for this method represents the dom
    * content window from which the method has been called.
    */
-   void registerContentHandler(in DOMString mimeType,
-                               in DOMString uri,
-                               in DOMString title,
-                               in nsISupports windowOrBrowser);
    void registerProtocolHandler(in DOMString protocol,
                                 in DOMString uri,
                                 in DOMString title,
                                 in nsISupports windowOrBrowser);
+  /**
+   * Removes a registered protocol handler
+   *
+   * While registerProtocolHandler is exposed on Navigator, unregistering
+   * is exposed through the UI code.
+   * @param   protocol
+   *          The protocol scheme to remove a service handler for
+   * @param   uri
+   *          The uri of the service handler to remove
+   */
+  void removeProtocolHandler(in AString protocol, in AString uri);
 };
 
 %{ C++
 
 #define NS_WEBCONTENTHANDLERREGISTRAR_CONTRACTID "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"
 %}