Merge mozilla-central to mozilla-inbound
authorEd Morley <bmo@edmorley.co.uk>
Sat, 21 Jan 2012 02:41:20 +0000
changeset 86280 a53e3dcc585c7a81b5561cba37997f0fc3f82309
parent 86279 374975f24277430b46c4dd87d93b5eeed80548a2 (current diff)
parent 86261 099ec081e8aa1a92cfbbd0f6d007b3900e02ea53 (diff)
child 86281 f1b3f874e000b373ec052e6800e13fcb8578a6c1
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.0a1
Merge mozilla-central to mozilla-inbound
browser/base/content/browser-thumbnails.js
browser/components/thumbnails/BrowserPageThumbs.manifest
browser/components/thumbnails/Makefile.in
browser/components/thumbnails/PageThumbsProtocol.js
browser/components/thumbnails/test/Makefile.in
browser/components/thumbnails/test/browser_thumbnails_cache.js
browser/components/thumbnails/test/browser_thumbnails_capture.js
browser/components/thumbnails/test/head.js
browser/modules/PageThumbs.jsm
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -26,16 +26,18 @@ const EVENT_TEXT_CARET_MOVED = nsIAccess
 const EVENT_TEXT_INSERTED = nsIAccessibleEvent.EVENT_TEXT_INSERTED;
 const EVENT_TEXT_REMOVED = nsIAccessibleEvent.EVENT_TEXT_REMOVED;
 const EVENT_TEXT_SELECTION_CHANGED = nsIAccessibleEvent.EVENT_TEXT_SELECTION_CHANGED;
 const EVENT_VALUE_CHANGE = nsIAccessibleEvent.EVENT_VALUE_CHANGE;
 
 ////////////////////////////////////////////////////////////////////////////////
 // General
 
+Components.utils.import("resource://gre/modules/Services.jsm");
+
 /**
  * Set up this variable to dump events into DOM.
  */
 var gA11yEventDumpID = "";
 
 /**
  * Set up this variable to dump event processing into console.
  */
@@ -1409,34 +1411,28 @@ function expandedStateChecker(aIsEnabled
 ////////////////////////////////////////////////////////////////////////////////
 // General
 
 var gA11yEventListeners = {};
 var gA11yEventApplicantsCount = 0;
 
 var gA11yEventObserver =
 {
-  // The service reference needs to live in the observer, instead of as a global var,
-  //   to be available in observe() catch case too.
-  observerService :
-    Components.classes["@mozilla.org/observer-service;1"]
-              .getService(nsIObserverService),
-
   observe: function observe(aSubject, aTopic, aData)
   {
     if (aTopic != "accessible-event")
       return;
 
     var event;
     try {
       event = aSubject.QueryInterface(nsIAccessibleEvent);
     } catch (ex) {
       // After a test is aborted (i.e. timed out by the harness), this exception is soon triggered.
       // Remove the leftover observer, otherwise it "leaks" to all the following tests.
-      this.observerService.removeObserver(this, "accessible-event");
+      Services.obs.removeObserver(this, "accessible-event");
       // Forward the exception, with added explanation.
       throw "[accessible/events.js, gA11yEventObserver.observe] This is expected if a previous test has been aborted... Initial exception was: [ " + ex + " ]";
     }
     var listenersArray = gA11yEventListeners[event.eventType];
 
     var eventFromDumpArea = false;
     if (gLogger.isEnabled()) { // debug stuff
       eventFromDumpArea = true;
@@ -1480,24 +1476,22 @@ var gA11yEventObserver =
   }
 };
 
 function listenA11yEvents(aStartToListen)
 {
   if (aStartToListen) {
     // Add observer when adding the first applicant only.
     if (!(gA11yEventApplicantsCount++))
-      gA11yEventObserver.observerService
-                        .addObserver(gA11yEventObserver, "accessible-event", false);
+      Services.obs.addObserver(gA11yEventObserver, "accessible-event", false);
   } else {
     // Remove observer when there are no more applicants only.
     // '< 0' case should not happen, but just in case: removeObserver() will throw.
     if (--gA11yEventApplicantsCount <= 0)
-      gA11yEventObserver.observerService
-                        .removeObserver(gA11yEventObserver, "accessible-event");
+      Services.obs.removeObserver(gA11yEventObserver, "accessible-event");
   }
 }
 
 function addA11yEventListener(aEventType, aEventHandler)
 {
   if (!(aEventType in gA11yEventListeners))
     gA11yEventListeners[aEventType] = new Array();
 
@@ -1604,21 +1598,18 @@ var gLogger =
   },
 
   /**
    * Log message to error console.
    */
   logToAppConsole: function logger_logToAppConsole(aMsg)
   {
     if (gA11yEventDumpToAppConsole)
-      consoleService.logStringMessage("events: " + aMsg);
-  },
-
-  consoleService: Components.classes["@mozilla.org/consoleservice;1"].
-    getService(Components.interfaces.nsIConsoleService)
+      Services.console.logStringMessage("events: " + aMsg);
+  }
 };
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // Sequence
 
 /**
  * Base class of sequence item.
--- a/accessible/tests/mochitest/events/test_focus_autocomplete.xul
+++ b/accessible/tests/mochitest/events/test_focus_autocomplete.xul
@@ -1,15 +1,19 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                  type="text/css"?>
 
+<!-- Firefox searchbar -->
 <?xml-stylesheet href="chrome://browser/content/browser.css"
                  type="text/css"?>
+<!-- SeaMonkey searchbar -->
+<?xml-stylesheet href="chrome://navigator/content/navigator.css"
+                 type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         title="Accessible focus event testing">
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
--- a/accessible/tests/mochitest/focus/test_takeFocus.xul
+++ b/accessible/tests/mochitest/focus/test_takeFocus.xul
@@ -1,16 +1,13 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                  type="text/css"?>
 
-<?xml-stylesheet href="chrome://browser/content/browser.css"
-                 type="text/css"?>
-
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         title="Accessible focus testing">
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
 
--- a/accessible/tests/mochitest/states/test_expandable.xul
+++ b/accessible/tests/mochitest/states/test_expandable.xul
@@ -1,14 +1,19 @@
 <?xml version="1.0"?>
 <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
                  type="text/css"?>
+
+<!-- Firefox searchbar -->
 <?xml-stylesheet href="chrome://browser/content/browser.css"
                  type="text/css"?>
+<!-- SeaMonkey searchbar -->
+<?xml-stylesheet href="chrome://navigator/content/navigator.css"
+                 type="text/css"?>
 
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         title="Expanded state change events tests for comboboxes and autocompletes.">
 
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
   <script type="application/javascript"
           src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" />
deleted file mode 100644
--- a/browser/base/content/browser-thumbnails.js
+++ /dev/null
@@ -1,119 +0,0 @@
-#ifdef 0
-/* 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/. */
-#endif
-
-/**
- * Keeps thumbnails of open web pages up-to-date.
- */
-let gBrowserThumbnails = {
-  _captureDelayMS: 2000,
-
-  /**
-   * Map of capture() timeouts assigned to their browsers.
-   */
-  _timeouts: null,
-
-  /**
-   * Cache for the PageThumbs module.
-   */
-  _pageThumbs: null,
-
-  /**
-   * List of tab events we want to listen for.
-   */
-  _tabEvents: ["TabClose", "TabSelect"],
-
-  init: function Thumbnails_init() {
-    gBrowser.addTabsProgressListener(this);
-
-    this._tabEvents.forEach(function (aEvent) {
-      gBrowser.tabContainer.addEventListener(aEvent, this, false);
-    }, this);
-
-    this._timeouts = new WeakMap();
-
-    XPCOMUtils.defineLazyModuleGetter(this, "_pageThumbs",
-      "resource:///modules/PageThumbs.jsm", "PageThumbs");
-  },
-
-  uninit: function Thumbnails_uninit() {
-    gBrowser.removeTabsProgressListener(this);
-
-    this._tabEvents.forEach(function (aEvent) {
-      gBrowser.tabContainer.removeEventListener(aEvent, this, false);
-    }, this);
-
-    this._timeouts = null;
-    this._pageThumbs = null;
-  },
-
-  handleEvent: function Thumbnails_handleEvent(aEvent) {
-    switch (aEvent.type) {
-      case "TabSelect":
-        this._delayedCapture(aEvent.target.linkedBrowser);
-        break;
-      case "TabClose": {
-        let browser = aEvent.target.linkedBrowser;
-        if (this._timeouts.has(browser)) {
-          clearTimeout(this._timeouts.get(browser));
-          this._timeouts.delete(browser);
-        }
-        break;
-      }
-    }
-  },
-
-  /**
-   * State change progress listener for all tabs.
-   */
-  onStateChange: function Thumbnails_onStateChange(aBrowser, aWebProgress,
-                                                   aRequest, aStateFlags, aStatus) {
-    if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
-        aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK)
-      this._delayedCapture(aBrowser);
-  },
-
-  _capture: function Thumbnails_capture(aBrowser) {
-    if (this._shouldCapture(aBrowser)) {
-      let canvas = this._pageThumbs.capture(aBrowser.contentWindow);
-      this._pageThumbs.store(aBrowser.currentURI.spec, canvas);
-    }
-  },
-
-  _delayedCapture: function Thumbnails_delayedCapture(aBrowser) {
-    if (this._timeouts.has(aBrowser))
-      clearTimeout(this._timeouts.get(aBrowser));
-
-    let timeout = setTimeout(function () {
-      this._timeouts.delete(aBrowser);
-      this._capture(aBrowser);
-    }.bind(this), this._captureDelayMS);
-
-    this._timeouts.set(aBrowser, timeout);
-  },
-
-  _shouldCapture: function Thumbnails_shouldCapture(aBrowser) {
-    // There's no point in taking screenshot of loading pages.
-    if (aBrowser.docShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
-      return false;
-
-    // Don't take screenshots of about: pages.
-    if (aBrowser.currentURI.schemeIs("about"))
-      return false;
-
-    let channel = aBrowser.docShell.currentDocumentChannel;
-
-    try {
-      // If the channel is a nsIHttpChannel get its http status code.
-      let httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
-
-      // Continue only if we have a 2xx status code.
-      return Math.floor(httpChannel.responseStatus / 100) == 2;
-    } catch (e) {
-      // Not a http channel, we just assume a success status code.
-      return true;
-    }
-  }
-};
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -191,17 +191,16 @@ let gInitialPages = [
   "about:privatebrowsing",
   "about:sessionrestore"
 ];
 
 #include browser-fullZoom.js
 #include browser-places.js
 #include browser-tabPreviews.js
 #include browser-tabview.js
-#include browser-thumbnails.js
 
 #ifdef MOZ_SERVICES_SYNC
 #include browser-syncui.js
 #endif
 
 XPCOMUtils.defineLazyGetter(this, "Win7Features", function () {
 #ifdef XP_WIN
   const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
@@ -1695,17 +1694,16 @@ function delayedStartup(isLoadingBlank, 
   if (document.mozFullScreen)
     onMozFullScreenChange();
 
 #ifdef MOZ_SERVICES_SYNC
   // initialize the sync UI
   gSyncUI.init();
 #endif
 
-  gBrowserThumbnails.init();
   TabView.init();
 
   setUrlAndSearchBarWidthForConditionalForwardButton();
   window.addEventListener("resize", function resizeHandler(event) {
     if (event.target == window)
       setUrlAndSearchBarWidthForConditionalForwardButton();
   });
 
@@ -1817,17 +1815,16 @@ function BrowserShutdown() {
   } else {
     if (Win7Features)
       Win7Features.onCloseWindow();
 
     gPrefService.removeObserver(ctrlTab.prefName, ctrlTab);
     gPrefService.removeObserver(allTabs.prefName, allTabs);
     ctrlTab.uninit();
     TabView.uninit();
-    gBrowserThumbnails.uninit();
 
     try {
       FullZoom.destroy();
     }
     catch(ex) {
       Components.utils.reportError(ex);
     }
 
--- a/browser/base/content/test/browser_bug416661.js
+++ b/browser/base/content/test/browser_bug416661.js
@@ -38,17 +38,18 @@ function test() {
   gBrowser.selectedTab = tabElm;
 
   afterZoomAndLoad(start_test_prefNotSet);
   content.location = 
     "http://mochi.test:8888/browser/browser/base/content/test/zoom_test.html";
 }
 
 function afterZoomAndLoad(cb) {
-  let didLoad = didZoom = false;
+  let didLoad = false;
+  let didZoom = false;
   tabElm.linkedBrowser.addEventListener("load", function() {
     tabElm.linkedBrowser.removeEventListener("load", arguments.callee, true);
     didLoad = true;
     if (didZoom)
       executeSoon(cb);
   }, true);
   let oldSZFB = ZoomManager.setZoomForBrowser;
   ZoomManager.setZoomForBrowser = function(browser, value) {
--- a/browser/base/content/test/browser_bug555224.js
+++ b/browser/base/content/test/browser_bug555224.js
@@ -32,17 +32,18 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 const TEST_PAGE = "/browser/browser/base/content/test/dummy_page.html";
 var gTestTab, gBgTab, gTestZoom;
 
 function afterZoomAndLoad(aCallback, aTab) {
-  let didLoad = didZoom = false;
+  let didLoad = false;
+  let didZoom = false;
   aTab.linkedBrowser.addEventListener("load", function() {
     aTab.linkedBrowser.removeEventListener("load", arguments.callee, true);
     didLoad = true;
     if (didZoom)
       executeSoon(aCallback);
   }, true);
   let oldAPTS = FullZoom._applyPrefToSetting;
   FullZoom._applyPrefToSetting = function(value, browser) {
--- a/browser/base/content/test/browser_bug592338.js
+++ b/browser/base/content/test/browser_bug592338.js
@@ -1,15 +1,17 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 const TESTROOT = "http://example.com/browser/toolkit/mozapps/extensions/test/xpinstall/";
 
-Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm");
+var tempScope = {};
+Components.utils.import("resource://gre/modules/LightweightThemeManager.jsm", tempScope);
+var LightweightThemeManager = tempScope.LightweightThemeManager;
 
 function wait_for_notification(aCallback) {
   PopupNotifications.panel.addEventListener("popupshown", function() {
     PopupNotifications.panel.removeEventListener("popupshown", arguments.callee, false);
     aCallback(PopupNotifications.panel);
   }, false);
 }
 
--- a/browser/base/content/test/browser_bug623155.js
+++ b/browser/base/content/test/browser_bug623155.js
@@ -38,16 +38,18 @@ 6. The redirected URI is <https://www.ba
    a cert-error page.
 
 7. Check the URLbar's value, expecting <https://www.bank1.com/#FG>
 
 8. End.
 
  */
 
+var gNewTab;
+
 function test() {
   waitForExplicitFinish();
 
   // Load a URI in the background.
   gNewTab = gBrowser.addTab(REDIRECT_FROM + "#BG");
   gBrowser.getBrowserForTab(gNewTab)
           .webProgress
           .addProgressListener(gWebProgressListener,
--- a/browser/base/content/test/browser_gestureSupport.js
+++ b/browser/base/content/test/browser_gestureSupport.js
@@ -378,17 +378,17 @@ function test_latchedGesture(gesture, in
   };
 
   // Test the gestures in each direction.
   test_emitLatchedEvents(eventPrefix, 500, cmd);
   test_emitLatchedEvents(eventPrefix, -500, cmd);
 
   // Restore the gesture to its original configuration.
   gPrefService.setBoolPref(branch + "latched", oldLatchedValue);
-  for (dir in cmd)
+  for (let dir in cmd)
     test_removeCommand(cmd[dir]);
 }
 
 // Test whether non-latched events are triggered upon sufficient motion.
 function test_thresholdGesture(gesture, inc, dec, eventPrefix)
 {
   let branch = test_prefBranch + gesture + ".";
 
--- a/browser/base/content/test/browser_identity_UI.js
+++ b/browser/base/content/test/browser_identity_UI.js
@@ -63,17 +63,17 @@ var tests = [
   {
     name: "IP address",
     location: "http://127.0.0.1:8888/",
     host: "127.0.0.1:8888",
     effectiveHost: "127.0.0.1"
   },
 ]
 
-let gCurrentTest, gCurrentTestIndex = -1;
+let gCurrentTest, gCurrentTestIndex = -1, gTestDesc;
 // Go through the tests in both directions, to add additional coverage for
 // transitions between different states.
 let gForward = true;
 function nextTest() {
   if (gForward)
     gCurrentTestIndex++;
   else
     gCurrentTestIndex--;
--- a/browser/components/Makefile.in
+++ b/browser/components/Makefile.in
@@ -66,17 +66,16 @@ PARALLEL_DIRS = \
   places \
   preferences \
   privatebrowsing \
   search \
   sessionstore \
   shell \
   sidebar \
   tabview \
-  thumbnails \
   migration \
   $(NULL)
 
 ifdef MOZ_SAFE_BROWSING
 PARALLEL_DIRS += safebrowsing
 endif
 
 TEST_DIRS += test
deleted file mode 100644
--- a/browser/components/thumbnails/BrowserPageThumbs.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-component {5a4ae9b5-f475-48ae-9dce-0b4c1d347884} PageThumbsProtocol.js
-contract @mozilla.org/network/protocol;1?name=moz-page-thumb {5a4ae9b5-f475-48ae-9dce-0b4c1d347884}
deleted file mode 100644
--- a/browser/components/thumbnails/Makefile.in
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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/.
-
-DEPTH		= ../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-EXTRA_COMPONENTS = \
-  BrowserPageThumbs.manifest \
-  PageThumbsProtocol.js \
-  $(NULL)
-
-ifdef ENABLE_TESTS
-	DIRS += test
-endif
-
-include $(topsrcdir)/config/rules.mk
-
-XPIDL_FLAGS += -I$(topsrcdir)/browser/components/
deleted file mode 100644
--- a/browser/components/thumbnails/PageThumbsProtocol.js
+++ /dev/null
@@ -1,448 +0,0 @@
-/* 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/. */
-
-/**
- * PageThumbsProtocol.js
- *
- * This file implements the moz-page-thumb:// protocol and the corresponding
- * channel delivering cached thumbnails.
- *
- * URL structure:
- *
- * moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F
- *
- * This URL requests an image for 'http://www.mozilla.org/'.
- */
-
-"use strict";
-
-const Cu = Components.utils;
-const Cc = Components.classes;
-const Cr = Components.results;
-const Ci = Components.interfaces;
-
-Cu.import("resource:///modules/PageThumbs.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
-  "resource://gre/modules/NetUtil.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Services",
-  "resource://gre/modules/Services.jsm");
-
-/**
- * Implements the thumbnail protocol handler responsible for moz-page-thumb: URIs.
- */
-function Protocol() {
-}
-
-Protocol.prototype = {
-  /**
-   * The scheme used by this protocol.
-   */
-  get scheme() PageThumbs.scheme,
-
-  /**
-   * The default port for this protocol (we don't support ports).
-   */
-  get defaultPort() -1,
-
-  /**
-   * The flags specific to this protocol implementation.
-   */
-  get protocolFlags() {
-    return Ci.nsIProtocolHandler.URI_IS_UI_RESOURCE |
-           Ci.nsIProtocolHandler.URI_NORELATIVE |
-           Ci.nsIProtocolHandler.URI_NOAUTH;
-  },
-
-  /**
-   * Creates a new URI object that is suitable for loading by this protocol.
-   * @param aSpec The URI string in UTF8 encoding.
-   * @param aOriginCharset The charset of the document from which the URI originated.
-   * @return The newly created URI.
-   */
-  newURI: function Proto_newURI(aSpec, aOriginCharset) {
-    let uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
-    uri.spec = aSpec;
-    return uri;
-  },
-
-  /**
-   * Constructs a new channel from the given URI for this protocol handler.
-   * @param aURI The URI for which to construct a channel.
-   * @return The newly created channel.
-   */
-  newChannel: function Proto_newChannel(aURI) {
-    return new Channel(aURI);
-  },
-
-  /**
-   * Decides whether to allow a blacklisted port.
-   * @return Always false, we'll never allow ports.
-   */
-  allowPort: function () false,
-
-  classID: Components.ID("{5a4ae9b5-f475-48ae-9dce-0b4c1d347884}"),
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler])
-};
-
-let NSGetFactory = XPCOMUtils.generateNSGetFactory([Protocol]);
-
-/**
- * A channel implementation responsible for delivering cached thumbnails.
- */
-function Channel(aURI) {
-  this._uri = aURI;
-
-  // nsIChannel
-  this.originalURI = aURI;
-
-  // nsIHttpChannel
-  this._responseHeaders = {"content-type": PageThumbs.contentType};
-}
-
-Channel.prototype = {
-  /**
-   * Tracks if the channel has been opened, yet.
-   */
-  _wasOpened: false,
-
-  /**
-   * Opens this channel asynchronously.
-   * @param aListener The listener that receives the channel data when available.
-   * @param aContext A custom context passed to the listener's methods.
-   */
-  asyncOpen: function Channel_asyncOpen(aListener, aContext) {
-    if (this._wasOpened)
-      throw Cr.NS_ERROR_ALREADY_OPENED;
-
-    if (this.canceled)
-      return;
-
-    this._listener = aListener;
-    this._context = aContext;
-
-    this._isPending = true;
-    this._wasOpened = true;
-
-    // Try to read the data from the thumbnail cache.
-    this._readCache(function (aData) {
-      // Update response if there's no data.
-      if (!aData) {
-        this._responseStatus = 404;
-        this._responseText = "Not Found";
-      }
-
-      this._startRequest();
-
-      if (!this.canceled) {
-        this._addToLoadGroup();
-
-        if (aData)
-          this._serveData(aData);
-
-        if (!this.canceled)
-          this._stopRequest();
-      }
-    }.bind(this));
-  },
-
-  /**
-   * Reads a data stream from the cache entry.
-   * @param aCallback The callback the data is passed to.
-   */
-  _readCache: function Channel_readCache(aCallback) {
-    let {url} = parseURI(this._uri);
-
-    // Return early if there's no valid URL given.
-    if (!url) {
-      aCallback(null);
-      return;
-    }
-
-    // Try to get a cache entry.
-    PageThumbsCache.getReadEntry(url, function (aEntry) {
-      let inputStream = aEntry && aEntry.openInputStream(0);
-
-      function closeEntryAndFinish(aData) {
-        if (aEntry) {
-          aEntry.close();
-        }
-        aCallback(aData);
-      }
-
-      // Check if we have a valid entry and if it has any data.
-      if (!inputStream || !inputStream.available()) {
-        closeEntryAndFinish();
-        return;
-      }
-
-      try {
-        // Read the cache entry's data.
-        NetUtil.asyncFetch(inputStream, function (aData, aStatus) {
-          // We might have been canceled while waiting.
-          if (this.canceled)
-            return;
-
-          // Check if we have a valid data stream.
-          if (!Components.isSuccessCode(aStatus) || !aData.available())
-            aData = null;
-
-          closeEntryAndFinish(aData);
-        }.bind(this));
-      } catch (e) {
-        closeEntryAndFinish();
-      }
-    }.bind(this));
-  },
-
-  /**
-   * Calls onStartRequest on the channel listener.
-   */
-  _startRequest: function Channel_startRequest() {
-    try {
-      this._listener.onStartRequest(this, this._context);
-    } catch (e) {
-      // The listener might throw if the request has been canceled.
-      this.cancel(Cr.NS_BINDING_ABORTED);
-    }
-  },
-
-  /**
-   * Calls onDataAvailable on the channel listener and passes the data stream.
-   * @param aData The data to be delivered.
-   */
-  _serveData: function Channel_serveData(aData) {
-    try {
-      let available = aData.available();
-      this._listener.onDataAvailable(this, this._context, aData, 0, available);
-    } catch (e) {
-      // The listener might throw if the request has been canceled.
-      this.cancel(Cr.NS_BINDING_ABORTED);
-    }
-  },
-
-  /**
-   * Calls onStopRequest on the channel listener.
-   */
-  _stopRequest: function Channel_stopRequest() {
-    try {
-      this._listener.onStopRequest(this, this._context, this.status);
-    } catch (e) {
-      // This might throw but is generally ignored.
-    }
-
-    // The request has finished, clean up after ourselves.
-    this._cleanup();
-  },
-
-  /**
-   * Adds this request to the load group, if any.
-   */
-  _addToLoadGroup: function Channel_addToLoadGroup() {
-    if (this.loadGroup)
-      this.loadGroup.addRequest(this, this._context);
-  },
-
-  /**
-   * Removes this request from its load group, if any.
-   */
-  _removeFromLoadGroup: function Channel_removeFromLoadGroup() {
-    if (!this.loadGroup)
-      return;
-
-    try {
-      this.loadGroup.removeRequest(this, this._context, this.status);
-    } catch (e) {
-      // This might throw but is ignored.
-    }
-  },
-
-  /**
-   * Cleans up the channel when the request has finished.
-   */
-  _cleanup: function Channel_cleanup() {
-    this._removeFromLoadGroup();
-    this.loadGroup = null;
-
-    this._isPending = false;
-
-    delete this._listener;
-    delete this._context;
-  },
-
-  /* :::::::: nsIChannel ::::::::::::::: */
-
-  contentType: PageThumbs.contentType,
-  contentLength: -1,
-  owner: null,
-  contentCharset: null,
-  notificationCallbacks: null,
-
-  get URI() this._uri,
-  get securityInfo() null,
-
-  /**
-   * Opens this channel synchronously. Not supported.
-   */
-  open: function Channel_open() {
-    // Synchronous data delivery is not implemented.
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  /* :::::::: nsIHttpChannel ::::::::::::::: */
-
-  redirectionLimit: 10,
-  requestMethod: "GET",
-  allowPipelining: true,
-  referrer: null,
-
-  get requestSucceeded() true,
-
-  _responseStatus: 200,
-  get responseStatus() this._responseStatus,
-
-  _responseText: "OK",
-  get responseStatusText() this._responseText,
-
-  /**
-   * Checks if the server sent the equivalent of a "Cache-control: no-cache"
-   * response header.
-   * @return Always false.
-   */
-  isNoCacheResponse: function () false,
-
-  /**
-   * Checks if the server sent the equivalent of a "Cache-control: no-cache"
-   * response header.
-   * @return Always false.
-   */
-  isNoStoreResponse: function () false,
-
-  /**
-   * Returns the value of a particular request header. Not implemented.
-   */
-  getRequestHeader: function Channel_getRequestHeader() {
-    throw Cr.NS_ERROR_NOT_AVAILABLE;
-  },
-
-  /**
-   * This method is called to set the value of a particular request header.
-   * Not implemented.
-   */
-  setRequestHeader: function Channel_setRequestHeader() {
-    if (this._wasOpened)
-      throw Cr.NS_ERROR_IN_PROGRESS;
-  },
-
-  /**
-   * Call this method to visit all request headers. Not implemented.
-   */
-  visitRequestHeaders: function () {},
-
-  /**
-   * Gets the value of a particular response header.
-   * @param aHeader The case-insensitive name of the response header to query.
-   * @return The header value.
-   */
-  getResponseHeader: function Channel_getResponseHeader(aHeader) {
-    let name = aHeader.toLowerCase();
-    if (name in this._responseHeaders)
-      return this._responseHeaders[name];
-
-    throw Cr.NS_ERROR_NOT_AVAILABLE;
-  },
-
-  /**
-   * This method is called to set the value of a particular response header.
-   * @param aHeader The case-insensitive name of the response header to query.
-   * @param aValue The response header value to set.
-   */
-  setResponseHeader: function Channel_setResponseHeader(aHeader, aValue, aMerge) {
-    let name = aHeader.toLowerCase();
-    if (!aValue && !aMerge)
-      delete this._responseHeaders[name];
-    else
-      this._responseHeaders[name] = aValue;
-  },
-
-  /**
-   * Call this method to visit all response headers.
-   * @param aVisitor The header visitor.
-   */
-  visitResponseHeaders: function Channel_visitResponseHeaders(aVisitor) {
-    for (let name in this._responseHeaders) {
-      let value = this._responseHeaders[name];
-
-      try {
-        aVisitor.visitHeader(name, value);
-      } catch (e) {
-        // The visitor can throw to stop the iteration.
-        return;
-      }
-    }
-  },
-
-  /* :::::::: nsIRequest ::::::::::::::: */
-
-  loadFlags: Ci.nsIRequest.LOAD_NORMAL,
-  loadGroup: null,
-
-  get name() this._uri.spec,
-
-  _status: Cr.NS_OK,
-  get status() this._status,
-
-  _isPending: false,
-  isPending: function () this._isPending,
-
-  resume: function () {},
-  suspend: function () {},
-
-  /**
-   * Cancels this request.
-   * @param aStatus The reason for cancelling.
-   */
-  cancel: function Channel_cancel(aStatus) {
-    if (this.canceled)
-      return;
-
-    this._isCanceled = true;
-    this._status = aStatus;
-
-    this._cleanup();
-  },
-
-  /* :::::::: nsIHttpChannelInternal ::::::::::::::: */
-
-  documentURI: null,
-
-  _isCanceled: false,
-  get canceled() this._isCanceled,
-
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel,
-                                         Ci.nsIHttpChannel,
-                                         Ci.nsIHttpChannelInternal,
-                                         Ci.nsIRequest])
-};
-
-/**
- * Parses a given URI and extracts all parameters relevant to this protocol.
- * @param aURI The URI to parse.
- * @return The parsed parameters.
- */
-function parseURI(aURI) {
-  let {scheme, staticHost} = PageThumbs;
-  let re = new RegExp("^" + scheme + "://" + staticHost + ".*?\\?");
-  let query = aURI.spec.replace(re, "");
-  let params = {};
-
-  query.split("&").forEach(function (aParam) {
-    let [key, value] = aParam.split("=").map(decodeURIComponent);
-    params[key.toLowerCase()] = value;
-  });
-
-  return params;
-}
deleted file mode 100644
--- a/browser/components/thumbnails/test/Makefile.in
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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/.
-
-DEPTH		= ../../../..
-topsrcdir	= @top_srcdir@
-srcdir		= @srcdir@
-VPATH		= @srcdir@
-relativesrcdir  = browser/components/thumbnails/test
-
-include $(DEPTH)/config/autoconf.mk
-include $(topsrcdir)/config/rules.mk
-
-_BROWSER_FILES = \
-	browser_thumbnails_cache.js \
-	browser_thumbnails_capture.js \
-	head.js \
-	$(NULL)
-
-libs::	$(_BROWSER_FILES)
-	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
deleted file mode 100644
--- a/browser/components/thumbnails/test/browser_thumbnails_cache.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * These tests ensure that saving a thumbnail to the cache works. They also
- * retrieve the thumbnail and display it using an <img> element to compare
- * its pixel colors.
- */
-function runTests() {
-  // Create a new tab with a red background.
-  yield addTab("data:text/html,<body bgcolor=ff0000></body>");
-  let cw = gBrowser.selectedTab.linkedBrowser.contentWindow;
-
-  // Capture a thumbnail for the tab.
-  let canvas = PageThumbs.capture(cw);
-
-  // Store the tab into the thumbnail cache.
-  yield PageThumbs.store("key", canvas, next);
-
-  let {width, height} = canvas;
-  let thumb = PageThumbs.getThumbnailURL("key", width, height);
-
-  // Create a new tab with an image displaying the previously stored thumbnail.
-  yield addTab("data:text/html,<img src='" + thumb + "'/>" + 
-               "<canvas width=" + width + " height=" + height + "/>");
-
-  cw = gBrowser.selectedTab.linkedBrowser.contentWindow;
-  let [img, canvas] = cw.document.querySelectorAll("img, canvas");
-
-  // Draw the image to a canvas and compare the pixel color values.
-  let ctx = canvas.getContext("2d");
-  ctx.drawImage(img, 0, 0, width, height);
-  checkCanvasColor(ctx, 255, 0, 0, "we have a red image and canvas");
-}
deleted file mode 100644
--- a/browser/components/thumbnails/test/browser_thumbnails_capture.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * These tests ensure that capturing a site's screenshot to a canvas actually
- * works.
- */
-function runTests() {
-  // Create a tab with a red background.
-  yield addTab("data:text/html,<body bgcolor=ff0000></body>");
-  checkCurrentThumbnailColor(255, 0, 0, "we have a red thumbnail");
-
-  // Load a page with a green background.
-  yield navigateTo("data:text/html,<body bgcolor=00ff00></body>");
-  checkCurrentThumbnailColor(0, 255, 0, "we have a green thumbnail");
-
-  // Load a page with a blue background.
-  yield navigateTo("data:text/html,<body bgcolor=0000ff></body>");
-  checkCurrentThumbnailColor(0, 0, 255, "we have a blue thumbnail");
-}
-
-/**
- * Captures a thumbnail of the currently selected tab and checks the color of
- * the resulting canvas.
- * @param aRed The red component's intensity.
- * @param aGreen The green component's intensity.
- * @param aBlue The blue component's intensity.
- * @param aMessage The info message to print when checking the pixel color.
- */
-function checkCurrentThumbnailColor(aRed, aGreen, aBlue, aMessage) {
-  let tab = gBrowser.selectedTab;
-  let cw = tab.linkedBrowser.contentWindow;
-
-  let canvas = PageThumbs.capture(cw);
-  let ctx = canvas.getContext("2d");
-
-  checkCanvasColor(ctx, aRed, aGreen, aBlue, aMessage);
-}
deleted file mode 100644
--- a/browser/components/thumbnails/test/head.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-Cu.import("resource:///modules/PageThumbs.jsm");
-
-registerCleanupFunction(function () {
-  while (gBrowser.tabs.length > 1)
-    gBrowser.removeTab(gBrowser.tabs[1]);
-});
-
-/**
- * Provide the default test function to start our test runner.
- */
-function test() {
-  TestRunner.run();
-}
-
-/**
- * The test runner that controls the execution flow of our tests.
- */
-let TestRunner = {
-  /**
-   * Starts the test runner.
-   */
-  run: function () {
-    waitForExplicitFinish();
-
-    this._iter = runTests();
-    this.next();
-  },
-
-  /**
-   * Runs the next available test or finishes if there's no test left.
-   */
-  next: function () {
-    try {
-      TestRunner._iter.next();
-    } catch (e if e instanceof StopIteration) {
-      finish();
-    }
-  }
-};
-
-/**
- * Continues the current test execution.
- */
-function next() {
-  TestRunner.next();
-}
-
-/**
- * Creates a new tab with the given URI.
- * @param aURI The URI that's loaded in the tab.
- */
-function addTab(aURI) {
-  let tab = gBrowser.selectedTab = gBrowser.addTab(aURI);
-  whenBrowserLoaded(tab.linkedBrowser);
-}
-
-/**
- * Loads a new URI into the currently selected tab.
- * @param aURI The URI to load.
- */
-function navigateTo(aURI) {
-  let browser = gBrowser.selectedTab.linkedBrowser;
-  whenBrowserLoaded(browser);
-  browser.loadURI(aURI);
-}
-
-/**
- * Continues the current test execution when a load event for the given browser
- * has been received
- * @param aBrowser The browser to listen on.
- */
-function whenBrowserLoaded(aBrowser) {
-  aBrowser.addEventListener("load", function onLoad() {
-    aBrowser.removeEventListener("load", onLoad, true);
-    executeSoon(next);
-  }, true);
-}
-
-/**
- * Checks the top-left pixel of a given canvas' 2d context for a given color.
- * @param aContext The 2D context of a canvas.
- * @param aRed The red component's intensity.
- * @param aGreen The green component's intensity.
- * @param aBlue The blue component's intensity.
- * @param aMessage The info message to print when comparing the pixel color.
- */
-function checkCanvasColor(aContext, aRed, aGreen, aBlue, aMessage) {
-  let [r, g, b] = aContext.getImageData(0, 0, 1, 1).data;
-  ok(r == aRed && g == aGreen && b == aBlue, aMessage);
-}
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -87,16 +87,20 @@ endif
 
 include $(topsrcdir)/ipc/app/defs.mk
 DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
 
 ifneq (,$(filter aurora beta,$(MOZ_UPDATE_CHANNEL)))
 DEFINES += -DSHIP_FEEDBACK=1
 endif
 
+ifneq (,$(filter WINNT Darwin Android,$(OS_TARGET)))
+DEFINES += -DMOZ_SHARED_MOZGLUE=1
+endif
+
 ifdef MOZ_PKG_MANIFEST_P
 MOZ_PKG_MANIFEST = package-manifest
 
 $(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P) $(GLOBAL_DEPS)
 	$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $< > $@
 
 GARBAGE += $(MOZ_PKG_MANIFEST)
 endif
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -44,17 +44,19 @@
 #ifndef MOZ_STATIC_JS
 @BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
 #endif
 @BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@xpcom@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
+#ifdef MOZ_SHARED_MOZGLUE
 @BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
+#endif
 #ifdef XP_MACOSX
 @BINPATH@/XUL
 #else
 @BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
 #endif
 #ifdef XP_MACOSX
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/
 @BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
@@ -278,17 +280,16 @@
 @BINPATH@/components/fuelApplication.js
 @BINPATH@/components/WebContentConverter.js
 @BINPATH@/components/BrowserComponents.manifest
 @BINPATH@/components/nsBrowserContentHandler.js
 @BINPATH@/components/nsBrowserGlue.js
 @BINPATH@/components/nsSetDefaultBrowser.manifest
 @BINPATH@/components/nsSetDefaultBrowser.js
 @BINPATH@/components/BrowserPlaces.manifest
-@BINPATH@/components/BrowserPageThumbs.manifest
 @BINPATH@/components/nsPrivateBrowsingService.manifest
 @BINPATH@/components/nsPrivateBrowsingService.js
 @BINPATH@/components/toolkitsearch.manifest
 @BINPATH@/components/nsSearchService.js
 @BINPATH@/components/nsSearchSuggestions.js
 @BINPATH@/components/passwordmgr.manifest
 @BINPATH@/components/nsLoginInfo.js
 @BINPATH@/components/nsLoginManager.js
@@ -342,17 +343,16 @@
 @BINPATH@/components/toolkitplaces.manifest
 @BINPATH@/components/nsLivemarkService.js
 @BINPATH@/components/nsTaggingService.js
 @BINPATH@/components/nsPlacesAutoComplete.manifest
 @BINPATH@/components/nsPlacesAutoComplete.js
 @BINPATH@/components/nsPlacesExpiration.js
 @BINPATH@/components/PlacesProtocolHandler.js
 @BINPATH@/components/PlacesCategoriesStarter.js
-@BINPATH@/components/PageThumbsProtocol.js
 @BINPATH@/components/nsDefaultCLH.manifest
 @BINPATH@/components/nsDefaultCLH.js
 @BINPATH@/components/nsContentPrefService.manifest
 @BINPATH@/components/nsContentPrefService.js
 @BINPATH@/components/nsContentDispatchChooser.manifest
 @BINPATH@/components/nsContentDispatchChooser.js
 @BINPATH@/components/nsHandlerService.manifest
 @BINPATH@/components/nsHandlerService.js
--- a/browser/modules/Makefile.in
+++ b/browser/modules/Makefile.in
@@ -47,17 +47,16 @@ include $(topsrcdir)/config/config.mk
 ifdef ENABLE_TESTS
 DIRS += test
 endif
 
 EXTRA_JS_MODULES = \
 	openLocationLastURL.jsm \
 	NetworkPrioritizer.jsm \
 	offlineAppCache.jsm \
-	PageThumbs.jsm \
 	$(NULL)
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows) 
 EXTRA_JS_MODULES += \
 	WindowsPreviewPerTab.jsm \
 	WindowsJumpLists.jsm \
 	$(NULL)
 endif
deleted file mode 100644
--- a/browser/modules/PageThumbs.jsm
+++ /dev/null
@@ -1,265 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-let EXPORTED_SYMBOLS = ["PageThumbs", "PageThumbsCache"];
-
-const Cu = Components.utils;
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
-const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
-
-/**
- * The default width for page thumbnails.
- *
- * Hint: This is the default value because the 'New Tab Page' is the only
- *       client for now.
- */
-const THUMBNAIL_WIDTH = 201;
-
-/**
- * The default height for page thumbnails.
- *
- * Hint: This is the default value because the 'New Tab Page' is the only
- *       client for now.
- */
-const THUMBNAIL_HEIGHT = 127;
-
-/**
- * The default background color for page thumbnails.
- */
-const THUMBNAIL_BG_COLOR = "#fff";
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
-  "resource://gre/modules/NetUtil.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Services",
-  "resource://gre/modules/Services.jsm");
-
-/**
- * Singleton providing functionality for capturing web page thumbnails and for
- * accessing them if already cached.
- */
-let PageThumbs = {
-  /**
-   * The scheme to use for thumbnail urls.
-   */
-  get scheme() "moz-page-thumb",
-
-  /**
-   * The static host to use for thumbnail urls.
-   */
-  get staticHost() "thumbnail",
-
-  /**
-   * The thumbnails' image type.
-   */
-  get contentType() "image/png",
-
-  /**
-   * Gets the thumbnail image's url for a given web page's url.
-   * @param aUrl The web page's url that is depicted in the thumbnail.
-   * @return The thumbnail image's url.
-   */
-  getThumbnailURL: function PageThumbs_getThumbnailURL(aUrl) {
-    return this.scheme + "://" + this.staticHost +
-           "?url=" + encodeURIComponent(aUrl);
-  },
-
-  /**
-   * Creates a canvas containing a thumbnail depicting the given window.
-   * @param aWindow The DOM window to capture a thumbnail from.
-   * @return The newly created canvas containing the image data.
-   */
-  capture: function PageThumbs_capture(aWindow) {
-    let [sx, sy, sw, sh, scale] = this._determineCropRectangle(aWindow);
-
-    let canvas = this._createCanvas();
-    let ctx = canvas.getContext("2d");
-
-    // Scale the canvas accordingly.
-    ctx.scale(scale, scale);
-
-    try {
-      // Draw the window contents to the canvas.
-      ctx.drawWindow(aWindow, sx, sy, sw, sh, THUMBNAIL_BG_COLOR,
-                     ctx.DRAWWINDOW_DO_NOT_FLUSH);
-    } catch (e) {
-      // We couldn't draw to the canvas for some reason.
-    }
-
-    return canvas;
-  },
-
-  /**
-   * Stores the image data contained in the given canvas to the underlying
-   * storage.
-   * @param aKey The key to use for the storage.
-   * @param aCanvas The canvas containing the thumbnail's image data.
-   * @param aCallback The function to be called when the canvas data has been
-   *                  stored (optional).
-   */
-  store: function PageThumbs_store(aKey, aCanvas, aCallback) {
-    let self = this;
-
-    function finish(aSuccessful) {
-      if (aCallback)
-        aCallback(aSuccessful);
-    }
-
-    // Get a writeable cache entry.
-    PageThumbsCache.getWriteEntry(aKey, function (aEntry) {
-      if (!aEntry) {
-        finish(false);
-        return;
-      }
-
-      // Extract image data from the canvas.
-      self._readImageData(aCanvas, function (aData) {
-        let outputStream = aEntry.openOutputStream(0);
-
-        // Write the image data to the cache entry.
-        NetUtil.asyncCopy(aData, outputStream, function (aResult) {
-          let success = Components.isSuccessCode(aResult);
-          if (success)
-            aEntry.markValid();
-
-          aEntry.close();
-          finish(success);
-        });
-      });
-    });
-  },
-
-  /**
-   * Reads the image data from a given canvas and passes it to the callback.
-   * @param aCanvas The canvas to read the image data from.
-   * @param aCallback The function that the image data is passed to.
-   */
-  _readImageData: function PageThumbs_readImageData(aCanvas, aCallback) {
-    let dataUri = aCanvas.toDataURL(PageThumbs.contentType, "");
-    let uri = Services.io.newURI(dataUri, "UTF8", null);
-
-    NetUtil.asyncFetch(uri, function (aData, aResult) {
-      if (Components.isSuccessCode(aResult) && aData && aData.available())
-        aCallback(aData);
-    });
-  },
-
-  /**
-   * Determines the crop rectangle for a given content window.
-   * @param aWindow The content window.
-   * @return An array containing x, y, width, heigh and the scale of the crop
-   *         rectangle.
-   */
-  _determineCropRectangle: function PageThumbs_determineCropRectangle(aWindow) {
-    let sx = 0;
-    let sy = 0;
-    let sw = aWindow.innerWidth;
-    let sh = aWindow.innerHeight;
-
-    let scale = Math.max(THUMBNAIL_WIDTH / sw, THUMBNAIL_HEIGHT / sh);
-    let scaledWidth = sw * scale;
-    let scaledHeight = sh * scale;
-
-    if (scaledHeight > THUMBNAIL_HEIGHT) {
-      sy = Math.floor(Math.abs((scaledHeight - THUMBNAIL_HEIGHT) / 2) / scale);
-      sh -= 2 * sy;
-    }
-
-    if (scaledWidth > THUMBNAIL_WIDTH) {
-      sx = Math.floor(Math.abs((scaledWidth - THUMBNAIL_WIDTH) / 2) / scale);
-      sw -= 2 * sx;
-    }
-
-    return [sx, sy, sw, sh, scale];
-  },
-
-  /**
-   * Creates a new hidden canvas element.
-   * @return The newly created canvas.
-   */
-  _createCanvas: function PageThumbs_createCanvas() {
-    let doc = Services.appShell.hiddenDOMWindow.document;
-    let canvas = doc.createElementNS(HTML_NAMESPACE, "canvas");
-    canvas.mozOpaque = true;
-    canvas.width = THUMBNAIL_WIDTH;
-    canvas.height = THUMBNAIL_HEIGHT;
-    return canvas;
-  }
-};
-
-/**
- * A singleton handling the storage of page thumbnails.
- */
-let PageThumbsCache = {
-  /**
-   * Calls the given callback with a cache entry opened for reading.
-   * @param aKey The key identifying the desired cache entry.
-   * @param aCallback The callback that is called when the cache entry is ready.
-   */
-  getReadEntry: function Cache_getReadEntry(aKey, aCallback) {
-    // Try to open the desired cache entry.
-    this._openCacheEntry(aKey, Ci.nsICache.ACCESS_READ, aCallback);
-  },
-
-  /**
-   * Calls the given callback with a cache entry opened for writing.
-   * @param aKey The key identifying the desired cache entry.
-   * @param aCallback The callback that is called when the cache entry is ready.
-   */
-  getWriteEntry: function Cache_getWriteEntry(aKey, aCallback) {
-    // Try to open the desired cache entry.
-    this._openCacheEntry(aKey, Ci.nsICache.ACCESS_WRITE, aCallback);
-  },
-
-  /**
-   * Opens the cache entry identified by the given key.
-   * @param aKey The key identifying the desired cache entry.
-   * @param aAccess The desired access mode (see nsICache.ACCESS_* constants).
-   * @param aCallback The function to be called when the cache entry was opened.
-   */
-  _openCacheEntry: function Cache_openCacheEntry(aKey, aAccess, aCallback) {
-    function onCacheEntryAvailable(aEntry, aAccessGranted, aStatus) {
-      let validAccess = aAccess == aAccessGranted;
-      let validStatus = Components.isSuccessCode(aStatus);
-
-      // Check if a valid entry was passed and if the
-      // access we requested was actually granted.
-      if (aEntry && !(validAccess && validStatus)) {
-        aEntry.close();
-        aEntry = null;
-      }
-
-      aCallback(aEntry);
-    }
-
-    let listener = this._createCacheListener(onCacheEntryAvailable);
-    this._cacheSession.asyncOpenCacheEntry(aKey, aAccess, listener);
-  },
-
-  /**
-   * Returns a cache listener implementing the nsICacheListener interface.
-   * @param aCallback The callback to be called when the cache entry is available.
-   * @return The new cache listener.
-   */
-  _createCacheListener: function Cache_createCacheListener(aCallback) {
-    return {
-      onCacheEntryAvailable: aCallback,
-      QueryInterface: XPCOMUtils.generateQI([Ci.nsICacheListener])
-    };
-  }
-};
-
-/**
- * Define a lazy getter for the cache session.
- */
-XPCOMUtils.defineLazyGetter(PageThumbsCache, "_cacheSession", function () {
-  return Services.cache.createSession(PageThumbs.scheme,
-                                     Ci.nsICache.STORE_ON_DISK, true);
-});
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2527df6e72b5c80b91e180af9644ba96a5c148d6
GIT binary patch
literal 2552
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
O0000<MNUMnLSTaa5%5U>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..389f689aa2a7611f53977594c048f79c4991affd
GIT binary patch
literal 1538
zc$@(O2L1VoP)<h;3K|Lk000e1NJLTq001BW001Ni1^@s6=<7J*00001b5ch_0Itp)
z=>Px#32;bRa{vGf6951U69E94oEQKA1*b_wK~z}7z1Lk#Q)e8<@o%-;l_RE+GhM_8
z&Z*1|BRcVpq)WWhXf)~+B`Co`d;xW!BVJ5kIGwy`!52``xw)t_CD}4`B+G6vOo(iX
zAqGoCN3E_gn~4eZ{GVOW9(rnfS}x{EPSW4gp8lWbJkL3wb8G-7F1F?XH@0n9?j>wH
zak13_tlYL?d9&;MH5F<v+O*OZFO$I5_>H^6-f+R4E27Q<y$u)K&cd7(UVw%RZik4v
z4rDf5a8DA^O$RHbEHi-X{I$7&8<-8)fMK8?SO=UGku1B2{xi@Aqyz28TYhi?!y@{1
zAQN~9v?`@)$J2ph=dPBDNEI+4tocn~9?%nNumRMaxjYs46_^9`0x!dgXYb5g<6#_I
z-I>dCfxE%t1Hjgud28D1&Ros{egobxbpYV#=}Y0AAXL00f1L-Qw)uNwh`Y9|wOM7Q
z)V<(H2a30@OAWQxG+pWdvcfxS4}H+}z%cM4?7J7iGXa2zm_})pm8kcEAJ>Q4zCQVF
zhv<?OdA95T)vgwYuAAokWoS)QyIP!OMVq}UqM%h4k%<6%Kh3!rYTI4#$<k=kWvi-h
zb^zhUvx6N7UlY##JGOWeT?5swmXYA#J}xWT+-~(-yXdkuym)zWz6YS9=5%(j6X`(i
zp@x<(LkE=>Znhn2Xi>4U9?<^)J_ODIDUn61>d!d#@5u85OeinTZxkiFMTt=ypu9NW
zD@w9O$-eU9{AwjaXb+w8SXqhWDG{YardQTBJ+7>6S_M#9+qAK=wrNO-JgKa0sxa2T
zfs%rw(N52Sk^(PKoyc_`o<HBUwd-KbslC8q;2q%V!J1QuGS-O#{xV&L|Ht;l(UVy~
zV{jVZ1pW@*A4(3C6m%IKNNe-w05={ibC?!dTASYitbDM{(VW)iH-`9NnZp(@C(^-p
ze|g?vPiyn%0%w8Vv^Kvp)QMp6>p*5&n|~4!mtEXE`XAO7=#phuy4ix%pPo8_VP(EA
zv?37}=n?mUh@ASPuT%vBiCK{99<sE+vtrt~ESTvYdc}f)71P>hx`$$0F!Rb_R0{@H
zr+9+j8*@CcI>ly{1q=%wu1+y5m~mw=wgqZ<#L@y4h<F~b$f91gVET8S4jBnVw_wJ(
zK8G3}iE6=&bA8T-xpTY(0_GzvvJy2B;PIx}h6Rt-r$)CR<@B9|EEvq6pRfhfn(rAF
z3~iZbZ2=>?$%4Vc3=cp`LyyUVl%~6e1%q4Px1}`QRk89&91EtNyyNf|%pbL2urQ-h
z>H2P^>qc>a!NLr$()Dbm>-z=^GpY&b7&~B<C7|a?Kvxpbr)#dB$C|5W6@cdI*{HdC
zh9sar(Of-a7ChR%FscQQwl5sBAkK9ko_$3Nx{~X<O%^2Ab%!t1*JHtynp-g~cvie<
z%mU5Tp99?R70og&G|koT09N{nW;JWBel<42S+;mNkq*Ay=;^R)u71M;&DHM=bs|{&
zI*_Tk`X>?j+#fHG{)eRnN+ipU5|ahm@%v6-7$s&4BHjy75%@&p<YV_sRif_&T793T
z1->0~#$`crecvk<Jl!#;J-NOwwgp;UZ&V9>JJUVE@5knNXS&TQiyE`w*{*cMf+@AV
zu`NK?EiD+&^FTBU97q4`5YeMspdGpGK%&1FXh&{4eR~#o<ITA#2QBdL$uKPNmwXW2
z0_|{DLKgV;W+rUG<gdC73!Z<rFpdRcelPHqE*_opL%*9W&<=MS7Wnoqv}uRCRjfR$
zi=_pVt8Y1;mn|B#z*oAs5hc4(ViX7Pl`i(8BpW6Be5H%4QG&6DPI-(hB6%XBL}YqW
zRp;ZRs?JpaNmZR2ld3w0MC3_QRp*!mzOp4zE%22sF)SF*8u(}bM_ox3H%%5KRoo0;
osISL@w<<bfTJUfA(k_7i0M-VmrtThlf&c&j07*qoM6N<$f_IMEO8@`>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2527df6e72b5c80b91e180af9644ba96a5c148d6
GIT binary patch
literal 2552
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
O0000<MNUMnLSTaa5%5U>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..75d6f13d8c6e6a1cfc0d5766cfec91378e0b60c0
GIT binary patch
literal 1568
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
Su_w;}0000<MNUMnLSTY9P~RW`
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2527df6e72b5c80b91e180af9644ba96a5c148d6
GIT binary patch
literal 2552
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
O0000<MNUMnLSTaa5%5U>
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..33bb4a320e76cc7a346ca4beb60e89a85a48aa2c
GIT binary patch
literal 1704
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
--- a/mozglue/build/Makefile.in
+++ b/mozglue/build/Makefile.in
@@ -51,16 +51,17 @@ ifdef MOZ_MEMORY
 SHARED_LIBRARY_LIBS = $(call EXPAND_LIBNAME_PATH,jemalloc,$(DEPTH)/memory/jemalloc)
 else
 # Temporary, until bug 662814 lands
 VISIBILITY_FLAGS =
 CPPSRCS = dummy.cpp
 endif
  
 # Build mozglue as a shared lib on Windows, OSX and Android.
+# If this is ever changed, update MOZ_SHARED_MOZGLUE in browser/installer/Makefile.in
 ifneq (,$(filter WINNT Darwin Android,$(OS_TARGET)))
 FORCE_SHARED_LIB = 1
 else
 FORCE_STATIC_LIB = 1
 endif
 
 MOZ_GLUE_LDFLAGS = # Don't link against ourselves
 
--- a/testing/mochitest/tests/SimpleTest/SimpleTest.js
+++ b/testing/mochitest/tests/SimpleTest/SimpleTest.js
@@ -606,17 +606,17 @@ SimpleTest.waitForClipboard = function(a
         if (++SimpleTest.waitForClipboard_polls > 50) {
             // Log the failure.
             SimpleTest.ok(false, "Timed out while polling clipboard for pasted data.");
             reset();
             failureFn();
             return;
         }
 
-        data = SpecialPowers.getClipboardData(flavor);
+        var data = SpecialPowers.getClipboardData(flavor);
 
         if (validatorFn(data)) {
             // Don't show the success message when waiting for preExpectedVal
             if (preExpectedVal)
                 preExpectedVal = null;
             else
                 SimpleTest.ok(true, "Clipboard has the correct value");
             reset();
--- a/testing/mochitest/tests/SimpleTest/specialpowersAPI.js
+++ b/testing/mochitest/tests/SimpleTest/specialpowersAPI.js
@@ -929,17 +929,17 @@ SpecialPowersAPI.prototype = {
   },
 
   openDialog: function(win, args) {
     return win.openDialog.apply(win, args);
   },
 
   // :jdm gets credit for this.  ex: getPrivilegedProps(window, 'location.href');
   getPrivilegedProps: function(obj, props) {
-    parts = props.split('.');
+    var parts = props.split('.');
 
     for (var i = 0; i < parts.length; i++) {
       var p = parts[i];
       if (obj[p]) {
         obj = obj[p];
       } else {
         return null;
       }
--- a/toolkit/content/Services.jsm
+++ b/toolkit/content/Services.jsm
@@ -58,18 +58,16 @@ XPCOMUtils.defineLazyGetter(Services, "a
 
 XPCOMUtils.defineLazyGetter(Services, "dirsvc", function () {
   return Cc["@mozilla.org/file/directory_service;1"]
            .getService(Ci.nsIDirectoryService)
            .QueryInterface(Ci.nsIProperties);
 });
 
 let initTable = [
-  ["appShell", "@mozilla.org/appshell/appShellService;1", "nsIAppShellService"],
-  ["cache", "@mozilla.org/network/cache-service;1", "nsICacheService"],
   ["console", "@mozilla.org/consoleservice;1", "nsIConsoleService"],
   ["contentPrefs", "@mozilla.org/content-pref/service;1", "nsIContentPrefService"],
   ["cookies", "@mozilla.org/cookiemanager;1", "nsICookieManager2"],
   ["droppedLinkHandler", "@mozilla.org/content/dropped-link-handler;1", "nsIDroppedLinkHandler"],
   ["eTLD", "@mozilla.org/network/effective-tld-service;1", "nsIEffectiveTLDService"],
   ["io", "@mozilla.org/network/io-service;1", "nsIIOService2"],
   ["locale", "@mozilla.org/intl/nslocaleservice;1", "nsILocaleService"],
   ["logins", "@mozilla.org/login-manager;1", "nsILoginManager"],