Merge inbound to m-c a=merge
authorWes Kocher <wkocher@mozilla.com>
Tue, 18 Nov 2014 18:07:51 -0800
changeset 216379 64e7a6391916f4fee997999b827a38e44553b2cc
parent 216378 3457abba4f2ae9584f7ca22e1ca5a3d6084db7ff (current diff)
parent 216295 f134d9b40fe8ad58c39acde5874a0f2167b84152 (diff)
child 216380 d197d16c0caa33d41c49d694abb773a24a728faf
child 216417 d0d8c407efb540ecc91df4574b3237cd65165b81
child 216426 1b8aaaa0e0763d2ecd9d07e0f956f7781fcf3104
child 216447 42d5fe8d7f48679543f59bbe1a318eb2985fd473
push id52026
push userkwierso@gmail.com
push dateWed, 19 Nov 2014 02:37:17 +0000
treeherdermozilla-inbound@d197d16c0caa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to m-c a=merge
media/libtheora/include/moz.build
media/libtheora/include/theora/moz.build
media/libtheora/lib/Makefile.in
media/libtheora/lib/moz.build
--- a/b2g/locales/en-US/chrome/overrides/appstrings.properties
+++ b/b2g/locales/en-US/chrome/overrides/appstrings.properties
@@ -26,11 +26,11 @@ unsafeContentType=The page you are tryin
 externalProtocolTitle=External Protocol Request
 externalProtocolPrompt=An external application must be launched to handle %1$S: links.\n\n\nRequested link:\n\n%2$S\n\nApplication: %3$S\n\n\nIf you were not expecting this request it may be an attempt to exploit a weakness in that other program. Cancel this request unless you are sure it is not malicious.\n
 #LOCALIZATION NOTE (externalProtocolUnknown): The following string is shown if the application name can't be determined
 externalProtocolUnknown=<Unknown>
 externalProtocolChkMsg=Remember my choice for all links of this type.
 externalProtocolLaunchBtn=Launch application
 malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
 phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
-cspFrameAncestorBlocked=This page has a content security policy that prevents it from being embedded in this way.
+cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
 remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
--- a/browser/base/content/aboutNetError.xhtml
+++ b/browser/base/content/aboutNetError.xhtml
@@ -181,18 +181,18 @@
         }
 
         if (err == "remoteXUL") {
           // Remove the "Try again" button for remote XUL errors given that
           // it is useless.
           document.getElementById("errorTryAgain").style.display = "none";
         }
 
-        if (err == "cspFrameAncestorBlocked") {
-          // Remove the "Try again" button for CSP frame ancestors violation, since it's
+        if (err == "cspBlocked") {
+          // Remove the "Try again" button for CSP violations, since it's
           // almost certainly useless. (Bug 553180)
           document.getElementById("errorTryAgain").style.display = "none";
         }
 
         window.addEventListener("AboutNetErrorOptions", function(evt) {
         // Pinning errors are of type nssFailure2 (don't ask me why)
           if (getErrorCode() == "nssFailure2") {
           // TODO: and the pref is set...
@@ -348,17 +348,17 @@
         <h1 id="et_deniedPortAccess">&deniedPortAccess.title;</h1>
         <h1 id="et_proxyResolveFailure">&proxyResolveFailure.title;</h1>
         <h1 id="et_proxyConnectFailure">&proxyConnectFailure.title;</h1>
         <h1 id="et_contentEncodingError">&contentEncodingError.title;</h1>
         <h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&nssBadCert.title;</h1>
         <h1 id="et_malwareBlocked">&malwareBlocked.title;</h1>
-        <h1 id="et_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.title;</h1>
+        <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc;</div>
@@ -374,17 +374,17 @@
         <div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div>
         <div id="ed_proxyResolveFailure">&proxyResolveFailure.longDesc;</div>
         <div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div>
         <div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div>
         <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
         <div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
         <div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
         <div id="ed_malwareBlocked">&malwareBlocked.longDesc;</div>
-        <div id="ed_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.longDesc;</div>
+        <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
 
--- a/browser/base/content/browser-sets.inc
+++ b/browser/base/content/browser-sets.inc
@@ -17,17 +17,17 @@
 
   <commandset id="mainCommandSet">
     <command id="cmd_newNavigator"                 oncommand="OpenBrowserWindow()"/>
     <command id="cmd_handleBackspace" oncommand="BrowserHandleBackspace();" />
     <command id="cmd_handleShiftBackspace" oncommand="BrowserHandleShiftBackspace();" />
 
     <command id="cmd_newNavigatorTab" oncommand="BrowserOpenNewTabOrWindow(event);"/>
     <command id="Browser:OpenFile"  oncommand="BrowserOpenFileWindow();"/>
-    <command id="Browser:SavePage" oncommand="saveDocument(window.content.document);"/>
+    <command id="Browser:SavePage" oncommand="saveDocument(gBrowser.selectedBrowser.contentDocumentAsCPOW);"/>
 
     <command id="Browser:SendLink"
              oncommand="MailIntegration.sendLinkForWindow(window.content);"/>
 
     <command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
     <command id="cmd_print" oncommand="PrintUtils.print(window.gBrowser.selectedBrowser.contentWindowAsCPOW, window.gBrowser.selectedBrowser);"/>
     <command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
     <command id="cmd_close" oncommand="BrowserCloseTabOrWindow()"/>
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1738,17 +1738,17 @@ function HandleAppCommandEvent(evt) {
   case "Open":
     BrowserOpenFileWindow();
     break;
   case "Print":
     PrintUtils.print(gBrowser.selectedBrowser.contentWindowAsCPOW,
                      gBrowser.selectedBrowser);
     break;
   case "Save":
-    saveDocument(window.content.document);
+    saveDocument(gBrowser.selectedBrowser.contentDocumentAsCPOW);
     break;
   case "SendMail":
     MailIntegration.sendLinkForWindow(window.content);
     break;
   default:
     return;
   }
   evt.stopPropagation();
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -303,17 +303,17 @@ const CustomizableWidgets = [
     shortcutId: "key_savePage",
     tooltiptext: "save-page-button.tooltiptext3",
     defaultArea: CustomizableUI.AREA_PANEL,
     onCommand: function(aEvent) {
       let win = aEvent.target &&
                 aEvent.target.ownerDocument &&
                 aEvent.target.ownerDocument.defaultView;
       if (win && typeof win.saveDocument == "function") {
-        win.saveDocument(win.content.document);
+        win.saveDocument(win.gBrowser.selectedBrowser.contentDocumentAsCPOW);
       }
     }
   }, {
     id: "find-button",
     shortcutId: "key_find",
     tooltiptext: "find-button.tooltiptext3",
     defaultArea: CustomizableUI.AREA_PANEL,
     onCommand: function(aEvent) {
--- a/browser/components/sessionstore/SessionHistory.jsm
+++ b/browser/components/sessionstore/SessionHistory.jsm
@@ -182,18 +182,20 @@ let SessionHistoryInternal = {
       // nsISerializable or something.
       entry.cacheKey = cacheKey.data;
     }
     entry.ID = shEntry.ID;
     entry.docshellID = shEntry.docshellID;
 
     // We will include the property only if it's truthy to save a couple of
     // bytes when the resulting object is stringified and saved to disk.
-    if (shEntry.referrerURI)
+    if (shEntry.referrerURI) {
       entry.referrer = shEntry.referrerURI.spec;
+      entry.referrerPolicy = shEntry.referrerPolicy;
+    }
 
     if (shEntry.srcdocData)
       entry.srcdocData = shEntry.srcdocData;
 
     if (shEntry.isSrcdocEntry)
       entry.isSrcdocEntry = shEntry.isSrcdocEntry;
 
     if (shEntry.baseURI)
@@ -335,18 +337,20 @@ let SessionHistoryInternal = {
 
     shEntry.setURI(Utils.makeURI(entry.url));
     shEntry.setTitle(entry.title || entry.url);
     if (entry.subframe)
       shEntry.setIsSubFrame(entry.subframe || false);
     shEntry.loadType = Ci.nsIDocShellLoadInfo.loadHistory;
     if (entry.contentType)
       shEntry.contentType = entry.contentType;
-    if (entry.referrer)
+    if (entry.referrer) {
       shEntry.referrerURI = Utils.makeURI(entry.referrer);
+      shEntry.referrerPolicy = entry.referrerPolicy;
+    }
     if (entry.isSrcdocEntry)
       shEntry.srcdocData = entry.srcdocData;
     if (entry.baseURI)
       shEntry.baseURI = Utils.makeURI(entry.baseURI);
 
     if (entry.cacheKey) {
       var cacheKey = Cc["@mozilla.org/supports-PRUint32;1"].
                      createInstance(Ci.nsISupportsPRUint32);
--- a/browser/components/shell/nsMacShellService.cpp
+++ b/browser/components/shell/nsMacShellService.cpp
@@ -200,17 +200,19 @@ nsMacShellService::SetDesktopBackground(
 
   nsCOMPtr<nsILoadContext> loadContext;
   nsCOMPtr<nsISupports> container = content->OwnerDoc()->GetContainer();
   nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
   if (docShell) {
     loadContext = do_QueryInterface(docShell);
   }
 
-  return wbp->SaveURI(imageURI, nullptr, docURI, nullptr, nullptr,
+  return wbp->SaveURI(imageURI, nullptr,
+                      docURI, content->OwnerDoc()->GetReferrerPolicy(),
+                      nullptr, nullptr,
                       mBackgroundFile, loadContext);
 }
 
 NS_IMETHODIMP
 nsMacShellService::OnProgressChange(nsIWebProgress* aWebProgress,
                                     nsIRequest* aRequest,
                                     int32_t aCurSelfProgress,
                                     int32_t aMaxSelfProgress,
--- a/browser/installer/Makefile.in
+++ b/browser/installer/Makefile.in
@@ -115,16 +115,23 @@ ifeq (bundle, $(MOZ_FS_LAYOUT))
 BINPATH = $(_BINPATH)
 DEFINES += -DAPPNAME=$(_APPNAME)
 else
 # Every other platform just winds up in dist/bin
 BINPATH = bin
 endif
 DEFINES += -DBINPATH=$(BINPATH)
 
+ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
+RESPATH = $(_APPNAME)/Contents/Resources
+else
+RESPATH = $(BINPATH)
+endif
+DEFINES += -DRESPATH=$(RESPATH)
+
 AB = $(firstword $(subst -, ,$(AB_CD)))
 DEFINES += -DAB=$(AB)
 
 DEFINES += -DMOZ_ICU_VERSION=$(MOZ_ICU_VERSION)
 ifdef MOZ_NATIVE_ICU
 DEFINES += -DMOZ_NATIVE_ICU
 endif
 ifdef MOZ_SHARED_ICU
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -12,94 +12,91 @@
 ; File format:
 ;
 ; [] designates a toplevel component. Example: [xpcom]
 ; - in front of a file specifies it to be removed from the destination
 ; * wildcard support to recursively copy the entire directory
 ; ; file comment
 ;
 
+; Due to Apple Mac OS X packaging requirements, files that are in the same
+; directory on other platforms must be located in different directories on
+; Mac OS X. The following defines allow specifying the Mac OS X bundle
+; location which also work on other platforms.
+;
+; @BINPATH@
+; Equals Contents/MacOS/ on Mac OS X and is the path to the main binary on other
+; platforms.
+;
+; @RESPATH@
+; Equals Contents/Resources/ on Mac OS X and is equivalent to @BINPATH@ on other
+; platforms.
+
 #filter substitution
 
 #ifdef XP_MACOSX
 ; Mac bundle stuff
 @APPNAME@/Contents/Info.plist
 @APPNAME@/Contents/PkgInfo
-@APPNAME@/Contents/Resources/firefox.icns
-@APPNAME@/Contents/Resources/document.icns
-@APPNAME@/Contents/Resources/@AB@.lproj/*
+@RESPATH@/firefox.icns
+@RESPATH@/document.icns
+@RESPATH@/@AB@.lproj/*
 #endif
 
 [@AB_CD@]
-@BINPATH@/browser/chrome/@AB_CD@@JAREXT@
-@BINPATH@/browser/chrome/@AB_CD@.manifest
-@BINPATH@/chrome/@AB_CD@@JAREXT@
-@BINPATH@/chrome/@AB_CD@.manifest
-@BINPATH@/browser/defaults/profile/bookmarks.html
-@BINPATH@/browser/defaults/profile/chrome/*
-@BINPATH@/browser/defaults/profile/localstore.rdf
-@BINPATH@/browser/defaults/profile/mimeTypes.rdf
-@BINPATH@/dictionaries/*
-@BINPATH@/hyphenation/*
-@BINPATH@/browser/@PREF_DIR@/firefox-l10n.js
-@BINPATH@/browser/searchplugins/*
+@RESPATH@/browser/chrome/@AB_CD@@JAREXT@
+@RESPATH@/browser/chrome/@AB_CD@.manifest
+@RESPATH@/chrome/@AB_CD@@JAREXT@
+@RESPATH@/chrome/@AB_CD@.manifest
+@RESPATH@/browser/defaults/profile/bookmarks.html
+@RESPATH@/browser/defaults/profile/chrome/*
+@RESPATH@/browser/defaults/profile/localstore.rdf
+@RESPATH@/browser/defaults/profile/mimeTypes.rdf
+@RESPATH@/dictionaries/*
+@RESPATH@/hyphenation/*
+@RESPATH@/browser/@PREF_DIR@/firefox-l10n.js
+@RESPATH@/browser/searchplugins/*
 #ifdef XP_WIN32
-@BINPATH@/uninstall/helper.exe
+@RESPATH@/uninstall/helper.exe
 #endif
 #ifdef MOZ_UPDATER
-@BINPATH@/update.locale
-@BINPATH@/updater.ini
+@RESPATH@/update.locale
+@RESPATH@/updater.ini
 #endif
 
 [xpcom]
-@BINPATH@/dependentlibs.list
+@RESPATH@/dependentlibs.list
 #ifdef GKMEDIAS_SHARED_LIBRARY
 @BINPATH@/@DLL_PREFIX@gkmedias@DLL_SUFFIX@
 #endif
-#ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
-#else
 @BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
-#endif
 #ifdef MOZ_SHARED_MOZGLUE
-#ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@mozglue@DLL_SUFFIX@
-#else
 @BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
 #endif
-#endif
 #ifndef MOZ_STATIC_JS
-#ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@mozjs@DLL_SUFFIX@
-#else
 @BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
 #endif
-#endif
 #ifdef MOZ_DMD
-#ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@dmd@DLL_SUFFIX@
-#else
 @BINPATH@/@DLL_PREFIX@dmd@DLL_SUFFIX@
 #endif
-#endif
 #ifndef MOZ_NATIVE_NSPR
 #ifndef MOZ_FOLD_LIBS
 @BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
 #endif
 #endif
 #ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/XUL
+@BINPATH@/XUL
 #else
 @BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
 #endif
 #ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/@MOZ_CHILD_PROCESS_NAME@.app/
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
+@BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/
+@BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
 #else
 @BINPATH@/@MOZ_CHILD_PROCESS_NAME@
 #endif
 #ifdef XP_WIN32
 @BINPATH@/plugin-hang-ui@BIN_SUFFIX@
 #if MOZ_PACKAGE_MSVC_DLLS
 @BINPATH@/@MSVC_C_RUNTIME_DLL@
 @BINPATH@/@MSVC_CXX_RUNTIME_DLL@
@@ -119,525 +116,518 @@
 @BINPATH@/libicudata.so.@MOZ_ICU_VERSION@
 @BINPATH@/libicui18n.so.@MOZ_ICU_VERSION@
 @BINPATH@/libicuuc.so.@MOZ_ICU_VERSION@
 #endif
 #endif
 #endif
 #ifdef MOZ_REPLACE_MALLOC
 #ifndef MOZ_JEMALLOC3
-#ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@replace_jemalloc@DLL_SUFFIX@
-#else
 @BINPATH@/@DLL_PREFIX@replace_jemalloc@DLL_SUFFIX@
 #endif
 #endif
-#endif
 #ifdef MOZ_GTK3
 @BINPATH@/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@mozgtk2@DLL_SUFFIX@
 #endif
 
 [browser]
 ; [Base Browser Files]
 #ifndef XP_UNIX
 @BINPATH@/@MOZ_APP_NAME@.exe
-#elif XP_MACOSX
-@APPNAME@/Contents/MacOS/@MOZ_APP_NAME@-bin
-@APPNAME@/Contents/MacOS/@MOZ_APP_NAME@
 #else
 @BINPATH@/@MOZ_APP_NAME@-bin
 @BINPATH@/@MOZ_APP_NAME@
 #endif
-@BINPATH@/application.ini
+@RESPATH@/application.ini
 #ifdef MOZ_UPDATER
-@BINPATH@/update-settings.ini
+@RESPATH@/update-settings.ini
 #endif
-@BINPATH@/platform.ini
+@RESPATH@/platform.ini
 #ifndef MOZ_NATIVE_SQLITE
 #ifndef MOZ_FOLD_LIBS
 @BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
 #endif
 #endif
-@BINPATH@/browser/blocklist.xml
+@RESPATH@/browser/blocklist.xml
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
-@BINPATH@/run-mozilla.sh
+@RESPATH@/run-mozilla.sh
 #endif
 #endif
 
 ; [Components]
-@BINPATH@/browser/components/components.manifest
-@BINPATH@/components/alerts.xpt
+@RESPATH@/browser/components/components.manifest
+@RESPATH@/components/alerts.xpt
 #ifdef ACCESSIBILITY
 #ifdef XP_WIN32
 @BINPATH@/AccessibleMarshal.dll
 #endif
-@BINPATH@/components/accessibility.xpt
+@RESPATH@/components/accessibility.xpt
 #endif
-@BINPATH@/components/appshell.xpt
-@BINPATH@/components/appstartup.xpt
-@BINPATH@/components/autocomplete.xpt
-@BINPATH@/components/autoconfig.xpt
-@BINPATH@/browser/components/browsercompsbase.xpt
-@BINPATH@/browser/components/browser-feeds.xpt
-@BINPATH@/components/caps.xpt
-@BINPATH@/components/chrome.xpt
-@BINPATH@/components/commandhandler.xpt
-@BINPATH@/components/commandlines.xpt
-@BINPATH@/components/composer.xpt
-@BINPATH@/components/content_events.xpt
-@BINPATH@/components/content_html.xpt
-@BINPATH@/components/content_geckomediaplugins.xpt
+@RESPATH@/components/appshell.xpt
+@RESPATH@/components/appstartup.xpt
+@RESPATH@/components/autocomplete.xpt
+@RESPATH@/components/autoconfig.xpt
+@RESPATH@/browser/components/browsercompsbase.xpt
+@RESPATH@/browser/components/browser-feeds.xpt
+@RESPATH@/components/caps.xpt
+@RESPATH@/components/chrome.xpt
+@RESPATH@/components/commandhandler.xpt
+@RESPATH@/components/commandlines.xpt
+@RESPATH@/components/composer.xpt
+@RESPATH@/components/content_events.xpt
+@RESPATH@/components/content_html.xpt
+@RESPATH@/components/content_geckomediaplugins.xpt
 #ifdef MOZ_WEBRTC
-@BINPATH@/components/content_webrtc.xpt
+@RESPATH@/components/content_webrtc.xpt
 #endif
-@BINPATH@/components/content_xslt.xpt
-@BINPATH@/components/cookie.xpt
-@BINPATH@/components/devtools_security.xpt
-@BINPATH@/components/directory.xpt
-@BINPATH@/components/docshell.xpt
-@BINPATH@/components/dom.xpt
+@RESPATH@/components/content_xslt.xpt
+@RESPATH@/components/cookie.xpt
+@RESPATH@/components/devtools_security.xpt
+@RESPATH@/components/directory.xpt
+@RESPATH@/components/docshell.xpt
+@RESPATH@/components/dom.xpt
 #ifdef MOZ_ACTIVITIES
-@BINPATH@/components/dom_activities.xpt
-@BINPATH@/components/dom_messages.xpt
+@RESPATH@/components/dom_activities.xpt
+@RESPATH@/components/dom_messages.xpt
 #endif
-@BINPATH@/components/dom_apps.xpt
-@BINPATH@/components/dom_base.xpt
-@BINPATH@/components/dom_system.xpt
+@RESPATH@/components/dom_apps.xpt
+@RESPATH@/components/dom_base.xpt
+@RESPATH@/components/dom_system.xpt
 #ifdef MOZ_B2G_BT
-@BINPATH@/components/dom_bluetooth.xpt
+@RESPATH@/components/dom_bluetooth.xpt
 #endif
-@BINPATH@/components/dom_canvas.xpt
-@BINPATH@/components/dom_alarm.xpt
-@BINPATH@/components/dom_core.xpt
-@BINPATH@/components/dom_css.xpt
-@BINPATH@/components/dom_devicestorage.xpt
-@BINPATH@/components/dom_events.xpt
-@BINPATH@/components/dom_geolocation.xpt
-@BINPATH@/components/dom_media.xpt
-@BINPATH@/components/dom_network.xpt
-@BINPATH@/components/dom_notification.xpt
-@BINPATH@/components/dom_html.xpt
-@BINPATH@/components/dom_offline.xpt
-@BINPATH@/components/dom_json.xpt
-@BINPATH@/components/dom_power.xpt
-@BINPATH@/components/dom_quota.xpt
-@BINPATH@/components/dom_range.xpt
-@BINPATH@/components/dom_security.xpt
-@BINPATH@/components/dom_settings.xpt
-@BINPATH@/components/dom_permissionsettings.xpt
-@BINPATH@/components/dom_sidebar.xpt
-@BINPATH@/components/dom_cellbroadcast.xpt
-@BINPATH@/components/dom_mobilemessage.xpt
-@BINPATH@/components/dom_storage.xpt
-@BINPATH@/components/dom_stylesheets.xpt
-@BINPATH@/components/dom_telephony.xpt
-@BINPATH@/components/dom_traversal.xpt
-@BINPATH@/components/dom_tv.xpt
-@BINPATH@/components/dom_voicemail.xpt
+@RESPATH@/components/dom_canvas.xpt
+@RESPATH@/components/dom_alarm.xpt
+@RESPATH@/components/dom_core.xpt
+@RESPATH@/components/dom_css.xpt
+@RESPATH@/components/dom_devicestorage.xpt
+@RESPATH@/components/dom_events.xpt
+@RESPATH@/components/dom_geolocation.xpt
+@RESPATH@/components/dom_media.xpt
+@RESPATH@/components/dom_network.xpt
+@RESPATH@/components/dom_notification.xpt
+@RESPATH@/components/dom_html.xpt
+@RESPATH@/components/dom_offline.xpt
+@RESPATH@/components/dom_json.xpt
+@RESPATH@/components/dom_power.xpt
+@RESPATH@/components/dom_quota.xpt
+@RESPATH@/components/dom_range.xpt
+@RESPATH@/components/dom_security.xpt
+@RESPATH@/components/dom_settings.xpt
+@RESPATH@/components/dom_permissionsettings.xpt
+@RESPATH@/components/dom_sidebar.xpt
+@RESPATH@/components/dom_cellbroadcast.xpt
+@RESPATH@/components/dom_mobilemessage.xpt
+@RESPATH@/components/dom_storage.xpt
+@RESPATH@/components/dom_stylesheets.xpt
+@RESPATH@/components/dom_telephony.xpt
+@RESPATH@/components/dom_traversal.xpt
+@RESPATH@/components/dom_tv.xpt
+@RESPATH@/components/dom_voicemail.xpt
 #ifdef MOZ_WEBSPEECH
-@BINPATH@/components/dom_webspeechrecognition.xpt
+@RESPATH@/components/dom_webspeechrecognition.xpt
 #endif
-@BINPATH@/components/dom_workers.xpt
-@BINPATH@/components/dom_xbl.xpt
-@BINPATH@/components/dom_xpath.xpt
-@BINPATH@/components/dom_xul.xpt
+@RESPATH@/components/dom_workers.xpt
+@RESPATH@/components/dom_xbl.xpt
+@RESPATH@/components/dom_xpath.xpt
+@RESPATH@/components/dom_xul.xpt
 #ifdef MOZ_GAMEPAD
-@BINPATH@/components/dom_gamepad.xpt
+@RESPATH@/components/dom_gamepad.xpt
 #endif
-@BINPATH@/components/dom_payment.xpt
-@BINPATH@/components/downloads.xpt
-@BINPATH@/components/editor.xpt
-@BINPATH@/components/embed_base.xpt
-@BINPATH@/components/extensions.xpt
-@BINPATH@/components/exthandler.xpt
-@BINPATH@/components/exthelper.xpt
-@BINPATH@/components/fastfind.xpt
-@BINPATH@/components/feeds.xpt
+@RESPATH@/components/dom_payment.xpt
+@RESPATH@/components/downloads.xpt
+@RESPATH@/components/editor.xpt
+@RESPATH@/components/embed_base.xpt
+@RESPATH@/components/extensions.xpt
+@RESPATH@/components/exthandler.xpt
+@RESPATH@/components/exthelper.xpt
+@RESPATH@/components/fastfind.xpt
+@RESPATH@/components/feeds.xpt
 #ifdef MOZ_GTK
-@BINPATH@/components/filepicker.xpt
+@RESPATH@/components/filepicker.xpt
 #endif
-@BINPATH@/components/find.xpt
-@BINPATH@/browser/components/fuel.xpt
-@BINPATH@/components/gfx.xpt
-@BINPATH@/components/html5.xpt
-@BINPATH@/components/htmlparser.xpt
-@BINPATH@/components/identity.xpt
-@BINPATH@/components/imglib2.xpt
-@BINPATH@/components/imgicon.xpt
-@BINPATH@/components/inspector.xpt
-@BINPATH@/components/intl.xpt
-@BINPATH@/components/jar.xpt
-@BINPATH@/components/jsdebugger.xpt
-@BINPATH@/components/jsdownloads.xpt
-@BINPATH@/components/jsinspector.xpt
-@BINPATH@/components/layout_base.xpt
+@RESPATH@/components/find.xpt
+@RESPATH@/browser/components/fuel.xpt
+@RESPATH@/components/gfx.xpt
+@RESPATH@/components/html5.xpt
+@RESPATH@/components/htmlparser.xpt
+@RESPATH@/components/identity.xpt
+@RESPATH@/components/imglib2.xpt
+@RESPATH@/components/imgicon.xpt
+@RESPATH@/components/inspector.xpt
+@RESPATH@/components/intl.xpt
+@RESPATH@/components/jar.xpt
+@RESPATH@/components/jsdebugger.xpt
+@RESPATH@/components/jsdownloads.xpt
+@RESPATH@/components/jsinspector.xpt
+@RESPATH@/components/layout_base.xpt
 #ifdef NS_PRINTING
-@BINPATH@/components/layout_printing.xpt
+@RESPATH@/components/layout_printing.xpt
 #endif
-@BINPATH@/components/layout_xul_tree.xpt
-@BINPATH@/components/layout_xul.xpt
-@BINPATH@/components/locale.xpt
-@BINPATH@/components/lwbrk.xpt
-@BINPATH@/browser/components/migration.xpt
-@BINPATH@/components/mimetype.xpt
-@BINPATH@/components/mozfind.xpt
-@BINPATH@/components/necko_about.xpt
-@BINPATH@/components/necko_cache.xpt
-@BINPATH@/components/necko_cache2.xpt
-@BINPATH@/components/necko_cookie.xpt
-@BINPATH@/components/necko_dns.xpt
-@BINPATH@/components/necko_file.xpt
-@BINPATH@/components/necko_ftp.xpt
-@BINPATH@/components/necko_http.xpt
-@BINPATH@/components/necko_res.xpt
-@BINPATH@/components/necko_socket.xpt
-@BINPATH@/components/necko_strconv.xpt
-@BINPATH@/components/necko_viewsource.xpt
-@BINPATH@/components/necko_websocket.xpt
+@RESPATH@/components/layout_xul_tree.xpt
+@RESPATH@/components/layout_xul.xpt
+@RESPATH@/components/locale.xpt
+@RESPATH@/components/lwbrk.xpt
+@RESPATH@/browser/components/migration.xpt
+@RESPATH@/components/mimetype.xpt
+@RESPATH@/components/mozfind.xpt
+@RESPATH@/components/necko_about.xpt
+@RESPATH@/components/necko_cache.xpt
+@RESPATH@/components/necko_cache2.xpt
+@RESPATH@/components/necko_cookie.xpt
+@RESPATH@/components/necko_dns.xpt
+@RESPATH@/components/necko_file.xpt
+@RESPATH@/components/necko_ftp.xpt
+@RESPATH@/components/necko_http.xpt
+@RESPATH@/components/necko_res.xpt
+@RESPATH@/components/necko_socket.xpt
+@RESPATH@/components/necko_strconv.xpt
+@RESPATH@/components/necko_viewsource.xpt
+@RESPATH@/components/necko_websocket.xpt
 #ifdef NECKO_WIFI
-@BINPATH@/components/necko_wifi.xpt
+@RESPATH@/components/necko_wifi.xpt
 #endif
-@BINPATH@/components/necko_wyciwyg.xpt
-@BINPATH@/components/necko.xpt
-@BINPATH@/components/loginmgr.xpt
-@BINPATH@/components/parentalcontrols.xpt
+@RESPATH@/components/necko_wyciwyg.xpt
+@RESPATH@/components/necko.xpt
+@RESPATH@/components/loginmgr.xpt
+@RESPATH@/components/parentalcontrols.xpt
 #ifdef MOZ_WEBRTC
-@BINPATH@/components/peerconnection.xpt
+@RESPATH@/components/peerconnection.xpt
 #endif
-@BINPATH@/components/places.xpt
-@BINPATH@/components/plugin.xpt
-@BINPATH@/components/pref.xpt
-@BINPATH@/components/prefetch.xpt
-@BINPATH@/components/profile.xpt
+@RESPATH@/components/places.xpt
+@RESPATH@/components/plugin.xpt
+@RESPATH@/components/pref.xpt
+@RESPATH@/components/prefetch.xpt
+@RESPATH@/components/profile.xpt
 #ifdef MOZ_ENABLE_PROFILER_SPS
-@BINPATH@/components/profiler.xpt
+@RESPATH@/components/profiler.xpt
 #endif
-@BINPATH@/components/rdf.xpt
-@BINPATH@/components/satchel.xpt
-@BINPATH@/components/saxparser.xpt
-@BINPATH@/browser/components/sessionstore.xpt
-@BINPATH@/components/services-crypto-component.xpt
+@RESPATH@/components/rdf.xpt
+@RESPATH@/components/satchel.xpt
+@RESPATH@/components/saxparser.xpt
+@RESPATH@/browser/components/sessionstore.xpt
+@RESPATH@/components/services-crypto-component.xpt
 #ifdef MOZ_CAPTIVEDETECT
-@BINPATH@/components/captivedetect.xpt
+@RESPATH@/components/captivedetect.xpt
 #endif
-@BINPATH@/browser/components/shellservice.xpt
-@BINPATH@/components/shistory.xpt
-@BINPATH@/components/spellchecker.xpt
-@BINPATH@/components/storage.xpt
-@BINPATH@/components/toolkit_asyncshutdown.xpt
-@BINPATH@/components/toolkit_filewatcher.xpt
-@BINPATH@/components/toolkit_finalizationwitness.xpt
-@BINPATH@/components/toolkit_formautofill.xpt
-@BINPATH@/components/toolkit_osfile.xpt
-@BINPATH@/components/toolkit_xulstore.xpt
-@BINPATH@/components/toolkitprofile.xpt
+@RESPATH@/browser/components/shellservice.xpt
+@RESPATH@/components/shistory.xpt
+@RESPATH@/components/spellchecker.xpt
+@RESPATH@/components/storage.xpt
+@RESPATH@/components/toolkit_asyncshutdown.xpt
+@RESPATH@/components/toolkit_filewatcher.xpt
+@RESPATH@/components/toolkit_finalizationwitness.xpt
+@RESPATH@/components/toolkit_formautofill.xpt
+@RESPATH@/components/toolkit_osfile.xpt
+@RESPATH@/components/toolkit_xulstore.xpt
+@RESPATH@/components/toolkitprofile.xpt
 #ifdef MOZ_ENABLE_XREMOTE
-@BINPATH@/components/toolkitremote.xpt
+@RESPATH@/components/toolkitremote.xpt
 #endif
-@BINPATH@/components/txtsvc.xpt
-@BINPATH@/components/txmgr.xpt
-@BINPATH@/components/uconv.xpt
-@BINPATH@/components/unicharutil.xpt
-@BINPATH@/components/update.xpt
-@BINPATH@/components/uriloader.xpt
-@BINPATH@/components/urlformatter.xpt
-@BINPATH@/components/webBrowser_core.xpt
-@BINPATH@/components/webbrowserpersist.xpt
-@BINPATH@/components/widget.xpt
+@RESPATH@/components/txtsvc.xpt
+@RESPATH@/components/txmgr.xpt
+@RESPATH@/components/uconv.xpt
+@RESPATH@/components/unicharutil.xpt
+@RESPATH@/components/update.xpt
+@RESPATH@/components/uriloader.xpt
+@RESPATH@/components/urlformatter.xpt
+@RESPATH@/components/webBrowser_core.xpt
+@RESPATH@/components/webbrowserpersist.xpt
+@RESPATH@/components/widget.xpt
 #ifdef XP_MACOSX
-@BINPATH@/components/widget_cocoa.xpt
+@RESPATH@/components/widget_cocoa.xpt
 #endif
-@BINPATH@/components/windowds.xpt
-@BINPATH@/components/windowwatcher.xpt
-@BINPATH@/components/xpcom_base.xpt
-@BINPATH@/components/xpcom_system.xpt
-@BINPATH@/components/xpcom_components.xpt
-@BINPATH@/components/xpcom_ds.xpt
-@BINPATH@/components/xpcom_io.xpt
-@BINPATH@/components/xpcom_threads.xpt
-@BINPATH@/components/xpcom_xpti.xpt
-@BINPATH@/components/xpconnect.xpt
-@BINPATH@/components/xulapp.xpt
-@BINPATH@/components/xul.xpt
-@BINPATH@/components/xultmpl.xpt
-@BINPATH@/components/zipwriter.xpt
-@BINPATH@/components/telemetry.xpt
+@RESPATH@/components/windowds.xpt
+@RESPATH@/components/windowwatcher.xpt
+@RESPATH@/components/xpcom_base.xpt
+@RESPATH@/components/xpcom_system.xpt
+@RESPATH@/components/xpcom_components.xpt
+@RESPATH@/components/xpcom_ds.xpt
+@RESPATH@/components/xpcom_io.xpt
+@RESPATH@/components/xpcom_threads.xpt
+@RESPATH@/components/xpcom_xpti.xpt
+@RESPATH@/components/xpconnect.xpt
+@RESPATH@/components/xulapp.xpt
+@RESPATH@/components/xul.xpt
+@RESPATH@/components/xultmpl.xpt
+@RESPATH@/components/zipwriter.xpt
+@RESPATH@/components/telemetry.xpt
 
 ; JavaScript components
-@BINPATH@/components/ChromeNotifications.js
-@BINPATH@/components/ChromeNotifications.manifest
-@BINPATH@/components/ConsoleAPI.manifest
-@BINPATH@/components/ConsoleAPIStorage.js
-@BINPATH@/components/BrowserElementParent.manifest
-@BINPATH@/components/BrowserElementParent.js
-@BINPATH@/components/FeedProcessor.manifest
-@BINPATH@/components/FeedProcessor.js
-@BINPATH@/browser/components/BrowserFeeds.manifest
-@BINPATH@/browser/components/FeedConverter.js
-@BINPATH@/browser/components/FeedWriter.js
-@BINPATH@/browser/components/fuelApplication.manifest
-@BINPATH@/browser/components/fuelApplication.js
-@BINPATH@/browser/components/WebContentConverter.js
-@BINPATH@/browser/components/BrowserComponents.manifest
-@BINPATH@/browser/components/nsBrowserContentHandler.js
-@BINPATH@/browser/components/nsBrowserGlue.js
-@BINPATH@/browser/components/nsSetDefaultBrowser.manifest
-@BINPATH@/browser/components/nsSetDefaultBrowser.js
-@BINPATH@/browser/components/BrowserDownloads.manifest
-@BINPATH@/browser/components/DownloadsStartup.js
-@BINPATH@/browser/components/DownloadsUI.js
-@BINPATH@/browser/components/BrowserPlaces.manifest
-@BINPATH@/browser/components/devtools-clhandler.manifest
-@BINPATH@/browser/components/devtools-clhandler.js
-@BINPATH@/browser/components/webideCli.js
-@BINPATH@/browser/components/webideComponents.manifest
-@BINPATH@/browser/components/Experiments.manifest
-@BINPATH@/browser/components/ExperimentsService.js
-@BINPATH@/browser/components/translation.manifest
-@BINPATH@/components/Downloads.manifest
-@BINPATH@/components/DownloadLegacy.js
-@BINPATH@/components/BrowserPageThumbs.manifest
-@BINPATH@/components/crashmonitor.manifest
-@BINPATH@/components/nsCrashMonitor.js
-@BINPATH@/components/SiteSpecificUserAgent.js
-@BINPATH@/components/SiteSpecificUserAgent.manifest
-@BINPATH@/components/toolkitsearch.manifest
-@BINPATH@/components/nsSearchService.js
-@BINPATH@/components/nsSearchSuggestions.js
-@BINPATH@/components/passwordmgr.manifest
-@BINPATH@/components/nsLoginInfo.js
-@BINPATH@/components/nsLoginManager.js
-@BINPATH@/components/nsLoginManagerPrompter.js
-@BINPATH@/components/storage-json.js
-@BINPATH@/components/crypto-SDR.js
-@BINPATH@/components/jsconsole-clhandler.manifest
-@BINPATH@/components/jsconsole-clhandler.js
-@BINPATH@/components/webvtt.xpt
-@BINPATH@/components/WebVTT.manifest
-@BINPATH@/components/WebVTTParserWrapper.js
+@RESPATH@/components/ChromeNotifications.js
+@RESPATH@/components/ChromeNotifications.manifest
+@RESPATH@/components/ConsoleAPI.manifest
+@RESPATH@/components/ConsoleAPIStorage.js
+@RESPATH@/components/BrowserElementParent.manifest
+@RESPATH@/components/BrowserElementParent.js
+@RESPATH@/components/FeedProcessor.manifest
+@RESPATH@/components/FeedProcessor.js
+@RESPATH@/browser/components/BrowserFeeds.manifest
+@RESPATH@/browser/components/FeedConverter.js
+@RESPATH@/browser/components/FeedWriter.js
+@RESPATH@/browser/components/fuelApplication.manifest
+@RESPATH@/browser/components/fuelApplication.js
+@RESPATH@/browser/components/WebContentConverter.js
+@RESPATH@/browser/components/BrowserComponents.manifest
+@RESPATH@/browser/components/nsBrowserContentHandler.js
+@RESPATH@/browser/components/nsBrowserGlue.js
+@RESPATH@/browser/components/nsSetDefaultBrowser.manifest
+@RESPATH@/browser/components/nsSetDefaultBrowser.js
+@RESPATH@/browser/components/BrowserDownloads.manifest
+@RESPATH@/browser/components/DownloadsStartup.js
+@RESPATH@/browser/components/DownloadsUI.js
+@RESPATH@/browser/components/BrowserPlaces.manifest
+@RESPATH@/browser/components/devtools-clhandler.manifest
+@RESPATH@/browser/components/devtools-clhandler.js
+@RESPATH@/browser/components/webideCli.js
+@RESPATH@/browser/components/webideComponents.manifest
+@RESPATH@/browser/components/Experiments.manifest
+@RESPATH@/browser/components/ExperimentsService.js
+@RESPATH@/browser/components/translation.manifest
+@RESPATH@/components/Downloads.manifest
+@RESPATH@/components/DownloadLegacy.js
+@RESPATH@/components/BrowserPageThumbs.manifest
+@RESPATH@/components/crashmonitor.manifest
+@RESPATH@/components/nsCrashMonitor.js
+@RESPATH@/components/SiteSpecificUserAgent.js
+@RESPATH@/components/SiteSpecificUserAgent.manifest
+@RESPATH@/components/toolkitsearch.manifest
+@RESPATH@/components/nsSearchService.js
+@RESPATH@/components/nsSearchSuggestions.js
+@RESPATH@/components/passwordmgr.manifest
+@RESPATH@/components/nsLoginInfo.js
+@RESPATH@/components/nsLoginManager.js
+@RESPATH@/components/nsLoginManagerPrompter.js
+@RESPATH@/components/storage-json.js
+@RESPATH@/components/crypto-SDR.js
+@RESPATH@/components/jsconsole-clhandler.manifest
+@RESPATH@/components/jsconsole-clhandler.js
+@RESPATH@/components/webvtt.xpt
+@RESPATH@/components/WebVTT.manifest
+@RESPATH@/components/WebVTTParserWrapper.js
 #ifdef MOZ_GTK
-@BINPATH@/components/nsFilePicker.manifest
-@BINPATH@/components/nsFilePicker.js
+@RESPATH@/components/nsFilePicker.manifest
+@RESPATH@/components/nsFilePicker.js
 #endif
-@BINPATH@/components/nsHelperAppDlg.manifest
-@BINPATH@/components/nsHelperAppDlg.js
-@BINPATH@/components/nsDownloadManagerUI.manifest
-@BINPATH@/components/nsDownloadManagerUI.js
-@BINPATH@/components/NetworkGeolocationProvider.manifest
-@BINPATH@/components/NetworkGeolocationProvider.js
-@BINPATH@/browser/components/nsSidebar.manifest
-@BINPATH@/browser/components/nsSidebar.js
-@BINPATH@/components/extensions.manifest
-@BINPATH@/components/addonManager.js
-@BINPATH@/components/amContentHandler.js
-@BINPATH@/components/amInstallTrigger.js
-@BINPATH@/components/amWebInstallListener.js
-@BINPATH@/components/nsBlocklistService.js
+@RESPATH@/components/nsHelperAppDlg.manifest
+@RESPATH@/components/nsHelperAppDlg.js
+@RESPATH@/components/nsDownloadManagerUI.manifest
+@RESPATH@/components/nsDownloadManagerUI.js
+@RESPATH@/components/NetworkGeolocationProvider.manifest
+@RESPATH@/components/NetworkGeolocationProvider.js
+@RESPATH@/browser/components/nsSidebar.manifest
+@RESPATH@/browser/components/nsSidebar.js
+@RESPATH@/components/extensions.manifest
+@RESPATH@/components/addonManager.js
+@RESPATH@/components/amContentHandler.js
+@RESPATH@/components/amInstallTrigger.js
+@RESPATH@/components/amWebInstallListener.js
+@RESPATH@/components/nsBlocklistService.js
 #ifdef MOZ_UPDATER
-@BINPATH@/components/nsUpdateService.manifest
-@BINPATH@/components/nsUpdateService.js
-@BINPATH@/components/nsUpdateServiceStub.js
+@RESPATH@/components/nsUpdateService.manifest
+@RESPATH@/components/nsUpdateService.js
+@RESPATH@/components/nsUpdateServiceStub.js
 #endif
-@BINPATH@/components/nsUpdateTimerManager.manifest
-@BINPATH@/components/nsUpdateTimerManager.js
-@BINPATH@/components/addoncompat.manifest
-@BINPATH@/components/multiprocessShims.js
-@BINPATH@/components/remoteTagService.js
-@BINPATH@/components/pluginGlue.manifest
-@BINPATH@/components/ProcessSingleton.manifest
-@BINPATH@/components/MainProcessSingleton.js
-@BINPATH@/components/ContentProcessSingleton.js
-@BINPATH@/browser/components/nsSessionStore.manifest
-@BINPATH@/browser/components/nsSessionStartup.js
-@BINPATH@/browser/components/nsSessionStore.js
-@BINPATH@/components/nsURLFormatter.manifest
-@BINPATH@/components/nsURLFormatter.js
-@BINPATH@/browser/components/@DLL_PREFIX@browsercomps@DLL_SUFFIX@
-@BINPATH@/components/txEXSLTRegExFunctions.manifest
-@BINPATH@/components/txEXSLTRegExFunctions.js
-@BINPATH@/components/toolkitplaces.manifest
-@BINPATH@/components/nsLivemarkService.js
-@BINPATH@/components/nsTaggingService.js
-@BINPATH@/components/nsPlacesAutoComplete.manifest
-@BINPATH@/components/nsPlacesAutoComplete.js
-@BINPATH@/components/UnifiedComplete.manifest
-@BINPATH@/components/UnifiedComplete.js
-@BINPATH@/components/nsPlacesExpiration.js
-@BINPATH@/browser/components/PlacesProtocolHandler.js
-@BINPATH@/components/PlacesCategoriesStarter.js
-@BINPATH@/components/ColorAnalyzer.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
-@BINPATH@/components/nsWebHandlerApp.manifest
-@BINPATH@/components/nsWebHandlerApp.js
-@BINPATH@/components/satchel.manifest
-@BINPATH@/components/nsFormAutoComplete.js
-@BINPATH@/components/nsFormHistory.js
-@BINPATH@/components/FormHistoryStartup.js
-@BINPATH@/components/nsInputListAutoComplete.js
-@BINPATH@/components/formautofill.manifest
-@BINPATH@/components/FormAutofillContentService.js
-@BINPATH@/components/FormAutofillStartup.js
-@BINPATH@/components/contentAreaDropListener.manifest
-@BINPATH@/components/contentAreaDropListener.js
-@BINPATH@/browser/components/BrowserProfileMigrators.manifest
-@BINPATH@/browser/components/ProfileMigrator.js
-@BINPATH@/browser/components/ChromeProfileMigrator.js
-@BINPATH@/browser/components/FirefoxProfileMigrator.js
+@RESPATH@/components/nsUpdateTimerManager.manifest
+@RESPATH@/components/nsUpdateTimerManager.js
+@RESPATH@/components/addoncompat.manifest
+@RESPATH@/components/multiprocessShims.js
+@RESPATH@/components/remoteTagService.js
+@RESPATH@/components/pluginGlue.manifest
+@RESPATH@/components/ProcessSingleton.manifest
+@RESPATH@/components/MainProcessSingleton.js
+@RESPATH@/components/ContentProcessSingleton.js
+@RESPATH@/browser/components/nsSessionStore.manifest
+@RESPATH@/browser/components/nsSessionStartup.js
+@RESPATH@/browser/components/nsSessionStore.js
+@RESPATH@/components/nsURLFormatter.manifest
+@RESPATH@/components/nsURLFormatter.js
+@RESPATH@/browser/components/@DLL_PREFIX@browsercomps@DLL_SUFFIX@
+@RESPATH@/components/txEXSLTRegExFunctions.manifest
+@RESPATH@/components/txEXSLTRegExFunctions.js
+@RESPATH@/components/toolkitplaces.manifest
+@RESPATH@/components/nsLivemarkService.js
+@RESPATH@/components/nsTaggingService.js
+@RESPATH@/components/nsPlacesAutoComplete.manifest
+@RESPATH@/components/nsPlacesAutoComplete.js
+@RESPATH@/components/UnifiedComplete.manifest
+@RESPATH@/components/UnifiedComplete.js
+@RESPATH@/components/nsPlacesExpiration.js
+@RESPATH@/browser/components/PlacesProtocolHandler.js
+@RESPATH@/components/PlacesCategoriesStarter.js
+@RESPATH@/components/ColorAnalyzer.js
+@RESPATH@/components/PageThumbsProtocol.js
+@RESPATH@/components/nsDefaultCLH.manifest
+@RESPATH@/components/nsDefaultCLH.js
+@RESPATH@/components/nsContentPrefService.manifest
+@RESPATH@/components/nsContentPrefService.js
+@RESPATH@/components/nsContentDispatchChooser.manifest
+@RESPATH@/components/nsContentDispatchChooser.js
+@RESPATH@/components/nsHandlerService.manifest
+@RESPATH@/components/nsHandlerService.js
+@RESPATH@/components/nsWebHandlerApp.manifest
+@RESPATH@/components/nsWebHandlerApp.js
+@RESPATH@/components/satchel.manifest
+@RESPATH@/components/nsFormAutoComplete.js
+@RESPATH@/components/nsFormHistory.js
+@RESPATH@/components/FormHistoryStartup.js
+@RESPATH@/components/nsInputListAutoComplete.js
+@RESPATH@/components/formautofill.manifest
+@RESPATH@/components/FormAutofillContentService.js
+@RESPATH@/components/FormAutofillStartup.js
+@RESPATH@/components/contentAreaDropListener.manifest
+@RESPATH@/components/contentAreaDropListener.js
+@RESPATH@/browser/components/BrowserProfileMigrators.manifest
+@RESPATH@/browser/components/ProfileMigrator.js
+@RESPATH@/browser/components/ChromeProfileMigrator.js
+@RESPATH@/browser/components/FirefoxProfileMigrator.js
 #ifdef XP_WIN
-@BINPATH@/browser/components/IEProfileMigrator.js
-@BINPATH@/browser/components/SafariProfileMigrator.js
+@RESPATH@/browser/components/IEProfileMigrator.js
+@RESPATH@/browser/components/SafariProfileMigrator.js
 #endif
 #ifdef XP_MACOSX
-@BINPATH@/browser/components/SafariProfileMigrator.js
+@RESPATH@/browser/components/SafariProfileMigrator.js
 #endif
 #ifdef MOZ_ENABLE_DBUS
-@BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
+@RESPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 #ifdef MOZ_ENABLE_GNOME_COMPONENT
-@BINPATH@/components/@DLL_PREFIX@mozgnome@DLL_SUFFIX@
+@RESPATH@/components/@DLL_PREFIX@mozgnome@DLL_SUFFIX@
 #endif
 #ifdef MOZ_ENABLE_GNOMEVFS
-@BINPATH@/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
+@RESPATH@/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
 #endif
 #if defined(MOZ_ENABLE_DBUS) || defined(MOZ_ENABLE_GNOME_COMPONENT) || defined(MOZ_ENABLE_GNOMEVFS)
-@BINPATH@/components/components.manifest
+@RESPATH@/components/components.manifest
 #endif
-@BINPATH@/components/nsINIProcessor.manifest
-@BINPATH@/components/nsINIProcessor.js
-@BINPATH@/components/nsPrompter.manifest
-@BINPATH@/components/nsPrompter.js
+@RESPATH@/components/nsINIProcessor.manifest
+@RESPATH@/components/nsINIProcessor.js
+@RESPATH@/components/nsPrompter.manifest
+@RESPATH@/components/nsPrompter.js
 #ifdef MOZ_DATA_REPORTING
-@BINPATH@/components/DataReporting.manifest
-@BINPATH@/components/DataReportingService.js
+@RESPATH@/components/DataReporting.manifest
+@RESPATH@/components/DataReportingService.js
 #endif
 #ifdef MOZ_SERVICES_HEALTHREPORT
-@BINPATH@/components/HealthReportComponents.manifest
-@BINPATH@/browser/components/SelfSupportService.manifest
-@BINPATH@/browser/components/SelfSupportService.js
+@RESPATH@/components/HealthReportComponents.manifest
+@RESPATH@/browser/components/SelfSupportService.manifest
+@RESPATH@/browser/components/SelfSupportService.js
 #endif
 #ifdef MOZ_SERVICES_SYNC
-@BINPATH@/components/SyncComponents.manifest
-@BINPATH@/components/Weave.js
+@RESPATH@/components/SyncComponents.manifest
+@RESPATH@/components/Weave.js
 #endif
 #ifdef MOZ_CAPTIVEDETECT
-@BINPATH@/components/CaptivePortalDetectComponents.manifest
-@BINPATH@/components/captivedetect.js
+@RESPATH@/components/CaptivePortalDetectComponents.manifest
+@RESPATH@/components/captivedetect.js
 #endif
-@BINPATH@/components/servicesComponents.manifest
-@BINPATH@/components/cryptoComponents.manifest
-@BINPATH@/components/TelemetryStartup.js
-@BINPATH@/components/TelemetryStartup.manifest
-@BINPATH@/components/XULStore.js
-@BINPATH@/components/XULStore.manifest
-@BINPATH@/components/messageWakeupService.js
-@BINPATH@/components/messageWakeupService.manifest
-@BINPATH@/components/SettingsManager.js
-@BINPATH@/components/SettingsManager.manifest
-@BINPATH@/components/Webapps.js
-@BINPATH@/components/Webapps.manifest
-@BINPATH@/components/AppsService.js
-@BINPATH@/components/AppsService.manifest
-@BINPATH@/components/nsDOMIdentity.js
-@BINPATH@/components/nsIDService.js
-@BINPATH@/components/Identity.manifest
-@BINPATH@/components/recording-cmdline.js
-@BINPATH@/components/recording-cmdline.manifest
+@RESPATH@/components/servicesComponents.manifest
+@RESPATH@/components/cryptoComponents.manifest
+@RESPATH@/components/TelemetryStartup.js
+@RESPATH@/components/TelemetryStartup.manifest
+@RESPATH@/components/XULStore.js
+@RESPATH@/components/XULStore.manifest
+@RESPATH@/components/messageWakeupService.js
+@RESPATH@/components/messageWakeupService.manifest
+@RESPATH@/components/SettingsManager.js
+@RESPATH@/components/SettingsManager.manifest
+@RESPATH@/components/Webapps.js
+@RESPATH@/components/Webapps.manifest
+@RESPATH@/components/AppsService.js
+@RESPATH@/components/AppsService.manifest
+@RESPATH@/components/nsDOMIdentity.js
+@RESPATH@/components/nsIDService.js
+@RESPATH@/components/Identity.manifest
+@RESPATH@/components/recording-cmdline.js
+@RESPATH@/components/recording-cmdline.manifest
 
-@BINPATH@/components/PermissionSettings.js
-@BINPATH@/components/PermissionSettings.manifest
-@BINPATH@/components/ContactManager.js
-@BINPATH@/components/ContactManager.manifest
-@BINPATH@/components/PhoneNumberService.js
-@BINPATH@/components/PhoneNumberService.manifest
-@BINPATH@/components/NotificationStorage.js
-@BINPATH@/components/NotificationStorage.manifest
-@BINPATH@/components/AlarmsManager.js
-@BINPATH@/components/AlarmsManager.manifest
-@BINPATH@/components/Push.js
-@BINPATH@/components/Push.manifest
-@BINPATH@/components/PushServiceLauncher.js
+@RESPATH@/components/PermissionSettings.js
+@RESPATH@/components/PermissionSettings.manifest
+@RESPATH@/components/ContactManager.js
+@RESPATH@/components/ContactManager.manifest
+@RESPATH@/components/PhoneNumberService.js
+@RESPATH@/components/PhoneNumberService.manifest
+@RESPATH@/components/NotificationStorage.js
+@RESPATH@/components/NotificationStorage.manifest
+@RESPATH@/components/AlarmsManager.js
+@RESPATH@/components/AlarmsManager.manifest
+@RESPATH@/components/Push.js
+@RESPATH@/components/Push.manifest
+@RESPATH@/components/PushServiceLauncher.js
 
-@BINPATH@/components/SlowScriptDebug.manifest
-@BINPATH@/components/SlowScriptDebug.js
+@RESPATH@/components/SlowScriptDebug.manifest
+@RESPATH@/components/SlowScriptDebug.js
 
 #ifndef RELEASE_BUILD
-@BINPATH@/components/InterAppComm.manifest
-@BINPATH@/components/InterAppCommService.js
-@BINPATH@/components/InterAppConnection.js
-@BINPATH@/components/InterAppMessagePort.js
+@RESPATH@/components/InterAppComm.manifest
+@RESPATH@/components/InterAppCommService.js
+@RESPATH@/components/InterAppConnection.js
+@RESPATH@/components/InterAppMessagePort.js
 #endif
 
-@BINPATH@/components/TCPSocket.js
-@BINPATH@/components/TCPServerSocket.js
-@BINPATH@/components/TCPSocketParentIntermediary.js
-@BINPATH@/components/TCPSocket.manifest
+@RESPATH@/components/TCPSocket.js
+@RESPATH@/components/TCPServerSocket.js
+@RESPATH@/components/TCPSocketParentIntermediary.js
+@RESPATH@/components/TCPSocket.manifest
 
 #ifdef MOZ_ACTIVITIES
-@BINPATH@/components/SystemMessageInternal.js
-@BINPATH@/components/SystemMessageManager.js
-@BINPATH@/components/SystemMessageManager.manifest
+@RESPATH@/components/SystemMessageInternal.js
+@RESPATH@/components/SystemMessageManager.js
+@RESPATH@/components/SystemMessageManager.manifest
 
-@BINPATH@/components/Activities.manifest
-@BINPATH@/components/ActivityProxy.js
-@BINPATH@/components/ActivityRequestHandler.js
-@BINPATH@/components/ActivityWrapper.js
-@BINPATH@/components/ActivityMessageConfigurator.js
+@RESPATH@/components/Activities.manifest
+@RESPATH@/components/ActivityProxy.js
+@RESPATH@/components/ActivityRequestHandler.js
+@RESPATH@/components/ActivityWrapper.js
+@RESPATH@/components/ActivityMessageConfigurator.js
 #endif
 
-@BINPATH@/components/Payment.js
-@BINPATH@/components/PaymentFlowInfo.js
-@BINPATH@/components/Payment.manifest
+@RESPATH@/components/Payment.js
+@RESPATH@/components/PaymentFlowInfo.js
+@RESPATH@/components/Payment.manifest
 
 #ifdef MOZ_WEBRTC
-@BINPATH@/components/PeerConnection.js
-@BINPATH@/components/PeerConnection.manifest
+@RESPATH@/components/PeerConnection.js
+@RESPATH@/components/PeerConnection.manifest
 #endif
 
-@BINPATH@/chrome/marionette@JAREXT@
-@BINPATH@/chrome/marionette.manifest
-@BINPATH@/components/MarionetteComponents.manifest
-@BINPATH@/components/marionettecomponent.js
+@RESPATH@/chrome/marionette@JAREXT@
+@RESPATH@/chrome/marionette.manifest
+@RESPATH@/components/MarionetteComponents.manifest
+@RESPATH@/components/marionettecomponent.js
 
 #ifdef MOZ_WEBSPEECH
-@BINPATH@/components/dom_webspeechsynth.xpt
+@RESPATH@/components/dom_webspeechsynth.xpt
 #endif
 
-@BINPATH@/components/nsAsyncShutdown.manifest
-@BINPATH@/components/nsAsyncShutdown.js
+@RESPATH@/components/nsAsyncShutdown.manifest
+@RESPATH@/components/nsAsyncShutdown.js
 
 ; InputMethod API
-@BINPATH@/components/MozKeyboard.js
-@BINPATH@/components/InputMethod.manifest
+@RESPATH@/components/MozKeyboard.js
+@RESPATH@/components/InputMethod.manifest
 
 #ifdef MOZ_DEBUG
-@BINPATH@/components/TestInterfaceJS.js
-@BINPATH@/components/TestInterfaceJS.manifest
+@RESPATH@/components/TestInterfaceJS.js
+@RESPATH@/components/TestInterfaceJS.manifest
 #endif
 
 ; Modules
-@BINPATH@/browser/modules/*
-@BINPATH@/modules/*
+@RESPATH@/browser/modules/*
+@RESPATH@/modules/*
 
 ; Safe Browsing
 #ifdef MOZ_URL_CLASSIFIER
-@BINPATH@/components/nsURLClassifier.manifest
-@BINPATH@/components/nsUrlClassifierHashCompleter.js
-@BINPATH@/components/nsUrlClassifierListManager.js
-@BINPATH@/components/nsUrlClassifierLib.js
-@BINPATH@/components/url-classifier.xpt
+@RESPATH@/components/nsURLClassifier.manifest
+@RESPATH@/components/nsUrlClassifierHashCompleter.js
+@RESPATH@/components/nsUrlClassifierListManager.js
+@RESPATH@/components/nsUrlClassifierLib.js
+@RESPATH@/components/url-classifier.xpt
 #endif
 
 ; ANGLE GLES-on-D3D rendering library
 #ifdef MOZ_ANGLE_RENDERER
 @BINPATH@/libEGL.dll
 @BINPATH@/libGLESv2.dll
 
 #ifdef MOZ_D3DCOMPILER_VISTA_DLL
@@ -645,164 +635,150 @@
 #endif
 
 #ifdef MOZ_D3DCOMPILER_XP_DLL
 @BINPATH@/@MOZ_D3DCOMPILER_XP_DLL@
 #endif
 #endif # MOZ_ANGLE_RENDERER
 
 ; [Browser Chrome Files]
-@BINPATH@/browser/chrome.manifest
-@BINPATH@/browser/chrome/browser@JAREXT@
-@BINPATH@/browser/chrome/browser.manifest
-@BINPATH@/browser/chrome/pdfjs.manifest
-@BINPATH@/browser/chrome/pdfjs/*
+@RESPATH@/browser/chrome.manifest
+@RESPATH@/browser/chrome/browser@JAREXT@
+@RESPATH@/browser/chrome/browser.manifest
+@RESPATH@/browser/chrome/pdfjs.manifest
+@RESPATH@/browser/chrome/pdfjs/*
 #ifdef NIGHTLY_BUILD
-@BINPATH@/browser/chrome/shumway.manifest
-@BINPATH@/browser/chrome/shumway/*
+@RESPATH@/browser/chrome/shumway.manifest
+@RESPATH@/browser/chrome/shumway/*
 #endif
-@BINPATH@/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
-@BINPATH@/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
-@BINPATH@/chrome/toolkit@JAREXT@
-@BINPATH@/chrome/toolkit.manifest
-@BINPATH@/chrome/recording.manifest
-@BINPATH@/chrome/recording/*
+@RESPATH@/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
+@RESPATH@/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
+@RESPATH@/chrome/toolkit@JAREXT@
+@RESPATH@/chrome/toolkit.manifest
+@RESPATH@/chrome/recording.manifest
+@RESPATH@/chrome/recording/*
 #ifdef MOZ_GTK
-@BINPATH@/browser/chrome/icons/default/default16.png
-@BINPATH@/browser/chrome/icons/default/default32.png
-@BINPATH@/browser/chrome/icons/default/default48.png
+@RESPATH@/browser/chrome/icons/default/default16.png
+@RESPATH@/browser/chrome/icons/default/default32.png
+@RESPATH@/browser/chrome/icons/default/default48.png
 #endif
 
 ; [Webide Files]
-@BINPATH@/browser/chrome/webide@JAREXT@
-@BINPATH@/browser/chrome/webide.manifest
-@BINPATH@/browser/@PREF_DIR@/webide-prefs.js
+@RESPATH@/browser/chrome/webide@JAREXT@
+@RESPATH@/browser/chrome/webide.manifest
+@RESPATH@/browser/@PREF_DIR@/webide-prefs.js
 
 ; shell icons
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 ; shell icons
-@BINPATH@/browser/icons/*.png
+@RESPATH@/browser/icons/*.png
 #ifdef MOZ_UPDATER
 ; updater icon
-@BINPATH@/icons/updater.png
+@RESPATH@/icons/updater.png
 #endif
 #endif
 #endif
 
 ; [Default Preferences]
 ; All the pref files must be part of base to prevent migration bugs
-@BINPATH@/browser/@PREF_DIR@/firefox.js
-@BINPATH@/browser/@PREF_DIR@/firefox-branding.js
-@BINPATH@/greprefs.js
-@BINPATH@/defaults/autoconfig/platform.js
-@BINPATH@/defaults/autoconfig/prefcalls.js
-@BINPATH@/browser/defaults/profile/prefs.js
+@RESPATH@/browser/@PREF_DIR@/firefox.js
+@RESPATH@/browser/@PREF_DIR@/firefox-branding.js
+@RESPATH@/greprefs.js
+@RESPATH@/defaults/autoconfig/platform.js
+@RESPATH@/defaults/autoconfig/prefcalls.js
+@RESPATH@/browser/defaults/profile/prefs.js
 
 #ifndef LIBXUL_SDK
 ; Warning: changing the path to channel-prefs.js can cause bugs (Bug 756325)
 ; Technically this is an app pref file, but we are keeping it in the original
 ; gre location for now.
-@BINPATH@/defaults/pref/channel-prefs.js
+@RESPATH@/defaults/pref/channel-prefs.js
 #else
 ; For Fx-on-xr, channel-prefs lives with the app preferences. (Bug 762588)
-@BINPATH@/@PREF_DIR@/channel-prefs.js
+@RESPATH@/@PREF_DIR@/channel-prefs.js
 #endif
 
 ; Services (gre) prefs
 #ifdef MOZ_SERVICES_NOTIFICATIONS
-@BINPATH@/defaults/pref/services-notifications.js
+@RESPATH@/defaults/pref/services-notifications.js
 #endif
 #ifdef MOZ_SERVICES_SYNC
-@BINPATH@/defaults/pref/services-sync.js
+@RESPATH@/defaults/pref/services-sync.js
 #endif
 
 ; [Layout Engine Resources]
 ; Style Sheets, Graphics and other Resources used by the layout engine.
-@BINPATH@/res/EditorOverride.css
-@BINPATH@/res/contenteditable.css
-@BINPATH@/res/designmode.css
-@BINPATH@/res/ImageDocument.css
-@BINPATH@/res/TopLevelImageDocument.css
-@BINPATH@/res/TopLevelVideoDocument.css
-@BINPATH@/res/table-add-column-after-active.gif
-@BINPATH@/res/table-add-column-after-hover.gif
-@BINPATH@/res/table-add-column-after.gif
-@BINPATH@/res/table-add-column-before-active.gif
-@BINPATH@/res/table-add-column-before-hover.gif
-@BINPATH@/res/table-add-column-before.gif
-@BINPATH@/res/table-add-row-after-active.gif
-@BINPATH@/res/table-add-row-after-hover.gif
-@BINPATH@/res/table-add-row-after.gif
-@BINPATH@/res/table-add-row-before-active.gif
-@BINPATH@/res/table-add-row-before-hover.gif
-@BINPATH@/res/table-add-row-before.gif
-@BINPATH@/res/table-remove-column-active.gif
-@BINPATH@/res/table-remove-column-hover.gif
-@BINPATH@/res/table-remove-column.gif
-@BINPATH@/res/table-remove-row-active.gif
-@BINPATH@/res/table-remove-row-hover.gif
-@BINPATH@/res/table-remove-row.gif
-@BINPATH@/res/grabber.gif
+@RESPATH@/res/EditorOverride.css
+@RESPATH@/res/contenteditable.css
+@RESPATH@/res/designmode.css
+@RESPATH@/res/ImageDocument.css
+@RESPATH@/res/TopLevelImageDocument.css
+@RESPATH@/res/TopLevelVideoDocument.css
+@RESPATH@/res/table-add-column-after-active.gif
+@RESPATH@/res/table-add-column-after-hover.gif
+@RESPATH@/res/table-add-column-after.gif
+@RESPATH@/res/table-add-column-before-active.gif
+@RESPATH@/res/table-add-column-before-hover.gif
+@RESPATH@/res/table-add-column-before.gif
+@RESPATH@/res/table-add-row-after-active.gif
+@RESPATH@/res/table-add-row-after-hover.gif
+@RESPATH@/res/table-add-row-after.gif
+@RESPATH@/res/table-add-row-before-active.gif
+@RESPATH@/res/table-add-row-before-hover.gif
+@RESPATH@/res/table-add-row-before.gif
+@RESPATH@/res/table-remove-column-active.gif
+@RESPATH@/res/table-remove-column-hover.gif
+@RESPATH@/res/table-remove-column.gif
+@RESPATH@/res/table-remove-row-active.gif
+@RESPATH@/res/table-remove-row-hover.gif
+@RESPATH@/res/table-remove-row.gif
+@RESPATH@/res/grabber.gif
 #ifdef XP_MACOSX
-@BINPATH@/res/cursors/*
+@RESPATH@/res/cursors/*
 #endif
-@BINPATH@/res/fonts/*
-@BINPATH@/res/dtd/*
-@BINPATH@/res/html/*
-@BINPATH@/res/langGroups.properties
-@BINPATH@/res/language.properties
-@BINPATH@/res/entityTables/*
+@RESPATH@/res/fonts/*
+@RESPATH@/res/dtd/*
+@RESPATH@/res/html/*
+@RESPATH@/res/langGroups.properties
+@RESPATH@/res/language.properties
+@RESPATH@/res/entityTables/*
 #ifdef XP_MACOSX
-@BINPATH@/res/MainMenu.nib/
+@RESPATH@/res/MainMenu.nib/
 #endif
 
 ; svg
-@BINPATH@/res/svg.css
-@BINPATH@/components/dom_svg.xpt
-@BINPATH@/components/dom_smil.xpt
+@RESPATH@/res/svg.css
+@RESPATH@/components/dom_svg.xpt
+@RESPATH@/components/dom_smil.xpt
 
 ; [Personal Security Manager]
 ;
 ; NSS libraries are signed in the staging directory,
 ; meaning their .chk files are created there directly.
 ;
 #ifndef MOZ_NATIVE_NSS
-#ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@freebl3@DLL_SUFFIX@
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@nss3@DLL_SUFFIX@
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
-#else
 @BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
-#endif
 #ifndef NSS_DISABLE_DBM
-#ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@nssdbm3@DLL_SUFFIX@
-#else
 @BINPATH@/@DLL_PREFIX@nssdbm3@DLL_SUFFIX@
 #endif
-#endif
 #ifndef MOZ_FOLD_LIBS
 @BINPATH@/@DLL_PREFIX@nssutil3@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@smime3@DLL_SUFFIX@
 @BINPATH@/@DLL_PREFIX@ssl3@DLL_SUFFIX@
 #endif
-#ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/@DLL_PREFIX@softokn3@DLL_SUFFIX@
-#else
 @BINPATH@/@DLL_PREFIX@softokn3@DLL_SUFFIX@
 #endif
-#endif
-@BINPATH@/chrome/pippki@JAREXT@
-@BINPATH@/chrome/pippki.manifest
-@BINPATH@/components/pipboot.xpt
-@BINPATH@/components/pipnss.xpt
-@BINPATH@/components/pippki.xpt
+@RESPATH@/chrome/pippki@JAREXT@
+@RESPATH@/chrome/pippki.manifest
+@RESPATH@/components/pipboot.xpt
+@RESPATH@/components/pipnss.xpt
+@RESPATH@/components/pippki.xpt
 
 ; For process sandboxing
 #if defined(MOZ_SANDBOX)
 #if defined(XP_WIN)
 @BINPATH@/@DLL_PREFIX@sandboxbroker@DLL_SUFFIX@
 #elif defined(XP_LINUX)
 @BINPATH@/@DLL_PREFIX@mozsandbox@DLL_SUFFIX@
 #endif
@@ -814,121 +790,121 @@ bin/libfreebl_32fpu_3.so
 bin/libfreebl_32int_3.so
 bin/libfreebl_32int64_3.so
 #endif
 
 ; [Updater]
 ;
 #ifdef MOZ_UPDATER
 #ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/updater.app/
+@BINPATH@/updater.app/
 #else
 @BINPATH@/updater@BIN_SUFFIX@
 #endif
 #endif
 
 ; [MaintenanceService]
 ;
 #ifdef MOZ_MAINTENANCE_SERVICE
 @BINPATH@/maintenanceservice.exe
 @BINPATH@/maintenanceservice_installer.exe
 #endif
 
 ; [Crash Reporter]
 ;
 #ifdef MOZ_CRASHREPORTER
-@BINPATH@/components/CrashService.manifest
-@BINPATH@/components/CrashService.js
-@BINPATH@/components/toolkit_crashservice.xpt
+@RESPATH@/components/CrashService.manifest
+@RESPATH@/components/CrashService.js
+@RESPATH@/components/toolkit_crashservice.xpt
 #ifdef XP_MACOSX
-@APPNAME@/Contents/MacOS/crashreporter.app/
+@BINPATH@/crashreporter.app/
 #else
 @BINPATH@/crashreporter@BIN_SUFFIX@
-@BINPATH@/crashreporter.ini
+@RESPATH@/crashreporter.ini
 #ifdef XP_UNIX
-@BINPATH@/Throbber-small.gif
+@RESPATH@/Throbber-small.gif
 #endif
 #endif
-@BINPATH@/browser/crashreporter-override.ini
+@RESPATH@/browser/crashreporter-override.ini
 #ifdef MOZ_CRASHREPORTER_INJECTOR
 @BINPATH@/breakpadinjector.dll
 #endif
 #endif
 
 #ifdef MOZ_WEBAPP_RUNTIME
 [WebappRuntime]
 #ifdef XP_WIN
 @BINPATH@/webapp-uninstaller@BIN_SUFFIX@
 #endif
-@BINPATH@/webapprt-stub@BIN_SUFFIX@
-@BINPATH@/webapprt/webapprt.ini
-@BINPATH@/webapprt/chrome.manifest
-@BINPATH@/webapprt/chrome/webapprt@JAREXT@
-@BINPATH@/webapprt/chrome/webapprt.manifest
-@BINPATH@/webapprt/chrome/@AB_CD@@JAREXT@
-@BINPATH@/webapprt/chrome/@AB_CD@.manifest
-@BINPATH@/webapprt/components/CommandLineHandler.js
-@BINPATH@/webapprt/components/ContentPermission.js
-@BINPATH@/webapprt/components/DirectoryProvider.js
-@BINPATH@/webapprt/components/PaymentUIGlue.js
-@BINPATH@/webapprt/components/components.manifest
-@BINPATH@/webapprt/defaults/preferences/prefs.js
-@BINPATH@/webapprt/modules/DownloadView.jsm
-@BINPATH@/webapprt/modules/Startup.jsm
-@BINPATH@/webapprt/modules/WebappRT.jsm
-@BINPATH@/webapprt/modules/WebappManager.jsm
-@BINPATH@/webapprt/modules/RemoteDebugger.jsm
-@BINPATH@/webapprt/modules/WebRTCHandler.jsm
+@RESPATH@/webapprt-stub@BIN_SUFFIX@
+@RESPATH@/webapprt/webapprt.ini
+@RESPATH@/webapprt/chrome.manifest
+@RESPATH@/webapprt/chrome/webapprt@JAREXT@
+@RESPATH@/webapprt/chrome/webapprt.manifest
+@RESPATH@/webapprt/chrome/@AB_CD@@JAREXT@
+@RESPATH@/webapprt/chrome/@AB_CD@.manifest
+@RESPATH@/webapprt/components/CommandLineHandler.js
+@RESPATH@/webapprt/components/ContentPermission.js
+@RESPATH@/webapprt/components/DirectoryProvider.js
+@RESPATH@/webapprt/components/PaymentUIGlue.js
+@RESPATH@/webapprt/components/components.manifest
+@RESPATH@/webapprt/defaults/preferences/prefs.js
+@RESPATH@/webapprt/modules/DownloadView.jsm
+@RESPATH@/webapprt/modules/Startup.jsm
+@RESPATH@/webapprt/modules/WebappRT.jsm
+@RESPATH@/webapprt/modules/WebappManager.jsm
+@RESPATH@/webapprt/modules/RemoteDebugger.jsm
+@RESPATH@/webapprt/modules/WebRTCHandler.jsm
 #endif
 
 #ifdef MOZ_METRO
-@BINPATH@/components/MetroUIUtils.js
-@BINPATH@/components/MetroUIUtils.manifest
+@RESPATH@/components/MetroUIUtils.js
+@RESPATH@/components/MetroUIUtils.manifest
 [metro]
 ; gre resources
 @BINPATH@/CommandExecuteHandler@BIN_SUFFIX@
-@BINPATH@/resources.pri
-@BINPATH@/VisualElementsManifest.xml
-@BINPATH@/tileresources
+@RESPATH@/resources.pri
+@RESPATH@/VisualElementsManifest.xml
+@RESPATH@/tileresources
 ; app dir resources
-@BINPATH@/metro/chrome.manifest
-@BINPATH@/metro/searchplugins
-@BINPATH@/metro/metroapp.ini
-@BINPATH@/metro/chrome/browser@JAREXT@
-@BINPATH@/metro/chrome/browser.manifest
-@BINPATH@/metro/chrome/chrome@JAREXT@
-@BINPATH@/metro/chrome/chrome.manifest
-@BINPATH@/metro/chrome/@AB_CD@@JAREXT@
-@BINPATH@/metro/chrome/@AB_CD@.manifest
+@RESPATH@/metro/chrome.manifest
+@RESPATH@/metro/searchplugins
+@RESPATH@/metro/metroapp.ini
+@RESPATH@/metro/chrome/browser@JAREXT@
+@RESPATH@/metro/chrome/browser.manifest
+@RESPATH@/metro/chrome/chrome@JAREXT@
+@RESPATH@/metro/chrome/chrome.manifest
+@RESPATH@/metro/chrome/@AB_CD@@JAREXT@
+@RESPATH@/metro/chrome/@AB_CD@.manifest
 #ifdef NIGHTLY_BUILD
-@BINPATH@/metro/chrome/shumway.manifest
-@BINPATH@/metro/chrome/shumway/*
-@BINPATH@/metro/chrome/pdfjs.manifest
-@BINPATH@/metro/chrome/pdfjs/*
+@RESPATH@/metro/chrome/shumway.manifest
+@RESPATH@/metro/chrome/shumway/*
+@RESPATH@/metro/chrome/pdfjs.manifest
+@RESPATH@/metro/chrome/pdfjs/*
 #endif
-@BINPATH@/metro/components
-@BINPATH@/metro/defaults
-@BINPATH@/metro/modules
+@RESPATH@/metro/components
+@RESPATH@/metro/defaults
+@RESPATH@/metro/modules
 #endif
 
-@BINPATH@/components/DataStore.manifest
-@BINPATH@/components/DataStoreImpl.js
-@BINPATH@/components/dom_datastore.xpt
+@RESPATH@/components/DataStore.manifest
+@RESPATH@/components/DataStoreImpl.js
+@RESPATH@/components/dom_datastore.xpt
 
 ; Shutdown Terminator
-@BINPATH@/components/nsTerminatorTelemetry.js
-@BINPATH@/components/terminator.manifest
+@RESPATH@/components/nsTerminatorTelemetry.js
+@RESPATH@/components/terminator.manifest
 
 #ifdef MOZ_ASAN
 #ifdef CLANG_CXX
 @BINPATH@/llvm-symbolizer
 #endif
 #ifdef CLANG_CL
 @BINPATH@/clang_rt.asan_dynamic-i386.dll
 #endif
 #endif
 
 
 ; media
 #ifdef MOZ_EME
-@BINPATH@/gmp-clearkey/0.1/@DLL_PREFIX@clearkey@DLL_SUFFIX@
-@BINPATH@/gmp-clearkey/0.1/clearkey.info
+@RESPATH@/gmp-clearkey/0.1/@DLL_PREFIX@clearkey@DLL_SUFFIX@
+@RESPATH@/gmp-clearkey/0.1/clearkey.info
 #endif
--- a/browser/locales/en-US/chrome/overrides/appstrings.properties
+++ b/browser/locales/en-US/chrome/overrides/appstrings.properties
@@ -26,11 +26,11 @@ unsafeContentType=The page you are tryin
 externalProtocolTitle=External Protocol Request
 externalProtocolPrompt=An external application must be launched to handle %1$S: links.\n\n\nRequested link:\n\n%2$S\n\nApplication: %3$S\n\n\nIf you were not expecting this request it may be an attempt to exploit a weakness in that other program. Cancel this request unless you are sure it is not malicious.\n
 #LOCALIZATION NOTE (externalProtocolUnknown): The following string is shown if the application name can't be determined
 externalProtocolUnknown=<Unknown>
 externalProtocolChkMsg=Remember my choice for all links of this type.
 externalProtocolLaunchBtn=Launch application
 malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
 phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
-cspFrameAncestorBlocked=This page has a content security policy that prevents it from being embedded in this way.
+cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
 remoteXUL=This page uses an unsupported technology that is no longer available by default in Firefox.
--- a/browser/locales/en-US/chrome/overrides/netError.dtd
+++ b/browser/locales/en-US/chrome/overrides/netError.dtd
@@ -165,18 +165,18 @@ be temporary, and you can try again late
 ">
 
 <!ENTITY phishingBlocked.title "Suspected Web Forgery!">
 <!ENTITY phishingBlocked.longDesc "
 <p>Entering any personal information on this page may result in identity theft or other fraud.</p>
 <p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
 ">
 
-<!ENTITY cspFrameAncestorBlocked.title "Blocked by Content Security Policy">
-<!ENTITY cspFrameAncestorBlocked.longDesc "<p>&brandShortName; prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
+<!ENTITY cspBlocked.title "Blocked by Content Security Policy">
+<!ENTITY cspBlocked.longDesc "<p>&brandShortName; prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
 
 <!ENTITY corruptedContentError.title "Corrupted Content Error">
 <!ENTITY corruptedContentError.longDesc "<p>The page you are trying to view cannot be shown because an error in the data transmission was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">
 
 
 <!ENTITY securityOverride.linkText "Or you can add an exception…">
 <!ENTITY securityOverride.getMeOutOfHereButton "Get me out of here!">
 <!ENTITY securityOverride.exceptionButtonLabel "Add Exception…">
--- a/browser/metro/base/content/pages/netError.xhtml
+++ b/browser/metro/base/content/pages/netError.xhtml
@@ -151,18 +151,18 @@
         }
 
         if (err == "remoteXUL") {
           // Remove the "Try again" button for remote XUL errors given that
           // it is useless.
           document.getElementById("errorTryAgain").style.display = "none";
         }
 
-        if (err == "cspFrameAncestorBlocked") {
-          // Remove the "Try again" button for CSP frame ancestors violation, since it's
+        if (err == "cspBlocked") {
+          // Remove the "Try again" button for CSP violations, since it's
           // almost certainly useless. (Bug 553180)
           document.getElementById("errorTryAgain").style.display = "none";
         }
 
         if (err == "nssBadCert") {
           // Remove the "Try again" button for security exceptions, since it's
           // almost certainly useless.
           document.getElementById("errorTryAgain").style.display = "none";
@@ -286,17 +286,17 @@
         <h1 id="et_netInterrupt">&netInterrupt.title;</h1>
         <h1 id="et_deniedPortAccess">&deniedPortAccess.title;</h1>
         <h1 id="et_proxyResolveFailure">&proxyResolveFailure.title;</h1>
         <h1 id="et_proxyConnectFailure">&proxyConnectFailure.title;</h1>
         <h1 id="et_contentEncodingError">&contentEncodingError.title;</h1>
         <h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&nssBadCert.title;</h1>
-        <h1 id="et_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.title;</h1>
+        <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc;</div>
@@ -311,17 +311,17 @@
         <div id="ed_netInterrupt">&netInterrupt.longDesc;</div>
         <div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div>
         <div id="ed_proxyResolveFailure">&proxyResolveFailure.longDesc;</div>
         <div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div>
         <div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div>
         <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
         <div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
         <div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
-        <div id="ed_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.longDesc;</div>
+        <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer" class="section">
 
--- a/browser/metro/components/SessionStore.js
+++ b/browser/metro/components/SessionStore.js
@@ -801,17 +801,17 @@ SessionStore.prototype = {
       file.append("thumbnail-" + browser.contentWindowId);
       file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
 
       let source = Services.io.newURI(aStringValue, "UTF8", null);
       let target = Services.io.newFileURI(file)
 
       let persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Ci.nsIWebBrowserPersist);
       persist.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES | Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
-      persist.saveURI(source, null, null, null, null, file);
+      persist.saveURI(source, null, null, 0, null, null, file);
 
       aStringValue = target.spec;
     }
 
     if (!browser.__SS_extdata)
       browser.__SS_extdata = {};
     browser.__SS_extdata[aKey] = aStringValue;
     this.saveStateDelayed();
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -33,16 +33,17 @@
 #include "nsIDOMElement.h"
 #include "nsIDOMStorage.h"
 #include "nsIContentViewer.h"
 #include "nsIDocumentLoaderFactory.h"
 #include "nsCURILoader.h"
 #include "nsDocShellCID.h"
 #include "nsDOMCID.h"
 #include "nsNetUtil.h"
+#include "mozilla/net/ReferrerPolicy.h"
 #include "nsRect.h"
 #include "prenv.h"
 #include "nsIDOMWindow.h"
 #include "nsIGlobalObject.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsPoint.h"
 #include "nsIObserverService.h"
 #include "nsIPrompt.h"
@@ -549,16 +550,17 @@ nsPingListener::AsyncOnChannelRedirect(n
 }
 
 struct SendPingInfo {
   int32_t numPings;
   int32_t maxPings;
   bool    requireSameHost;
   nsIURI *target;
   nsIURI *referrer;
+  uint32_t referrerPolicy;
 };
 
 static void
 SendPing(void *closure, nsIContent *content, nsIURI *uri, nsIIOService *ios)
 {
   SendPingInfo *info = static_cast<SendPingInfo *>(closure);
   if (info->maxPings > -1 && info->numPings >= info->maxPings)
     return;
@@ -628,17 +630,17 @@ SendPing(void *closure, nsIContent *cont
       if (NS_SUCCEEDED(info->referrer->GetSpec(pingFrom)))
         httpChan->SetRequestHeader(NS_LITERAL_CSTRING("Ping-From"), pingFrom, false);
     }
 
     // If the document containing the hyperlink being audited was not retrieved
     // over an encrypted connection and its address does not have the same
     // origin as "ping URL", send a referrer.
     if (!sameOrigin && !referrerIsSecure)
-      httpChan->SetReferrer(info->referrer);
+      httpChan->SetReferrerWithPolicy(info->referrer, info->referrerPolicy);
   }
 
   nsCOMPtr<nsIUploadChannel2> uploadChan = do_QueryInterface(httpChan);
   if (!uploadChan)
     return;
 
   NS_NAMED_LITERAL_CSTRING(uploadData, "PING");
 
@@ -686,28 +688,32 @@ SendPing(void *closure, nsIContent *cont
     // If we failed to setup the timer, then we should just cancel the channel
     // because we won't be able to ensure that it goes away in a timely manner.
     chan->Cancel(NS_ERROR_ABORT);
   }
 }
 
 // Spec: http://whatwg.org/specs/web-apps/current-work/#ping
 static void
-DispatchPings(nsIContent *content, nsIURI *target, nsIURI *referrer)
+DispatchPings(nsIContent *content,
+              nsIURI *target,
+              nsIURI *referrer,
+              uint32_t referrerPolicy)
 {
   SendPingInfo info;
 
   if (!PingsEnabled(&info.maxPings, &info.requireSameHost))
     return;
   if (info.maxPings == 0)
     return;
 
   info.numPings = 0;
   info.target = target;
   info.referrer = referrer;
+  info.referrerPolicy = referrerPolicy;
 
   ForEachPing(content, SendPing, &info);
 }
 
 static nsDOMPerformanceNavigationType
 ConvertLoadTypeToNavigationType(uint32_t aLoadType)
 {
   // Not initialized, assume it's normal load.
@@ -1341,16 +1347,17 @@ nsDocShell::LoadURI(nsIURI * aURI,
     }
     nsCOMPtr<nsIURI> referrer;
     nsCOMPtr<nsIInputStream> postStream;
     nsCOMPtr<nsIInputStream> headersStream;
     nsCOMPtr<nsISupports> owner;
     bool inheritOwner = false;
     bool ownerIsExplicit = false;
     bool sendReferrer = true;
+    uint32_t referrerPolicy = mozilla::net::RP_Default;
     bool isSrcdoc = false;
     nsCOMPtr<nsISHEntry> shEntry;
     nsXPIDLString target;
     nsAutoString srcdoc;
     nsCOMPtr<nsIDocShell> sourceDocShell;
     nsCOMPtr<nsIURI> baseURI;
 
     uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags);    
@@ -1374,16 +1381,17 @@ nsDocShell::LoadURI(nsIURI * aURI,
         aLoadInfo->GetOwner(getter_AddRefs(owner));
         aLoadInfo->GetInheritOwner(&inheritOwner);
         aLoadInfo->GetOwnerIsExplicit(&ownerIsExplicit);
         aLoadInfo->GetSHEntry(getter_AddRefs(shEntry));
         aLoadInfo->GetTarget(getter_Copies(target));
         aLoadInfo->GetPostDataStream(getter_AddRefs(postStream));
         aLoadInfo->GetHeadersStream(getter_AddRefs(headersStream));
         aLoadInfo->GetSendReferrer(&sendReferrer);
+        aLoadInfo->GetReferrerPolicy(&referrerPolicy);
         aLoadInfo->GetIsSrcdocLoad(&isSrcdoc);
         aLoadInfo->GetSrcdocData(srcdoc);
         aLoadInfo->GetSourceDocShell(getter_AddRefs(sourceDocShell));
         aLoadInfo->GetBaseURI(getter_AddRefs(baseURI));
     }
 
 #if defined(PR_LOGGING) && defined(DEBUG)
     if (PR_LOG_TEST(gDocShellLog, PR_LOG_DEBUG)) {
@@ -1597,16 +1605,17 @@ nsDocShell::LoadURI(nsIURI * aURI,
     if (aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_COOKIES)
         flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES;
 
     if (isSrcdoc)
         flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
 
     return InternalLoad(aURI,
                         referrer,
+                        referrerPolicy,
                         owner,
                         flags,
                         target.get(),
                         nullptr,         // No type hint
                         NullString(),    // No forced download
                         postStream,
                         headersStream,
                         loadType,
@@ -4860,20 +4869,21 @@ nsDocShell::DisplayLoadError(nsresult aE
         NS_ENSURE_ARG_POINTER(aURI);
         // Get the host
         nsAutoCString host;
         aURI->GetHost(host);
         CopyUTF8toUTF16(host, formatStrs[0]);
         formatStrCount = 1;
         error.AssignLiteral("netTimeout");
     }
-    else if (NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION == aError) {
+    else if (NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION == aError ||
+             NS_ERROR_CSP_FORM_ACTION_VIOLATION == aError) {
         // CSP error
         cssClass.AssignLiteral("neterror");
-        error.AssignLiteral("cspFrameAncestorBlocked");
+        error.AssignLiteral("cspBlocked");
     }
     else if (NS_ERROR_GET_MODULE(aError) == NS_ERROR_MODULE_SECURITY) {
         nsCOMPtr<nsINSSErrorsService> nsserr =
             do_GetService(NS_NSS_ERRORS_SERVICE_CONTRACTID);
 
         uint32_t errorClass;
         if (!nsserr ||
             NS_FAILED(nsserr->GetErrorClass(aError, &errorClass))) {
@@ -5259,18 +5269,18 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, 
     // end of the URL, so append it last.
     errorPageUrl.AppendLiteral("&d=");
     errorPageUrl.AppendASCII(escapedDescription.get());
 
     nsCOMPtr<nsIURI> errorPageURI;
     rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    return InternalLoad(errorPageURI, nullptr, nullptr,
-                        INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr,
+    return InternalLoad(errorPageURI, nullptr, mozilla::net::RP_Default,
+                        nullptr, INTERNAL_LOAD_FLAGS_INHERIT_OWNER, nullptr, nullptr,
                         NullString(), nullptr, nullptr, LOAD_ERROR_PAGE,
                         nullptr, true, NullString(), this, nullptr, nullptr,
                         nullptr);
 }
 
 
 NS_IMETHODIMP
 nsDocShell::Reload(uint32_t aReloadFlags)
@@ -5322,16 +5332,17 @@ nsDocShell::Reload(uint32_t aReloadFlags
             if (doc->IsSrcdocDocument()) {
                 doc->GetSrcdocData(srcdoc);
                 flags |= INTERNAL_LOAD_FLAGS_IS_SRCDOC;
                 baseURI = doc->GetBaseURI();
             }
         }
         rv = InternalLoad(mCurrentURI,
                           mReferrerURI,
+                          mReferrerPolicy,
                           principal,
                           flags,
                           nullptr,         // No window target
                           NS_LossyConvertUTF16toASCII(contentTypeHint).get(),
                           NullString(),    // No forced download
                           nullptr,         // No post data
                           nullptr,         // No headers data
                           loadType,        // Load type
@@ -9224,27 +9235,29 @@ void CopyFavicon(nsIURI *aOldURI, nsIURI
 #endif
 }
 
 } // anonymous namespace
 
 class InternalLoadEvent : public nsRunnable
 {
 public:
-    InternalLoadEvent(nsDocShell* aDocShell, nsIURI * aURI, nsIURI * aReferrer,
+    InternalLoadEvent(nsDocShell* aDocShell, nsIURI * aURI,
+                      nsIURI * aReferrer, uint32_t aReferrerPolicy,
                       nsISupports * aOwner, uint32_t aFlags,
                       const char* aTypeHint, nsIInputStream * aPostData,
                       nsIInputStream * aHeadersData, uint32_t aLoadType,
                       nsISHEntry * aSHEntry, bool aFirstParty,
                       const nsAString &aSrcdoc, nsIDocShell* aSourceDocShell,
                       nsIURI * aBaseURI) :
         mSrcdoc(aSrcdoc),
         mDocShell(aDocShell),
         mURI(aURI),
         mReferrer(aReferrer),
+        mReferrerPolicy(aReferrerPolicy),
         mOwner(aOwner),
         mPostData(aPostData),
         mHeadersData(aHeadersData),
         mSHEntry(aSHEntry),
         mFlags(aFlags),
         mLoadType(aLoadType),
         mFirstParty(aFirstParty),
         mSourceDocShell(aSourceDocShell),
@@ -9252,17 +9265,19 @@ public:
     {
         // Make sure to keep null things null as needed
         if (aTypeHint) {
             mTypeHint = aTypeHint;
         }
     }
 
     NS_IMETHOD Run() {
-        return mDocShell->InternalLoad(mURI, mReferrer, mOwner, mFlags,
+        return mDocShell->InternalLoad(mURI, mReferrer,
+                                       mReferrerPolicy,
+                                       mOwner, mFlags,
                                        nullptr, mTypeHint.get(),
                                        NullString(), mPostData, mHeadersData,
                                        mLoadType, mSHEntry, mFirstParty,
                                        mSrcdoc, mSourceDocShell, mBaseURI,
                                        nullptr, nullptr);
     }
 
 private:
@@ -9270,16 +9285,17 @@ private:
     // Use IDL strings so .get() returns null by default
     nsXPIDLString mWindowTarget;
     nsXPIDLCString mTypeHint;
     nsString mSrcdoc;
 
     nsRefPtr<nsDocShell> mDocShell;
     nsCOMPtr<nsIURI> mURI;
     nsCOMPtr<nsIURI> mReferrer;
+    uint32_t mReferrerPolicy;
     nsCOMPtr<nsISupports> mOwner;
     nsCOMPtr<nsIInputStream> mPostData;
     nsCOMPtr<nsIInputStream> mHeadersData;
     nsCOMPtr<nsISHEntry> mSHEntry;
     uint32_t mFlags;
     uint32_t mLoadType;
     bool mFirstParty;
     nsCOMPtr<nsIDocShell> mSourceDocShell;
@@ -9324,16 +9340,17 @@ nsDocShell::CreatePrincipalFromReferrer(
                                        outPrincipal);
   NS_ENSURE_SUCCESS(rv, rv);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocShell::InternalLoad(nsIURI * aURI,
                          nsIURI * aReferrer,
+                         uint32_t aReferrerPolicy,
                          nsISupports * aOwner,
                          uint32_t aFlags,
                          const char16_t *aWindowTarget,
                          const char* aTypeHint,
                          const nsAString& aFileName,
                          nsIInputStream * aPostData,
                          nsIInputStream * aHeadersData,
                          uint32_t aLoadType,
@@ -9580,16 +9597,17 @@ nsDocShell::InternalLoad(nsIURI * aURI,
 
         //
         // Transfer the load to the target DocShell...  Pass nullptr as the
         // window target name from to prevent recursive retargeting!
         //
         if (NS_SUCCEEDED(rv) && targetDocShell) {
             rv = targetDocShell->InternalLoad(aURI,
                                               aReferrer,
+                                              aReferrerPolicy,
                                               owner,
                                               aFlags,
                                               nullptr,         // No window target
                                               aTypeHint,
                                               NullString(),    // No forced download
                                               aPostData,
                                               aHeadersData,
                                               aLoadType,
@@ -9660,17 +9678,18 @@ nsDocShell::InternalLoad(nsIURI * aURI,
             // the unload event also a replace load, so we don't
             // create extra history entries.
             if (LOAD_TYPE_HAS_FLAGS(aLoadType, LOAD_FLAGS_REPLACE_HISTORY)) {
                 mLoadType = LOAD_NORMAL_REPLACE;
             }
             
             // Do this asynchronously
             nsCOMPtr<nsIRunnable> ev =
-                new InternalLoadEvent(this, aURI, aReferrer, aOwner, aFlags,
+                new InternalLoadEvent(this, aURI, aReferrer,
+                                      aReferrerPolicy, aOwner, aFlags,
                                       aTypeHint, aPostData, aHeadersData,
                                       aLoadType, aSHEntry, aFirstParty, aSrcdoc,
                                       aSourceDocShell, aBaseURI);
             return NS_DispatchToCurrentThread(ev);
         }
 
         // Just ignore this load attempt
         return NS_OK;
@@ -10112,16 +10131,17 @@ nsDocShell::InternalLoad(nsIURI * aURI,
 
     mozilla::net::PredictorPredict(aURI, nullptr,
                                    nsINetworkPredictor::PREDICT_LOAD,
                                    this, nullptr);
 
     nsCOMPtr<nsIRequest> req;
     rv = DoURILoad(aURI, aReferrer,
                    !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
+                   aReferrerPolicy,
                    owner, aTypeHint, aFileName, aPostData, aHeadersData,
                    aFirstParty, aDocShell, getter_AddRefs(req),
                    (aFlags & INTERNAL_LOAD_FLAGS_FIRST_LOAD) != 0,
                    (aFlags & INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER) != 0,
                    (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES) != 0,
                    srcdoc, aBaseURI, contentType);
     if (req && aRequest)
         NS_ADDREF(*aRequest = req);
@@ -10185,16 +10205,17 @@ nsDocShell::GetInheritedPrincipal(bool a
 
     return nullptr;
 }
 
 nsresult
 nsDocShell::DoURILoad(nsIURI * aURI,
                       nsIURI * aReferrerURI,
                       bool aSendReferrer,
+                      uint32_t aReferrerPolicy,
                       nsISupports * aOwner,
                       const char * aTypeHint,
                       const nsAString & aFileName,
                       nsIInputStream * aPostData,
                       nsIInputStream * aHeadersData,
                       bool aFirstParty,
                       nsIDocShell ** aDocShell,
                       nsIRequest ** aRequest,
@@ -10514,17 +10535,17 @@ nsDocShell::DoURILoad(nsIURI * aURI,
             }
         }
         if (aHeadersData) {
             rv = AddHeadersToChannel(aHeadersData, httpChannel);
         }
         // Set the referrer explicitly
         if (aReferrerURI && aSendReferrer) {
             // Referrer is currenly only set for link clicks here.
-            httpChannel->SetReferrer(aReferrerURI);
+            httpChannel->SetReferrerWithPolicy(aReferrerURI, aReferrerPolicy);
         }
     }
 
     nsCOMPtr<nsIScriptChannel> scriptChannel = do_QueryInterface(channel);
     if (scriptChannel) {
         // Allow execution against our context if the principals match
         scriptChannel->
             SetExecutionPolicy(nsIScriptChannel::EXECUTE_NORMAL);
@@ -10850,16 +10871,21 @@ nsDocShell::SetupReferrerFromChannel(nsI
 {
     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel));
     if (httpChannel) {
         nsCOMPtr<nsIURI> referrer;
         nsresult rv = httpChannel->GetReferrer(getter_AddRefs(referrer));
         if (NS_SUCCEEDED(rv)) {
             SetReferrerURI(referrer);
         }
+        uint32_t referrerPolicy;
+        rv = httpChannel->GetReferrerPolicy(&referrerPolicy);
+        if (NS_SUCCEEDED(rv)) {
+            SetReferrerPolicy(referrerPolicy);
+        }
     }
 }
 
 bool
 nsDocShell::OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner,
                      uint32_t aLoadType, bool aFireOnLocationChange,
                      bool aAddToGlobalHistory, bool aCloneSHChildren)
 {
@@ -11117,16 +11143,22 @@ nsDocShell::OnLoadingSite(nsIChannel * a
 }
 
 void
 nsDocShell::SetReferrerURI(nsIURI * aURI)
 {
     mReferrerURI = aURI;        // This assigment addrefs
 }
 
+void
+nsDocShell::SetReferrerPolicy(uint32_t referrerPolicy)
+{
+    mReferrerPolicy = referrerPolicy;
+}
+
 //*****************************************************************************
 // nsDocShell: Session History
 //*****************************************************************************
 
 NS_IMETHODIMP
 nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
                      const nsAString& aURL, bool aReplace, JSContext* aCx)
 {
@@ -11546,16 +11578,17 @@ nsDocShell::AddToSessionHistory(nsIURI *
         if (!entry) {
             return NS_ERROR_OUT_OF_MEMORY;
         }
     }
 
     // Get the post data & referrer
     nsCOMPtr<nsIInputStream> inputStream;
     nsCOMPtr<nsIURI> referrerURI;
+    uint32_t referrerPolicy = mozilla::net::RP_Default;
     nsCOMPtr<nsISupports> cacheKey;
     nsCOMPtr<nsISupports> owner = aOwner;
     bool expired = false;
     bool discardLayoutState = false;
     nsCOMPtr<nsICachingChannel> cacheChannel;
     if (aChannel) {
         cacheChannel = do_QueryInterface(aChannel);
 
@@ -11572,16 +11605,17 @@ nsDocShell::AddToSessionHistory(nsIURI *
             GetHttpChannel(aChannel, getter_AddRefs(httpChannel));
         }
         if (httpChannel) {
             nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel));
             if (uploadChannel) {
                 uploadChannel->GetUploadStream(getter_AddRefs(inputStream));
             }
             httpChannel->GetReferrer(getter_AddRefs(referrerURI));
+            httpChannel->GetReferrerPolicy(&referrerPolicy);
 
             discardLayoutState = ShouldDiscardLayoutState(httpChannel);
         }
         aChannel->GetOwner(getter_AddRefs(owner));
         if (!owner) {
             nsCOMPtr<nsILoadInfo> loadInfo;
             aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
             if (loadInfo) {
@@ -11602,16 +11636,17 @@ nsDocShell::AddToSessionHistory(nsIURI *
                   inputStream,       // Post data stream
                   nullptr,            // LayoutHistory state
                   cacheKey,          // CacheKey
                   mContentTypeHint,  // Content-type
                   owner,             // Channel or provided owner
                   mHistoryID,
                   mDynamicallyCreated);
     entry->SetReferrerURI(referrerURI);
+    entry->SetReferrerPolicy(referrerPolicy);
     nsCOMPtr<nsIInputStreamChannel> inStrmChan = do_QueryInterface(aChannel);
     if (inStrmChan) {
         bool isSrcdocChannel;
         inStrmChan->GetIsSrcdocChannel(&isSrcdocChannel);
         if (isSrcdocChannel) {
             nsAutoString srcdoc;
             inStrmChan->GetSrcdocData(srcdoc);
             entry->SetSrcdocData(srcdoc);
@@ -11701,24 +11736,27 @@ nsDocShell::LoadHistoryEntry(nsISHEntry 
 {
     if (!IsNavigationAllowed()) {
         return NS_OK;
     }
     
     nsCOMPtr<nsIURI> uri;
     nsCOMPtr<nsIInputStream> postData;
     nsCOMPtr<nsIURI> referrerURI;
+    uint32_t referrerPolicy;
     nsAutoCString contentType;
     nsCOMPtr<nsISupports> owner;
 
     NS_ENSURE_TRUE(aEntry, NS_ERROR_FAILURE);
 
     NS_ENSURE_SUCCESS(aEntry->GetURI(getter_AddRefs(uri)), NS_ERROR_FAILURE);
     NS_ENSURE_SUCCESS(aEntry->GetReferrerURI(getter_AddRefs(referrerURI)),
                       NS_ERROR_FAILURE);
+    NS_ENSURE_SUCCESS(aEntry->GetReferrerPolicy(&referrerPolicy),
+                      NS_ERROR_FAILURE);
     NS_ENSURE_SUCCESS(aEntry->GetPostData(getter_AddRefs(postData)),
                       NS_ERROR_FAILURE);
     NS_ENSURE_SUCCESS(aEntry->GetContentType(contentType), NS_ERROR_FAILURE);
     NS_ENSURE_SUCCESS(aEntry->GetOwner(getter_AddRefs(owner)),
                       NS_ERROR_FAILURE);
 
     // Calling CreateAboutBlankContentViewer can set mOSHE to null, and if
     // that's the only thing holding a ref to aEntry that will cause aEntry to
@@ -11785,16 +11823,17 @@ nsDocShell::LoadHistoryEntry(nsISHEntry 
     }
 
     // Passing nullptr as aSourceDocShell gives the same behaviour as before
     // aSourceDocShell was introduced. According to spec we should be passing
     // the source browsing context that was used when the history entry was
     // first created. bug 947716 has been created to address this issue.
     rv = InternalLoad(uri,
                       referrerURI,
+                      referrerPolicy,
                       owner,
                       flags,
                       nullptr,            // No window target
                       contentType.get(),  // Type hint
                       NullString(),       // No forced file download
                       postData,           // Post data stream
                       nullptr,            // No headers stream
                       aLoadType,          // Load type
@@ -13186,16 +13225,17 @@ nsDocShell::OnLinkClickSync(nsIContent *
   NS_ENSURE_TRUE(refererInner, NS_ERROR_UNEXPECTED);
   if (!mScriptGlobal ||
       mScriptGlobal->GetCurrentInnerWindow() != refererInner) {
       // We're no longer the current inner window
       return NS_OK;
   }
 
   nsCOMPtr<nsIURI> referer = refererDoc->GetDocumentURI();
+  uint32_t refererPolicy = refererDoc->GetReferrerPolicy();
 
   // referer could be null here in some odd cases, but that's ok,
   // we'll just load the link w/o sending a referer in those cases.
 
   nsAutoString target(aTargetSpec);
 
   // If this is an anchor element, grab its type property to use as a hint
   nsAutoString typeHint;
@@ -13214,16 +13254,17 @@ nsDocShell::OnLinkClickSync(nsIContent *
   nsCOMPtr<nsIURI> clonedURI;
   aURI->Clone(getter_AddRefs(clonedURI));
   if (!clonedURI) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   nsresult rv = InternalLoad(clonedURI,                 // New URI
                              referer,                   // Referer URI
+                             refererPolicy,             // Referer policy
                              aContent->NodePrincipal(), // Owner is our node's
                                                         // principal
                              flags,
                              target.get(),              // Window target
                              NS_LossyConvertUTF16toASCII(typeHint).get(),
                              aFileName,                 // Download as file
                              aPostDataStream,           // Post data stream
                              aHeadersDataStream,        // Headers stream
@@ -13231,17 +13272,17 @@ nsDocShell::OnLinkClickSync(nsIContent *
                              nullptr,                   // No SHEntry
                              true,                      // first party site
                              NullString(),              // No srcdoc
                              this,                      // We are the source
                              nullptr,                   // baseURI not needed
                              aDocShell,                 // DocShell out-param
                              aRequest);                 // Request out-param
   if (NS_SUCCEEDED(rv)) {
-    DispatchPings(aContent, aURI, referer);
+    DispatchPings(aContent, aURI, referer, refererPolicy);
   }
   return rv;
 }
 
 NS_IMETHODIMP
 nsDocShell::OnOverLink(nsIContent* aContent,
                        nsIURI* aURI,
                        const char16_t* aTargetSpec)
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -305,16 +305,17 @@ protected:
     // Actually open a channel and perform a URI load.  Note: whatever owner is
     // passed to this function will be set on the channel.  Callers who wish to
     // not have an owner on the channel should just pass null.
     // If aSrcdoc is not void, the load will be considered as a srcdoc load,
     // and the contents of aSrcdoc will be loaded instead of aURI.
     virtual nsresult DoURILoad(nsIURI * aURI,
                                nsIURI * aReferrer,
                                bool aSendReferrer,
+                               uint32_t aReferrerPolicy,
                                nsISupports * aOwner,
                                const char * aTypeHint,
                                const nsAString & aFileName,
                                nsIInputStream * aPostData,
                                nsIInputStream * aHeadersData,
                                bool firstParty,
                                nsIDocShell ** aDocShell,
                                nsIRequest ** aRequest,
@@ -353,16 +354,17 @@ protected:
     // aCloneSHChildren argument as aCloneChildren.
     bool OnNewURI(nsIURI * aURI, nsIChannel * aChannel, nsISupports* aOwner,
                     uint32_t aLoadType,
                     bool aFireOnLocationChange,
                     bool aAddToGlobalHistory,
                     bool aCloneSHChildren);
 
     virtual void SetReferrerURI(nsIURI * aURI);
+    virtual void SetReferrerPolicy(uint32_t referrerPolicy);
 
     // Session History
     virtual bool ShouldAddToSessionHistory(nsIURI * aURI);
     // Either aChannel or aOwner must be null.  If aChannel is
     // present, the owner should be gotten from it.
     // If aCloneChildren is true, then our current session history's
     // children will be cloned onto the new entry.  This should be
     // used when we aren't actually changing the document while adding
@@ -747,16 +749,17 @@ protected:
     nsCOMPtr<nsISupportsArray> mSavedRefreshURIList;
     nsRefPtr<nsDSURIContentListener> mContentListener;
     nsCOMPtr<nsIContentViewer> mContentViewer;
     nsCOMPtr<nsIWidget>        mParentWidget;
 
     // mCurrentURI should be marked immutable on set if possible.
     nsCOMPtr<nsIURI>           mCurrentURI;
     nsCOMPtr<nsIURI>           mReferrerURI;
+    uint32_t                   mReferrerPolicy;
     nsRefPtr<nsGlobalWindow>   mScriptGlobal;
     nsCOMPtr<nsISHistory>      mSessionHistory;
     nsCOMPtr<nsIGlobalHistory2> mGlobalHistory;
     nsCOMPtr<nsIWebBrowserFind> mFind;
     nsCOMPtr<nsICommandManager> mCommandManager;
     // Reference to the SHEntry for this docshell until the page is destroyed.
     // Somebody give me better name
     nsCOMPtr<nsISHEntry>       mOSHE;
--- a/docshell/base/nsDocShellLoadInfo.cpp
+++ b/docshell/base/nsDocShellLoadInfo.cpp
@@ -5,25 +5,27 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Local Includes
 #include "nsDocShellLoadInfo.h"
 #include "nsISHEntry.h"
 #include "nsIInputStream.h"
 #include "nsIURI.h"
 #include "nsIDocShell.h"
+#include "mozilla/net/ReferrerPolicy.h"
 
 //*****************************************************************************
 //***    nsDocShellLoadInfo: Object Management
 //*****************************************************************************
 
 nsDocShellLoadInfo::nsDocShellLoadInfo()
   : mInheritOwner(false),
     mOwnerIsExplicit(false),
     mSendReferrer(true),
+    mReferrerPolicy(mozilla::net::RP_Default),
     mLoadType(nsIDocShellLoadInfo::loadNormal),
     mIsSrcdocLoad(false)
 {
 }
 
 nsDocShellLoadInfo::~nsDocShellLoadInfo()
 {
 }
@@ -187,16 +189,28 @@ NS_IMETHODIMP nsDocShellLoadInfo::GetSen
 }
 
 NS_IMETHODIMP nsDocShellLoadInfo::SetSendReferrer(bool aSendReferrer)
 {
    mSendReferrer = aSendReferrer;
    return NS_OK;
 }
 
+NS_IMETHODIMP nsDocShellLoadInfo::GetReferrerPolicy(nsDocShellInfoReferrerPolicy* aReferrerPolicy)
+{
+   *aReferrerPolicy = mReferrerPolicy;
+   return NS_OK;
+}
+
+NS_IMETHODIMP nsDocShellLoadInfo::SetReferrerPolicy(nsDocShellInfoReferrerPolicy aReferrerPolicy)
+{
+    mReferrerPolicy = aReferrerPolicy;
+    return NS_OK;
+}
+
 NS_IMETHODIMP nsDocShellLoadInfo::GetIsSrcdocLoad(bool* aIsSrcdocLoad)
 {
    *aIsSrcdocLoad = mIsSrcdocLoad;
    return NS_OK;
 }
 
 NS_IMETHODIMP nsDocShellLoadInfo::GetSrcdocData(nsAString &aSrcdocData)
 {
--- a/docshell/base/nsDocShellLoadInfo.h
+++ b/docshell/base/nsDocShellLoadInfo.h
@@ -32,16 +32,17 @@ protected:
   virtual ~nsDocShellLoadInfo();
 
 protected:
   nsCOMPtr<nsIURI>                 mReferrer;
   nsCOMPtr<nsISupports>            mOwner;
   bool                             mInheritOwner;
   bool                             mOwnerIsExplicit;
   bool                             mSendReferrer;
+  nsDocShellInfoReferrerPolicy     mReferrerPolicy;
   nsDocShellInfoLoadType           mLoadType;
   nsCOMPtr<nsISHEntry>             mSHEntry;
   nsString                         mTarget;
   nsCOMPtr<nsIInputStream>         mPostDataStream;
   nsCOMPtr<nsIInputStream>         mHeadersStream;
   bool                             mIsSrcdocLoad;
   nsString                         mSrcdocData;
   nsCOMPtr<nsIDocShell>            mSourceDocShell;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -49,17 +49,17 @@ interface nsIWebBrowserPrint;
 interface nsIVariant;
 interface nsIPrivacyTransitionObserver;
 interface nsIReflowObserver;
 interface nsIScrollObserver;
 interface nsITabParent;
  
 typedef unsigned long nsLoadFlags;
 
-[scriptable, builtinclass, uuid(4e3de242-0b2a-4cf0-81b5-a5fe8628431c)]
+[scriptable, builtinclass, uuid(c2756385-bc54-417b-9ae4-c5a40053a2a3)]
 interface nsIDocShell : nsIDocShellTreeItem
 {
   /**
    * Loads a given URI.  This will give priority to loading the requested URI
    * in the object implementing	this interface.  If it can't be loaded here
    * however, the URL dispatcher will go through its normal process of content
    * loading.
    *
@@ -127,16 +127,17 @@ interface nsIDocShell : nsIDocShellTreeI
 
   /**
    * Loads the given URI.  This method is identical to loadURI(...) except
    * that its parameter list is broken out instead of being packaged inside
    * of an nsIDocShellLoadInfo object...
    *
    * @param aURI            - The URI to load.
    * @param aReferrer       - Referring URI
+   * @param aReferrerPolicy - Referrer policy
    * @param aOwner          - Owner (security principal) 
    * @param aInheritOwner   - Flag indicating whether the owner of the current
    *                          document should be inherited if aOwner is null.
    * @param aStopActiveDoc  - Flag indicating whether loading the current
    *                          document should be stopped.
    * @param aWindowTarget   - Window target for the load.
    * @param aTypeHint       - A hint as to the content-type of the resulting
    *                          data.  May be null or empty if no hint.
@@ -152,16 +153,17 @@ interface nsIDocShell : nsIDocShellTreeI
    *                          of aURI.
    * @param aSourceDocShell - The source browsing context for the navigation.
    * @param aBaseURI        - The base URI to be used for the load.  Set in
    *                          srcdoc loads as it cannot otherwise be inferred
    *                          in certain situations such as view-source.
    */
   [noscript]void internalLoad(in nsIURI aURI,
                               in nsIURI aReferrer,
+                              in unsigned long aReferrerPolicy,
                               in nsISupports aOwner,
                               in uint32_t aFlags,
                               in wstring aWindowTarget,
                               in string aTypeHint,
                               in AString aFileName,
                               in nsIInputStream aPostDataStream,
                               in nsIInputStream aHeadersStream,
                               in unsigned long aLoadFlags,
--- a/docshell/base/nsIDocShellLoadInfo.idl
+++ b/docshell/base/nsIDocShellLoadInfo.idl
@@ -12,18 +12,19 @@
  */
  
 interface nsIURI;
 interface nsIInputStream;
 interface nsISHEntry;
 interface nsIDocShell;
 
 typedef long nsDocShellInfoLoadType;
+typedef unsigned long nsDocShellInfoReferrerPolicy;
 
-[scriptable, uuid(c8d3b1e1-565a-427e-9d68-b109910ce9b7)]
+[scriptable, uuid(c63e9d64-490d-48bf-8013-b5d8ee4dbc25)]
 interface nsIDocShellLoadInfo : nsISupports
 {
     /** This is the referrer for the load. */
     attribute nsIURI referrer;
 
     /** The owner of the load, that is, the entity responsible for 
      *  causing the load to occur. This should be a nsIPrincipal typically.
      */
@@ -80,16 +81,21 @@ interface nsIDocShellLoadInfo : nsISuppo
     /** Additional headers */
     attribute nsIInputStream headersStream;
 
     /** True if the referrer should be sent, false if it shouldn't be
      *  sent, even if it's available. This attribute defaults to true.
      */
     attribute boolean sendReferrer;
 
+    /** Referrer policy for the load. This attribute holds one of
+     *  the values (REFERRER_POLICY_*) defined in nsIHttpChannel.
+     */
+    attribute nsDocShellInfoReferrerPolicy referrerPolicy;
+
     /** True if the docshell has been created to load an iframe where the
      * srcdoc attribute has been set.  Set when srcdocData is specified.
      */
     readonly attribute boolean isSrcdocLoad;
 
     /** When set, the load will be interpreted as a srcdoc load, where contents
      * of this string will be loaded instead of the URI.  Setting srcdocData
      * sets isSrcdocLoad to true
--- a/docshell/resources/content/netError.xhtml
+++ b/docshell/resources/content/netError.xhtml
@@ -150,18 +150,18 @@
         }
 
         if (err == "remoteXUL") {
           // Remove the "Try again" button for remote XUL errors given that
           // it is useless.
           document.getElementById("errorTryAgain").style.display = "none";
         }
 
-        if (err == "cspFrameAncestorBlocked") {
-          // Remove the "Try again" button for CSP frame ancestors violation, since it's
+        if (err == "cspBlocked") {
+          // Remove the "Try again" button for CSP violations, since it's
           // almost certainly useless. (Bug 553180)
           document.getElementById("errorTryAgain").style.display = "none";
         }
 
         if (err == "nssBadCert") {
           // Remove the "Try again" button for security exceptions, since it's
           // almost certainly useless.
           document.getElementById("errorTryAgain").style.display = "none";
@@ -286,17 +286,17 @@
         <h1 id="et_deniedPortAccess">&deniedPortAccess.title;</h1>
         <h1 id="et_proxyResolveFailure">&proxyResolveFailure.title;</h1>
         <h1 id="et_proxyConnectFailure">&proxyConnectFailure.title;</h1>
         <h1 id="et_contentEncodingError">&contentEncodingError.title;</h1>
         <h1 id="et_unsafeContentType">&unsafeContentType.title;</h1>
         <h1 id="et_nssFailure2">&nssFailure2.title;</h1>
         <h1 id="et_nssBadCert">&nssBadCert.title;</h1>
         <h1 id="et_malwareBlocked">&malwareBlocked.title;</h1>
-        <h1 id="et_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.title;</h1>
+        <h1 id="et_cspBlocked">&cspBlocked.title;</h1>
         <h1 id="et_remoteXUL">&remoteXUL.title;</h1>
         <h1 id="et_corruptedContentError">&corruptedContentError.title;</h1>
       </div>
       <div id="errorDescriptionsContainer">
         <div id="ed_generic">&generic.longDesc;</div>
         <div id="ed_dnsNotFound">&dnsNotFound.longDesc;</div>
         <div id="ed_fileNotFound">&fileNotFound.longDesc;</div>
         <div id="ed_malformedURI">&malformedURI.longDesc;</div>
@@ -312,17 +312,17 @@
         <div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div>
         <div id="ed_proxyResolveFailure">&proxyResolveFailure.longDesc;</div>
         <div id="ed_proxyConnectFailure">&proxyConnectFailure.longDesc;</div>
         <div id="ed_contentEncodingError">&contentEncodingError.longDesc;</div>
         <div id="ed_unsafeContentType">&unsafeContentType.longDesc;</div>
         <div id="ed_nssFailure2">&nssFailure2.longDesc2;</div>
         <div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
         <div id="ed_malwareBlocked">&malwareBlocked.longDesc;</div>
-        <div id="ed_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.longDesc;</div>
+        <div id="ed_cspBlocked">&cspBlocked.longDesc;</div>
         <div id="ed_remoteXUL">&remoteXUL.longDesc;</div>
         <div id="ed_corruptedContentError">&corruptedContentError.longDesc;</div>
       </div>
     </div>
 
     <!-- PAGE CONTAINER (for styling purposes only) -->
     <div id="errorPageContainer">
     
--- a/docshell/shistory/public/nsISHEntry.idl
+++ b/docshell/shistory/public/nsISHEntry.idl
@@ -25,17 +25,17 @@ interface nsIBFCacheEntry;
 struct nsIntRect;
 class nsDocShellEditorData;
 class nsSHEntryShared;
 %}
 [ref] native nsIntRect(nsIntRect);
 [ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
 [ptr] native nsSHEntryShared(nsSHEntryShared);
 
-[scriptable, uuid(9eed7e92-1121-46f2-95e5-2f5c0dca46f0)]
+[scriptable, uuid(d5fbeb10-f373-4677-b69a-2694aa706cac)]
 interface nsISHEntry : nsISupports
 {
     /**
      * A readonly property that returns the URI
      * of the current entry. The object returned is
      * of type nsIURI
      */
     readonly attribute nsIURI URI;
@@ -59,16 +59,21 @@ interface nsISHEntry : nsISupports
     readonly attribute boolean isSubFrame;
 
     /** URI for the document */
     void setURI(in nsIURI aURI);
 
     /** Referrer URI */
     attribute nsIURI referrerURI;
 
+    /** Referrer policy, holding one of the values (REFERRER_POLICY_*)
+     *  defined in nsIHttpChannel.
+     */
+    attribute unsigned long referrerPolicy;
+
     /** Content viewer, for fast restoration of presentation */
     attribute nsIContentViewer contentViewer;
 
     /** Whether the content viewer is marked "sticky" */
     attribute boolean sticky;
 
     /** Saved state of the global window object */
     attribute nsISupports windowState;
--- a/docshell/shistory/src/nsSHEntry.cpp
+++ b/docshell/shistory/src/nsSHEntry.cpp
@@ -10,43 +10,46 @@
 #include "nsDocShellEditorData.h"
 #include "nsSHEntryShared.h"
 #include "nsILayoutHistoryState.h"
 #include "nsIContentViewer.h"
 #include "nsISupportsArray.h"
 #include "nsIStructuredCloneContainer.h"
 #include "nsIInputStream.h"
 #include "nsIURI.h"
+#include "mozilla/net/ReferrerPolicy.h"
 #include <algorithm>
 
 namespace dom = mozilla::dom;
 
 static uint32_t gEntryID = 0;
 
 //*****************************************************************************
 //***    nsSHEntry: Object Management
 //*****************************************************************************
 
 
 nsSHEntry::nsSHEntry()
-  : mLoadType(0)
+  : mReferrerPolicy(mozilla::net::RP_Default)
+  , mLoadType(0)
   , mID(gEntryID++)
   , mScrollPositionX(0)
   , mScrollPositionY(0)
   , mParent(nullptr)
   , mURIWasModified(false)
   , mIsSrcdocEntry(false)
 {
   mShared = new nsSHEntryShared();
 }
 
 nsSHEntry::nsSHEntry(const nsSHEntry &other)
   : mShared(other.mShared)
   , mURI(other.mURI)
   , mReferrerURI(other.mReferrerURI)
+  , mReferrerPolicy(other.mReferrerPolicy)
   , mTitle(other.mTitle)
   , mPostData(other.mPostData)
   , mLoadType(0)         // XXX why not copy?
   , mID(other.mID)
   , mScrollPositionX(0)  // XXX why not copy?
   , mScrollPositionY(0)  // XXX why not copy?
   , mParent(other.mParent)
   , mURIWasModified(other.mURIWasModified)
@@ -129,16 +132,28 @@ NS_IMETHODIMP nsSHEntry::GetReferrerURI(
 }
 
 NS_IMETHODIMP nsSHEntry::SetReferrerURI(nsIURI *aReferrerURI)
 {
   mReferrerURI = aReferrerURI;
   return NS_OK;
 }
 
+NS_IMETHODIMP nsSHEntry::GetReferrerPolicy(uint32_t *aReferrerPolicy)
+{
+  *aReferrerPolicy = mReferrerPolicy;
+  return NS_OK;
+}
+
+NS_IMETHODIMP nsSHEntry::SetReferrerPolicy(uint32_t aReferrerPolicy)
+{
+  mReferrerPolicy = aReferrerPolicy;
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsSHEntry::SetContentViewer(nsIContentViewer *aViewer)
 {
   return mShared->SetContentViewer(aViewer);
 }
 
 NS_IMETHODIMP
 nsSHEntry::GetContentViewer(nsIContentViewer **aResult)
--- a/docshell/shistory/src/nsSHEntry.h
+++ b/docshell/shistory/src/nsSHEntry.h
@@ -45,16 +45,17 @@ private:
 
   // We share the state in here with other SHEntries which correspond to the
   // same document.
   nsRefPtr<nsSHEntryShared> mShared;
 
   // See nsSHEntry.idl for comments on these members.
   nsCOMPtr<nsIURI>         mURI;
   nsCOMPtr<nsIURI>         mReferrerURI;
+  uint32_t                 mReferrerPolicy;
   nsString                 mTitle;
   nsCOMPtr<nsIInputStream> mPostData;
   uint32_t                 mLoadType;
   uint32_t                 mID;
   int32_t                  mScrollPositionX;
   int32_t                  mScrollPositionY;
   nsISHEntry*              mParent;
   nsCOMArray<nsISHEntry>   mChildren;
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -695,16 +695,27 @@ EventSource::GetBaseURI(nsIURI **aBaseUR
   }
 
   NS_ENSURE_STATE(baseURI);
 
   baseURI.forget(aBaseURI);
   return NS_OK;
 }
 
+net::ReferrerPolicy
+EventSource::GetReferrerPolicy()
+{
+  nsresult rv;
+  nsIScriptContext* sc = GetContextForEventHandlers(&rv);
+  NS_ENSURE_SUCCESS(rv, mozilla::net::RP_Default);
+
+  nsCOMPtr<nsIDocument> doc = nsContentUtils::GetDocumentFromScriptContext(sc);
+  return doc ? doc->GetReferrerPolicy() : mozilla::net::RP_Default;
+}
+
 nsresult
 EventSource::SetupHttpChannel()
 {
   mHttpChannel->SetRequestMethod(NS_LITERAL_CSTRING("GET"));
 
   /* set the http request headers */
 
   mHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
@@ -715,17 +726,17 @@ EventSource::SetupHttpChannel()
   if (!mLastEventID.IsEmpty()) {
     mHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Last-Event-ID"),
       NS_ConvertUTF16toUTF8(mLastEventID), false);
   }
 
   nsCOMPtr<nsIURI> codebase;
   nsresult rv = GetBaseURI(getter_AddRefs(codebase));
   if (NS_SUCCEEDED(rv)) {
-    rv = mHttpChannel->SetReferrer(codebase);
+    rv = mHttpChannel->SetReferrerWithPolicy(codebase, this->GetReferrerPolicy());
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 nsresult
 EventSource::InitChannelAndRequestEventSource()
--- a/dom/base/EventSource.h
+++ b/dom/base/EventSource.h
@@ -104,16 +104,18 @@ protected:
   virtual ~EventSource();
 
   nsresult Init(nsISupports* aOwner,
                 const nsAString& aURL,
                 bool aWithCredentials);
 
   nsresult GetBaseURI(nsIURI **aBaseURI);
 
+  net::ReferrerPolicy GetReferrerPolicy();
+
   nsresult SetupHttpChannel();
   nsresult InitChannelAndRequestEventSource();
   nsresult ResetConnection();
   nsresult DispatchFailConnection();
   nsresult SetReconnectionTimeout();
 
   void AnnounceConnection();
   void DispatchAllMessageEvents();
--- a/dom/base/nsContentAreaDragDrop.cpp
+++ b/dom/base/nsContentAreaDragDrop.cpp
@@ -153,17 +153,20 @@ nsContentAreaDragDropDataProvider::SaveU
   // so we don't keep a ref to it. It will die when finished.
   nsCOMPtr<nsIWebBrowserPersist> persist =
     do_CreateInstance("@mozilla.org/embedding/browser/nsWebBrowserPersist;1",
                       &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   persist->SetPersistFlags(nsIWebBrowserPersist::PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION);
 
-  return persist->SavePrivacyAwareURI(sourceURI, nullptr, nullptr, nullptr, nullptr,
+  // referrer policy can be anything since the referrer is nullptr
+  return persist->SavePrivacyAwareURI(sourceURI, nullptr, nullptr,
+                                      mozilla::net::RP_Default,
+                                      nullptr, nullptr,
                                       inDestFile, isPrivate);
 }
 
 // This is our nsIFlavorDataProvider callback. There are several
 // assumptions here that make this work:
 //
 // 1. Someone put a kFilePromiseURLMime flavor into the transferable
 //    with the source URI of the file to save (as a string). We did
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -731,17 +731,17 @@ nsContentSink::ProcessStyleLink(nsIConte
   NS_ASSERTION(!aElement ||
                aElement->NodeType() == nsIDOMNode::PROCESSING_INSTRUCTION_NODE,
                "We only expect processing instructions here");
 
   // If this is a fragment parser, we don't want to observe.
   // We don't support CORS for processing instructions
   bool isAlternate;
   rv = mCSSLoader->LoadStyleLink(aElement, url, aTitle, aMedia, aAlternate,
-                                 CORS_NONE,
+                                 CORS_NONE, mDocument->GetReferrerPolicy(),
                                  mRunsToCompletion ? nullptr : this, &isAlternate);
   NS_ENSURE_SUCCESS(rv, rv);
   
   if (!isAlternate && !mRunsToCompletion) {
     ++mPendingSheetCount;
     mScriptLoader->AddExecuteBlocker();
   }
 
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2980,16 +2980,17 @@ nsContentUtils::IsImageInCache(nsIURI* a
     nsresult rv = cache->FindEntryProperties(aURI, getter_AddRefs(props));
     return (NS_SUCCEEDED(rv) && props);
 }
 
 // static
 nsresult
 nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
                           nsIPrincipal* aLoadingPrincipal, nsIURI* aReferrer,
+                          net::ReferrerPolicy aReferrerPolicy,
                           imgINotificationObserver* aObserver, int32_t aLoadFlags,
                           const nsAString& initiatorType,
                           imgRequestProxy** aRequest,
                           uint32_t aContentPolicyType)
 {
   NS_PRECONDITION(aURI, "Must have a URI");
   NS_PRECONDITION(aLoadingDocument, "Must have a document");
   NS_PRECONDITION(aLoadingPrincipal, "Must have a principal");
@@ -3011,16 +3012,17 @@ nsContentUtils::LoadImage(nsIURI* aURI, 
   // Make the URI immutable so people won't change it under us
   NS_TryToSetImmutable(aURI);
 
   // XXXbz using "documentURI" for the initialDocumentURI is not quite
   // right, but the best we can do here...
   return imgLoader->LoadImage(aURI,                 /* uri to load */
                               documentURI,          /* initialDocumentURI */
                               aReferrer,            /* referrer */
+                              aReferrerPolicy,      /* referrer policy */
                               aLoadingPrincipal,    /* loading principal */
                               loadGroup,            /* loadgroup */
                               aObserver,            /* imgINotificationObserver */
                               aLoadingDocument,     /* uniquification key */
                               aLoadFlags,           /* load flags */
                               nullptr,              /* cache key */
                               aContentPolicyType,   /* content policy type */
                               initiatorType,        /* the load initiator */
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -25,16 +25,17 @@
 #include "mozilla/TimeStamp.h"
 #include "nsContentListDeclarations.h"
 #include "nsMathUtils.h"
 #include "nsTArrayForwardDeclare.h"
 #include "Units.h"
 #include "mozilla/dom/AutocompleteInfoBinding.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/FloatingPoint.h"
+#include "mozilla/net/ReferrerPolicy.h"
 #include "nsIContentPolicy.h"
 
 #if defined(XP_WIN)
 // Undefine LoadImage to prevent naming conflict with Windows.
 #undef LoadImage
 #endif
 
 class imgICache;
@@ -614,26 +615,29 @@ public:
    * Method to start an image load.  This does not do any security checks.
    * This method will attempt to make aURI immutable; a caller that wants to
    * keep a mutable version around should pass in a clone.
    *
    * @param aURI uri of the image to be loaded
    * @param aLoadingDocument the document we belong to
    * @param aLoadingPrincipal the principal doing the load
    * @param aReferrer the referrer URI
+   * @param aReferrerPolicy the referrer-sending policy to use on channel
+   *         creation
    * @param aObserver the observer for the image load
    * @param aLoadFlags the load flags to use.  See nsIRequest
    * @param [aContentPolicyType=nsIContentPolicy::TYPE_IMAGE] (Optional)
    *        The CP content type to use
    * @return the imgIRequest for the image load
    */
   static nsresult LoadImage(nsIURI* aURI,
                             nsIDocument* aLoadingDocument,
                             nsIPrincipal* aLoadingPrincipal,
                             nsIURI* aReferrer,
+                            mozilla::net::ReferrerPolicy aReferrerPolicy,
                             imgINotificationObserver* aObserver,
                             int32_t aLoadFlags,
                             const nsAString& initiatorType,
                             imgRequestProxy** aRequest,
                             uint32_t aContentPolicyType = nsIContentPolicy::TYPE_IMAGE);
 
   /**
    * Obtain an image loader that respects the given document/channel's privacy status.
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -1534,16 +1534,18 @@ struct nsIDocument::FrameRequest
 
 static already_AddRefed<mozilla::dom::NodeInfo> nullNodeInfo;
 
 // ==================================================================
 // =
 // ==================================================================
 nsIDocument::nsIDocument()
   : nsINode(nullNodeInfo),
+    mReferrerPolicySet(false),
+    mReferrerPolicy(mozilla::net::RP_Default),
     mCharacterSet(NS_LITERAL_CSTRING("ISO-8859-1")),
     mNodeInfoManager(nullptr),
     mCompatMode(eCompatibility_FullStandards),
     mVisibilityState(dom::VisibilityState::Hidden),
     mIsInitialDocumentInWindow(false),
     mMayStartLayout(true),
     mVisible(true),
     mRemovedFromDocShell(false),
@@ -3696,16 +3698,30 @@ nsDocument::SetHeaderData(nsIAtom* aHead
       aHeaderField == nsGkAtoms::viewport_minimum_scale ||
       aHeaderField == nsGkAtoms::viewport_maximum_scale ||
       aHeaderField == nsGkAtoms::viewport_initial_scale ||
       aHeaderField == nsGkAtoms::viewport_height ||
       aHeaderField == nsGkAtoms::viewport_width ||
       aHeaderField ==  nsGkAtoms::viewport_user_scalable) {
     mViewportType = Unknown;
   }
+
+  // Referrer policy spec says to ignore any empty referrer policies.
+  if (aHeaderField == nsGkAtoms::referrer && !aData.IsEmpty()) {
+    ReferrerPolicy policy = mozilla::net::ReferrerPolicyFromString(aData);
+
+    // Referrer policy spec (section 6.1) says that once the referrer policy
+    // is set, any future attempts to change it result in No-Referrer.
+    if (!mReferrerPolicySet) {
+      mReferrerPolicy = policy;
+      mReferrerPolicySet = true;
+    } else if (mReferrerPolicy != policy) {
+      mReferrerPolicy = mozilla::net::RP_No_Referrer;
+    }
+  }
 }
 
 void
 nsDocument::TryChannelCharset(nsIChannel *aChannel,
                               int32_t& aCharsetSource,
                               nsACString& aCharset,
                               nsHtml5TreeOpExecutor* aExecutor)
 {
@@ -9480,17 +9496,18 @@ FireOrClearDelayedEvents(nsTArray<nsCOMP
                     aDocuments[i]->GetInnerWindow()->IsCurrentInnerWindow();
         shell->FireOrClearDelayedEvents(fire);
       }
     }
   }
 }
 
 void
-nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr)
+nsDocument::MaybePreLoadImage(nsIURI* uri, const nsAString &aCrossOriginAttr,
+                              ReferrerPolicy aReferrerPolicy)
 {
   // Early exit if the img is already present in the img-cache
   // which indicates that the "real" load has already started and
   // that we shouldn't preload it.
   int16_t blockingStatus;
   if (nsContentUtils::IsImageInCache(uri, static_cast<nsIDocument *>(this)) ||
       !nsContentUtils::CanLoadImage(uri, static_cast<nsIDocument *>(this),
                                     this, NodePrincipal(), &blockingStatus)) {
@@ -9514,16 +9531,17 @@ nsDocument::MaybePreLoadImage(nsIURI* ur
 
   // Image not in cache - trigger preload
   nsRefPtr<imgRequestProxy> request;
   nsresult rv =
     nsContentUtils::LoadImage(uri,
                               this,
                               NodePrincipal(),
                               mDocumentURI, // uri of document used as referrer
+                              aReferrerPolicy,
                               nullptr,       // no observer
                               loadFlags,
                               NS_LITERAL_STRING("img"),
                               getter_AddRefs(request));
 
   // Pin image-reference to avoid evicting it from the img-cache before
   // the "real" load occurs. Unpinned in DispatchContentLoadedEvents and
   // unlink
@@ -9569,26 +9587,28 @@ public:
   NS_DECL_ISUPPORTS
 };
 NS_IMPL_ISUPPORTS(StubCSSLoaderObserver, nsICSSLoaderObserver)
 
 }
 
 void
 nsDocument::PreloadStyle(nsIURI* uri, const nsAString& charset,
-                         const nsAString& aCrossOriginAttr)
+                         const nsAString& aCrossOriginAttr,
+                         const ReferrerPolicy aReferrerPolicy)
 {
   // The CSSLoader will retain this object after we return.
   nsCOMPtr<nsICSSLoaderObserver> obs = new StubCSSLoaderObserver();
 
   // Charset names are always ASCII.
   CSSLoader()->LoadSheet(uri, NodePrincipal(),
                          NS_LossyConvertUTF16toASCII(charset),
                          obs,
-                         Element::StringToCORSMode(aCrossOriginAttr));
+                         Element::StringToCORSMode(aCrossOriginAttr),
+                         aReferrerPolicy);
 }
 
 nsresult
 nsDocument::LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
                                 CSSStyleSheet** sheet)
 {
   return CSSLoader()->LoadSheetSync(uri, isAgentSheet, isAgentSheet, sheet);
 }
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -115,16 +115,17 @@ class CallbackFunction;
  * the ID's nsIdentifierMapEntry, the document.all result is released too.
  * Perhaps the document.all results should have their own hashtable
  * in nsHTMLDocument.
  */
 class nsIdentifierMapEntry : public nsStringHashKey
 {
 public:
   typedef mozilla::dom::Element Element;
+  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
 
   explicit nsIdentifierMapEntry(const nsAString& aKey) :
     nsStringHashKey(&aKey), mNameContentList(nullptr)
   {
   }
   explicit nsIdentifierMapEntry(const nsAString* aKey) :
     nsStringHashKey(aKey), mNameContentList(nullptr)
   {
@@ -1086,20 +1087,22 @@ public:
 
   nsresult CloneDocHelper(nsDocument* clone) const;
 
   void MaybeInitializeFinalizeFrameLoaders();
 
   void MaybeEndOutermostXBLUpdate();
 
   virtual void MaybePreLoadImage(nsIURI* uri,
-                                 const nsAString &aCrossOriginAttr) MOZ_OVERRIDE;
+                                 const nsAString &aCrossOriginAttr,
+                                 ReferrerPolicy aReferrerPolicy) MOZ_OVERRIDE;
 
   virtual void PreloadStyle(nsIURI* uri, const nsAString& charset,
-                            const nsAString& aCrossOriginAttr) MOZ_OVERRIDE;
+                            const nsAString& aCrossOriginAttr,
+                            ReferrerPolicy aReferrerPolicy) MOZ_OVERRIDE;
 
   virtual nsresult LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet,
                                        mozilla::CSSStyleSheet** sheet) MOZ_OVERRIDE;
 
   virtual nsISupports* GetCurrentContentSink() MOZ_OVERRIDE;
 
   virtual mozilla::EventStates GetDocumentState() MOZ_OVERRIDE;
 
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -427,16 +427,18 @@ nsFrameLoader::ReallyStartLoadingInterna
   if (referrer) {
     bool isNullPrincipalScheme;
     rv = referrer->SchemeIs(NS_NULLPRINCIPAL_SCHEME, &isNullPrincipalScheme);
     if (NS_SUCCEEDED(rv) && !isNullPrincipalScheme) {
       loadInfo->SetReferrer(referrer);
     }
   }
 
+  loadInfo->SetReferrerPolicy(mOwnerContent->OwnerDoc()->GetReferrerPolicy());
+
   // Default flags:
   int32_t flags = nsIWebNavigation::LOAD_FLAGS_NONE;
 
   // Flags for browser frame:
   if (OwnerIsBrowserFrame()) {
     flags = nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
             nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
   }
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -971,16 +971,17 @@ nsFrameMessageManager::ReceiveMessage(ns
       // AutoEntryScript aes;
       // if (!aes.Init(wrappedJS->GetJSObject())) {
       //   continue;
       // }
       // JSContext* cx = aes.cx();
       nsIGlobalObject* nativeGlobal =
         xpc::NativeGlobal(js::GetGlobalForObjectCrossCompartment(wrappedJS->GetJSObject()));
       AutoEntryScript aes(nativeGlobal);
+      aes.TakeOwnershipOfErrorReporting();
       JSContext* cx = aes.cx();
       JS::Rooted<JSObject*> object(cx, wrappedJS->GetJSObject());
 
       // The parameter for the listener function.
       JS::Rooted<JSObject*> param(cx,
         JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
       NS_ENSURE_TRUE(param, NS_ERROR_OUT_OF_MEMORY);
 
@@ -1012,33 +1013,41 @@ nsFrameMessageManager::ReceiveMessage(ns
         return NS_OK;
       }
       JS::Rooted<JSString*> jsMessage(cx,
         JS_NewUCStringCopyN(cx,
                             static_cast<const char16_t*>(aMessage.BeginReading()),
                             aMessage.Length()));
       NS_ENSURE_TRUE(jsMessage, NS_ERROR_OUT_OF_MEMORY);
       JS::Rooted<JS::Value> syncv(cx, JS::BooleanValue(aIsSync));
-      JS_DefineProperty(cx, param, "target", targetv, JSPROP_ENUMERATE);
-      JS_DefineProperty(cx, param, "name", jsMessage, JSPROP_ENUMERATE);
-      JS_DefineProperty(cx, param, "sync", syncv, JSPROP_ENUMERATE);
-      JS_DefineProperty(cx, param, "json", json, JSPROP_ENUMERATE); // deprecated
-      JS_DefineProperty(cx, param, "data", json, JSPROP_ENUMERATE);
-      JS_DefineProperty(cx, param, "objects", cpowsv, JSPROP_ENUMERATE);
+      bool ok = JS_DefineProperty(cx, param, "target", targetv, JSPROP_ENUMERATE) &&
+                JS_DefineProperty(cx, param, "name", jsMessage, JSPROP_ENUMERATE) &&
+                JS_DefineProperty(cx, param, "sync", syncv, JSPROP_ENUMERATE) &&
+                JS_DefineProperty(cx, param, "json", json, JSPROP_ENUMERATE) && // deprecated
+                JS_DefineProperty(cx, param, "data", json, JSPROP_ENUMERATE) &&
+                JS_DefineProperty(cx, param, "objects", cpowsv, JSPROP_ENUMERATE);
+      NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
 
       // message.principal == null
       if (!aPrincipal) {
-        JS_DefineProperty(cx, param, "principal", JS::UndefinedHandleValue, JSPROP_ENUMERATE);
+        bool ok = JS_DefineProperty(cx, param, "principal",
+                                    JS::UndefinedHandleValue, JSPROP_ENUMERATE);
+        NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
       }
 
       // message.principal = the principal
       else {
         JS::Rooted<JS::Value> principalValue(cx);
-        rv = nsContentUtils::WrapNative(cx, aPrincipal, &NS_GET_IID(nsIPrincipal), &principalValue);
-        JS_DefineProperty(cx, param, "principal", principalValue, JSPROP_ENUMERATE);
+        nsresult rv = nsContentUtils::WrapNative(cx, aPrincipal,
+                                                 &NS_GET_IID(nsIPrincipal),
+                                                 &principalValue);
+        NS_ENSURE_SUCCESS(rv, rv);
+        bool ok = JS_DefineProperty(cx, param, "principal", principalValue,
+                                    JSPROP_ENUMERATE);
+        NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
       }
 
       JS::Rooted<JS::Value> thisValue(cx, JS::UndefinedValue());
 
       JS::Rooted<JS::Value> funval(cx);
       if (JS::IsCallable(object)) {
         // If the listener is a JS function:
         funval.setObject(*object);
@@ -1052,18 +1061,19 @@ nsFrameMessageManager::ReceiveMessage(ns
           defaultThisValue = aTarget;
         }
         js::AssertSameCompartment(cx, object);
         nsresult rv = nsContentUtils::WrapNative(cx, defaultThisValue, &thisValue);
         NS_ENSURE_SUCCESS(rv, rv);
       } else {
         // If the listener is a JS object which has receiveMessage function:
         if (!JS_GetProperty(cx, object, "receiveMessage", &funval) ||
-            !funval.isObject())
+            !funval.isObject()) {
           return NS_ERROR_UNEXPECTED;
+        }
 
         // Check if the object is even callable.
         NS_ENSURE_STATE(JS::IsCallable(&funval.toObject()));
         thisValue.setObject(*object);
       }
 
       JS::Rooted<JS::Value> rval(cx, JSVAL_VOID);
       JS::Rooted<JS::Value> argv(cx, JS::ObjectValue(*param));
@@ -1071,25 +1081,24 @@ nsFrameMessageManager::ReceiveMessage(ns
       {
         JS::Rooted<JSObject*> thisObject(cx, thisValue.toObjectOrNull());
 
         JSAutoCompartment tac(cx, thisObject);
         if (!JS_WrapValue(cx, &argv)) {
           return NS_ERROR_UNEXPECTED;
         }
 
-        if (!JS_CallFunctionValue(cx, thisObject, funval, JS::HandleValueArray(argv), &rval)) {
-          nsJSUtils::ReportPendingException(cx);
+        if (!JS_CallFunctionValue(cx, thisObject, funval,
+                                  JS::HandleValueArray(argv), &rval)) {
           continue;
         }
         if (aJSONRetVal) {
           nsString json;
           if (!JS_Stringify(cx, &rval, JS::NullPtr(), JS::NullHandleValue,
                            JSONCreator, &json)) {
-            nsJSUtils::ReportPendingException(cx);
             continue;
           }
           aJSONRetVal->AppendElement(json);
         }
       }
     }
   }
   nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -577,16 +577,17 @@ GK_ATOM(menubutton, "menubutton")
 GK_ATOM(menuButton, "menu-button")
 GK_ATOM(menugroup, "menugroup")
 GK_ATOM(menuitem, "menuitem")
 GK_ATOM(menulist, "menulist")
 GK_ATOM(menupopup, "menupopup")
 GK_ATOM(menuseparator, "menuseparator")
 GK_ATOM(message, "message")
 GK_ATOM(meta, "meta")
+GK_ATOM(referrer, "referrer")
 GK_ATOM(meter, "meter")
 GK_ATOM(method, "method")
 GK_ATOM(microdataProperties, "microdataProperties")
 GK_ATOM(middle, "middle")
 GK_ATOM(min, "min")
 GK_ATOM(minheight, "minheight")
 GK_ATOM(minimum_scale, "minimum-scale")
 GK_ATOM(minpos, "minpos")
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -14,16 +14,17 @@
 #include "nsGkAtoms.h"                   // for static class members
 #include "nsIDocumentObserver.h"         // for typedef (nsUpdateType)
 #include "nsILoadGroup.h"                // for member (in nsCOMPtr)
 #include "nsINode.h"                     // for base class
 #include "nsIScriptGlobalObject.h"       // for member (in nsCOMPtr)
 #include "nsPIDOMWindow.h"               // for use in inline functions
 #include "nsPropertyTable.h"             // for member
 #include "nsTHashtable.h"                // for member
+#include "mozilla/net/ReferrerPolicy.h"  // for member
 #include "nsWeakReference.h"
 #include "mozilla/dom/DocumentBinding.h"
 #include "mozilla/WeakPtr.h"
 #include "Units.h"
 #include "nsExpirationTracker.h"
 #include "nsClassHashtable.h"
 
 class imgIRequest;
@@ -164,16 +165,17 @@ NS_GetContentList(nsINode* aRootNode,
 //----------------------------------------------------------------------
 
 // Document interface.  This is implemented by all document objects in
 // Gecko.
 class nsIDocument : public nsINode
 {
   typedef mozilla::dom::GlobalObject GlobalObject;
 public:
+  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
   typedef mozilla::dom::Element Element;
 
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)
   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
 #ifdef MOZILLA_INTERNAL_API
   nsIDocument();
 #endif
@@ -267,16 +269,25 @@ public:
 
   /**
    * Set the base URI for the document loaded via XHR, when accessed from
    * chrome privileged script.
    */
   virtual void SetChromeXHRDocBaseURI(nsIURI* aURI) = 0;
 
   /**
+   * Return the referrer policy of the document. Return "default" if there's no
+   * valid meta referrer tag found in the document.
+   */
+  ReferrerPolicy GetReferrerPolicy() const
+  {
+    return mReferrerPolicy;
+  }
+
+  /**
    * Set the principal responsible for this document.
    */
   virtual void SetPrincipal(nsIPrincipal *aPrincipal) = 0;
 
   /**
    * Return the LoadGroup for the document. May return null.
    */
   already_AddRefed<nsILoadGroup> GetDocumentLoadGroup() const
@@ -1881,25 +1892,27 @@ public:
 
   /**
    * Called by nsParser to preload images. Can be removed and code moved
    * to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
    * parser-module is linked with gklayout-module.  aCrossOriginAttr should
    * be a void string if the attr is not present.
    */
   virtual void MaybePreLoadImage(nsIURI* uri,
-                                 const nsAString& aCrossOriginAttr) = 0;
+                                 const nsAString& aCrossOriginAttr,
+                                 ReferrerPolicy aReferrerPolicy) = 0;
 
   /**
    * Called by nsParser to preload style sheets.  Can also be merged into the
    * parser if and when the parser is merged with libgklayout.  aCrossOriginAttr
    * should be a void string if the attr is not present.
    */
   virtual void PreloadStyle(nsIURI* aURI, const nsAString& aCharset,
-                            const nsAString& aCrossOriginAttr) = 0;
+                            const nsAString& aCrossOriginAttr,
+                            ReferrerPolicy aReferrerPolicy) = 0;
 
   /**
    * Called by the chrome registry to load style sheets.  Can be put
    * back there if and when when that module is merged with libgklayout.
    *
    * This always does a synchronous load.  If aIsAgentSheet is true,
    * it also uses the system principal and enables unsafe rules.
    * DO NOT USE FOR UNTRUSTED CONTENT.
@@ -2463,16 +2476,19 @@ protected:
   nsCOMPtr<nsIURI> mDocumentURI;
   nsCOMPtr<nsIURI> mOriginalURI;
   nsCOMPtr<nsIURI> mChromeXHRDocURI;
   nsCOMPtr<nsIURI> mDocumentBaseURI;
   nsCOMPtr<nsIURI> mChromeXHRDocBaseURI;
 
   nsWeakPtr mDocumentLoadGroup;
 
+  bool mReferrerPolicySet;
+  ReferrerPolicy mReferrerPolicy;
+
   mozilla::WeakPtr<nsDocShell> mDocumentContainer;
 
   nsCString mCharacterSet;
   int32_t mCharacterSetSource;
 
   // This is just a weak pointer; the parent document owns its children.
   nsIDocument* mParentDocument;
 
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -882,16 +882,17 @@ nsImageLoadingContent::LoadImage(nsIURI*
   // Not blocked. Do the load.
   nsRefPtr<imgRequestProxy>& req = PrepareNextRequest(aImageLoadType);
   nsCOMPtr<nsIContent> content =
       do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
   nsresult rv;
   rv = nsContentUtils::LoadImage(aNewURI, aDocument,
                                  aDocument->NodePrincipal(),
                                  aDocument->GetDocumentURI(),
+                                 aDocument->GetReferrerPolicy(),
                                  this, loadFlags,
                                  content->LocalName(),
                                  getter_AddRefs(req),
                                  policyType);
 
   if (NS_SUCCEEDED(rv)) {
     TrackImage(req);
     ResetAnimationIfNeeded();
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -164,53 +164,55 @@ nsJSUtils::CompileFunction(AutoJSAPI& js
 }
 
 nsresult
 nsJSUtils::EvaluateString(JSContext* aCx,
                           const nsAString& aScript,
                           JS::Handle<JSObject*> aEvaluationGlobal,
                           JS::CompileOptions& aCompileOptions,
                           const EvaluateOptions& aEvaluateOptions,
-                          JS::MutableHandle<JS::Value> aRetValue,
-                          void **aOffThreadToken)
+                          JS::MutableHandle<JS::Value> aRetValue)
 {
   const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
   JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
                                 JS::SourceBufferHolder::NoOwnership);
   return EvaluateString(aCx, srcBuf, aEvaluationGlobal, aCompileOptions,
-                        aEvaluateOptions, aRetValue, aOffThreadToken);
+                        aEvaluateOptions, aRetValue, nullptr);
 }
 
 nsresult
 nsJSUtils::EvaluateString(JSContext* aCx,
                           JS::SourceBufferHolder& aSrcBuf,
                           JS::Handle<JSObject*> aEvaluationGlobal,
                           JS::CompileOptions& aCompileOptions,
                           const EvaluateOptions& aEvaluateOptions,
                           JS::MutableHandle<JS::Value> aRetValue,
                           void **aOffThreadToken)
 {
   PROFILER_LABEL("nsJSUtils", "EvaluateString",
     js::ProfileEntry::Category::JS);
 
   MOZ_ASSERT_IF(aCompileOptions.versionSet,
                 aCompileOptions.version != JSVERSION_UNKNOWN);
-  MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, aEvaluateOptions.needResult);
-  MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, aEvaluateOptions.needResult);
+  MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, !aCompileOptions.noScriptRval);
+  MOZ_ASSERT_IF(!aEvaluateOptions.reportUncaught, !aCompileOptions.noScriptRval);
+  // Note that the above assert means that if aCompileOptions.noScriptRval then
+  // also aEvaluateOptions.reportUncaught.
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(aSrcBuf.get());
   MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
              aEvaluationGlobal);
+  MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval);
 
   // Unfortunately, the JS engine actually compiles scripts with a return value
   // in a different, less efficient way.  Furthermore, it can't JIT them in many
   // cases.  So we need to be explicitly told whether the caller cares about the
   // return value.  Callers can do this by calling the other overload of
-  // EvaluateString() which calls this function with aEvaluateOptions.needResult
-  // set to false.
+  // EvaluateString() which calls this function with
+  // aCompileOptions.noScriptRval set to true.
   aRetValue.setUndefined();
 
   nsresult rv = NS_OK;
 
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
   NS_ENSURE_TRUE(ssm->ScriptAllowed(aEvaluationGlobal), NS_OK);
 
   mozilla::Maybe<AutoDontReportUncaught> dontReport;
@@ -241,26 +243,22 @@ nsJSUtils::EvaluateString(JSContext* aCx
       }
     }
 
     if (ok && aOffThreadToken) {
       JS::Rooted<JSScript*>
         script(aCx, JS::FinishOffThreadScript(aCx, JS_GetRuntime(aCx), *aOffThreadToken));
       *aOffThreadToken = nullptr; // Mark the token as having been finished.
       if (script) {
-        if (aEvaluateOptions.needResult) {
-          ok = JS_ExecuteScript(aCx, scopeChain, script, aRetValue);
-        } else {
-          ok = JS_ExecuteScript(aCx, scopeChain, script);
-        }
+        ok = JS_ExecuteScript(aCx, scopeChain, script);
       } else {
         ok = false;
       }
     } else if (ok) {
-      if (aEvaluateOptions.needResult) {
+      if (!aCompileOptions.noScriptRval) {
         ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf, aRetValue);
       } else {
         ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf);
       }
     }
 
     if (ok && aEvaluateOptions.coerceToString && !aRetValue.isUndefined()) {
       JS::Rooted<JS::Value> value(aCx, aRetValue);
@@ -268,65 +266,73 @@ nsJSUtils::EvaluateString(JSContext* aCx
       ok = !!str;
       aRetValue.set(ok ? JS::StringValue(str) : JS::UndefinedValue());
     }
   }
 
   if (!ok) {
     if (aEvaluateOptions.reportUncaught) {
       ReportPendingException(aCx);
-      if (aEvaluateOptions.needResult) {
+      if (!aCompileOptions.noScriptRval) {
         aRetValue.setUndefined();
       }
     } else {
       rv = JS_IsExceptionPending(aCx) ? NS_ERROR_FAILURE
                                       : NS_ERROR_OUT_OF_MEMORY;
       JS::Rooted<JS::Value> exn(aCx);
       JS_GetPendingException(aCx, &exn);
-      if (aEvaluateOptions.needResult) {
-        aRetValue.set(exn);
-      }
+      MOZ_ASSERT(!aCompileOptions.noScriptRval); // we asserted this on entry
+      aRetValue.set(exn);
       JS_ClearPendingException(aCx);
     }
   }
 
   // Wrap the return value into whatever compartment aCx was in.
-  if (aEvaluateOptions.needResult) {
-    JS::Rooted<JS::Value> v(aCx, aRetValue);
-    if (!JS_WrapValue(aCx, &v)) {
+  if (!aCompileOptions.noScriptRval) {
+    if (!JS_WrapValue(aCx, aRetValue)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
-    aRetValue.set(v);
   }
   return rv;
 }
 
 nsresult
 nsJSUtils::EvaluateString(JSContext* aCx,
-                          const nsAString& aScript,
+                          JS::SourceBufferHolder& aSrcBuf,
                           JS::Handle<JSObject*> aEvaluationGlobal,
                           JS::CompileOptions& aCompileOptions,
-                          void **aOffThreadToken)
+                          const EvaluateOptions& aEvaluateOptions,
+                          JS::MutableHandle<JS::Value> aRetValue)
+{
+  return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
+                        aEvaluateOptions, aRetValue, nullptr);
+}
+
+nsresult
+nsJSUtils::EvaluateString(JSContext* aCx,
+                          const nsAString& aScript,
+                          JS::Handle<JSObject*> aEvaluationGlobal,
+                          JS::CompileOptions& aCompileOptions)
 {
   EvaluateOptions options(aCx);
-  options.setNeedResult(false);
+  aCompileOptions.setNoScriptRval(true);
   JS::RootedValue unused(aCx);
   return EvaluateString(aCx, aScript, aEvaluationGlobal, aCompileOptions,
-                        options, &unused, aOffThreadToken);
+                        options, &unused);
 }
 
 nsresult
 nsJSUtils::EvaluateString(JSContext* aCx,
                           JS::SourceBufferHolder& aSrcBuf,
                           JS::Handle<JSObject*> aEvaluationGlobal,
                           JS::CompileOptions& aCompileOptions,
                           void **aOffThreadToken)
 {
   EvaluateOptions options(aCx);
-  options.setNeedResult(false);
+  aCompileOptions.setNoScriptRval(true);
   JS::RootedValue unused(aCx);
   return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
                         options, &unused, aOffThreadToken);
 }
 
 /* static */
 bool
 nsJSUtils::GetScopeChainForElement(JSContext* aCx,
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -63,79 +63,78 @@ public:
                                   uint32_t aArgCount,
                                   const char** aArgArray,
                                   const nsAString& aBody,
                                   JSObject** aFunctionObject);
 
   struct MOZ_STACK_CLASS EvaluateOptions {
     bool coerceToString;
     bool reportUncaught;
-    bool needResult;
     JS::AutoObjectVector scopeChain;
 
     explicit EvaluateOptions(JSContext* cx)
       : coerceToString(false)
       , reportUncaught(true)
-      , needResult(true)
       , scopeChain(cx)
     {}
 
     EvaluateOptions& setCoerceToString(bool aCoerce) {
       coerceToString = aCoerce;
       return *this;
     }
 
     EvaluateOptions& setReportUncaught(bool aReport) {
       reportUncaught = aReport;
       return *this;
     }
-
-    EvaluateOptions& setNeedResult(bool aNeedResult) {
-      needResult = aNeedResult;
-      return *this;
-    }
   };
 
   // aEvaluationGlobal is the global to evaluate in.  The return value
   // will then be wrapped back into the compartment aCx is in when
   // this function is called.
   static nsresult EvaluateString(JSContext* aCx,
                                  const nsAString& aScript,
                                  JS::Handle<JSObject*> aEvaluationGlobal,
                                  JS::CompileOptions &aCompileOptions,
                                  const EvaluateOptions& aEvaluateOptions,
-                                 JS::MutableHandle<JS::Value> aRetValue,
-                                 void **aOffThreadToken = nullptr);
+                                 JS::MutableHandle<JS::Value> aRetValue);
 
   static nsresult EvaluateString(JSContext* aCx,
                                  JS::SourceBufferHolder& aSrcBuf,
                                  JS::Handle<JSObject*> aEvaluationGlobal,
                                  JS::CompileOptions &aCompileOptions,
                                  const EvaluateOptions& aEvaluateOptions,
-                                 JS::MutableHandle<JS::Value> aRetValue,
-                                 void **aOffThreadToken = nullptr);
+                                 JS::MutableHandle<JS::Value> aRetValue);
 
 
   static nsresult EvaluateString(JSContext* aCx,
                                  const nsAString& aScript,
                                  JS::Handle<JSObject*> aEvaluationGlobal,
-                                 JS::CompileOptions &aCompileOptions,
-                                 void **aOffThreadToken = nullptr);
+                                 JS::CompileOptions &aCompileOptions);
 
   static nsresult EvaluateString(JSContext* aCx,
                                  JS::SourceBufferHolder& aSrcBuf,
                                  JS::Handle<JSObject*> aEvaluationGlobal,
                                  JS::CompileOptions &aCompileOptions,
-                                 void **aOffThreadToken = nullptr);
+                                 void **aOffThreadToken);
 
   // Returns false if an exception got thrown on aCx.  Passing a null
   // aElement is allowed; that wil produce an empty aScopeChain.
   static bool GetScopeChainForElement(JSContext* aCx,
                                       mozilla::dom::Element* aElement,
                                       JS::AutoObjectVector& aScopeChain);
+private:
+  // Implementation for our EvaluateString bits
+  static nsresult EvaluateString(JSContext* aCx,
+                                 JS::SourceBufferHolder& aSrcBuf,
+                                 JS::Handle<JSObject*> aEvaluationGlobal,
+                                 JS::CompileOptions& aCompileOptions,
+                                 const EvaluateOptions& aEvaluateOptions,
+                                 JS::MutableHandle<JS::Value> aRetValue,
+                                 void **aOffThreadToken);
 };
 
 class MOZ_STACK_CLASS AutoDontReportUncaught {
   JSContext* mContext;
   bool mWasSet;
 
 public:
   explicit AutoDontReportUncaught(JSContext* aContext) : mContext(aContext) {
--- a/dom/base/nsLocation.cpp
+++ b/dom/base/nsLocation.cpp
@@ -109,16 +109,17 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDo
 {
   *aLoadInfo = nullptr;
 
   nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mDocShell));
   NS_ENSURE_TRUE(docShell, NS_ERROR_NOT_AVAILABLE);
 
   nsCOMPtr<nsISupports> owner;
   nsCOMPtr<nsIURI> sourceURI;
+  net::ReferrerPolicy referrerPolicy = net::RP_Default;
 
   if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) {
     // No cx means that there's no JS running, or at least no JS that
     // was run through code that properly pushed a context onto the
     // context stack (as all code that runs JS off of web pages
     // does). We won't bother with security checks in this case, but
     // we need to create the loadinfo etc.
 
@@ -144,16 +145,17 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDo
     if (incumbent) {
       doc = incumbent->GetDoc();
     }
     if (doc) {
       docOriginalURI = doc->GetOriginalURI();
       docCurrentURI = doc->GetDocumentURI();
       rv = doc->NodePrincipal()->GetURI(getter_AddRefs(principalURI));
       NS_ENSURE_SUCCESS(rv, rv);
+      referrerPolicy = doc->GetReferrerPolicy();
     }
 
     bool urisEqual = false;
     if (docOriginalURI && docCurrentURI && principalURI) {
       principalURI->Equals(docOriginalURI, &urisEqual);
     }
 
     if (urisEqual) {
@@ -181,16 +183,17 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDo
   nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
   docShell->CreateLoadInfo(getter_AddRefs(loadInfo));
   NS_ENSURE_TRUE(loadInfo, NS_ERROR_FAILURE);
 
   loadInfo->SetOwner(owner);
 
   if (sourceURI) {
     loadInfo->SetReferrer(sourceURI);
+    loadInfo->SetReferrerPolicy(referrerPolicy);
   }
 
   loadInfo.swap(*aLoadInfo);
 
   return NS_OK;
 }
 
 nsresult
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -2505,17 +2505,18 @@ nsObjectLoadingContent::OpenChannel()
                      nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
                      nsIChannel::LOAD_CLASSIFY_URI);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Referrer
   nsCOMPtr<nsIHttpChannel> httpChan(do_QueryInterface(chan));
   if (httpChan) {
-    httpChan->SetReferrer(doc->GetDocumentURI());
+    httpChan->SetReferrerWithPolicy(doc->GetDocumentURI(),
+                                    doc->GetReferrerPolicy());
 
     // Set the initiator type
     nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChan));
     if (timedChannel) {
       timedChannel->SetInitiatorType(thisContent->LocalName());
     }
   }
 
--- a/dom/base/nsScriptLoader.cpp
+++ b/dom/base/nsScriptLoader.cpp
@@ -78,17 +78,18 @@ public:
     : mElement(aElement),
       mLoading(true),
       mIsInline(true),
       mHasSourceMapURL(false),
       mScriptTextBuf(nullptr),
       mScriptTextLength(0),
       mJSVersion(aVersion),
       mLineNo(1),
-      mCORSMode(aCORSMode)
+      mCORSMode(aCORSMode),
+      mReferrerPolicy(mozilla::net::RP_Default)
   {
   }
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
   void FireScriptAvailable(nsresult aResult)
   {
     mElement->ScriptAvailable(aResult, mElement, mIsInline, mURI, mLineNo);
@@ -111,16 +112,17 @@ public:
   char16_t* mScriptTextBuf; // Holds script text for non-inline scripts. Don't
   size_t mScriptTextLength; // use nsString so we can give ownership to jsapi.
   uint32_t mJSVersion;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIPrincipal> mOriginPrincipal;
   nsAutoCString mURL;   // Keep the URI's filename alive during off thread parsing.
   int32_t mLineNo;
   const CORSMode mCORSMode;
+  mozilla::net::ReferrerPolicy mReferrerPolicy;
 };
 
 // The nsScriptLoadRequest is passed as the context to necko, and thus
 // it needs to be threadsafe. Necko won't do anything with this
 // context, but it will AddRef and Release it on other threads.
 NS_IMPL_ISUPPORTS0(nsScriptLoadRequest)
 
 //////////////////////////////////////////////////////////////
@@ -335,17 +337,18 @@ nsScriptLoader::StartLoad(nsScriptLoadRe
   }
 
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
   if (httpChannel) {
     // HTTP content negotation has little value in this context.
     httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                   NS_LITERAL_CSTRING("*/*"),
                                   false);
-    httpChannel->SetReferrer(mDocument->GetDocumentURI());
+    httpChannel->SetReferrerWithPolicy(mDocument->GetDocumentURI(),
+                                       aRequest->mReferrerPolicy);
   }
 
   nsCOMPtr<nsILoadContext> loadContext(do_QueryInterface(docshell));
   mozilla::net::PredictorLearn(aRequest->mURI, mDocument->GetDocumentURI(),
       nsINetworkPredictor::LEARN_LOAD_SUBRESOURCE, loadContext);
 
   // Set the initiator type
   nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChannel));
@@ -589,47 +592,52 @@ nsScriptLoader::ProcessScriptElement(nsI
     nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
     if (!scriptURI) {
       // Asynchronously report the failure to create a URI object
       NS_DispatchToCurrentThread(
         NS_NewRunnableMethod(aElement,
                              &nsIScriptElement::FireErrorEvent));
       return false;
     }
+
+    // Double-check that the preload matches what we're asked to load now.
+    mozilla::net::ReferrerPolicy ourRefPolicy = mDocument->GetReferrerPolicy();
     CORSMode ourCORSMode = aElement->GetCORSMode();
     nsTArray<PreloadInfo>::index_type i =
       mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
     if (i != nsTArray<PreloadInfo>::NoIndex) {
       // preloaded
       // note that a script-inserted script can steal a preload!
       request = mPreloads[i].mRequest;
       request->mElement = aElement;
       nsString preloadCharset(mPreloads[i].mCharset);
       mPreloads.RemoveElementAt(i);
 
       // Double-check that the charset the preload used is the same as
       // the charset we have now.
       nsAutoString elementCharset;
       aElement->GetScriptCharset(elementCharset);
       if (elementCharset.Equals(preloadCharset) &&
-          ourCORSMode == request->mCORSMode) {
+          ourCORSMode == request->mCORSMode &&
+          ourRefPolicy == request->mReferrerPolicy) {
         rv = CheckContentPolicy(mDocument, aElement, request->mURI, type);
         NS_ENSURE_SUCCESS(rv, false);
       } else {
         // Drop the preload
         request = nullptr;
       }
     }
 
     if (!request) {
       // no usable preload
       request = new nsScriptLoadRequest(aElement, version, ourCORSMode);
       request->mURI = scriptURI;
       request->mIsInline = false;
       request->mLoading = true;
+      request->mReferrerPolicy = ourRefPolicy;
 
       // set aScriptFromHead to false so we don't treat non preloaded scripts as
       // blockers for full page load. See bug 792438.
       rv = StartLoad(request, type, false);
       if (NS_FAILED(rv)) {
         // Asynchronously report the load failure
         NS_DispatchToCurrentThread(
           NS_NewRunnableMethod(aElement,
@@ -1035,16 +1043,19 @@ nsScriptLoader::FillCompileOptionsForReq
   // It's very important to use aRequest->mURI, not the final URI of the channel
   // aRequest ended up getting script data from, as the script filename.
   nsContentUtils::GetWrapperSafeScriptFilename(mDocument, aRequest->mURI, aRequest->mURL);
 
   aOptions->setIntroductionType("scriptElement");
   aOptions->setFileAndLine(aRequest->mURL.get(), aRequest->mLineNo);
   aOptions->setVersion(JSVersion(aRequest->mJSVersion));
   aOptions->setCompileAndGo(JS_IsGlobalObject(aScopeChain));
+  // We only need the setNoScriptRval bit when compiling off-thread here, since
+  // otherwise nsJSUtils::EvaluateString will set it up for us.
+  aOptions->setNoScriptRval(true);
   if (aRequest->mHasSourceMapURL) {
     aOptions->setSourceMapURL(aRequest->mSourceMapURL.get());
   }
   if (aRequest->mOriginPrincipal) {
     nsIPrincipal* scriptPrin = nsContentUtils::ObjectPrincipal(aScopeChain);
     bool subsumes = scriptPrin->Subsumes(aRequest->mOriginPrincipal);
     aOptions->setMutedErrors(!subsumes);
   }
@@ -1551,29 +1562,32 @@ nsScriptLoader::ParsingComplete(bool aTe
   // onload and all.
   ProcessPendingRequests();
 }
 
 void
 nsScriptLoader::PreloadURI(nsIURI *aURI, const nsAString &aCharset,
                            const nsAString &aType,
                            const nsAString &aCrossOrigin,
-                           bool aScriptFromHead)
+                           bool aScriptFromHead,
+                           const mozilla::net::ReferrerPolicy aReferrerPolicy)
 {
   // Check to see if scripts has been turned off.
   if (!mEnabled || !mDocument->IsScriptEnabled()) {
     return;
   }
 
   nsRefPtr<nsScriptLoadRequest> request =
     new nsScriptLoadRequest(nullptr, 0,
                             Element::StringToCORSMode(aCrossOrigin));
   request->mURI = aURI;
   request->mIsInline = false;
   request->mLoading = true;
+  request->mReferrerPolicy = aReferrerPolicy;
+
   nsresult rv = StartLoad(request, aType, aScriptFromHead);
   if (NS_FAILED(rv)) {
     return;
   }
 
   PreloadInfo *pi = mPreloads.AppendElement();
   pi->mRequest = request;
   pi->mCharset = aCharset;
--- a/dom/base/nsScriptLoader.h
+++ b/dom/base/nsScriptLoader.h
@@ -12,16 +12,17 @@
 
 #include "nsCOMPtr.h"
 #include "nsIScriptElement.h"
 #include "nsCOMArray.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "nsIDocument.h"
 #include "nsIStreamLoader.h"
+#include "mozilla/net/ReferrerPolicy.h"
 
 class nsScriptLoadRequest;
 class nsIURI;
 
 namespace JS {
   class SourceBufferHolder;
 }
 
@@ -235,17 +236,18 @@ public:
    * @param aType The type parameter for the script.
    * @param aCrossOrigin The crossorigin attribute for the script.
    *                     Void if not present.
    * @param aScriptFromHead Whether or not the script was a child of head
    */
   virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
                           const nsAString &aType,
                           const nsAString &aCrossOrigin,
-                          bool aScriptFromHead);
+                          bool aScriptFromHead,
+                          const mozilla::net::ReferrerPolicy aReferrerPolicy);
 
   /**
    * Process a request that was deferred so that the script could be compiled
    * off thread.
    */
   nsresult ProcessOffThreadRequest(nsScriptLoadRequest *aRequest,
                                    void **aOffThreadToken);
 
--- a/dom/base/nsStyleLinkElement.cpp
+++ b/dom/base/nsStyleLinkElement.cpp
@@ -421,17 +421,18 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
   }
   else {
     // XXXbz clone the URI here to work around content policies modifying URIs.
     nsCOMPtr<nsIURI> clonedURI;
     uri->Clone(getter_AddRefs(clonedURI));
     NS_ENSURE_TRUE(clonedURI, NS_ERROR_OUT_OF_MEMORY);
     rv = doc->CSSLoader()->
       LoadStyleLink(thisContent, clonedURI, title, media, isAlternate,
-                    GetCORSMode(), aObserver, &isAlternate);
+                    GetCORSMode(), doc->GetReferrerPolicy(),
+                    aObserver, &isAlternate);
     if (NS_FAILED(rv)) {
       // Don't propagate LoadStyleLink() errors further than this, since some
       // consumers (e.g. nsXMLContentSink) will completely abort on innocuous
       // things like a stylesheet load being blocked by the security system.
       doneLoading = true;
       isAlternate = false;
       rv = NS_OK;
     }
--- a/dom/base/nsSyncLoadService.cpp
+++ b/dom/base/nsSyncLoadService.cpp
@@ -21,32 +21,35 @@
 #include "nsContentUtils.h" // for kLoadAsData
 #include "nsThreadUtils.h"
 #include "nsNetUtil.h"
 #include "nsAutoPtr.h"
 #include "nsStreamUtils.h"
 #include "nsCrossSiteListenerProxy.h"
 #include <algorithm>
 
+using mozilla::net::ReferrerPolicy;
+
 /**
  * This class manages loading a single XML document
  */
 
 class nsSyncLoader : public nsIStreamListener,
                      public nsIChannelEventSink,
                      public nsIInterfaceRequestor,
                      public nsSupportsWeakReference
 {
 public:
     nsSyncLoader() : mLoading(false) {}
 
     NS_DECL_ISUPPORTS
 
     nsresult LoadDocument(nsIChannel* aChannel, nsIPrincipal *aLoaderPrincipal,
                           bool aChannelIsSync, bool aForceToXML,
+                          ReferrerPolicy aReferrerPolicy,
                           nsIDOMDocument** aResult);
 
     NS_FORWARD_NSISTREAMLISTENER(mListener->)
     NS_DECL_NSIREQUESTOBSERVER
 
     NS_DECL_NSICHANNELEVENTSINK
 
     NS_DECL_NSIINTERFACEREQUESTOR
@@ -125,35 +128,36 @@ NS_IMPL_ISUPPORTS(nsSyncLoader,
                   nsIInterfaceRequestor,
                   nsISupportsWeakReference)
 
 nsresult
 nsSyncLoader::LoadDocument(nsIChannel* aChannel,
                            nsIPrincipal *aLoaderPrincipal,
                            bool aChannelIsSync,
                            bool aForceToXML,
+                           ReferrerPolicy aReferrerPolicy,
                            nsIDOMDocument **aResult)
 {
     NS_ENSURE_ARG_POINTER(aResult);
     *aResult = nullptr;
     nsresult rv = NS_OK;
 
     nsCOMPtr<nsIURI> loaderUri;
     if (aLoaderPrincipal) {
         aLoaderPrincipal->GetURI(getter_AddRefs(loaderUri));
     }
 
     mChannel = aChannel;
     nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(mChannel);
     if (http) {
-        http->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),     
+        http->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
                                false);
         if (loaderUri) {
-            http->SetReferrer(loaderUri);
+            http->SetReferrerWithPolicy(loaderUri, aReferrerPolicy);
         }
     }
 
     // Hook us up to listen to redirects and the like.
     // Do this before setting up the cross-site proxy since
     // that installs its own proxies.
     mChannel->SetNotificationCallbacks(this);
 
@@ -302,16 +306,17 @@ nsSyncLoader::GetInterface(const nsIID &
 {
     return QueryInterface(aIID, aResult);
 }
 
 /* static */
 nsresult
 nsSyncLoadService::LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
                                 nsILoadGroup *aLoadGroup, bool aForceToXML,
+                                ReferrerPolicy aReferrerPolicy,
                                 nsIDOMDocument** aResult)
 {
     nsCOMPtr<nsIChannel> channel;
     nsresult rv = NS_NewChannel(getter_AddRefs(channel),
                                 aURI,
                                 aLoaderPrincipal,
                                 nsILoadInfo::SEC_NORMAL,
                                 nsIContentPolicy::TYPE_OTHER,
@@ -325,17 +330,17 @@ nsSyncLoadService::LoadDocument(nsIURI *
     bool isChrome = false, isResource = false;
     bool isSync = (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) &&
                      isChrome) ||
                     (NS_SUCCEEDED(aURI->SchemeIs("resource", &isResource)) &&
                      isResource);
 
     nsRefPtr<nsSyncLoader> loader = new nsSyncLoader();
     return loader->LoadDocument(channel, aLoaderPrincipal, isSync,
-                                aForceToXML, aResult);
+                                aForceToXML, aReferrerPolicy, aResult);
 
 }
 
 /* static */
 nsresult
 nsSyncLoadService::PushSyncStreamToListener(nsIInputStream* aIn,
                                             nsIStreamListener* aListener,
                                             nsIChannel* aChannel)
--- a/dom/base/nsSyncLoadService.h
+++ b/dom/base/nsSyncLoadService.h
@@ -6,16 +6,17 @@
 /*
  * A service that provides methods for synchronously loading a DOM in various ways.
  */
 
 #ifndef nsSyncLoadService_h__
 #define nsSyncLoadService_h__
 
 #include "nscore.h"
+#include "mozilla/net/ReferrerPolicy.h"
 
 class nsIInputStream;
 class nsILoadGroup;
 class nsIStreamListener;
 class nsIURI;
 class nsIPrincipal;
 class nsIDOMDocument;
 class nsIChannel;
@@ -28,20 +29,22 @@ public:
      *
      * @param aURI URI to load the document from.
      * @param aLoaderPrincipal Principal of loading document. For security
      *                         checks and referrer header. May be null if no
      *                         security checks should be done.
      * @param aLoadGroup The loadgroup to use for loading the document.
      * @param aForceToXML Whether to parse the document as XML, regardless of
      *                    content type.
+     * @param referrerPolicy Referrer policy.
      * @param aResult [out] The document loaded from the URI.
      */
     static nsresult LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
                                  nsILoadGroup *aLoadGroup, bool aForceToXML,
+                                 mozilla::net::ReferrerPolicy aReferrerPolicy,
                                  nsIDOMDocument** aResult);
 
     /**
      * Read input stream aIn in chunks and deliver synchronously to aListener.
      *
      * @param aIn The stream to be read.
      * @param aListener The listener that will receive
      *                  OnStartRequest/OnDataAvailable/OnStopRequest
--- a/dom/base/nsTreeSanitizer.cpp
+++ b/dom/base/nsTreeSanitizer.cpp
@@ -1090,17 +1090,17 @@ nsTreeSanitizer::SanitizeStyleSheet(cons
                                     nsIURI* aBaseURI)
 {
   nsresult rv;
   aSanitized.Truncate();
   // aSanitized will hold the permitted CSS text.
   // -moz-binding is blacklisted.
   bool didSanitize = false;
   // Create a sheet to hold the parsed CSS
-  nsRefPtr<CSSStyleSheet> sheet = new CSSStyleSheet(CORS_NONE);
+  nsRefPtr<CSSStyleSheet> sheet = new CSSStyleSheet(CORS_NONE, aDocument->GetReferrerPolicy());
   sheet->SetURIs(aDocument->GetDocumentURI(), nullptr, aBaseURI);
   sheet->SetPrincipal(aDocument->NodePrincipal());
   // Create the CSS parser, and parse the CSS text.
   nsCSSParser parser(nullptr, sheet);
   rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI,
                          aDocument->NodePrincipal(), 0, false);
   NS_ENSURE_SUCCESS(rv, true);
   // Mark the sheet as complete.
--- a/dom/base/nsXMLHttpRequest.cpp
+++ b/dom/base/nsXMLHttpRequest.cpp
@@ -2717,35 +2717,38 @@ nsXMLHttpRequest::Send(nsIVariant* aVari
 
       nsIScriptContext* sc = GetContextForEventHandlers(&rv);
       NS_ENSURE_SUCCESS(rv, rv);
       nsCOMPtr<nsIDocument> doc =
         nsContentUtils::GetDocumentFromScriptContext(sc);
 
       nsCOMPtr<nsIURI> docCurURI;
       nsCOMPtr<nsIURI> docOrigURI;
+      net::ReferrerPolicy referrerPolicy = net::RP_Default;
+
       if (doc) {
         docCurURI = doc->GetDocumentURI();
         docOrigURI = doc->GetOriginalURI();
+        referrerPolicy = doc->GetReferrerPolicy();
       }
 
       nsCOMPtr<nsIURI> referrerURI;
 
       if (principalURI && docCurURI && docOrigURI) {
         bool equal = false;
         principalURI->Equals(docOrigURI, &equal);
         if (equal) {
           referrerURI = docCurURI;
         }
       }
 
       if (!referrerURI)
         referrerURI = principalURI;
 
-      httpChannel->SetReferrer(referrerURI);
+      httpChannel->SetReferrerWithPolicy(referrerURI, referrerPolicy);
     }
 
     // Some extensions override the http protocol handler and provide their own
     // implementation. The channels returned from that implementation doesn't
     // seem to always implement the nsIUploadChannel2 interface, presumably
     // because it's a new interface.
     // Eventually we should remove this and simply require that http channels
     // implement the new interface.
new file mode 100644
--- /dev/null
+++ b/dom/base/test/bug704320.sjs
@@ -0,0 +1,269 @@
+var BASE_URL = 'example.com/tests/dom/base/test/bug704320.sjs';
+
+function createTestUrl(schemeFrom, schemeTo, policy, action, type) {
+  return schemeTo + '://' + BASE_URL + '?' +
+         'action=' + action + '&' +
+         'scheme=' + schemeFrom + '-to-' + schemeTo + '&' +
+         'policy=' + policy + '&' +
+         'type=' + type;
+}
+
+function create2ndLevelIframeUrl(schemeFrom, schemeTo, policy, type) {
+  return schemeFrom + '://' + BASE_URL + '?' +
+         'action=create-2nd-level-iframe&' +
+         'scheme-from=' + schemeFrom + '&' +
+         'scheme-to=' + schemeTo + '&' +
+         'policy=' + policy + '&' +
+         'type=' + type;
+}
+
+// Creates the following test cases for the specified scheme and referrer
+// policy combination:
+//   <link>
+//   @import
+//   font-face
+//   bg-url
+//   <script>
+//   <img>
+//   <iframe>
+//   <audio>
+//   <video>
+//   <object type="bogus"> 
+//   <object type="image/svg+xml">
+//   <a>
+//   <a ping>
+//   <form>
+//   window.location
+//   window.open
+//   XMLHttpRequest
+//   EventSource
+//   TODO: XSLT?
+//
+// This returns a page that loads all of the above resources and contains a
+// script that clicks a link after all resources are (hopefully)
+// loaded. The click triggers a redirection to file_bug704320_redirect.html,
+// which in turn notifies the main window that it's time to check the test
+// results.
+function createTest(schemeFrom, schemeTo, policy) {
+  var _createTestUrl = createTestUrl.bind(
+      null, schemeFrom, schemeTo, policy, 'test');
+
+  var _create2ndLevelIframeUrl = create2ndLevelIframeUrl.bind(
+      null, schemeFrom, schemeTo, policy);
+
+  return '<!DOCTYPE HTML>\n\
+         <html>\n\
+         <head>\n\
+           <meta name="referrer" content="' + policy + '">\n\
+           <link rel="stylesheet" type="text/css" href="' + _createTestUrl('stylesheet') + '">\n\
+           <style type="text/css">\n\
+             @import "' + _createTestUrl('import-css') + '";\n\
+             @font-face {\n\
+               font-family: "Fake Serif Bold";\n\
+               src: url("' + _createTestUrl('font-face') + '");\n\
+             }\n\
+             body {\n\
+               font-family: "Fake Serif Bold", serif;\n\
+               background: url("' + _createTestUrl('bg-url') + '");\n\
+             }\n\
+           </style>\n\
+         </head>\n\
+         <body>\n\
+           <script src="' + _createTestUrl('script') + '"></script>\n\
+           <img src="' + _createTestUrl('img') + '"></img>\n\
+           <iframe src="' + _createTestUrl('iframe') + '"></iframe>\n\
+           <audio src="' + _createTestUrl('audio') + '"></audio>\n\
+           <video src="' + _createTestUrl('video') + '"></video>\n\
+           <object type="bogus" data="' + _createTestUrl('object') + '"></object>\n\
+           <object type="image/svg+xml" data="' + _createTestUrl('object-svg') + '"></object>\n\
+           <a id="link" href="' + _createTestUrl('link') + '" ping="' + _createTestUrl('link-ping') + '"></a>\n\
+           <iframe src="' + _create2ndLevelIframeUrl('form') + '"></iframe>\n\
+           <iframe src="' + _create2ndLevelIframeUrl('window.location') + '"></iframe>\n\
+           <script>\n\
+             (function() {\n\
+               var x = new XMLHttpRequest();\n\
+               x.open("GET", "' + _createTestUrl('xmlhttprequest') + '");\n\
+               x.send();\n\
+             })();\n\
+             (function() {\n\
+               var eventSource = new EventSource("' + _createTestUrl('eventsource') + '");\n\
+             })();' +
+
+             // LOAD EVENT (most of the tests)
+             // fires when the resources for the page are loaded
+             'var _isLoaded = false;\n\
+             window.addEventListener("load", function() {\n\
+               this._isLoaded = true;\n\
+               this.checkForFinish();\n\
+             }.bind(window), false);' +
+
+             // WINDOW.OPEN test
+             // listen for incoming status from window.open, close the window
+             // and check if we're done.
+             'var _openedWindowLoaded = false;\n\
+             window.addEventListener("message", function(message) {\n\
+               if (message.data == "window.open") {\n\
+                 this._openedWindowLoaded = true;\n\
+                 this.win.close();\n\
+                 this.checkForFinish();\n\
+               }\n\
+             }.bind(window), false);\n\
+             var win = window.open("' + _createTestUrl('window.open') + '", "");' +
+
+             // called by the two things that must complete: window.open page
+             // and the window load event.  When both are complete, this
+             // "finishes" the iframe subtest by clicking the link.
+             'function checkForFinish() {\n\
+               if (window._isLoaded && window._openedWindowLoaded) {\n\
+                 document.getElementById("link").click();\n\
+               }\n\
+             }\n\
+           </script>\n\
+         </body>\n\
+         </html>';
+}
+
+function createIframedFormTest(schemeFrom, schemeTo, policy) {
+  var actionUrl = schemeTo + '://' + BASE_URL;
+
+  return '<!DOCTYPE HTML>\n\
+         <html>\n\
+         <head>\n\
+           <meta name="referrer" content="' + policy + '">\n\
+         </head>\n\
+         <body>\n\
+           <form id="form" action="' + actionUrl + '">\n\
+             <input type="hidden" name="action" value="test">\n\
+             <input type="hidden" name="scheme" value="' + schemeFrom + '-to-' + schemeTo + '">\n\
+             <input type="hidden" name="policy" value="' + policy + '">\n\
+             <input type="hidden" name="type" value="form">\n\
+           </form>\n\
+           <script>\n\
+             document.getElementById("form").submit();\n\
+           </script>\n\
+         </body>\n\
+         </html>';
+}
+
+function createIframedWindowLocationTest(schemeFrom, schemeTo, policy) {
+  var url = createTestUrl(
+      schemeFrom, schemeTo, policy, 'test', 'window.location');
+
+  return '<!DOCTYPE HTML>\n\
+         <html>\n\
+         <head>\n\
+           <meta name="referrer" content="' + policy + '">\n\
+         </head>\n\
+         <body>\n\
+           <script>\n\
+            window.location = "' + url + '";\n\
+           </script>\n\
+         </body>\n\
+         </html>';
+}
+
+function createPolicyTest(refpol) {
+  return '<!DOCTYPE HTML>\n\
+          <html>\n\
+          <head>\n\
+            <meta name="referrer" content="' + refpol + '">\n\
+            <script type="text/javascript" src="/tests/dom/base/test/file_bug704320_preload_common.js"></script>\n\
+          </head>\n\
+          <body>\n\
+            <img src="/tests/dom/base/test/bug704320_counter.sjs?type=img"\n\
+                    onload="incrementLoad2(\'img\', 2);">\n\
+            <img src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=img"\n\
+                    onload="incrementLoad2(\'img\', 2);">\n\
+          </body>\n\
+          </html>';
+}
+
+function handleRequest(request, response) {
+  var sharedKey = 'bug704320.sjs';
+  var params = request.queryString.split('&');
+  var action = params[0].split('=')[1];
+
+  if (action === 'create-1st-level-iframe') {
+    // ?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=origin
+    var schemeFrom = params[1].split('=')[1];
+    var schemeTo = params[2].split('=')[1];
+    var policy = params[3].split('=')[1];
+
+    response.setHeader('Content-Type', 'text/html; charset=utf-8', false);
+    response.setHeader('Cache-Control', 'no-cache', false);
+    response.write(createTest(schemeFrom, schemeTo, policy));
+  }
+  else if (action === 'create-2nd-level-iframe') {
+    // ?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=origin&type=form"
+    var schemeFrom = params[1].split('=')[1];
+    var schemeTo = params[2].split('=')[1];
+    var policy = params[3].split('=')[1];
+    var type = params[4].split('=')[1];
+
+    response.setHeader('Content-Type', 'text/html; charset=utf-8', false);
+    response.setHeader('Cache-Control', 'no-cache', false);
+
+    if (type === 'form') {
+      response.write(createIframedFormTest(schemeFrom, schemeTo, policy));
+    } else if (type === 'window.location') {
+      response.write(createIframedWindowLocationTest(
+            schemeFrom, schemeTo, policy));
+    }
+  }
+  else if (action === 'test') {
+    // ?action=test&scheme=http-to-https&policy=origin&type=img
+    var scheme = params[1].split('=')[1];
+    var policy = params[2].split('=')[1];
+    var type = params[3].split('=')[1];
+    var result = getSharedState(sharedKey);
+
+    if (result === '') {
+      result = {};
+    } else {
+      result = JSON.parse(result);
+    }
+
+    if (!result[type]) {
+      result[type] = {};
+    }
+
+    if (!result[type][scheme]) {
+      result[type][scheme] = {};
+    }
+
+    if (request.hasHeader('Referer')) {
+      result[type][scheme][policy] = request.getHeader('Referer');
+    } else {
+      result[type][scheme][policy] = '';
+    }
+
+    setSharedState(sharedKey, JSON.stringify(result));
+
+    if (type === 'link') {
+      var loc = 'https://example.com/tests/dom/base/test/file_bug704320_redirect.html';
+      response.setStatusLine('1.1', 302, 'Found');
+      response.setHeader('Location', loc, false);
+    }
+
+    if (type === 'window.open') {
+      response.setHeader('Cache-Control', 'no-cache', false);
+      response.setHeader('Content-Type', 'text/html', false);
+      response.write('<html><body><script>'
+                   + 'window.opener.postMessage("window.open", "*");'
+                   + '</script></body></html>');
+    }
+  }
+  else if (action === 'get-test-results') {
+    // ?action=get-result
+    response.setHeader('Cache-Control', 'no-cache', false);
+    response.setHeader('Content-Type', 'text/plain', false);
+    response.write(getSharedState(sharedKey));
+  }
+  else if (action === 'generate-policy-test') {
+    // ?action=generate-policy-test&policy=b64-encoded-string
+    response.setHeader('Cache-Control', 'no-cache', false);
+    response.setHeader('Content-Type', 'text/html', false);
+    var refpol = unescape(params[1].split('=')[1]);
+    response.write(createPolicyTest(refpol));
+  }
+}
new file mode 100644
--- /dev/null
+++ b/dom/base/test/bug704320_counter.sjs
@@ -0,0 +1,94 @@
+// Handle counting loads for bug 704320.
+
+const SHARED_KEY="bug704320_counter";
+const DEFAULT_STATE = {'css': {'count': 0, 'referrers': []},
+                       'img': {'count': 0, 'referrers': []},
+                       'js':  {'count': 0, 'referrers': []}};
+const TYPE_MAP = {'css': 'text/css',
+                  'js':  'application/javascript',
+                  'img': 'image/png',
+                  'html': 'text/html'};
+
+// Writes an image to the response
+function WriteOutImage(response)
+{
+  var file = Components.classes["@mozilla.org/file/directory_service;1"]
+             .getService(Components.interfaces.nsIProperties)
+             .get("CurWorkD", Components.interfaces.nsIFile);
+
+  file.append("tests");
+  file.append("image");
+  file.append("test");
+  file.append("mochitest");
+  file.append('blue.png');
+
+  var fileStream = Components.classes['@mozilla.org/network/file-input-stream;1']
+                   .createInstance(Components.interfaces.nsIFileInputStream);
+  fileStream.init(file, 1, 0, false);
+  response.bodyOutputStream.writeFrom(fileStream, fileStream.available());
+}
+
+function handleRequest(request, response)
+{
+  var query = {};
+  request.queryString.split('&').forEach(function (val) {
+    var [name, value] = val.split('=');
+    query[name] = unescape(value);
+  });
+
+  var referrerLevel = "none";
+  if (request.hasHeader('Referer')) {
+    let referrer = request.getHeader('Referer');
+    if (referrer.indexOf("bug704320") > 0) {
+      referrerLevel = "full";
+    } else if (referrer == "http://mochi.test:8888") {
+      referrerLevel = "origin";
+    }
+  }
+
+  var state = getSharedState(SHARED_KEY);
+  if (state === '') {
+    state = DEFAULT_STATE;
+  } else {
+    state = JSON.parse(state);
+  }
+
+  response.setStatusLine(request.httpVersion, 200, "OK");
+
+
+  //avoid confusing cache behaviors
+  response.setHeader("Cache-Control", "no-cache", false);
+
+  if ("reset" in query) {
+    //reset server state
+    setSharedState(SHARED_KEY, JSON.stringify(DEFAULT_STATE));
+    //serve any CSS that we want to use.
+    response.write("");
+    return;
+  }
+
+  if ("results" in query) {
+    response.setHeader("Content-Type", "text/javascript", false);
+    response.write(JSON.stringify(state));
+    return;
+  }
+
+  if ('type' in query) {
+    state[query.type].count++;
+    response.setHeader("Content-Type", TYPE_MAP[query.type], false);
+    if (state[query.type].referrers.indexOf(referrerLevel) < 0) {
+      state[query.type].referrers.push(referrerLevel);
+    }
+
+    if (query.type == 'img') {
+      WriteOutImage(response);
+    }
+  }
+
+  if ('content' in query) {
+    response.write(unescape(query['content']));
+  }
+
+  setSharedState(SHARED_KEY, JSON.stringify(state));
+  return;
+}
--- a/dom/base/test/chrome/chrome.ini
+++ b/dom/base/test/chrome/chrome.ini
@@ -28,16 +28,17 @@ support-files =
 [test_bug391728.html]
 [test_bug421622.xul]
 [test_bug429785.xul]
 [test_bug430050.xul]
 [test_bug467123.xul]
 [test_bug549682.xul]
 [test_bug571390.xul]
 [test_bug574596.html]
+[test_bug1098074_throw_from_ReceiveMessage.xul]
 skip-if = buildapp == 'mulet'
 [test_bug599295.html]
 [test_bug616841.xul]
 [test_bug635835.xul]
 [test_bug650776.html]
 [test_bug650784.html]
 [test_bug682305.html]
 [test_bug683852.xul]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/chrome/test_bug1098074_throw_from_ReceiveMessage.xul
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1098074
+-->
+<window title="Mozilla Bug 1098074"
+    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+    onload="start();">
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+  <!-- test code goes here -->
+  <script type="application/javascript">
+  <![CDATA[
+  /** Test for Bug 1098074 **/
+  SimpleTest.waitForExplicitFinish();
+  SimpleTest.expectUncaughtException();
+
+  // Tell the test to expect exactly one console error with the given parameters,
+  // with SimpleTest.finish as a continuation function.
+  SimpleTest.monitorConsole(SimpleTest.finish, [{errorMessage: new RegExp('acopia')}]);
+
+  var Cc = Components.classes;
+  var Ci = Components.interfaces;
+  var globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
+                   .getService(Ci.nsIMessageListenerManager);
+  globalMM.addMessageListener("flimfniffle", function onMessage(msg) {
+    globalMM.removeMessageListener("flimfniffle", onMessage);
+    is(msg.data, "teufeltor", "correct message");
+
+    // Cleanup the monitor after we throw.
+    SimpleTest.executeSoon(SimpleTest.endMonitorConsole);
+
+    throw "acopia";
+  });
+
+  function start() {
+    globalMM.loadFrameScript("data:,sendAsyncMessage('flimfniffle', 'teufeltor')", true);
+  }
+
+  ]]>
+  </script>
+
+  <!-- test results are displayed in the html:body -->
+  <body xmlns="http://www.w3.org/1999/xhtml">
+  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1098074"
+     target="_blank">Mozilla Bug 1098074</a>
+  </body>
+</window>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/csp/file_form-action.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 529697 - Test mapping of form submission to form-action</title>
+</head>
+<body>
+  <form action="submit-form">
+    <input id="submitButton" type="submit" value="Submit form">
+  </form>
+  <script type="text/javascript">
+  var submitButton = document.getElementById('submitButton');
+  submitButton.click();
+  </script>
+</body>
+</html>
--- a/dom/base/test/csp/mochitest.ini
+++ b/dom/base/test/csp/mochitest.ini
@@ -95,16 +95,17 @@ support-files =
   file_redirect_report.sjs
   file_subframe_run_js_if_allowed.html
   file_subframe_run_js_if_allowed.html^headers^
   file_leading_wildcard.html
   file_multi_policy_injection_bypass.html
   file_multi_policy_injection_bypass.html^headers^
   file_multi_policy_injection_bypass_2.html
   file_multi_policy_injection_bypass_2.html^headers^
+  file_form-action.html
 
 [test_base-uri.html]
 [test_connect-src.html]
 [test_CSP.html]
 [test_csp_allow_https_schemes.html]
 skip-if = buildapp == 'b2g' #no ssl support
 [test_CSP_bug663567.html]
 [test_CSP_bug802872.html]
@@ -119,16 +120,18 @@ skip-if = (buildapp == 'b2g' && (toolkit
 [test_bug836922_npolicies.html]
 [test_bug886164.html]
 [test_csp_redirects.html]
 [test_CSP_bug910139.html]
 [test_CSP_bug909029.html]
 [test_policyuri_regression_from_multipolicy.html]
 [test_nonce_source.html]
 [test_CSP_bug941404.html]
+[test_form-action.html]
+skip-if = e10s || buildapp == 'b2g' # http-on-opening-request observers are not available in child processes
 [test_hash_source.html]
 skip-if = e10s || buildapp == 'b2g' # can't compute hashes in child process (bug 958702)
 [test_self_none_as_hostname_confusion.html]
 [test_bug949549.html]
 [test_csp_path_matching.html]
 [test_csp_path_matching_redirect.html]
 [test_report_uri_missing_in_report_only_header.html]
 [test_csp_report.html]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/csp/test_form-action.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Bug 529697 - Test mapping of form submission to form-action</title>
+  <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+  <p id="display"></p>
+  <div id="content" style="visibility: hidden">
+    <iframe style="width:100%;" id="testframe"></iframe>
+  </div>
+
+<script class="testbody" type="text/javascript">
+
+/*
+ * Description of the test:
+ *   We load a page with a given CSP and verify that form submissions are correctly
+ *   evaluated through the "form-action" directive.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+var tests = [
+  {
+    page   : "file_form-action.html",
+    result : "allowed",
+    policy : "form-action 'self'"
+  },
+  {
+    page   : "file_form-action.html",
+    result : "blocked",
+    policy : "form-action 'none'"
+  }
+];
+
+// initializing to -1 so we start at index 0 when we start the test
+var counter = -1;
+
+function checkResult(aResult) {
+  is(aResult, tests[counter].result, "should be " + tests[counter].result + " in test " + counter + "!");
+  loadNextTest();
+}
+
+// We use the examiner to identify requests that hit the wire and requests
+// that are blocked by CSP and bubble up the result to the including iframe
+// document (parent).
+function examiner() {
+  SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
+  SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false);
+}
+examiner.prototype  = {
+  observe: function(subject, topic, data) {
+   if (topic === "specialpowers-http-notify-request") {
+      // making sure we do not bubble a result for something other
+      // then the request in question.
+      if (!data.contains("submit-form")) {
+        return;
+      }
+      checkResult("allowed");
+    }
+
+    if (topic === "csp-on-violate-policy") {
+      // making sure we do not bubble a result for something other
+      // then the request in question.
+      var asciiSpec = SpecialPowers.getPrivilegedProps(
+                        SpecialPowers.do_QueryInterface(subject, "nsIURI"),
+                        "asciiSpec");
+      if (!asciiSpec.contains("submit-form")) {
+        return;
+      }
+      checkResult("blocked");
+    }
+  },
+  remove: function() {
+    SpecialPowers.removeObserver(this, "csp-on-violate-policy");
+    SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
+  }
+}
+window.FormActionExaminer = new examiner();
+
+function loadNextTest() {
+  counter++;
+  if (counter == tests.length) {
+    window.FormActionExaminer.remove();
+    SimpleTest.finish();
+    return;
+  }
+
+  var src = "file_csp_testserver.sjs";
+  // append the file that should be served
+  src += "?file=" + escape("tests/dom/base/test/csp/" + tests[counter].page);
+  // append the CSP that should be used to serve the file
+  src += "&csp=" + escape(tests[counter].policy);
+
+  document.getElementById("testframe").src = src;
+}
+
+// start running the tests
+loadNextTest();
+
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_bug704320_preload_common.js
@@ -0,0 +1,34 @@
+// Common code for the iframes used by bug704320_preload.
+
+var loadCount = 0;
+
+// Called by the various onload handlers to indicate that a resource has
+// been fully loaded.  We require three loads to complete (img, script,
+// link) for this test.
+function incrementLoad(tag) {
+  loadCount++;
+  if (loadCount == 3) {
+    window.parent.postMessage("childLoadComplete", window.location.origin);
+  } else if (loadCount > 3) {
+    document.write("<h1>Too Many Load Events!</h1>");
+    window.parent.postMessage("childOverload", window.location.origin);
+  }
+}
+
+// This is same as incrementLoad, but the caller passes in the loadCount.
+function incrementLoad2(tag, expectedLoadCount) {
+  loadCount++;
+  if (loadCount == expectedLoadCount) {
+    window.parent.postMessage("childLoadComplete", window.location.origin);
+  } else if (loadCount > expectedLoadCount) {
+    document.write("<h1>Too Many Load Events!</h1>");
+    window.parent.postMessage("childOverload", window.location.origin);
+  }
+}
+
+// in case something fails to load, cause the test to fail.
+function postfail(msg) {
+  window.parent.postMessage("fail-" + msg, window.location.origin);
+}
+
+
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_bug704320_preload_noreuse.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed.
+https://bugzilla.mozilla.org/show_bug.cgi?id=704320
+-->
+<head>
+  <meta charset="utf-8">
+  <script type="text/javascript" src="file_bug704320_preload_common.js"></script>
+
+  <script type="text/javascript">
+    // mess with parser speculation's choice of referrer policy
+    document.write("<meta name='referrer' content='origin'>");
+  </script>
+
+  <!-- preload happens with full referrer, but real load should happen with origin -->
+  <script src="/tests/dom/base/test/bug704320_counter.sjs?type=js"
+          onload="incrementLoad('script');"></script>
+
+  <!-- preload happens with full referrer, but real load should happen with origin -->
+  <link rel="stylesheet"
+        href="/tests/dom/base/test/bug704320_counter.sjs?type=css"
+        onload="incrementLoad('link');"/>
+
+</head>
+<body>
+
+  <!-- preload happens with full referrer, but real load should happen with origin -->
+<img src="/tests/dom/base/test/bug704320_counter.sjs?type=img"
+     onload="incrementLoad('img');"
+     onerror="postfail('image load caused an error in noreuse test');"/>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_bug704320_preload_reuse.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed.
+https://bugzilla.mozilla.org/show_bug.cgi?id=704320
+-->
+<head>
+  <meta charset="utf-8">
+  <meta name="referrer" content="origin">
+  <script type="text/javascript" src="file_bug704320_preload_common.js"></script>
+  <script language="javascript" type="text/javascript">
+    // mess with parser speculation -- the loads here MAY be reused because the
+    // referrer policy did not change.
+    document.write("<meta name='referrer' content='origin'>");
+  </script>
+
+  <script src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=js"
+          onload="incrementLoad('script');"></script>
+
+  <link rel="stylesheet"
+        href="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=css"
+        onload="incrementLoad('link');"/>
+
+</head>
+<body>
+
+<img src="http://example.com/tests/dom/base/test/bug704320_counter.sjs?type=img"
+     onload="incrementLoad('img');"
+     onerror="postfail('image load caused an error in reuse test');"/>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/file_bug704320_redirect.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <script>
+    parent.postMessage('', 'http://mochi.test:8888');
+  </script>
+</head>
+<body>
+</body>
+</html>
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -47,16 +47,18 @@ support-files =
   bug578096LoadChromeScript.js
   bug638112-response.txt
   bug638112.sjs
   bug682592-subframe-ref.html
   bug682592-subframe.html
   bug696301-script-1.js
   bug696301-script-1.js^headers^
   bug696301-script-2.js
+  bug704320.sjs
+  bug704320_counter.sjs
   bug819051.sjs
   copypaste.js
   delayedServerEvents.sjs
   echo.sjs
   eventsource.resource
   eventsource.resource^headers^
   eventsource_redirect.resource
   eventsource_redirect.resource^headers^
@@ -133,16 +135,20 @@ support-files =
   file_bug687859-16.js^headers^
   file_bug687859-bom.js
   file_bug687859-bom.js^headers^
   file_bug687859-charset.js
   file_bug687859-http.js
   file_bug687859-http.js^headers^
   file_bug687859-inherit.js
   file_bug692434.xml
+  file_bug704320_preload_common.js
+  file_bug704320_preload_reuse.html
+  file_bug704320_preload_noreuse.html
+  file_bug704320_redirect.html
   file_bug707142_baseline.json
   file_bug707142_bom.json
   file_bug707142_utf-16.json
   file_bug708620-2.html
   file_bug708620.html
   file_bug782342.txt
   file_bug787778.sjs
   file_bug804395.jar
@@ -588,16 +594,20 @@ skip-if = buildapp == 'b2g'
 [test_bug693615.html]
 [test_bug693875.html]
 [test_bug694754.xhtml]
 [test_bug696301-1.html]
 [test_bug696301-2.html]
 [test_bug698381.html]
 [test_bug698384.html]
 [test_bug704063.html]
+[test_bug704320.html]
+skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # b2g (Needs multiple window.open support) android(times out, bug 1100609) e10s(randomly fails, bug 1100362)
+[test_bug704320_policyset.html]
+[test_bug704320_preload.html]
 [test_bug707142.html]
 [test_bug708620.html]
 [test_bug711047.html]
 [test_bug711180.html]
 [test_bug719533.html]
 [test_bug726364.html]
 [test_bug737087.html]
 [test_bug737565.html]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_bug704320.html
@@ -0,0 +1,232 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=704320
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 704320</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=704320">Mozilla Bug 704320</a>
+<p id="display"></p>
+<pre id="content">
+</pre>
+<pre id="test">
+</pre>
+
+<script type="application/javascript">
+
+
+var testIframeUrls = [
+  // HTTP to HTTP
+  'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade',
+  'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer',
+  'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url',
+  'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=origin',
+  // HTTP to HTTPS
+  'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade',
+  'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer',
+  'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url',
+  'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=origin',
+  // HTTPS to HTTP
+  'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=no-referrer-when-downgrade',
+  'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=no-referrer',
+  'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url',
+  'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=origin',
+  // HTTPS to HTTPS
+  'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade',
+  'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer',
+  'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url',
+  'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=origin'
+];
+
+var expectedResults = {
+  // From docshell/base/nsDocShell.cpp:
+  //   "If the document containing the hyperlink being audited was not retrieved
+  //    over an encrypted connection and its address does not have the same
+  //    origin as "ping URL", send a referrer."
+  'link-ping': {
+    // Same-origin
+    'http-to-http': {
+      'no-referrer': '',
+      'unsafe-url': '',
+      'origin': '',
+      'no-referrer-when-downgrade': ''
+    },
+    'http-to-https': {
+      'no-referrer': '',
+      'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url',
+      'origin': 'http://example.com',
+      'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade'
+    },
+    // Encrypted and not same-origin
+    'https-to-http': {
+      'no-referrer': '',
+      'unsafe-url': '',
+      'origin': '',
+      'no-referrer-when-downgrade': ''
+    },
+    // Encrypted
+    'https-to-https': {
+      'no-referrer': '',
+      'unsafe-url': '',
+      'origin': '',
+      'no-referrer-when-downgrade': ''
+    }
+  },
+  // form is tested in a 2nd level iframe.
+  'form': {
+    'http-to-http': {
+      'no-referrer': '',
+      'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=form',
+      'origin': 'http://example.com',
+      'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=form'
+    },
+    'http-to-https': {
+      'no-referrer': '',
+      'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=form',
+      'origin': 'http://example.com',
+      'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=form'
+    },
+    'https-to-http': {
+      'no-referrer': '',
+      'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=form',
+      'origin': 'https://example.com',
+      'no-referrer-when-downgrade': ''
+    },
+    'https-to-https': {
+      'no-referrer': '',
+      'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=form',
+      'origin': 'https://example.com',
+      'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=form'
+    }
+  },
+  // window.location is tested in a 2nd level iframe.
+  'window.location': {
+    'http-to-http': {
+      'no-referrer': '',
+      'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url&type=window.location',
+      'origin': 'http://example.com',
+      'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade&type=window.location'
+    },
+    'http-to-https': {
+      'no-referrer': '',
+      'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url&type=window.location',
+      'origin': 'http://example.com',
+      'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location'
+    },
+    'https-to-http': {
+      'no-referrer': '',
+      'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url&type=window.location',
+      'origin': 'https://example.com',
+      'no-referrer-when-downgrade': ''
+    },
+    'https-to-https': {
+      'no-referrer': '',
+      'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url&type=window.location',
+      'origin': 'https://example.com',
+      'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-2nd-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade&type=window.location'
+    }
+  },
+  'default': {
+    'http-to-http': {
+      'no-referrer': '',
+      'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=unsafe-url',
+      'origin': 'http://example.com',
+      'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=http&policy=no-referrer-when-downgrade'
+    },
+    'http-to-https': {
+      'no-referrer': '',
+      'unsafe-url': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=unsafe-url',
+      'origin': 'http://example.com',
+      'no-referrer-when-downgrade': 'http://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=http&scheme-to=https&policy=no-referrer-when-downgrade'
+    },
+    'https-to-http': {
+      'no-referrer': '',
+      'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=http&policy=unsafe-url',
+      'origin': 'https://example.com',
+      'no-referrer-when-downgrade': ''
+    },
+    'https-to-https': {
+      'no-referrer': '',
+      'unsafe-url': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=unsafe-url',
+      'origin': 'https://example.com',
+      'no-referrer-when-downgrade': 'https://example.com/tests/dom/base/test/bug704320.sjs?action=create-1st-level-iframe&scheme-from=https&scheme-to=https&policy=no-referrer-when-downgrade'
+    }
+  }
+};
+
+function runit() {
+  var url = 'bug704320.sjs?action=get-test-results';
+  var xhr = new XMLHttpRequest();
+
+  xhr.open('GET', url);
+  xhr.onreadystatechange = function() {
+    //dump("\n\n >>>>>>>>>>> XHR ReadyState change \n" + url + "\n\n\n\n");
+    if (this.readyState == 4) {
+      document.getElementById('content').textContent +=
+          JSON.stringify(JSON.parse(this.response), null, 4);
+
+      //dump("\n\n >>>>>>>>>>> GOT RESPONSE: \n" + this.response + "\n\n\n\n");
+      var response = JSON.parse(this.response);
+
+      for (type in response) {
+        for (scheme in response[type]) {
+          for (policy in response[type][scheme]) {
+            var expectedResult = expectedResults[type] === undefined ?
+              expectedResults['default'][scheme][policy] :
+              expectedResults[type][scheme][policy];
+
+            is(response[type][scheme][policy], expectedResult,
+               type + ' ' + scheme + ' ' + policy);
+          }
+        }
+      }
+
+      SimpleTest.finish();
+    }
+  };
+  xhr.send();
+}
+
+// BEGIN
+// Currently triggers assertions on e10s due to bug 820466.  If you try to run
+// this on e10s, you'll get some ssl-related assertions and should add this line:
+// SimpleTest.expectAssertions(0,15);
+// But this test is disabled on e10s for unexpected failures.  See bug 1100362.
+
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({
+    'set': [['security.mixed_content.block_active_content',   false],
+            ['security.mixed_content.block_display_content',  false],
+            ['browser.send_pings',                            true],
+            ['browser.send_pings.max_per_link',               1],
+            ['browser.send_pings.require_same_host',          false]]
+    },
+    function() {
+      var testContainer = document.getElementById('test');
+
+      testIframeUrls.forEach(function(url) {
+        var iframe = document.createElement('iframe');
+        iframe.setAttribute('class', 'test');
+        iframe.src = url;
+        testContainer.appendChild(iframe);
+      });
+
+      var numFrames = testIframeUrls.length;
+      var numFramesReady = 0;
+
+      window.addEventListener('message', function(event) {
+        ++numFramesReady;
+        if (numFramesReady >= numFrames) {
+          runit();
+        }
+      }, false);
+    });
+</script>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_bug704320_policyset.html
@@ -0,0 +1,179 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+This checks if the right policies are applied from a given string (including whitespace, invalid policy strings, etc).  It doesn't do a complete check for all load types; that's done in another test.
+https://bugzilla.mozilla.org/show_bug.cgi?id=704320
+-->
+
+<head>
+  <meta charset="utf-8">
+  <title>Test policies for Bug 704320</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+<script type="application/javascript;version=1.7">
+
+SimpleTest.waitForExplicitFinish();
+var advance = function() { tests.next(); };
+
+/**
+ * Listen for notifications from the child.
+ * These are sent in case of error, or when the loads we await have completed.
+ */
+window.addEventListener("message", function(event) {
+    if (event.data == "childLoadComplete") {
+      // all loads happen, continue the test.
+      advance();
+    } else if (event.data == "childOverload") {
+      // too many loads happened in a test frame, abort.
+      ok(false, "Too many load handlers called in test.");
+      SimpleTest.finish();
+    } else if (event.data.indexOf("fail-") == 0) {
+      // something else failed in the test frame, abort.
+      ok(false, "Child failed the test with error " + event.data.substr(5));
+      SimpleTest.finish();
+    }});
+
+/**
+ * This is the main test routine -- serialized by use of a generator.
+ * It resets the counter, then performs two tests in sequence using
+ * the same iframe.
+ */
+var tests = (function() {
+  var iframe = document.getElementById("testframe");
+  const sjs = "/tests/dom/base/test/bug704320.sjs?action=generate-policy-test";
+
+
+  // basic calibration check
+  // reset the counter
+  yield resetCounter();
+
+  // load the first test frame
+  // it will call back into this function via postMessage when it finishes loading.
+  // and continue beyond the yield.
+  yield iframe.src = sjs + "&policy=" + escape('default');
+
+  // check the first test (two images, no referrers)
+  yield checkResults("default", ["full"]);
+
+  // check invalid policy
+  // According to the spec section 6.4, if there is a policy token
+  // and it is not one of the expected tokens, "No Referrer"
+  // should be the policy used.
+  yield resetCounter();
+  yield iframe.src = sjs + "&policy=" + escape('invalid-policy');
+  yield checkResults("invalid", ["none"]);
+
+  // whitespace checks.
+  // according to the spec section 4.1, the content attribute's value
+  // is fed to the token policy algorithm after stripping leading and
+  // trailing whitespace.
+  yield resetCounter();
+  yield iframe.src = sjs + "&policy=" + escape('default   ');
+  yield checkResults("trailing whitespace", ["full"]);
+
+  yield resetCounter();
+  yield iframe.src = sjs + "&policy=" + escape(' origin\f');
+  yield checkResults("trailing form feed", ["origin"]);
+
+  yield resetCounter();
+  yield iframe.src = sjs + "&policy=" + escape('\f origin');
+  yield checkResults("leading form feed", ["origin"]);
+
+  // origin when cross-origin (trimming whitespace)
+  yield resetCounter();
+  yield iframe.src = sjs + "&policy=" + escape(' origin-when-crossorigin');
+  yield checkResults("origin-when-crossorigin", ["origin", "full"]);
+
+  // according to the spec section 4.1:
+  // "If the meta element lacks a content attribute, or if that attribute’s
+  //  value is the empty string, then abort these steps."
+  // This means empty or missing content attribute means to ignore the meta
+  // tag and use default policy.
+  // Whitespace here is space, tab, LF, FF and CR.
+  // http://www.w3.org/html/wg/drafts/html/CR/infrastructure.html#space-character
+  yield resetCounter();
+  yield iframe.src = sjs + "&policy=" + escape(' \t  ');
+  yield checkResults("basic whitespace only policy", ["full"]);
+
+  yield resetCounter();
+  yield iframe.src = sjs + "&policy=" + escape(' \f\r\n\t  ');
+  yield checkResults("whitespace only policy", ["full"]);
+
+  // and double-check that no-referrer works.
+  yield resetCounter();
+  yield iframe.src = sjs + "&policy=" + escape('no-referrer');
+  yield checkResults("no-referrer", ["none"]);
+
+  // complete.  Be sure to yield so we don't call this twice.
+  yield SimpleTest.finish();
+})();
+
+// Helper functions below.
+
+
+/**
+ * helper to perform an XHR.
+ * Used by resetCounter() and checkResults().
+ */
+function doXHR(url, onSuccess, onFail) {
+  var xhr = new XMLHttpRequest();
+  xhr.onload = function () {
+    if (xhr.status == 200) {
+      onSuccess(xhr);
+    } else {
+      onFail(xhr);
+    }
+  };
+  xhr.open('GET', url, true);
+  xhr.send(null);
+}
+
+/**
+ * This triggers state-resetting on the counter server.
+ */
+function resetCounter() {
+  doXHR('/tests/dom/base/test/bug704320_counter.sjs?reset',
+        advance,
+        function(xhr) {
+          ok(false, "Need to be able to reset the request counter");
+          SimpleTest.finish();
+        });
+}
+
+/**
+ * Grabs the results via XHR and passes to checker.
+ */
+function checkResults(testname, expected) {
+  doXHR('/tests/dom/base/test/bug704320_counter.sjs?results',
+        function(xhr) {
+          var results = JSON.parse(xhr.responseText);
+          info(xhr.responseText);
+
+          ok('img' in results,
+              testname + " test: some image loads required in results object.");
+          is(results['img'].count, 2,
+            testname + " Test: Expected 2 loads for image requests.");
+
+          expected.forEach(function (ref) {
+            ok(results['img'].referrers.indexOf(ref) >= 0,
+                testname + " Test: Expected " + ref + " referrer policy in test, results were " + 
+                JSON.stringify(results['img'].referrers) +".");
+            });
+          advance();
+        },
+        function(xhr) {
+          ok(false, "Can't get results from the counter server.");
+          SimpleTest.finish();
+        });
+}
+
+</script>
+</head>
+
+<body onload="tests.next();">
+  <iframe id="testframe"></iframe>
+
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_bug704320_preload.html
@@ -0,0 +1,189 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+This is a spot check for whether the speculative parser reuses style, script or image loads after the referrer policy has changed.
+https://bugzilla.mozilla.org/show_bug.cgi?id=704320
+-->
+
+<head>
+  <meta charset="utf-8">
+  <title>Test preloads for Bug 704320</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+
+<script type="application/javascript;version=1.7">
+
+SimpleTest.waitForExplicitFinish();
+var advance = function() { tests.next(); };
+
+/**
+ * Listen for notifications from the child.
+ * These are sent in case of error, or when the loads we await have completed.
+ */
+window.addEventListener("message", function(event) {
+    if (event.data == "childLoadComplete") {
+      // all three loads happen, continue the test.
+      advance();
+    } else if (event.data == "childOverload") {
+      // too many loads happened in a test frame, abort.
+      ok(false, "Too many load handlers called in test.");
+      SimpleTest.finish();
+    } else if (event.data.indexOf("fail-") == 0) {
+      // something else failed in the test frame, abort.
+      ok(false, "Child failed the test with error " + event.data.substr(5));
+      SimpleTest.finish();
+    }});
+
+/**
+ * This is the main test routine -- serialized by use of a generator.
+ * It resets the counter, then performs two tests in sequence using
+ * the same iframe.
+ */
+var tests = (function() {
+  var iframe = document.getElementById("testframe");
+
+  // reset the counter
+  yield resetCounter();
+
+  // load the first test frame
+  // it will call back into this function via postMessage when it finishes loading.
+  // and continue beyond the yield.
+  yield iframe.src = 'file_bug704320_preload_noreuse.html';
+
+  // check the first test
+  yield checkResults(finalizePreloadNoreuse);
+
+  // reset the counter
+  yield resetCounter();
+
+  // load the second test frame
+  // it will call back into this function via postMessage when it finishes loading.
+  // and continue beyond the yield.
+  yield iframe.src = 'file_bug704320_preload_reuse.html';
+
+  // check the second test
+  yield checkResults(finalizePreloadReuse);
+
+  // complete.  Be sure to yield so we don't call this twice.
+  yield SimpleTest.finish();
+})();
+
+// Helper functions below.
+
+/**
+ * This checks the first test: a test where the preloads should not
+ * be reused.  * we expect two requests for each image, script, js request
+ * since the referrer policy changed after speculative loads were started.
+ * Problem is that the "origin"/revised loads won't necessarily happen,
+ * so we test for one or two loads (both are OK) and make the 'origin'
+ * referrer optional.
+ */
+function finalizePreloadNoreuse(results) {
+  console.log("<br/><pre>" + JSON.stringify(results) + "</pre>");
+  var expected = {'css': {'count': 2, 'referrers': ['full', 'origin']},
+                  'img': {'count': 2, 'referrers': ['full', 'origin']},
+                  'js':  {'count': 2, 'referrers': ['full', 'origin']}};
+
+  for (var x in expected) {
+    ok(x in results, "some " + x + " loads required in results object.");
+
+    ok(results[x].count == 1 || results[x].count == 2,
+       "Expected 1-2  loads for " + x + " requests.");
+
+    // the 'full' preload is optional, but required if count > 1
+    if (results[x].count > 1) {
+      ok(results[x].referrers.indexOf('full') >= 0,
+         "More than one load for " + x + ", so expected an 'full' referrer preload.")
+    }
+
+    // 'origin' (final load) is required
+    ok(results[x].referrers.indexOf('origin') >= 0,
+       "One load for " + x + " should have had 'origin' referrer.");
+
+    // no other values should be in the referrers.
+    is(results[x].referrers.indexOf('none'), -1,
+       "No loads for " + x + " should have a missing referrer.");
+  }
+
+  advance();
+}
+
+/**
+ * This checks the second test: a test where preloads SHOULD be reused.
+ * We expect one request for each image, script, js request since
+ * the referrer policy does not change after speculative loads.
+ */
+function finalizePreloadReuse(results) {
+  var expected = {'css': {'count': 1, 'referrers': ['origin']},
+                  'img': {'count': 1, 'referrers': ['origin']},
+                  'js':  {'count': 1, 'referrers': ['origin']}};
+
+  for (var x in expected) {
+    ok(x in results, "some " + x + " loads required in results object.");
+
+    is(results[x].count, expected[x].count,
+       "Expected " + expected[x].count + " loads for " + x + " requests.");
+
+    // 'origin' is required
+    ok(results[x].referrers.indexOf('origin') >= 0,
+       "One load for " + x + " should have had 'origin' referrer.");
+
+    // no other values should be in the referrers.
+    is(results[x].referrers.indexOf('none'), -1,
+       "No loads for " + x + " should have a missing referrer.");
+    is(results[x].referrers.indexOf('full'), -1,
+       "No loads for " + x + " should have an 'full' referrer.")
+  }
+
+  advance();
+}
+
+/**
+ * helper to perform an XHR.
+ * Used by resetCounter() and checkResults().
+ */
+function doXHR(url, onSuccess, onFail) {
+  var xhr = new XMLHttpRequest();
+  xhr.onload = function () {
+    if (xhr.status == 200) {
+      onSuccess(xhr);
+    } else {
+      onFail(xhr);
+    }
+  };
+  xhr.open('GET', url, true);
+  xhr.send(null);
+}
+
+/**
+ * This triggers state-resetting on the counter server.
+ */
+function resetCounter() {
+  doXHR('/tests/dom/base/test/bug704320_counter.sjs?reset',
+        advance,
+        function(xhr) {
+          ok(false, "Need to be able to reset the request counter");
+        });
+}
+
+/**
+ * Grabs the results via XHR and passes to checker.
+ */
+function checkResults(checker) {
+  doXHR('/tests/dom/base/test/bug704320_counter.sjs?results',
+        function(xhr) {
+          checker(JSON.parse(xhr.responseText));
+        },
+        function(xhr) {
+          ok(false, "Can't get results from the counter server.");
+        });
+}
+
+</script>
+</head>
+
+<body onload="tests.next();">
+  <iframe id="testframe"></iframe>
+
+</body>
+</html>
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -56,16 +56,18 @@
 #include "mozAutoDocUpdate.h"
 #include "nsIHTMLCollection.h"
 
 #include "nsIConstraintValidation.h"
 
 #include "nsIDOMHTMLButtonElement.h"
 #include "nsSandboxFlags.h"
 
+#include "nsIContentSecurityPolicy.h"
+
 // images
 #include "mozilla/dom/HTMLImageElement.h"
 
 // construction, destruction
 NS_IMPL_NS_NEW_HTML_ELEMENT(Form)
 
 namespace mozilla {
 namespace dom {
@@ -1620,16 +1622,29 @@ HTMLFormElement::GetActionURL(nsIURI** a
   //
   nsIScriptSecurityManager *securityManager =
       nsContentUtils::GetSecurityManager();
   rv = securityManager->
     CheckLoadURIWithPrincipal(NodePrincipal(), actionURL,
                               nsIScriptSecurityManager::STANDARD);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Check if CSP allows this form-action
+  nsCOMPtr<nsIContentSecurityPolicy> csp;
+  rv = NodePrincipal()->GetCsp(getter_AddRefs(csp));
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (csp) {
+    bool permitsFormAction = true;
+    rv = csp->PermitsFormAction(actionURL, &permitsFormAction);
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (!permitsFormAction) {
+      rv = NS_ERROR_CSP_FORM_ACTION_VIOLATION;
+    }
+  }
+
   //
   // Assign to the output
   //
   *aActionURL = actionURL;
   NS_ADDREF(*aActionURL);
 
   return rv;
 }
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -3714,17 +3714,18 @@ void HTMLMediaElement::SetRequestHeaders
   // which prevents us from estimating the video length (if explicit Content-Duration
   // and a length spec in the container are not present either) and from seeking.
   // So, disable the standard "Accept-Encoding: gzip,deflate" that we usually send.
   // See bug 614760.
   aChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept-Encoding"),
                              EmptyCString(), false);
 
   // Set the Referer header
-  aChannel->SetReferrer(OwnerDoc()->GetDocumentURI());
+  aChannel->SetReferrerWithPolicy(OwnerDoc()->GetDocumentURI(),
+                                  OwnerDoc()->GetReferrerPolicy());
 }
 
 void HTMLMediaElement::FireTimeUpdate(bool aPeriodic)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
   TimeStamp now = TimeStamp::Now();
   double time = CurrentTime();
--- a/dom/html/HTMLMetaElement.cpp
+++ b/dom/html/HTMLMetaElement.cpp
@@ -72,17 +72,31 @@ HTMLMetaElement::BindToTree(nsIDocument*
                                                  aBindingParent,
                                                  aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
   if (aDocument &&
       AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, nsGkAtoms::viewport, eIgnoreCase)) {
     nsAutoString content;
     rv = GetContent(content);
     NS_ENSURE_SUCCESS(rv, rv);
-    nsContentUtils::ProcessViewportInfo(aDocument, content);  
+    nsContentUtils::ProcessViewportInfo(aDocument, content);
+  }
+  if (aDocument &&
+      AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, nsGkAtoms::referrer, eIgnoreCase)) {
+    nsAutoString content;
+    rv = GetContent(content);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    // Referrer Policy spec requires a <meta name="referrer" tag to be in the
+    // <head> element.
+    Element* headElt = aDocument->GetHeadElement();
+    if (headElt && nsContentUtils::ContentIsDescendantOf(this, headElt)) {
+      content = nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(content);
+      aDocument->SetHeaderData(nsGkAtoms::referrer, content);
+    }
   }
   CreateAndDispatchEvent(aDocument, NS_LITERAL_STRING("DOMMetaAdded"));
   return rv;
 }
 
 void
 HTMLMetaElement::UnbindFromTree(bool aDeep, bool aNullParent)
 {
--- a/dom/interfaces/security/nsIContentSecurityPolicy.idl
+++ b/dom/interfaces/security/nsIContentSecurityPolicy.idl
@@ -202,16 +202,25 @@ interface nsIContentSecurityPolicy : nsI
    *
    * @return
    *    Whether or not the provided URI is allowed to be used as the
    *    document's base URI. (block the setting if false).
    */
   boolean permitsBaseURI(in nsIURI aURI);
 
   /**
+   * Whether this policy allows submitting HTML forms to a given URI.
+   *
+   * @return
+   *    Whether or not the provided URI is allowed to be used as a
+   *    form's action URI.
+   */
+  boolean permitsFormAction(in nsIURI aURI);
+
+  /**
    * Delegate method called by the service when sub-elements of the protected
    * document are being loaded.  Given a bit of information about the request,
    * decides whether or not the policy is satisfied.
    *
    * Calls to this may trigger violation reports when queried, so
    * this value should not be cached.
    */
   short shouldLoad(in nsContentPolicyType aContentType,
--- a/dom/locales/en-US/chrome/appstrings.properties
+++ b/dom/locales/en-US/chrome/appstrings.properties
@@ -25,11 +25,11 @@ unsafeContentType=The page you are tryin
 externalProtocolTitle=External Protocol Request
 externalProtocolPrompt=An external application must be launched to handle %1$S: links.\n\n\nRequested link:\n\n%2$S\n\nApplication: %3$S\n\n\nIf you were not expecting this request it may be an attempt to exploit a weakness in that other program. Cancel this request unless you are sure it is not malicious.\n
 #LOCALIZATION NOTE (externalProtocolUnknown): The following string is shown if the application name can't be determined
 externalProtocolUnknown=<Unknown>
 externalProtocolChkMsg=Remember my choice for all links of this type.
 externalProtocolLaunchBtn=Launch application
 malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
 phishingBlocked=The website at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
-cspFrameAncestorBlocked=This page has a content security policy that prevents it from being embedded in this way.
+cspBlocked=This page has a content security policy that prevents it from being loaded in this way.
 corruptedContentError=The page you are trying to view cannot be shown because an error in the data transmission was detected.
 remoteXUL=This page uses an unsupported technology that is no longer available by default.
--- a/dom/locales/en-US/chrome/netError.dtd
+++ b/dom/locales/en-US/chrome/netError.dtd
@@ -82,18 +82,18 @@
 ">
 
 <!ENTITY phishingBlocked.title "Suspected Web Forgery!">
 <!ENTITY phishingBlocked.longDesc "
 <p>Entering any personal information on this page may result in identity theft or other fraud.</p>
 <p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
 ">
 
-<!ENTITY cspFrameAncestorBlocked.title "Blocked by Content Security Policy">
-<!ENTITY cspFrameAncestorBlocked.longDesc "<p>The browser prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
+<!ENTITY cspBlocked.title "Blocked by Content Security Policy">
+<!ENTITY cspBlocked.longDesc "<p>The browser prevented this page from loading in this way because the page has a content security policy that disallows it.</p>">
 
 <!ENTITY corruptedContentError.title "Corrupted Content Error">
 <!ENTITY corruptedContentError.longDesc "<p>The page you are trying to view cannot be shown because an error in the data transmission was detected.</p><ul><li>Please contact the website owners to inform them of this problem.</li></ul>">
 
 <!ENTITY remoteXUL.title "Remote XUL">
 <!ENTITY remoteXUL.longDesc "<p><ul><li>Please contact the website owners to inform them of this problem.</li></ul></p>">
 
 <!-- Include app-specific error messages - do not change this in localization!
--- a/dom/media/mediasource/test/test_WaitingOnMissingData.html
+++ b/dom/media/mediasource/test/test_WaitingOnMissingData.html
@@ -56,17 +56,17 @@ runWithMSE(function(ms, v) {
 
         info("Playing video. It should play for a bit, then fire 'waiting'");
         v.play();
       });
     });
   });
   v.addEventListener("ended", function () {
     ok(Math.abs(v.duration - 4) < 0.1, "Video has correct duration. This fuzz factor is due to bug 1065207");
-    is(v.currentTime, v.duration, "Video has correct current time: " + v.currentTime);
+    ok(Math.abs(v.currentTime - 4) < 0.1, "Video has correct currentTime. See bug 1101062");
     ok(gotWaiting, "Received waiting event and playback continued after data added");
     SimpleTest.finish();
   });
 });
 </script>
 </pre>
 </body>
 </html>
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -3117,30 +3117,32 @@ nsresult nsPluginHost::NewPluginURLStrea
   // deal with headers and post data
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
   if (httpChannel) {
     if (!aPostStream) {
       // Only set the Referer header for GET requests because IIS throws
       // errors about malformed requests if we include it in POSTs. See
       // bug 724465.
       nsCOMPtr<nsIURI> referer;
+      net::ReferrerPolicy referrerPolicy = net::RP_Default;
 
       nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(element);
       if (olc)
         olc->GetSrcURI(getter_AddRefs(referer));
 
 
       if (!referer) {
         if (!doc) {
           return NS_ERROR_FAILURE;
         }
         referer = doc->GetDocumentURI();
+        referrerPolicy = doc->GetReferrerPolicy();
       }
 
-      rv = httpChannel->SetReferrer(referer);
+      rv = httpChannel->SetReferrerWithPolicy(referer, referrerPolicy);
       NS_ENSURE_SUCCESS(rv,rv);
     }
 
     if (aPostStream) {
       // XXX it's a bit of a hack to rewind the postdata stream
       // here but it has to be done in case the post data is
       // being reused multiple times.
       nsCOMPtr<nsISeekableStream>
--- a/dom/security/nsCSPContext.cpp
+++ b/dom/security/nsCSPContext.cpp
@@ -1097,17 +1097,17 @@ nsCSPContext::PermitsBaseURI(nsIURI* aUR
 
   for (uint32_t i = 0; i < mPolicies.Length(); i++) {
     if (!mPolicies[i]->permitsBaseURI(aURI)) {
       // policy is violated, report to caller if not report-only
       if (!mPolicies[i]->getReportOnlyFlag()) {
         *outPermitsBaseURI = false;
       }
       nsAutoString violatedDirective;
-      mPolicies[i]->getDirectiveStringForBaseURI(violatedDirective);
+      mPolicies[i]->getDirectiveAsString(CSP_BASE_URI, violatedDirective);
       this->AsyncReportViolation(aURI,
                                  nullptr,       /* originalURI in case of redirect */
                                  violatedDirective,
                                  i,             /* policy index        */
                                  EmptyString(), /* no observer subject */
                                  EmptyString(), /* no source file      */
                                  EmptyString(), /* no script sample    */
                                  0);            /* no line number      */
@@ -1122,16 +1122,58 @@ nsCSPContext::PermitsBaseURI(nsIURI* aUR
                   spec.get(),
                   *outPermitsBaseURI ? "allow" : "deny"));
   }
 #endif
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsCSPContext::PermitsFormAction(nsIURI* aURI, bool* outPermitsFormAction)
+{
+  // Can't perform check without aURI
+  if (!aURI) {
+    return NS_ERROR_FAILURE;
+  }
+
+  *outPermitsFormAction = true;
+
+  for (uint32_t i = 0; i < mPolicies.Length(); i++) {
+    if (!mPolicies[i]->permitsFormAction(aURI)) {
+      // policy is violated, report to caller if not report-only
+      if (!mPolicies[i]->getReportOnlyFlag()) {
+        *outPermitsFormAction = false;
+      }
+      nsAutoString violatedDirective;
+      mPolicies[i]->getDirectiveAsString(CSP_FORM_ACTION, violatedDirective);
+      this->AsyncReportViolation(aURI,
+                                 mSelfURI,
+                                 violatedDirective,
+                                 i,             /* policy index        */
+                                 EmptyString(), /* no observer subject */
+                                 EmptyString(), /* no source file      */
+                                 EmptyString(), /* no script sample    */
+                                 0);            /* no line number      */
+    }
+  }
+
+#ifdef PR_LOGGING
+  {
+    nsAutoCString spec;
+    aURI->GetSpec(spec);
+    CSPCONTEXTLOG(("nsCSPContext::PermitsFormAction, aUri: %s, isAllowed: %s",
+                  spec.get(),
+                  *outPermitsFormAction ? "allow" : "deny"));
+  }
+#endif
+
+  return NS_OK;
+}
+
 /* ========== CSPViolationReportListener implementation ========== */
 
 NS_IMPL_ISUPPORTS(CSPViolationReportListener, nsIStreamListener, nsIRequestObserver, nsISupports);
 
 CSPViolationReportListener::CSPViolationReportListener()
 {
 }
 
--- a/dom/security/nsCSPUtils.cpp
+++ b/dom/security/nsCSPUtils.cpp
@@ -868,16 +868,40 @@ nsCSPPolicy::permitsBaseURI(nsIURI* aUri
 
   // base-uri is only enforced if explicitly defined in the
   // policy - do *not* consult default-src, see:
   // http://www.w3.org/TR/CSP11/#directive-default-src
   return true;
 }
 
 bool
+nsCSPPolicy::permitsFormAction(nsIURI* aUri) const
+{
+#ifdef PR_LOGGING
+  {
+    nsAutoCString spec;
+    aUri->GetSpec(spec);
+    CSPUTILSLOG(("nsCSPPolicy::permitsFormAction, aUri: %s", spec.get()));
+  }
+#endif
+
+  // Try to find a form-action directive
+  for (uint32_t i = 0; i < mDirectives.Length(); i++) {
+    if (mDirectives[i]->equals(CSP_FORM_ACTION)) {
+      return mDirectives[i]->permits(aUri);
+    }
+  }
+
+  // form-action is only enforced if explicitly defined in the
+  // policy - do *not* consult default-src, see:
+  // http://www.w3.org/TR/CSP2/#directive-default-src
+  return true;
+}
+
+bool
 nsCSPPolicy::allows(nsContentPolicyType aContentType,
                     enum CSPKeyword aKeyword,
                     const nsAString& aHashOrNonce) const
 {
   CSPUTILSLOG(("nsCSPPolicy::allows, aKeyWord: %s, a HashOrNonce: %s",
               CSP_EnumToKeyword(aKeyword), NS_ConvertUTF16toUTF8(aHashOrNonce).get()));
 
   nsCSPDirective* defaultDir = nullptr;
@@ -970,20 +994,20 @@ nsCSPPolicy::getDirectiveStringForConten
     defaultDir->toString(outDirective);
     return;
   }
   NS_ASSERTION(false, "Can not query directive string for contentType!");
   outDirective.AppendASCII("couldNotQueryViolatedDirective");
 }
 
 void
-nsCSPPolicy::getDirectiveStringForBaseURI(nsAString& outDirective) const
+nsCSPPolicy::getDirectiveAsString(enum CSPDirective aDir, nsAString& outDirective) const
 {
   for (uint32_t i = 0; i < mDirectives.Length(); i++) {
-    if (mDirectives[i]->equals(CSP_BASE_URI)) {
+    if (mDirectives[i]->equals(aDir)) {
       mDirectives[i]->toString(outDirective);
       return;
     }
   }
 }
 
 void
 nsCSPPolicy::getReportURIs(nsTArray<nsString>& outReportURIs) const
--- a/dom/security/nsCSPUtils.h
+++ b/dom/security/nsCSPUtils.h
@@ -67,16 +67,17 @@ enum CSPDirective {
   CSP_MEDIA_SRC,
   CSP_FRAME_SRC,
   CSP_FONT_SRC,
   CSP_CONNECT_SRC,
   CSP_REPORT_URI,
   CSP_FRAME_ANCESTORS,
   CSP_REFLECTED_XSS,
   CSP_BASE_URI,
+  CSP_FORM_ACTION,
   // CSP_LAST_DIRECTIVE_VALUE always needs to be the last element in the enum
   // because we use it to calculate the size for the char* array.
   CSP_LAST_DIRECTIVE_VALUE
 };
 
 static const char* CSPStrDirectives[] = {
   "default-src",     // CSP_DEFAULT_SRC = 0
   "script-src",      // CSP_SCRIPT_SRC
@@ -85,17 +86,18 @@ static const char* CSPStrDirectives[] = 
   "img-src",         // CSP_IMG_SRC
   "media-src",       // CSP_MEDIA_SRC
   "frame-src",       // CSP_FRAME_SRC
   "font-src",        // CSP_FONT_SRC
   "connect-src",     // CSP_CONNECT_SRC
   "report-uri",      // CSP_REPORT_URI
   "frame-ancestors", // CSP_FRAME_ANCESTORS
   "reflected-xss",   // CSP_REFLECTED_XSS
-  "base-uri"         // CSP_BASE_URI
+  "base-uri",        // CSP_BASE_URI
+  "form-action"      // CSP_FORM_ACTION
 };
 
 inline const char* CSP_EnumToDirective(enum CSPDirective aDir)
 {
   // Make sure all elements in enum CSPDirective got added to CSPStrDirectives.
   static_assert((sizeof(CSPStrDirectives) / sizeof(CSPStrDirectives[0]) ==
                 static_cast<uint32_t>(CSP_LAST_DIRECTIVE_VALUE)),
                 "CSP_LAST_DIRECTIVE_VALUE does not match length of CSPStrDirectives");
@@ -328,16 +330,17 @@ class nsCSPPolicy {
     virtual ~nsCSPPolicy();
 
     bool permits(nsContentPolicyType aContentType,
                  nsIURI* aUri,
                  const nsAString& aNonce,
                  bool aWasRedirected,
                  nsAString& outViolatedDirective) const;
     bool permitsBaseURI(nsIURI* aUri) const;
+    bool permitsFormAction(nsIURI* aUri) const;
     bool allows(nsContentPolicyType aContentType,
                 enum CSPKeyword aKeyword,
                 const nsAString& aHashOrNonce) const;
     bool allows(nsContentPolicyType aContentType,
                 enum CSPKeyword aKeyword) const;
     void toString(nsAString& outStr) const;
 
     inline void addDirective(nsCSPDirective* aDir)
@@ -351,17 +354,17 @@ class nsCSPPolicy {
     inline bool getReportOnlyFlag() const
       { return mReportOnly; }
 
     void getReportURIs(nsTArray<nsString> &outReportURIs) const;
 
     void getDirectiveStringForContentType(nsContentPolicyType aContentType,
                                           nsAString& outDirective) const;
 
-    void getDirectiveStringForBaseURI(nsAString& outDirective) const;
+    void getDirectiveAsString(enum CSPDirective aDir, nsAString& outDirective) const;
 
     inline uint32_t getNumDirectives() const
       { return mDirectives.Length(); }
 
   private:
     nsTArray<nsCSPDirective*> mDirectives;
     bool                      mReportOnly;
 };
--- a/dom/xbl/nsXBLProtoImplMethod.cpp
+++ b/dom/xbl/nsXBLProtoImplMethod.cpp
@@ -290,16 +290,17 @@ nsXBLProtoImplAnonymousMethod::Execute(n
     do_QueryInterface(document->GetInnerWindow());
   if (!global) {
     return NS_OK;
   }
 
   // We are going to run script via JS::Call, so we need a script entry point,
   // but as this is XBL related it does not appear in the HTML spec.
   dom::AutoEntryScript aes(global);
+  aes.TakeOwnershipOfErrorReporting();
   JSContext* cx = aes.cx();
 
   JS::Rooted<JSObject*> globalObject(cx, global->GetGlobalJSObject());
 
   JS::Rooted<JSObject*> scopeObject(cx, xpc::GetScopeForXBLExecution(cx, globalObject, aAddonId));
   NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
 
   JSAutoCompartment ac(cx, scopeObject);
@@ -319,30 +320,22 @@ nsXBLProtoImplAnonymousMethod::Execute(n
     return NS_ERROR_OUT_OF_MEMORY;
 
   // Now call the method
 
   // Check whether script is enabled.
   bool scriptAllowed = nsContentUtils::GetSecurityManager()->
                          ScriptAllowed(js::GetGlobalForObjectCrossCompartment(method));
 
-  bool ok = true;
   if (scriptAllowed) {
     JS::Rooted<JS::Value> retval(cx);
     JS::Rooted<JS::Value> methodVal(cx, JS::ObjectValue(*method));
-    ok = ::JS::Call(cx, scopeChain[0], methodVal, JS::HandleValueArray::empty(), &retval);
-  }
-
-  if (!ok) {
-    // If a constructor or destructor threw an exception, it doesn't stop
-    // anything else.  We just report it.  Note that we need to set aside the
-    // frame chain here, since the constructor invocation is not related to
-    // whatever is on the stack right now, really.
-    nsJSUtils::ReportPendingException(cx);
-    return NS_ERROR_FAILURE;
+    // No need to check the return here as AutoEntryScript has taken ownership
+    // of error reporting.
+    ::JS::Call(cx, scopeChain[0], methodVal, JS::HandleValueArray::empty(), &retval);
   }
 
   return NS_OK;
 }
 
 nsresult
 nsXBLProtoImplAnonymousMethod::Write(nsIObjectOutputStream* aStream,
                                      XBLBindingSerializeDetails aType)
--- a/dom/xbl/nsXBLResourceLoader.cpp
+++ b/dom/xbl/nsXBLResourceLoader.cpp
@@ -115,17 +115,18 @@ nsXBLResourceLoader::LoadResources(bool*
         // We're not permitted to load this image, move on...
         continue;
       }
 
       // Now kick off the image load...
       // Passing nullptr for pretty much everything -- cause we don't care!
       // XXX: initialDocumentURI is nullptr! 
       nsRefPtr<imgRequestProxy> req;
-      nsContentUtils::LoadImage(url, doc, docPrincipal, docURL, nullptr,
+      nsContentUtils::LoadImage(url, doc, docPrincipal, docURL,
+                                doc->GetReferrerPolicy(), nullptr,
                                 nsIRequest::LOAD_BACKGROUND, EmptyString(),
                                 getter_AddRefs(req));
     }
     else if (curr->mType == nsGkAtoms::stylesheet) {
       // Kick off the load of the stylesheet.
 
       // Always load chrome synchronously
       // XXXbz should that still do a content policy check?
--- a/dom/xbl/test/mochitest.ini
+++ b/dom/xbl/test/mochitest.ini
@@ -37,8 +37,9 @@ skip-if = (buildapp == 'b2g' && toolkit 
 [test_bug639338.xhtml]
 [test_bug790265.xhtml]
 [test_bug821850.html]
 [test_bug844783.html]
 [test_bug872273.xhtml]
 [test_bug946815.html]
 skip-if = toolkit != "gonk"
 [test_bug1086996.xhtml]
+[test_bug1098628_throw_from_construct.xhtml]
new file mode 100644
--- /dev/null
+++ b/dom/xbl/test/test_bug1098628_throw_from_construct.xhtml
@@ -0,0 +1,41 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1098628
+-->
+<head>
+  <title>Test for Bug 1098628</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+  <bindings xmlns="http://www.mozilla.org/xbl">
+    <binding id="test">
+      <implementation>
+        <constructor><![CDATA[
+          throw "flimfniffle";
+        ]]></constructor>
+      </implementation>
+    </binding>
+  </bindings>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1098628">Mozilla Bug 1098628</a>
+<p id="display" style="-moz-binding: url(#test)"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+<![CDATA[
+
+/** Test for Bug 1098628 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.expectUncaughtException();
+SimpleTest.monitorConsole(SimpleTest.finish, [{errorMessage: new RegExp('flimfniffle')}]);
+addLoadEvent(function() {
+  SimpleTest.executeSoon(SimpleTest.endMonitorConsole);
+});
+]]>
+</script>
+</pre>
+</body>
+</html>
+
--- a/dom/xml/nsXMLPrettyPrinter.cpp
+++ b/dom/xml/nsXMLPrettyPrinter.cpp
@@ -97,17 +97,17 @@ nsXMLPrettyPrinter::PrettyPrint(nsIDocum
     // Load the XSLT
     nsCOMPtr<nsIURI> xslUri;
     rv = NS_NewURI(getter_AddRefs(xslUri),
                    NS_LITERAL_CSTRING("chrome://global/content/xml/XMLPrettyPrint.xsl"));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIDOMDocument> xslDocument;
     rv = nsSyncLoadService::LoadDocument(xslUri, nsContentUtils::GetSystemPrincipal(),
-                                         nullptr, true,
+                                         nullptr, true, mozilla::net::RP_Default,
                                          getter_AddRefs(xslDocument));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Transform the document
     nsCOMPtr<nsIXSLTProcessor> transformer =
         do_CreateInstance("@mozilla.org/document-transformer;1?type=xslt", &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/xslt/xml/txXMLParser.cpp
+++ b/dom/xslt/xml/txXMLParser.cpp
@@ -31,17 +31,19 @@ txParseDocumentFromURI(const nsAString& 
     // since that means that chrome documents can load any uri.
 
     // Raw pointer, we want the resulting txXPathNode to hold a reference to
     // the document.
     nsIDOMDocument* theDocument = nullptr;
     nsAutoSyncOperation sync(loaderDocument);
     rv = nsSyncLoadService::LoadDocument(documentURI,
                                          loaderDocument->NodePrincipal(),
-                                         loadGroup, true, &theDocument);
+                                         loadGroup, true,
+                                         loaderDocument->GetReferrerPolicy(),
+                                         &theDocument);
 
     if (NS_FAILED(rv)) {
         aErrMsg.AppendLiteral("Document load of ");
         aErrMsg.Append(aHref);
         aErrMsg.AppendLiteral(" failed.");
         return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
     }
 
--- a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
@@ -37,16 +37,17 @@
 #include "nsCrossSiteListenerProxy.h"
 #include "nsError.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/EncodingUtils.h"
 
 using namespace mozilla;
 using mozilla::dom::EncodingUtils;
+using mozilla::net::ReferrerPolicy;
 
 static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
 
 static void
 getSpec(nsIChannel* aChannel, nsAString& aSpec)
 {
     if (!aChannel) {
         return;
@@ -369,17 +370,18 @@ class txCompileObserver MOZ_FINAL : publ
 public:
     txCompileObserver(txMozillaXSLTProcessor* aProcessor,
                       nsIDocument* aLoaderDocument);
 
     TX_DECL_ACOMPILEOBSERVER
     NS_INLINE_DECL_REFCOUNTING(txCompileObserver)
 
     nsresult startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
-                       nsIPrincipal* aSourcePrincipal);
+                       nsIPrincipal* aSourcePrincipal,
+                       ReferrerPolicy aReferrerPolicy);
 
 private:
     nsRefPtr<txMozillaXSLTProcessor> mProcessor;
     nsCOMPtr<nsIDocument> mLoaderDocument;
 
     // This exists solely to suppress a warning from nsDerivedSafe
     txCompileObserver();
 
@@ -394,16 +396,17 @@ txCompileObserver::txCompileObserver(txM
     : mProcessor(aProcessor),
       mLoaderDocument(aLoaderDocument)
 {
 }
 
 nsresult
 txCompileObserver::loadURI(const nsAString& aUri,
                            const nsAString& aReferrerUri,
+                           ReferrerPolicy aReferrerPolicy,
                            txStylesheetCompiler* aCompiler)
 {
     if (mProcessor->IsLoadDisabled()) {
         return NS_ERROR_XSLT_LOAD_BLOCKED_ERROR;
     }
 
     nsCOMPtr<nsIURI> uri;
     nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
@@ -428,17 +431,17 @@ txCompileObserver::loadURI(const nsAStri
                                    NS_LITERAL_CSTRING("application/xml"),
                                    nullptr,
                                    &shouldLoad);
     NS_ENSURE_SUCCESS(rv, rv);
     if (NS_CP_REJECTED(shouldLoad)) {
         return NS_ERROR_DOM_BAD_URI;
     }
 
-    return startLoad(uri, aCompiler, referrerPrincipal);
+    return startLoad(uri, aCompiler, referrerPrincipal, aReferrerPolicy);
 }
 
 void
 txCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
                                    nsresult aResult,
                                    const char16_t *aErrorText,
                                    const char16_t *aParam)
 {
@@ -447,17 +450,18 @@ txCompileObserver::onDoneCompiling(txSty
     }
     else {
         mProcessor->reportError(aResult, aErrorText, aParam);
     }
 }
 
 nsresult
 txCompileObserver::startLoad(nsIURI* aUri, txStylesheetCompiler* aCompiler,
-                             nsIPrincipal* aReferrerPrincipal)
+                             nsIPrincipal* aReferrerPrincipal,
+                             ReferrerPolicy aReferrerPolicy)
 {
     nsCOMPtr<nsILoadGroup> loadGroup = mLoaderDocument->GetDocumentLoadGroup();
     if (!loadGroup) {
         return NS_ERROR_FAILURE;
     }
 
     nsCOMPtr<nsIChannel> channel;
     nsresult rv = NS_NewChannelWithTriggeringPrincipal(
@@ -477,17 +481,17 @@ txCompileObserver::startLoad(nsIURI* aUr
     if (httpChannel) {
         httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                       NS_LITERAL_CSTRING("*/*"),
                                       false);
 
         nsCOMPtr<nsIURI> referrerURI;
         aReferrerPrincipal->GetURI(getter_AddRefs(referrerURI));
         if (referrerURI) {
-            httpChannel->SetReferrer(referrerURI);
+            httpChannel->SetReferrerWithPolicy(referrerURI, aReferrerPolicy);
         }
     }
 
     nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsRefPtr<txStylesheetSink> sink = new txStylesheetSink(aCompiler, parser);
     NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY);
@@ -504,17 +508,17 @@ txCompileObserver::startLoad(nsIURI* aUr
     rv = listener->Init(channel);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return channel->AsyncOpen(listener, parser);
 }
 
 nsresult
 TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
-             nsIDocument* aLoaderDocument)
+             nsIDocument* aLoaderDocument, ReferrerPolicy aReferrerPolicy)
 {
     nsIPrincipal* principal = aLoaderDocument->NodePrincipal();
 
     nsAutoCString spec;
     aUri->GetSpec(spec);
     PR_LOG(txLog::xslt, PR_LOG_ALWAYS, ("TX_LoadSheet: %s\n", spec.get()));
 
     // Content Policy
@@ -532,20 +536,21 @@ TX_LoadSheet(nsIURI* aUri, txMozillaXSLT
         return NS_ERROR_DOM_BAD_URI;
     }
 
     nsRefPtr<txCompileObserver> observer =
         new txCompileObserver(aProcessor, aLoaderDocument);
     NS_ENSURE_TRUE(observer, NS_ERROR_OUT_OF_MEMORY);
 
     nsRefPtr<txStylesheetCompiler> compiler =
-        new txStylesheetCompiler(NS_ConvertUTF8toUTF16(spec), observer);
+        new txStylesheetCompiler(NS_ConvertUTF8toUTF16(spec), aReferrerPolicy,
+                                 observer);
     NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
 
-    return observer->startLoad(aUri, compiler, principal);
+    return observer->startLoad(aUri, compiler, principal, aReferrerPolicy);
 }
 
 /**
  * handling DOM->txStylesheet
  * Observer needs to do synchronous loads.
  */
 static nsresult
 handleNode(nsINode* aNode, txStylesheetCompiler* aCompiler)
@@ -633,16 +638,17 @@ private:
 txSyncCompileObserver::txSyncCompileObserver(txMozillaXSLTProcessor* aProcessor)
   : mProcessor(aProcessor)
 {
 }
 
 nsresult
 txSyncCompileObserver::loadURI(const nsAString& aUri,
                                const nsAString& aReferrerUri,
+                               ReferrerPolicy aReferrerPolicy,
                                txStylesheetCompiler* aCompiler)
 {
     if (mProcessor->IsLoadDisabled()) {
         return NS_ERROR_XSLT_LOAD_BLOCKED_ERROR;
     }
 
     nsCOMPtr<nsIURI> uri;
     nsresult rv = NS_NewURI(getter_AddRefs(uri), aUri);
@@ -677,17 +683,18 @@ txSyncCompileObserver::loadURI(const nsA
     nsCOMPtr<nsINode> source;
     if (mProcessor) {
       source =
         do_QueryInterface(mProcessor->GetSourceContentModel());
     }
     nsAutoSyncOperation sync(source ? source->OwnerDoc() : nullptr);
     nsCOMPtr<nsIDOMDocument> document;
     rv = nsSyncLoadService::LoadDocument(uri, referrerPrincipal, nullptr,
-                                         false, getter_AddRefs(document));
+                                         false, aReferrerPolicy,
+                                         getter_AddRefs(document));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
     rv = handleNode(doc, aCompiler);
     if (NS_FAILED(rv)) {
         nsAutoCString spec;
         uri->GetSpec(spec);
         aCompiler->cancel(rv, nullptr, NS_ConvertUTF8toUTF16(spec).get());
@@ -737,17 +744,17 @@ TX_CompileStylesheet(nsINode* aNode, txM
     uri->GetSpec(spec);
     NS_ConvertUTF8toUTF16 stylesheetURI(spec);
 
     nsRefPtr<txSyncCompileObserver> obs =
         new txSyncCompileObserver(aProcessor);
     NS_ENSURE_TRUE(obs, NS_ERROR_OUT_OF_MEMORY);
 
     nsRefPtr<txStylesheetCompiler> compiler =
-        new txStylesheetCompiler(stylesheetURI, obs);
+        new txStylesheetCompiler(stylesheetURI, doc->GetReferrerPolicy(), obs);
     NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
 
     compiler->setBaseURI(baseURI);
 
     nsresult rv = handleNode(aNode, compiler);
     if (NS_FAILED(rv)) {
         compiler->cancel(rv);
         return rv;
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp
@@ -1035,17 +1035,22 @@ txMozillaXSLTProcessor::GetFlags(uint32_
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 txMozillaXSLTProcessor::LoadStyleSheet(nsIURI* aUri,
                                        nsIDocument* aLoaderDocument)
 {
-    nsresult rv = TX_LoadSheet(aUri, this, aLoaderDocument);
+    mozilla::net::ReferrerPolicy refpol = mozilla::net::RP_Default;
+    if (mStylesheetDocument) {
+        refpol = mStylesheetDocument->GetReferrerPolicy();
+    }
+
+    nsresult rv = TX_LoadSheet(aUri, this, aLoaderDocument, refpol);
     if (NS_FAILED(rv) && mObserver) {
         // This is most likely a network or security error, just
         // use the uri as context.
         nsAutoCString spec;
         aUri->GetSpec(spec);
         CopyUTF8toUTF16(spec, mSourceText);
         nsresult status = NS_ERROR_GET_MODULE(rv) == NS_ERROR_MODULE_XSLT ? rv :
                           NS_ERROR_XSLT_NETWORK_ERROR;
--- a/dom/xslt/xslt/txMozillaXSLTProcessor.h
+++ b/dom/xslt/xslt/txMozillaXSLTProcessor.h
@@ -12,16 +12,17 @@
 #include "nsIXSLTProcessor.h"
 #include "nsIXSLTProcessorPrivate.h"
 #include "txExpandedNameMap.h"
 #include "txNamespaceMap.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsWrapperCache.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ErrorResult.h"
+#include "mozilla/net/ReferrerPolicy.h"
 
 class nsINode;
 class nsIDOMNode;
 class nsIURI;
 class nsIXMLContentSink;
 class txStylesheet;
 class txResultRecycler;
 class txIGlobalParameter;
@@ -180,15 +181,16 @@ private:
     txOwningExpandedNameMap<txIGlobalParameter> mVariables;
     txNamespaceMap mParamNamespaceMap;
     nsRefPtr<txResultRecycler> mRecycler;
 
     uint32_t mFlags;
 };
 
 extern nsresult TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
-                             nsIDocument* aLoaderDocument);
+                             nsIDocument* aLoaderDocument,
+                             mozilla::net::ReferrerPolicy aReferrerPolicy);
 
 extern nsresult TX_CompileStylesheet(nsINode* aNode,
                                      txMozillaXSLTProcessor* aProcessor,
                                      txStylesheet** aStylesheet);
 
 #endif
--- a/dom/xslt/xslt/txStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txStylesheetCompiler.cpp
@@ -19,31 +19,35 @@
 #include "txPatternParser.h"
 #include "txStringUtils.h"
 #include "txXSLTFunctions.h"
 #include "nsICategoryManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsTArray.h"
 
 using namespace mozilla;
+using mozilla::net::ReferrerPolicy;
 
 txStylesheetCompiler::txStylesheetCompiler(const nsAString& aStylesheetURI,
+                                           ReferrerPolicy aReferrerPolicy,
                                            txACompileObserver* aObserver)
     : txStylesheetCompilerState(aObserver)
 {
-    mStatus = init(aStylesheetURI, nullptr, nullptr);
+    mStatus = init(aStylesheetURI, aReferrerPolicy, nullptr, nullptr);
 }
 
 txStylesheetCompiler::txStylesheetCompiler(const nsAString& aStylesheetURI,
                                            txStylesheet* aStylesheet,
                                            txListIterator* aInsertPosition,
+                                           ReferrerPolicy aReferrerPolicy,
                                            txACompileObserver* aObserver)
     : txStylesheetCompilerState(aObserver)
 {
-    mStatus = init(aStylesheetURI, aStylesheet, aInsertPosition);
+    mStatus = init(aStylesheetURI, aReferrerPolicy, aStylesheet,
+                   aInsertPosition);
 }
 
 void
 txStylesheetCompiler::setBaseURI(const nsString& aBaseURI)
 {
     NS_ASSERTION(mObjectStack.size() == 1 && !mObjectStack.peek(),
                  "Execution already started");
 
@@ -410,27 +414,29 @@ txStylesheet*
 txStylesheetCompiler::getStylesheet()
 {
     return mStylesheet;
 }
 
 nsresult
 txStylesheetCompiler::loadURI(const nsAString& aUri,
                               const nsAString& aReferrerUri,
+                              ReferrerPolicy aReferrerPolicy,
                               txStylesheetCompiler* aCompiler)
 {
     PR_LOG(txLog::xslt, PR_LOG_ALWAYS,
            ("Compiler::loadURI forwards %s thru %s\n",
             NS_LossyConvertUTF16toASCII(aUri).get(),
             NS_LossyConvertUTF16toASCII(mStylesheetURI).get()));
     if (mStylesheetURI.Equals(aUri)) {
         return NS_ERROR_XSLT_LOAD_RECURSION;
     }
-    return mObserver ? mObserver->loadURI(aUri, aReferrerUri, aCompiler) :
-                       NS_ERROR_FAILURE;
+    return mObserver ?
+        mObserver->loadURI(aUri, aReferrerUri, aReferrerPolicy, aCompiler) :
+        NS_ERROR_FAILURE;
 }
 
 void
 txStylesheetCompiler::onDoneCompiling(txStylesheetCompiler* aCompiler,
                                       nsresult aResult,
                                       const char16_t *aErrorText,
                                       const char16_t *aParam)
 {
@@ -531,22 +537,24 @@ txStylesheetCompilerState::txStylesheetC
     // Embedded stylesheets have another handler, which is set in
     // txStylesheetCompiler::init if the baseURI has a fragment identifier.
     mHandlerTable = gTxRootHandler;
 
 }
 
 nsresult
 txStylesheetCompilerState::init(const nsAString& aStylesheetURI,
+                                ReferrerPolicy aReferrerPolicy,
                                 txStylesheet* aStylesheet,
                                 txListIterator* aInsertPosition)
 {
     NS_ASSERTION(!aStylesheet || aInsertPosition,
                  "must provide insertposition if loading subsheet");
     mStylesheetURI = aStylesheetURI;
+    mReferrerPolicy = aReferrerPolicy;
     // Check for fragment identifier of an embedded stylesheet.
     int32_t fragment = aStylesheetURI.FindChar('#') + 1;
     if (fragment > 0) {
         int32_t fragmentLength = aStylesheetURI.Length() - fragment;
         if (fragmentLength > 0) {
             // This is really an embedded stylesheet, not just a
             // "url#". We may want to unescape the fragment.
             mTarget = Substring(aStylesheetURI, (uint32_t)fragment,
@@ -760,27 +768,27 @@ txStylesheetCompilerState::loadIncludedS
 
     // step back to the dummy-item
     mToplevelIterator.previous();
     
     txACompileObserver* observer = static_cast<txStylesheetCompiler*>(this);
 
     nsRefPtr<txStylesheetCompiler> compiler =
         new txStylesheetCompiler(aURI, mStylesheet, &mToplevelIterator,
-                                 observer);
+                                 mReferrerPolicy, observer);
     NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
 
     // step forward before calling the observer in case of syncronous loading
     mToplevelIterator.next();
 
     if (mChildCompilerList.AppendElement(compiler) == nullptr) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    rv = mObserver->loadURI(aURI, mStylesheetURI, compiler);
+    rv = mObserver->loadURI(aURI, mStylesheetURI, mReferrerPolicy, compiler);
     if (NS_FAILED(rv)) {
         mChildCompilerList.RemoveElement(compiler);
     }
 
     return rv;
 }
 
 nsresult
@@ -796,24 +804,26 @@ txStylesheetCompilerState::loadImportedS
     NS_ENSURE_TRUE(mObserver, NS_ERROR_NOT_IMPLEMENTED);
 
     txListIterator iter(&aFrame->mToplevelItems);
     iter.next(); // go to the end of the list
 
     txACompileObserver* observer = static_cast<txStylesheetCompiler*>(this);
 
     nsRefPtr<txStylesheetCompiler> compiler =
-        new txStylesheetCompiler(aURI, mStylesheet, &iter, observer);
+        new txStylesheetCompiler(aURI, mStylesheet, &iter, mReferrerPolicy,
+                                 observer);
     NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
 
     if (mChildCompilerList.AppendElement(compiler) == nullptr) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    nsresult rv = mObserver->loadURI(aURI, mStylesheetURI, compiler);
+    nsresult rv = mObserver->loadURI(aURI, mStylesheetURI, mReferrerPolicy,
+                                     compiler);
     if (NS_FAILED(rv)) {
         mChildCompilerList.RemoveElement(compiler);
     }
 
     return rv;  
 }
 
 nsresult
@@ -1065,17 +1075,18 @@ findFunction(nsIAtom* aName, int32_t aNa
     return TX_ResolveFunctionCallXPCOM(map->mContractID, aNamespaceID, aName,
                                        nullptr, aResult);
 }
 
 extern bool
 TX_XSLTFunctionAvailable(nsIAtom* aName, int32_t aNameSpaceID)
 {
     nsRefPtr<txStylesheetCompiler> compiler =
-        new txStylesheetCompiler(EmptyString(), nullptr);
+        new txStylesheetCompiler(EmptyString(),
+                                 mozilla::net::RP_Default, nullptr);
     NS_ENSURE_TRUE(compiler, false);
 
     nsAutoPtr<FunctionCall> fnCall;
 
     return NS_SUCCEEDED(findFunction(aName, aNameSpaceID, compiler,
                                      getter_Transfers(fnCall)));
 }
 
--- a/dom/xslt/xslt/txStylesheetCompiler.h
+++ b/dom/xslt/xslt/txStylesheetCompiler.h
@@ -9,16 +9,17 @@
 #include "mozilla/Attributes.h"
 #include "txStack.h"
 #include "txXSLTPatterns.h"
 #include "txExpr.h"
 #include "txIXPathContext.h"
 #include "nsAutoPtr.h"
 #include "txStylesheet.h"
 #include "nsTArray.h"
+#include "mozilla/net/ReferrerPolicy.h"
 
 extern bool
 TX_XSLTFunctionAvailable(nsIAtom* aName, int32_t aNameSpaceID);
 
 class txHandlerTable;
 class txElementContext;
 class txInstructionContainer;
 class txInstruction;
@@ -45,38 +46,41 @@ public:
 class txACompileObserver
 {
 public:
     NS_IMETHOD_(MozExternalRefCountType) AddRef() = 0;
     NS_IMETHOD_(MozExternalRefCountType) Release() = 0;
 
     virtual nsresult loadURI(const nsAString& aUri,
                              const nsAString& aReferrerUri,
+                             mozilla::net::ReferrerPolicy aReferrerPolicy,
                              txStylesheetCompiler* aCompiler) = 0;
     virtual void onDoneCompiling(txStylesheetCompiler* aCompiler,
                                  nsresult aResult,
                                  const char16_t *aErrorText = nullptr,
                                  const char16_t *aParam = nullptr) = 0;
 };
 
 #define TX_DECL_ACOMPILEOBSERVER \
   nsresult loadURI(const nsAString& aUri, const nsAString& aReferrerUri, \
+                   mozilla::net::ReferrerPolicy aReferrerPolicy, \
                    txStylesheetCompiler* aCompiler); \
   void onDoneCompiling(txStylesheetCompiler* aCompiler, nsresult aResult, \
                        const char16_t *aErrorText = nullptr, \
                        const char16_t *aParam = nullptr);
 
 class txStylesheetCompilerState : public txIParseContext
 {
 public:
     explicit txStylesheetCompilerState(txACompileObserver* aObserver);
     ~txStylesheetCompilerState();
     
-    nsresult init(const nsAString& aStylesheetURI, txStylesheet* aStylesheet,
-                  txListIterator* aInsertPosition);
+    nsresult init(const nsAString& aStylesheetURI,
+                  mozilla::net::ReferrerPolicy aReferrerPolicy,
+                  txStylesheet* aStylesheet, txListIterator* aInsertPosition);
 
     // Embedded stylesheets state
     bool handleEmbeddedSheet()
     {
         return mEmbedStatus == eInEmbed;
     }
     void doneEmbedding()
     {
@@ -166,16 +170,17 @@ protected:
     txStack mObjectStack;
     txStack mOtherStack;
     nsTArray<enumStackType> mTypeStack;
 
 private:
     txInstruction** mNextInstrPtr;
     txListIterator mToplevelIterator;
     nsTArray<txInstruction**> mGotoTargetPointers;
+    mozilla::net::ReferrerPolicy mReferrerPolicy;
 };
 
 struct txStylesheetAttr
 {
     int32_t mNamespaceID;
     nsCOMPtr<nsIAtom> mLocalName;
     nsCOMPtr<nsIAtom> mPrefix;
     nsString mValue;
@@ -184,20 +189,22 @@ struct txStylesheetAttr
 class txStylesheetCompiler MOZ_FINAL : private txStylesheetCompilerState,
                                        public txACompileObserver
 {
 public:
     friend class txStylesheetCompilerState;
     friend bool TX_XSLTFunctionAvailable(nsIAtom* aName,
                                            int32_t aNameSpaceID);
     txStylesheetCompiler(const nsAString& aStylesheetURI,
+                         mozilla::net::ReferrerPolicy  aReferrerPolicy,
                          txACompileObserver* aObserver);
     txStylesheetCompiler(const nsAString& aStylesheetURI,
                          txStylesheet* aStylesheet,
                          txListIterator* aInsertPosition,
+                         mozilla::net::ReferrerPolicy aReferrerPolicy,
                          txACompileObserver* aObserver);
 
     void setBaseURI(const nsString& aBaseURI);
 
     nsresult startElement(int32_t aNamespaceID, nsIAtom* aLocalName,
                           nsIAtom* aPrefix, txStylesheetAttr* aAttributes,
                           int32_t aAttrCount);
     nsresult startElement(const char16_t *aName,
--- a/embedding/browser/nsContextMenuInfo.cpp
+++ b/embedding/browser/nsContextMenuInfo.cpp
@@ -289,17 +289,18 @@ nsContextMenuInfo::GetBackgroundImageReq
         if (!bgStringValue.EqualsLiteral("none")) {
           nsCOMPtr<nsIURI> bgUri;
           NS_NewURI(getter_AddRefs(bgUri), bgStringValue);
           NS_ENSURE_TRUE(bgUri, NS_ERROR_FAILURE);
 
           nsRefPtr<imgLoader> il = imgLoader::GetInstance();
           NS_ENSURE_TRUE(il, NS_ERROR_FAILURE);
 
-          return il->LoadImage(bgUri, nullptr, nullptr, principal, nullptr,
+          return il->LoadImage(bgUri, nullptr, nullptr,
+                               doc->GetReferrerPolicy(), principal, nullptr,
                                nullptr, nullptr, nsIRequest::LOAD_NORMAL,
                                nullptr, nsIContentPolicy::TYPE_IMAGE,
                                EmptyString(), aRequest);
         }
       }
 
       // bail if we encounter non-transparent background-color
       computedStyle->GetPropertyCSSValue(NS_LITERAL_STRING("background-color"),
--- a/embedding/browser/nsWebBrowser.cpp
+++ b/embedding/browser/nsWebBrowser.cpp
@@ -942,30 +942,35 @@ NS_IMETHODIMP nsWebBrowser::GetProgressL
 }
   
 NS_IMETHODIMP nsWebBrowser::SetProgressListener(nsIWebProgressListener * aProgressListener)
 {
     mProgressListener = aProgressListener;
     return NS_OK;
 }
 
-/* void saveURI (in nsIURI aURI, in nsIURI aReferrer,
+/* void saveURI (in nsIURI aURI, in nsIURI aReferrer, in unsigned long aReferrerPolicy
    in nsISupports aCacheKey, in nsIInputStream aPostData, in wstring aExtraHeaders,
    in nsISupports aFile, in nsILoadContext aPrivacyContext); */
 NS_IMETHODIMP nsWebBrowser::SaveURI(
-    nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer, nsIInputStream *aPostData,
-    const char *aExtraHeaders, nsISupports *aFile, nsILoadContext* aPrivacyContext)
+    nsIURI *aURI, nsISupports *aCacheKey,
+    nsIURI *aReferrer, uint32_t aReferrerPolicy,
+    nsIInputStream *aPostData, const char *aExtraHeaders,
+    nsISupports *aFile, nsILoadContext* aPrivacyContext)
 {
-    return SavePrivacyAwareURI(aURI, aCacheKey, aReferrer, aPostData, aExtraHeaders,
+    return SavePrivacyAwareURI(aURI, aCacheKey, aReferrer, aReferrerPolicy,
+                               aPostData, aExtraHeaders,
                                aFile, aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
 }
 
 NS_IMETHODIMP nsWebBrowser::SavePrivacyAwareURI(
-    nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer, nsIInputStream *aPostData,
-    const char *aExtraHeaders, nsISupports *aFile, bool aIsPrivate)
+    nsIURI *aURI, nsISupports *aCacheKey,
+    nsIURI *aReferrer, uint32_t aReferrerPolicy,
+    nsIInputStream *aPostData, const char *aExtraHeaders,
+    nsISupports *aFile, bool aIsPrivate)
 {
     if (mPersist)
     {
         uint32_t currentState;
         mPersist->GetCurrentState(&currentState);
         if (currentState == PERSIST_STATE_FINISHED)
         {
             mPersist = nullptr;
@@ -993,18 +998,19 @@ NS_IMETHODIMP nsWebBrowser::SavePrivacyA
 
     // Create a throwaway persistence object to do the work
     nsresult rv;
     mPersist = do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     mPersist->SetProgressListener(this);
     mPersist->SetPersistFlags(mPersistFlags);
     mPersist->GetCurrentState(&mPersistCurrentState);
-    rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aPostData,
-                                       aExtraHeaders, aFile, aIsPrivate);
+
+    rv = mPersist->SavePrivacyAwareURI(uri, aCacheKey, aReferrer, aReferrerPolicy,
+                                       aPostData, aExtraHeaders, aFile, aIsPrivate);
     if (NS_FAILED(rv))
     {
         mPersist = nullptr;
     }
     return rv;
 }
 
 /* void saveChannel (in nsIChannel aChannel, in nsISupports aFile); */
--- a/embedding/components/webbrowserpersist/nsIWebBrowserPersist.idl
+++ b/embedding/components/webbrowserpersist/nsIWebBrowserPersist.idl
@@ -118,16 +118,20 @@ interface nsIWebBrowserPersist : nsICanc
    *                   may also support <CODE>nullptr</CODE> to imply the currently
    *                   loaded URI.
    * @param aCacheKey  An object representing the URI in the cache or
    *                   <CODE>nullptr</CODE>.  This can be a necko cache key,
    *                   an nsIWebPageDescriptor, or the currentDescriptor of an
    *                   nsIWebPageDescriptor.
    * @param aReferrer  The referrer URI to pass with an HTTP request or
    *                   <CODE>nullptr</CODE>.
+   * @param aReferrerPolicy  The referrer policy for when and what to send via
+   *                   HTTP Referer header.  Ignored if aReferrer is
+   *                   <CODE>nullptr</CODE>.  Taken from REFERRER_POLICY
+   *                   constants in nsIHttpChannel.
    * @param aPostData  Post data to pass with an HTTP request or
    *                   <CODE>nullptr</CODE>.
    * @param aExtraHeaders Additional headers to supply with an HTTP request
    *                   or <CODE>nullptr</CODE>.
    * @param aFile      Target file. This may be a nsIFile object or an
    *                   nsIURI object with a file scheme or a scheme that
    *                   supports uploading (e.g. ftp).
    * @param aPrivacyContext A context from which the privacy status of this
@@ -138,28 +142,30 @@ interface nsIWebBrowserPersist : nsICanc
    *
    * @see nsIFile
    * @see nsIURI
    * @see nsIInputStream
    *
    * @throws NS_ERROR_INVALID_ARG One or more arguments was invalid.
    */
   void saveURI(in nsIURI aURI, in nsISupports aCacheKey,
-      in nsIURI aReferrer, in nsIInputStream aPostData,
+      in nsIURI aReferrer, in unsigned long aReferrerPolicy,
+      in nsIInputStream aPostData,
       in string aExtraHeaders, in nsISupports aFile,
       in nsILoadContext aPrivacyContext);
 
   /**
    * @param aIsPrivate Treat the save operation as private (ie. with
    *                   regards to networking operations and persistence
    *                   of intermediate data, etc.)
    * @see saveURI for all other parameter descriptions
    */
   void savePrivacyAwareURI(in nsIURI aURI, in nsISupports aCacheKey,
-      in nsIURI aReferrer, in nsIInputStream aPostData,
+      in nsIURI aReferrer, in unsigned long aReferrerPolicy,
+      in nsIInputStream aPostData,
       in string aExtraHeaders, in nsISupports aFile,
       in boolean aIsPrivate);
 
   /**
    * Save a channel to a file. It must not be opened yet.
    * @see saveURI
    */
   void saveChannel(in nsIChannel aChannel, in nsISupports aFile);
--- a/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -327,36 +327,44 @@ NS_IMETHODIMP nsWebBrowserPersist::SetPr
     mEventSink = do_GetInterface(aProgressListener);
     return NS_OK;
 }
 
 /* void saveURI (in nsIURI aURI, in nsISupports aCacheKey, in nsIURI aReferrer,
    in nsIInputStream aPostData, in wstring aExtraHeaders,
    in nsISupports aFile, in nsILoadContext aPrivayContext); */
 NS_IMETHODIMP nsWebBrowserPersist::SaveURI(
-    nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer, nsIInputStream *aPostData, const char *aExtraHeaders, nsISupports *aFile, nsILoadContext* aPrivacyContext)
+    nsIURI *aURI, nsISupports *aCacheKey,
+    nsIURI *aReferrer, uint32_t aReferrerPolicy,
+    nsIInputStream *aPostData, const char *aExtraHeaders,
+    nsISupports *aFile, nsILoadContext* aPrivacyContext)
 {
-    return SavePrivacyAwareURI(aURI, aCacheKey, aReferrer, aPostData, aExtraHeaders, aFile,
+    return SavePrivacyAwareURI(aURI, aCacheKey, aReferrer, aReferrerPolicy,
+                               aPostData, aExtraHeaders, aFile,
                                aPrivacyContext && aPrivacyContext->UsePrivateBrowsing());
 }
 
 NS_IMETHODIMP nsWebBrowserPersist::SavePrivacyAwareURI(
-    nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer, nsIInputStream *aPostData, const char *aExtraHeaders, nsISupports *aFile, bool aIsPrivate)
+    nsIURI *aURI, nsISupports *aCacheKey,
+    nsIURI *aReferrer, uint32_t aReferrerPolicy,
+    nsIInputStream *aPostData, const char *aExtraHeaders, 
+    nsISupports *aFile, bool aIsPrivate)
 {
     NS_ENSURE_TRUE(mFirstAndOnlyUse, NS_ERROR_FAILURE);
     mFirstAndOnlyUse = false; // Stop people from reusing this object!
 
     nsCOMPtr<nsIURI> fileAsURI;
     nsresult rv;
     rv = GetValidURIFromObject(aFile, getter_AddRefs(fileAsURI));
     NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
 
     // SaveURI doesn't like broken uris.
     mPersistFlags |= PERSIST_FLAGS_FAIL_ON_BROKEN_LINKS;
-    rv = SaveURIInternal(aURI, aCacheKey, aReferrer, aPostData, aExtraHeaders, fileAsURI, false, aIsPrivate);
+    rv = SaveURIInternal(aURI, aCacheKey, aReferrer, aReferrerPolicy,
+                         aPostData, aExtraHeaders, fileAsURI, false, aIsPrivate);
     return NS_FAILED(rv) ? rv : NS_OK;
 }
 
 /* void saveChannel (in nsIChannel aChannel, in nsISupports aFile); */
 NS_IMETHODIMP nsWebBrowserPersist::SaveChannel(
     nsIChannel *aChannel, nsISupports *aFile)
 {
     NS_ENSURE_TRUE(mFirstAndOnlyUse, NS_ERROR_FAILURE);
@@ -1143,18 +1151,19 @@ nsresult nsWebBrowserPersist::AppendPath
     AppendUTF16toUTF8(aPath, newPath);
     aURI->SetPath(newPath);
 
     return NS_OK;
 }
 
 nsresult nsWebBrowserPersist::SaveURIInternal(
     nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer,
-    nsIInputStream *aPostData, const char *aExtraHeaders,
-    nsIURI *aFile, bool aCalcFileExt, bool aIsPrivate)
+    uint32_t aReferrerPolicy, nsIInputStream *aPostData,
+    const char *aExtraHeaders, nsIURI *aFile,
+    bool aCalcFileExt, bool aIsPrivate)
 {
     NS_ENSURE_ARG_POINTER(aURI);
     NS_ENSURE_ARG_POINTER(aFile);
 
     nsresult rv = NS_OK;
 
     mURI = aURI;
 
@@ -1241,17 +1250,17 @@ nsresult nsWebBrowserPersist::SaveURIInt
 
     // Set the referrer, post data and headers if any
     nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(inputChannel));
     if (httpChannel)
     {
         // Referrer
         if (aReferrer)
         {
-            httpChannel->SetReferrer(aReferrer);
+            httpChannel->SetReferrerWithPolicy(aReferrer, aReferrerPolicy);
         }
 
         // Post data
         if (aPostData)
         {
             nsCOMPtr<nsISeekableStream> stream(do_QueryInterface(aPostData));
             if (stream)
             {
@@ -2467,18 +2476,19 @@ nsWebBrowserPersist::EnumPersistURIs(con
 
     // Make a URI to save the data to
     nsCOMPtr<nsIURI> fileAsURI;
     rv = aData->mDataPath->Clone(getter_AddRefs(fileAsURI));
     NS_ENSURE_SUCCESS(rv, PL_DHASH_STOP);
     rv = pthis->AppendPathToURI(fileAsURI, aData->mFilename);
     NS_ENSURE_SUCCESS(rv, PL_DHASH_STOP);
 
-    rv = pthis->SaveURIInternal(uri, nullptr, nullptr, nullptr, nullptr, fileAsURI, true,
-                                pthis->mIsPrivate);
+    // The Referrer Policy doesn't matter here since the referrer is nullptr.
+    rv = pthis->SaveURIInternal(uri, nullptr, nullptr, mozilla::net::RP_Default,
+                                nullptr, nullptr, fileAsURI, true, pthis->mIsPrivate);
     // if SaveURIInternal fails, then it will have called EndDownload,
     // which means that |aData| is no longer valid memory.  we MUST bail.
     NS_ENSURE_SUCCESS(rv, PL_DHASH_STOP);
 
     if (rv == NS_OK)
     {
         // Store the actual object because once it's persisted this
         // will be fixed up with the right file extension.
--- a/embedding/components/webbrowserpersist/nsWebBrowserPersist.h
+++ b/embedding/components/webbrowserpersist/nsWebBrowserPersist.h
@@ -60,17 +60,18 @@ public:
 
 // Protected members
 protected:
     virtual ~nsWebBrowserPersist();
     nsresult CloneNodeWithFixedUpAttributes(
         nsIDOMNode *aNodeIn, bool *aSerializeCloneKids, nsIDOMNode **aNodeOut);
     nsresult SaveURIInternal(
         nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer,
-        nsIInputStream *aPostData, const char *aExtraHeaders, nsIURI *aFile,
+        uint32_t aReferrerPolicy, nsIInputStream *aPostData,
+        const char *aExtraHeaders, nsIURI *aFile,
         bool aCalcFileExt, bool aIsPrivate);
     nsresult SaveChannelInternal(
         nsIChannel *aChannel, nsIURI *aFile, bool aCalcFileExt);
     nsresult SaveDocumentInternal(
         nsIDOMDocument *aDocument, nsIURI *aFile, nsIURI *aDataPath);
     nsresult SaveDocuments();
     nsresult GetDocEncoderContentType(
         nsIDOMDocument *aDocument, const char16_t *aContentType,
--- a/embedding/components/windowwatcher/nsWindowWatcher.cpp
+++ b/embedding/components/windowwatcher/nsWindowWatcher.cpp
@@ -903,16 +903,17 @@ nsWindowWatcher::OpenWindowInternal(nsID
          it has no better answer, and we only care about a real document.
          Also using GetDocument to force document creation seems to
          screw up focus in the hidden window; see bug 36016.
       */
       nsCOMPtr<nsIDocument> doc = referrerWindow->GetExtantDoc();
       if (doc) {
         // Set the referrer
         loadInfo->SetReferrer(doc->GetDocumentURI());
+        loadInfo->SetReferrerPolicy(doc->GetReferrerPolicy());
       }
     }
   }
 
   if (isNewToplevelWindow) {
     // Notify observers that the window is open and ready.
     // The window has not yet started to load a document.
     nsCOMPtr<nsIObserverService> obsSvc =
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -71,16 +71,25 @@ BasicCompositor::BasicCompositor(nsIWidg
   SetBackend(LayersBackend::LAYERS_BASIC);
 }
 
 BasicCompositor::~BasicCompositor()
 {
   MOZ_COUNT_DTOR(BasicCompositor);
 }
 
+void
+BasicCompositingRenderTarget::BindRenderTarget()
+{
+  if (mClearOnBind) {
+    mDrawTarget->ClearRect(Rect(0, 0, mSize.width, mSize.height));
+    mClearOnBind = false;
+  }
+}
+
 void BasicCompositor::Destroy()
 {
   mWidget->CleanupRemoteDrawing();
   mWidget = nullptr;
 }
 
 TemporaryRef<CompositingRenderTarget>
 BasicCompositor::CreateRenderTarget(const IntRect& aRect, SurfaceInitMode aInit)
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -22,16 +22,18 @@ public:
   BasicCompositingRenderTarget(gfx::DrawTarget* aDrawTarget, const gfx::IntRect& aRect)
     : CompositingRenderTarget(aRect.TopLeft())
     , mDrawTarget(aDrawTarget)
     , mSize(aRect.Size())
   { }
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
 
+  void BindRenderTarget();
+
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
   {
     return mDrawTarget ? mDrawTarget->GetFormat()
                        : gfx::SurfaceFormat(gfx::SurfaceFormat::UNKNOWN);
   }
 
   RefPtr<gfx::DrawTarget> mDrawTarget;
   gfx::IntSize mSize;
@@ -68,16 +70,17 @@ public:
   virtual TemporaryRef<DataTextureSource>
   CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) MOZ_OVERRIDE;
 
   virtual bool SupportsEffect(EffectTypes aEffect) MOZ_OVERRIDE;
 
   virtual void SetRenderTarget(CompositingRenderTarget *aSource) MOZ_OVERRIDE
   {
     mRenderTarget = static_cast<BasicCompositingRenderTarget*>(aSource);
+    mRenderTarget->BindRenderTarget();
   }
   virtual CompositingRenderTarget* GetCurrentRenderTarget() const MOZ_OVERRIDE
   {
     return mRenderTarget;
   }
 
   virtual void DrawQuad(const gfx::Rect& aRect,
                         const gfx::Rect& aClipRect,
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -183,17 +183,20 @@ ContainerPrepare(ContainerT* aContainer,
     if (!surfaceCopyNeeded) {
       // If we don't need a copy we can render to the intermediate now to avoid
       // unecessary render target switching. This brings a big perf boost on mobile gpus.
       RefPtr<CompositingRenderTarget> surface = CreateTemporaryTarget(aContainer, aManager);
       RenderIntermediate(aContainer, aManager, RenderTargetPixel::ToUntyped(aClipRect), surface);
       aContainer->mPrepared->mTmpTarget = surface;
     } else {
       aContainer->mPrepared->mNeedsSurfaceCopy = true;
+      aContainer->mLastIntermediateSurface = nullptr;
     }
+  } else {
+    aContainer->mLastIntermediateSurface = nullptr;
   }
 }
 
 template<class ContainerT> void
 RenderLayers(ContainerT* aContainer,
 	     LayerManagerComposite* aManager,
 	     const RenderTargetIntRect& aClipRect)
 {
@@ -274,17 +277,29 @@ CreateTemporaryTarget(ContainerT* aConta
   SurfaceInitMode mode = INIT_MODE_CLEAR;
   gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y,
                                           visibleRect.width, visibleRect.height);
   if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 &&
       (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE))
   {
     mode = INIT_MODE_NONE;
   }
-  return compositor->CreateRenderTarget(surfaceRect, mode);
+
+  RefPtr<CompositingRenderTarget>& lastSurf = aContainer->mLastIntermediateSurface;
+  if (lastSurf && lastSurf->GetRect().IsEqualEdges(surfaceRect)) {
+    if (mode == INIT_MODE_CLEAR) {
+      lastSurf->ClearOnBind();
+    }
+
+    return lastSurf;
+  } else {
+    lastSurf = compositor->CreateRenderTarget(surfaceRect, mode);
+
+    return lastSurf;
+  }
 }
 
 template<class ContainerT> RefPtr<CompositingRenderTarget>
 CreateTemporaryTargetAndCopyFromBackground(ContainerT* aContainer,
                                            LayerManagerComposite* aManager)
 {
   Compositor* compositor = aManager->GetCompositor();
   nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds();
@@ -457,16 +472,18 @@ void
 ContainerLayerComposite::Prepare(const RenderTargetIntRect& aClipRect)
 {
   ContainerPrepare(this, mCompositeManager, aClipRect);
 }
 
 void
 ContainerLayerComposite::CleanupResources()
 {
+  mLastIntermediateSurface = nullptr;
+
   for (Layer* l = GetFirstChild(); l; l = l->GetNextSibling()) {
     LayerComposite* layerToCleanup = static_cast<LayerComposite*>(l->ImplData());
     layerToCleanup->CleanupResources();
   }
 }
 
 RefLayerComposite::RefLayerComposite(LayerManagerComposite* aManager)
   : RefLayer(aManager, nullptr)
@@ -507,12 +524,13 @@ RefLayerComposite::Prepare(const RenderT
 {
   ContainerPrepare(this, mCompositeManager, aClipRect);
 }
 
 
 void
 RefLayerComposite::CleanupResources()
 {
+  mLastIntermediateSurface = nullptr;
 }
 
 } /* layers */
 } /* mozilla */
--- a/gfx/layers/composite/ContainerLayerComposite.h
+++ b/gfx/layers/composite/ContainerLayerComposite.h
@@ -89,16 +89,18 @@ public:
 
   virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; }
 
   // container layers don't use a compositable
   CompositableHost* GetCompositableHost() MOZ_OVERRIDE { return nullptr; }
 
   virtual const char* Name() const MOZ_OVERRIDE { return "ContainerLayerComposite"; }
   UniquePtr<PreparedData> mPrepared;
+
+  RefPtr<CompositingRenderTarget> mLastIntermediateSurface;
 };
 
 class RefLayerComposite : public RefLayer,
                           public LayerComposite
 {
   template<class ContainerT>
   friend void ContainerPrepare(ContainerT* aContainer,
                                LayerManagerComposite* aManager,
@@ -153,14 +155,15 @@ public:
 
   virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; }
 
   // ref layers don't use a compositable
   CompositableHost* GetCompositableHost() MOZ_OVERRIDE { return nullptr; }
 
   virtual const char* Name() const MOZ_OVERRIDE { return "RefLayerComposite"; }
   UniquePtr<PreparedData> mPrepared;
+  RefPtr<CompositingRenderTarget> mLastIntermediateSurface;
 };
 
 } /* layers */
 } /* mozilla */
 
 #endif /* GFX_ContainerLayerComposite_H */
--- a/gfx/layers/composite/TextureHost.h
+++ b/gfx/layers/composite/TextureHost.h
@@ -750,25 +750,38 @@ private:
  * This can be used as an offscreen rendering target by the compositor, and
  * subsequently can be used as a source by the compositor.
  */
 class CompositingRenderTarget: public TextureSource
 {
 public:
 
   explicit CompositingRenderTarget(const gfx::IntPoint& aOrigin)
-    : mOrigin(aOrigin)
+    : mClearOnBind(false)
+    , mOrigin(aOrigin)
   {}
   virtual ~CompositingRenderTarget() {}
 
 #ifdef MOZ_DUMP_PAINTING
   virtual TemporaryRef<gfx::DataSourceSurface> Dump(Compositor* aCompositor) { return nullptr; }
 #endif
 
+  /**
+   * Perform a clear when recycling a non opaque surface.
+   * The clear is deferred to when the render target is bound.
+   */
+  void ClearOnBind() {
+    mClearOnBind = true;
+  }
+
   const gfx::IntPoint& GetOrigin() { return mOrigin; }
+  gfx::IntRect GetRect() { return gfx::IntRect(GetOrigin(), GetSize()); }
+
+protected:
+  bool mClearOnBind;
 
 private:
   gfx::IntPoint mOrigin;
 };
 
 /**
  * Creates a TextureHost that can be used with any of the existing backends
  * Not all SurfaceDescriptor types are supported
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -489,19 +489,18 @@ CompositorD3D11::CreateRenderTargetFromS
 }
 
 void
 CompositorD3D11::SetRenderTarget(CompositingRenderTarget* aRenderTarget)
 {
   MOZ_ASSERT(aRenderTarget);
   CompositingRenderTargetD3D11* newRT =
     static_cast<CompositingRenderTargetD3D11*>(aRenderTarget);
-  ID3D11RenderTargetView* view = newRT->mRTView;
   mCurrentRT = newRT;
-  mContext->OMSetRenderTargets(1, &view, nullptr);
+  mCurrentRT->BindRenderTarget(mContext);
   PrepareViewport(newRT->GetSize());
 }
 
 void
 CompositorD3D11::SetPSForEffect(Effect* aEffect, MaskType aMaskType, gfx::SurfaceFormat aFormat)
 {
   switch (aEffect->mType) {
   case EffectTypes::SOLID_COLOR:
--- a/gfx/layers/d3d11/TextureD3D11.cpp
+++ b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -650,16 +650,28 @@ CompositingRenderTargetD3D11::Compositin
 
   HRESULT hr = device->CreateRenderTargetView(mTexture, nullptr, byRef(mRTView));
 
   if (FAILED(hr)) {
     LOGD3D11("Failed to create RenderTargetView.");
   }
 }
 
+void
+CompositingRenderTargetD3D11::BindRenderTarget(ID3D11DeviceContext* aContext)
+{
+  if (!mClearOnBind) {
+    FLOAT clear[] = { 0, 0, 0, 0 };
+    aContext->ClearRenderTargetView(mRTView, clear);
+    mClearOnBind = false;
+  }
+  ID3D11RenderTargetView* view = mRTView;
+  aContext->OMSetRenderTargets(1, &view, nullptr);
+}
+
 IntSize
 CompositingRenderTargetD3D11::GetSize() const
 {
   return TextureSourceD3D11::GetSize();
 }
 
 }
 }
--- a/gfx/layers/d3d11/TextureD3D11.h
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -213,16 +213,18 @@ class CompositingRenderTargetD3D11 : pub
                                      public TextureSourceD3D11
 {
 public:
   CompositingRenderTargetD3D11(ID3D11Texture2D* aTexture,
                                const gfx::IntPoint& aOrigin);
 
   virtual TextureSourceD3D11* AsSourceD3D11() MOZ_OVERRIDE { return this; }
 
+  void BindRenderTarget(ID3D11DeviceContext* aContext);
+
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   void SetSize(const gfx::IntSize& aSize) { mSize = aSize; }
 
 private:
   friend class CompositorD3D11;
 
   RefPtr<ID3D11RenderTargetView> mRTView;
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -1325,17 +1325,17 @@ InsertVsyncProfilerMarker(TimeStamp aVsy
   VsyncPayload* payload = new VsyncPayload(aVsyncTimestamp);
   PROFILER_MARKER_PAYLOAD("VsyncTimestamp", payload);
 #endif
 }
 
 /*static */ void
 CompositorParent::PostInsertVsyncProfilerMarker(TimeStamp aVsyncTimestamp)
 {
-  if (profiler_is_active()) {
+  if (profiler_is_active() && sCompositorThreadHolder) {
     CompositorLoop()->PostTask(FROM_HERE,
       NewRunnableFunction(InsertVsyncProfilerMarker, aVsyncTimestamp));
   }
 }
 
 /**
  * This class handles layer updates pushed directly from child
  * processes to the compositor thread.  It's associated with a
--- a/gfx/layers/opengl/CompositingRenderTargetOGL.cpp
+++ b/gfx/layers/opengl/CompositingRenderTargetOGL.cpp
@@ -11,16 +11,17 @@
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 
 CompositingRenderTargetOGL::~CompositingRenderTargetOGL()
 {
+  mGL->MakeCurrent();
   mGL->fDeleteTextures(1, &mTextureHandle);
   mGL->fDeleteFramebuffers(1, &mFBO);
 }
 
 void
 CompositingRenderTargetOGL::BindTexture(GLenum aTextureUnit, GLenum aTextureTarget)
 {
   MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED);
@@ -53,16 +54,22 @@ CompositingRenderTargetOGL::BindRenderTa
                          result, mGL, mGL->IsOffscreen(), mFBO, mInitParams.mFBOTextureTarget,
                          mInitParams.mSize.width, mInitParams.mSize.height);
         NS_WARNING(msg.get());
       }
     }
 
     mCompositor->PrepareViewport(mInitParams.mSize);
   }
+
+  if (mClearOnBind) {
+    mGL->fClearColor(0.0, 0.0, 0.0, 0.0);
+    mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
+    mClearOnBind = false;
+  }
 }
 
 #ifdef MOZ_DUMP_PAINTING
 TemporaryRef<DataSourceSurface>
 CompositingRenderTargetOGL::Dump(Compositor* aCompositor)
 {
   MOZ_ASSERT(mInitParams.mStatus == InitParams::INITIALIZED);
   CompositorOGL* compositorOGL = static_cast<CompositorOGL*>(aCompositor);
@@ -94,14 +101,15 @@ CompositingRenderTargetOGL::InitializeIm
 
   mInitParams.mStatus = InitParams::INITIALIZED;
 
   mCompositor->PrepareViewport(mInitParams.mSize);
   mGL->fScissor(0, 0, mInitParams.mSize.width, mInitParams.mSize.height);
   if (mInitParams.mInit == INIT_MODE_CLEAR) {
     mGL->fClearColor(0.0, 0.0, 0.0, 0.0);
     mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT);
+    mClearOnBind = false;
   }
 
 }
 
 }
 }
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -82,16 +82,17 @@ CompositorOGL::CompositorOGL(nsIWidget *
   : mWidget(aWidget)
   , mWidgetSize(-1, -1)
   , mSurfaceSize(aSurfaceWidth, aSurfaceHeight)
   , mHasBGRA(0)
   , mUseExternalSurfaceSize(aUseExternalSurfaceSize)
   , mFrameInProgress(false)
   , mDestroyed(false)
   , mHeight(0)
+  , mCurrentProgram(nullptr)
 {
   MOZ_COUNT_CTOR(CompositorOGL);
   SetBackend(LayersBackend::LAYERS_OPENGL);
 }
 
 CompositorOGL::~CompositorOGL()
 {
   MOZ_COUNT_DTOR(CompositorOGL);
@@ -810,16 +811,33 @@ CompositorOGL::GetShaderProgramFor(const
     delete shader;
     return nullptr;
   }
 
   mPrograms[aConfig] = shader;
   return shader;
 }
 
+void
+CompositorOGL::ActivateProgram(ShaderProgramOGL* aProg)
+{
+  if (mCurrentProgram != aProg) {
+    gl()->fUseProgram(aProg->GetProgram());
+    mCurrentProgram = aProg;
+  }
+}
+
+void
+CompositorOGL::ResetProgram()
+{
+  mCurrentProgram = nullptr;
+}
+
+
+
 static bool SetBlendMode(GLContext* aGL, gfx::CompositionOp aBlendMode, bool aIsPremultiplied = true)
 {
   if (aBlendMode == gfx::CompositionOp::OP_OVER && aIsPremultiplied) {
     return false;
   }
 
   GLenum srcBlend;
   GLenum dstBlend;
@@ -952,17 +970,17 @@ CompositorOGL::DrawQuad(const Rect& aRec
       static_cast<EffectBlendMode*>(aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get());
     blendMode = blendEffect->mBlendMode;
   }
 
   bool colorMatrix = aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX];
   ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, maskType, blendMode, colorMatrix);
   config.SetOpacity(aOpacity != 1.f);
   ShaderProgramOGL *program = GetShaderProgramFor(config);
-  program->Activate();
+  ActivateProgram(program);
   program->SetProjectionMatrix(mProjMatrix);
   program->SetLayerTransform(aTransform);
 
   if (colorMatrix) {
       EffectColorMatrix* effectColorMatrix =
         static_cast<EffectColorMatrix*>(aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX].get());
       program->SetColorMatrix(effectColorMatrix->mColorMatrix);
   }
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -250,16 +250,21 @@ public:
   }
 
   virtual void Pause() MOZ_OVERRIDE;
   virtual bool Resume() MOZ_OVERRIDE;
 
   virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
 
   GLContext* gl() const { return mGLContext; }
+  /**
+   * Clear the program state. This must be called
+   * before operating on the GLContext directly. */
+  void ResetProgram();
+
   gfx::SurfaceFormat GetFBOFormat() const {
     return gfx::SurfaceFormat::R8G8B8A8;
   }
 
   GLBlitTextureImageHelper* BlitTextureImageHelper();
 
   /**
    * The compositor provides with temporary textures for use with direct
@@ -365,16 +370,17 @@ private:
     textureRects[0] = aTextureRect;
     BindAndDrawQuads(aProg, 1, layerRects, textureRects);
   }
   void BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
                                       const gfx::Rect& aRect,
                                       const gfx::Rect& aTexCoordRect,
                                       TextureSource *aTexture);
 
+  void ActivateProgram(ShaderProgramOGL *aProg);
   void CleanupResources();
 
   /**
    * Copies the content of our backbuffer to the set transaction target.
    * Does not restore the target FBO, so only call from EndFrame.
    */
   void CopyToTarget(gfx::DrawTarget* aTarget, const nsIntPoint& aTopLeft, const gfx::Matrix& aWorldMatrix);
 
@@ -397,14 +403,15 @@ private:
 
   /**
    * Height of the OpenGL context's primary framebuffer in pixels. Used by
    * FlipY for the y-flipping calculation.
    */
   GLint mHeight;
 
   FenceHandle mReleaseFenceHandle;
+  ShaderProgramOGL *mCurrentProgram;
 };
 
 }
 }
 
 #endif /* MOZILLA_GFX_COMPOSITOROGL_H */
--- a/gfx/layers/opengl/GLBlitTextureImageHelper.cpp
+++ b/gfx/layers/opengl/GLBlitTextureImageHelper.cpp
@@ -192,16 +192,20 @@ GLBlitTextureImageHelper::SetBlitFramebu
         // size via a call to TexImage2D.
         NS_RUNTIMEABORT(msg.get());
     }
 }
 
 void
 GLBlitTextureImageHelper::UseBlitProgram()
 {
+    // XXX: GLBlitTextureImageHelper doesn't use ShaderProgramOGL
+    // so we need to Reset the program
+    mCompositor->ResetProgram();
+
     GLContext *gl = mCompositor->gl();
     if (mBlitProgram) {
         gl->fUseProgram(mBlitProgram);
         return;
     }
 
     mBlitProgram = gl->fCreateProgram();
 
--- a/gfx/layers/opengl/GLManager.cpp
+++ b/gfx/layers/opengl/GLManager.cpp
@@ -27,16 +27,21 @@ public:
     : mImpl(aCompositor)
   {}
 
   virtual GLContext* gl() const MOZ_OVERRIDE
   {
     return mImpl->gl();
   }
 
+  virtual void ActivateProgram(ShaderProgramOGL *aProg) MOZ_OVERRIDE
+  {
+    mImpl->ActivateProgram(aProg);
+  }
+
   virtual ShaderProgramOGL* GetProgram(GLenum aTarget, gfx::SurfaceFormat aFormat) MOZ_OVERRIDE
   {
     ShaderConfigOGL config = ShaderConfigFromTargetAndFormat(aTarget, aFormat);
     return mImpl->GetShaderProgramFor(config);
   }
 
   virtual const gfx::Matrix4x4& GetProjMatrix() const MOZ_OVERRIDE
   {
--- a/gfx/layers/opengl/GLManager.h
+++ b/gfx/layers/opengl/GLManager.h
@@ -27,16 +27,17 @@ class GLManager
 {
 public:
   static GLManager* CreateGLManager(LayerManagerComposite* aManager);
 
   virtual ~GLManager() {}
 
   virtual gl::GLContext* gl() const = 0;
   virtual ShaderProgramOGL* GetProgram(GLenum aTarget, gfx::SurfaceFormat aFormat) = 0;
+  virtual void ActivateProgram(ShaderProgramOGL* aPrg) = 0;
   virtual const gfx::Matrix4x4& GetProjMatrix() const = 0;
   virtual void BindAndDrawQuad(ShaderProgramOGL *aProg, const gfx::Rect& aLayerRect,
                                const gfx::Rect& aTextureRect) = 0;
 };
 
 }
 }
 #endif
--- a/gfx/layers/opengl/OGLShaderProgram.cpp
+++ b/gfx/layers/opengl/OGLShaderProgram.cpp
@@ -535,27 +535,26 @@ ShaderProgramOGL::CreateProgram(const ch
     mGL->fDeleteProgram(result);
     return false;
   }
 
   mProgram = result;
   return true;
 }
 
-void
-ShaderProgramOGL::Activate()
+GLuint
+ShaderProgramOGL::GetProgram()
 {
   if (mProgramState == STATE_NEW) {
     if (!Initialize()) {
       NS_WARNING("Shader could not be initialised");
-      return;
     }
   }
-  NS_ASSERTION(HasInitialized(), "Attempting to activate a program that's not in use!");
-  mGL->fUseProgram(mProgram);
+  MOZ_ASSERT(HasInitialized(), "Attempting to get a program that's not been initialized!");
+  return mProgram;
 }
 
 void
 ShaderProgramOGL::SetBlurRadius(float aRX, float aRY)
 {
   float f[] = {aRX, aRY};
   SetUniform(KnownUniform::BlurRadius, 2, f);
 
--- a/gfx/layers/opengl/OGLShaderProgram.h
+++ b/gfx/layers/opengl/OGLShaderProgram.h
@@ -252,17 +252,17 @@ struct ProgramProfileOGL
 
 
 #if defined(DEBUG)
 #define CHECK_CURRENT_PROGRAM 1
 #define ASSERT_THIS_PROGRAM                                             \
   do {                                                                  \
     GLuint currentProgram;                                              \
     mGL->GetUIntegerv(LOCAL_GL_CURRENT_PROGRAM, &currentProgram);       \
-    NS_ASSERTION(currentProgram == mProgram,                            \
+    MOZ_ASSERT(currentProgram == mProgram,                              \
                  "SetUniform with wrong program active!");              \
   } while (0)
 #else
 #define ASSERT_THIS_PROGRAM                                             \
   do { } while (0)
 #endif
 
 /**
@@ -278,17 +278,17 @@ public:
 
   ~ShaderProgramOGL();
 
   bool HasInitialized() {
     NS_ASSERTION(mProgramState != STATE_OK || mProgram > 0, "Inconsistent program state");
     return mProgramState == STATE_OK;
   }
 
-  void Activate();
+  GLuint GetProgram();
 
   bool Initialize();
 
   GLint CreateShader(GLenum aShaderType, const char *aShaderSource);
 
   /**
    * Creates a program and stores its id.
    */
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -455,16 +455,20 @@ gfxPlatform::Init()
 
     // Request the imgITools service, implicitly initializing ImageLib.
     nsCOMPtr<imgITools> imgTools = do_GetService("@mozilla.org/image/tools;1");
     if (!imgTools) {
       NS_RUNTIMEABORT("Could not initialize ImageLib");
     }
 
     RegisterStrongMemoryReporter(new GfxMemoryImageReporter());
+
+    if (gfxPrefs::HardwareVsyncEnabled() && gfxPrefs::VsyncAlignedCompositor()) {
+      gPlatform->InitHardwareVsync();
+    }
 }
 
 static bool sLayersIPCIsUp = false;
 
 void
 gfxPlatform::Shutdown()
 {
     if (!gPlatform) {
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -582,20 +582,25 @@ public:
 
     static bool UsesOffMainThreadCompositing();
 
     bool HasEnoughTotalSystemMemoryForSkiaGL();
 protected:
     gfxPlatform();
     virtual ~gfxPlatform();
 
-    void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], uint32_t &aLen, 
+    void AppendCJKPrefLangs(eFontPrefLang aPrefLangs[], uint32_t &aLen,
                             eFontPrefLang aCharLang, eFontPrefLang aPageLang);
 
     /**
+     * Initialized hardware vsync based on each platform.
+     */
+    virtual void InitHardwareVsync() {}
+
+    /**
      * Helper method, creates a draw target for a specific Azure backend.
      * Used by CreateOffscreenDrawTarget.
      */
     mozilla::TemporaryRef<DrawTarget>
       CreateDrawTargetForBackend(mozilla::gfx::BackendType aBackend,
                                  const mozilla::gfx::IntSize& aSize,
                                  mozilla::gfx::SurfaceFormat aFormat);
 
--- a/gfx/thebes/gfxPlatformMac.cpp
+++ b/gfx/thebes/gfxPlatformMac.cpp
@@ -12,21 +12,23 @@
 #include "gfxMacPlatformFontList.h"
 #include "gfxMacFont.h"
 #include "gfxCoreTextShaper.h"
 #include "gfxTextRun.h"
 #include "gfxUserFontSet.h"
 
 #include "nsTArray.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/VsyncDispatcher.h"
 #include "qcms.h"
 #include "gfx2DGlue.h"
 #include "gfxPrefs.h"
 
 #include <dlfcn.h>
+#include <CoreVideo/CoreVideo.h>
 
 #include "nsCocoaFeatures.h"
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 // cribbed from CTFontManager.h
 enum {
@@ -368,24 +370,24 @@ gfxPlatformMac::GetCommonFallbackFonts(u
     // Arial Unicode MS has lots of glyphs for obscure, use it as a last resort
     aFontList.AppendElement(kFontArialUnicodeMS);
 }
 
 uint32_t
 gfxPlatformMac::ReadAntiAliasingThreshold()
 {
     uint32_t threshold = 0;  // default == no threshold
-    
+
     // first read prefs flag to determine whether to use the setting or not
     bool useAntiAliasingThreshold = Preferences::GetBool("gfx.use_text_smoothing_setting", false);
 
     // if the pref setting is disabled, return 0 which effectively disables this feature
     if (!useAntiAliasingThreshold)
         return threshold;
-        
+
     // value set via Appearance pref panel, "Turn off text smoothing for font sizes xxx and smaller"
     CFNumberRef prefValue = (CFNumberRef)CFPreferencesCopyAppValue(CFSTR("AppleAntiAliasingThreshold"), kCFPreferencesCurrentApplication);
 
     if (prefValue) {
         if (!CFNumberGetValue(prefValue, kCFNumberIntType, &threshold)) {
             threshold = 0;
         }
         CFRelease(prefValue);
@@ -414,16 +416,101 @@ gfxPlatformMac::UseTiling()
 bool
 gfxPlatformMac::UseProgressivePaint()
 {
   // Progressive painting requires cross-process mutexes, which don't work so
   // well on OS X 10.6 so we disable there.
   return nsCocoaFeatures::OnLionOrLater() && gfxPlatform::UseProgressivePaint();
 }
 
+// This is the renderer output callback function, called on the vsync thread
+static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink,
+                              const CVTimeStamp* aNow,
+                              const CVTimeStamp* aOutputTime,
+                              CVOptionFlags aFlagsIn,
+                              CVOptionFlags* aFlagsOut,
+                              void* aDisplayLinkContext)
+{
+  mozilla::VsyncSource* vsyncSource = (mozilla::VsyncSource*) aDisplayLinkContext;
+  if (vsyncSource->IsVsyncEnabled()) {
+    // Now refers to "Now" as in when this callback is called or when the current frame
+    // is displayed. aOutputTime is when the next frame should be displayed.
+    // Now is VERY VERY noisy, aOutputTime is in the future though.
+    int64_t timestamp = aOutputTime->hostTime;
+    mozilla::TimeStamp vsyncTime = mozilla::TimeStamp::FromSystemTime(timestamp);
+    mozilla::VsyncDispatcher::GetInstance()->NotifyVsync(vsyncTime);
+    return kCVReturnSuccess;
+  } else {
+    return kCVReturnDisplayLinkNotRunning;
+  }
+}
+
+class OSXVsyncSource MOZ_FINAL : public mozilla::VsyncSource
+{
+public:
+  OSXVsyncSource()
+  {
+    EnableVsync();
+  }
+
+  virtual void EnableVsync() MOZ_OVERRIDE
+  {
+    // Create a display link capable of being used with all active displays
+    // TODO: See if we need to create an active DisplayLink for each monitor in multi-monitor
+    // situations. According to the docs, it is compatible with all displays running on the computer
+    // But if we have different monitors at different display rates, we may hit issues.
+    if (CVDisplayLinkCreateWithActiveCGDisplays(&mDisplayLink) != kCVReturnSuccess) {
+      NS_WARNING("Could not create a display link, returning");
+      return;
+    }
+
+    // Set the renderer output callback function
+    if (CVDisplayLinkSetOutputCallback(mDisplayLink, &VsyncCallback, this) != kCVReturnSuccess) {
+      NS_WARNING("Could not set displaylink output callback");
+      return;
+    }
+
+    // Activate the display link
+    if (CVDisplayLinkStart(mDisplayLink) != kCVReturnSuccess) {
+      NS_WARNING("Could not activate the display link");
+      mDisplayLink = nullptr;
+    }
+  }
+
+  virtual void DisableVsync() MOZ_OVERRIDE
+  {
+    // Release the display link
+    if (mDisplayLink) {
+      CVDisplayLinkRelease(mDisplayLink);
+      mDisplayLink = nullptr;
+    }
+  }
+
+  virtual bool IsVsyncEnabled() MOZ_OVERRIDE
+  {
+    return mDisplayLink != nullptr;
+  }
+
+private:
+  virtual ~OSXVsyncSource()
+  {
+    DisableVsync();
+  }
+
+  // Manages the display link render thread
+  CVDisplayLinkRef   mDisplayLink;
+}; // OSXVsyncSource
+
+void
+gfxPlatformMac::InitHardwareVsync()
+{
+  nsRefPtr<VsyncSource> osxVsyncSource = new OSXVsyncSource();
+  mozilla::VsyncDispatcher::GetInstance()->SetVsyncSource(osxVsyncSource);
+}
+
 void
 gfxPlatformMac::GetPlatformCMSOutputProfile(void* &mem, size_t &size)
 {
     mem = nullptr;
     size = 0;
 
     CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID());
     if (!cspace) {
--- a/gfx/thebes/gfxPlatformMac.h
+++ b/gfx/thebes/gfxPlatformMac.h
@@ -67,16 +67,17 @@ public:
     virtual bool CanRenderContentToDataSurface() const MOZ_OVERRIDE {
       return true;
     }
 
     bool UseAcceleratedCanvas();
 
     virtual bool UseTiling() MOZ_OVERRIDE;
     virtual bool UseProgressivePaint() MOZ_OVERRIDE;
+    virtual void InitHardwareVsync() MOZ_OVERRIDE;
 
     // lower threshold on font anti-aliasing
     uint32_t GetAntiAliasingThreshold() { return mFontAntiAliasingThreshold; }
 
 private:
     virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size);
 
     // read in the pref value for the lower threshold on font anti-aliasing
--- a/gfx/thebes/gfxUserFontSet.h
+++ b/gfx/thebes/gfxUserFontSet.h
@@ -9,16 +9,17 @@
 #include "gfxFont.h"
 #include "nsRefPtrHashtable.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsIURI.h"
 #include "nsIPrincipal.h"
 #include "nsIScriptError.h"
 #include "nsURIHashKey.h"
+#include "mozilla/net/ReferrerPolicy.h"
 
 class nsFontFaceLoader;
 
 //#define DEBUG_USERFONT_CACHE
 
 class gfxFontFaceBufferSource
 {
   NS_INLINE_DECL_REFCOUNTING(gfxFontFaceBufferSource)
@@ -47,16 +48,17 @@ struct gfxFontFaceSrc {
     // format hint flags, union of all possible formats
     // (e.g. TrueType, EOT, SVG, etc.)
     // see FLAG_FORMAT_* enum values below
     uint32_t               mFormatFlags;
 
     nsString               mLocalName;     // full font name if local
     nsCOMPtr<nsIURI>       mURI;           // uri if url
     nsCOMPtr<nsIURI>       mReferrer;      // referrer url if url
+    mozilla::net::ReferrerPolicy mReferrerPolicy;
     nsCOMPtr<nsIPrincipal> mOriginPrincipal; // principal if url
 
     nsRefPtr<gfxFontFaceBufferSource> mBuffer;
 };
 
 inline bool
 operator==(const gfxFontFaceSrc& a, const gfxFontFaceSrc& b)
 {
@@ -68,16 +70,17 @@ operator==(const gfxFontFaceSrc& a, cons
             return a.mLocalName == b.mLocalName;
         case gfxFontFaceSrc::eSourceType_URL: {
             bool equals;
             return a.mUseOriginPrincipal == b.mUseOriginPrincipal &&
                    a.mFormatFlags == b.mFormatFlags &&
                    NS_SUCCEEDED(a.mURI->Equals(b.mURI, &equals)) && equals &&
                    NS_SUCCEEDED(a.mReferrer->Equals(b.mReferrer, &equals)) &&
                      equals &&
+                   a.mReferrerPolicy == b.mReferrerPolicy &&
                    a.mOriginPrincipal->Equals(b.mOriginPrincipal);
         }
         case gfxFontFaceSrc::eSourceType_Buffer:
             return a.mBuffer == b.mBuffer;
     }
     NS_WARNING("unexpected mSourceType");
     return false;
 }
--- a/image/decoders/nsJPEGDecoder.cpp
+++ b/image/decoders/nsJPEGDecoder.cpp
@@ -176,30 +176,21 @@ nsJPEGDecoder::InitInternal()
   // Record app markers for ICC data
   for (uint32_t m = 0; m < 16; m++)
     jpeg_save_markers(&mInfo, JPEG_APP0 + m, 0xFFFF);
 }
 
 void
 nsJPEGDecoder::FinishInternal()
 {
-  // If we're not in any sort of error case, flush the decoder.
-  //
-  // XXXbholley - It seems wrong that this should be necessary, but at the
-  // moment I'm just folding the contents of Flush() into Close() so that
-  // we can get rid of it.
-  //
-  // XXX(seth): It'd be great to get rid of this. For now, we treat this as a
-  // write to a synchronous decoder, which means that this must be called only
-  // on the main thread. (That's asserted in Decoder::Finish and
-  // Decoder::FinishSharedDecoder.)
+  // If we're not in any sort of error case, force our state to JPEG_DONE.
   if ((mState != JPEG_DONE && mState != JPEG_SINK_NON_JPEG_TRAILER) &&
       (mState != JPEG_ERROR) &&
       !IsSizeDecode()) {
-    this->Write(nullptr, 0, DECODE_SYNC);
+    mState = JPEG_DONE;
   }
 }
 
 void
 nsJPEGDecoder::WriteInternal(const char* aBuffer, uint32_t aCount,
                              DecodeStrategy)
 {
   mSegment = (const JOCTET*)aBuffer;
--- a/image/public/imgILoader.idl
+++ b/image/public/imgILoader.idl
@@ -22,29 +22,32 @@ interface nsISimpleEnumerator;
 
 /**
  * imgILoader interface
  *
  * @author Stuart Parmenter <pavlov@netscape.com>
  * @version 0.3
  * @see imagelib2
  */
-[scriptable, builtinclass, uuid(42ef3b0a-cd82-454b-b4c4-f3470014a68b)]
+[scriptable, builtinclass, uuid(e61377d2-910e-4c65-a64b-428d150e1fd1)]
 interface imgILoader : nsISupports
 {
   // Extra flags to pass to loadImage if you want a load to use CORS
   // validation.
   const unsigned long LOAD_CORS_ANONYMOUS = 1 << 16;
   const unsigned long LOAD_CORS_USE_CREDENTIALS = 1 << 17;
 
   /**
    * Start the load and decode of an image.
    * @param aURI the URI to load
    * @param aInitialDocumentURI the URI that 'initiated' the load -- used for 3rd party cookie blocking
    * @param aReferrerURI the 'referring' URI
+   * @param aReferrerPolicy the policy to apply to sending referrers.
+   *           examples: "default", "never", "always", "origin"
+   *           (see W3C referrer-policy spec for valid policy strings)
    * @param aLoadingPrincipal the principal of the loading document
    * @param aLoadGroup Loadgroup to put the image load into
    * @param aObserver the observer (may be null)
    * @param aCX some random data
    * @param aLoadFlags Load flags for the request
    * @param aCacheKey cache key to use for a load if the original
    *                  image came from a request that had post data
    * @param aContentPolicyType [optional] the nsContentPolicyType to
@@ -55,16 +58,17 @@ interface imgILoader : nsISupports
    * ImageLib does NOT keep a strong ref to the observer; this prevents
    * reference cycles.  This means that callers of loadImage should
    * make sure to Cancel() the resulting request before the observer
    * goes away.
    */
   imgIRequest loadImageXPCOM(in nsIURI aURI,
                              in nsIURI aInitialDocumentURL,
                              in nsIURI aReferrerURI,
+                             in AString aReferrerPolicy,
                              in nsIPrincipal aLoadingPrincipal,
                              in nsILoadGroup aLoadGroup,
                              in imgINotificationObserver aObserver,
                              in nsISupports aCX,
                              in nsLoadFlags aLoadFlags,
                              in nsISupports cacheKey,
                              [optional]
                              in nsContentPolicyType aContentPolicyType);
--- a/image/src/Decoder.cpp
+++ b/image/src/Decoder.cpp
@@ -15,23 +15,25 @@ namespace mozilla {
 namespace image {
 
 Decoder::Decoder(RasterImage &aImage)
   : mImage(aImage)
   , mCurrentFrame(nullptr)
   , mProgress(NoProgress)
   , mImageData(nullptr)
   , mColormap(nullptr)
+  , mChunkCount(0)
   , mDecodeFlags(0)
   , mBytesDecoded(0)
   , mDecodeDone(false)
   , mDataError(false)
   , mFrameCount(0)
   , mFailCode(NS_OK)
   , mNeedsNewFrame(false)
+  , mNeedsToFlushData(false)
   , mInitialized(false)
   , mSizeDecode(false)
   , mInFrame(false)
   , mIsAnimated(false)
 { }
 
 Decoder::~Decoder()
 {
@@ -95,20 +97,30 @@ Decoder::Write(const char* aBuffer, uint
     js::ProfileEntry::Category::GRAPHICS);
 
   MOZ_ASSERT(NS_IsMainThread() || aStrategy == DECODE_ASYNC);
 
   // We're strict about decoder errors
   MOZ_ASSERT(!HasDecoderError(),
              "Not allowed to make more decoder calls after error!");
 
+  // Begin recording telemetry data.
+  TimeStamp start = TimeStamp::Now();
+  mChunkCount++;
+
   // Keep track of the total number of bytes written.
   mBytesDecoded += aCount;
 
-  // If a data error occured, just ignore future data
+  // If we're flushing data, clear the flag.
+  if (aBuffer == nullptr && aCount == 0) {
+    MOZ_ASSERT(mNeedsToFlushData, "Flushing when we don't need to");
+    mNeedsToFlushData = false;
+  }
+
+  // If a data error occured, just ignore future data.
   if (HasDataError())
     return;
 
   if (IsSizeDecode() && HasSize()) {
     // More data came in since we found the size. We have nothing to do here.
     return;
   }
 
@@ -120,16 +132,19 @@ Decoder::Write(const char* aBuffer, uint
   while (aStrategy == DECODE_SYNC && NeedsNewFrame() && !HasDataError()) {
     nsresult rv = AllocateFrame();
 
     if (NS_SUCCEEDED(rv)) {
       // Tell the decoder to use the data it saved when it asked for a new frame.
       WriteInternal(nullptr, 0, aStrategy);
     }
   }
+
+  // Finish telemetry.
+  mDecodeTime += (TimeStamp::Now() - start);
 }
 
 void
 Decoder::Finish(RasterImage::eShutdownIntent aShutdownIntent)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   // Implementation-specific finalization
@@ -241,16 +256,22 @@ Decoder::AllocateFrame()
   } else if (NS_FAILED(rv)) {
     PostDataError();
   }
 
   // Mark ourselves as not needing another frame before talking to anyone else
   // so they can tell us if they need yet another.
   mNeedsNewFrame = false;
 
+  // If we've received any data at all, we may have pending data that needs to
+  // be flushed now that we have a frame to decode into.
+  if (mBytesDecoded > 0) {
+    mNeedsToFlushData = true;
+  }
+
   return rv;
 }
 
 void
 Decoder::SetSizeOnImage()
 {
   MOZ_ASSERT(mImageMetadata.HasSize(), "Should have size");
   MOZ_ASSERT(mImageMetadata.HasOrientation(), "Should have orientation");
--- a/image/src/Decoder.h
+++ b/image/src/Decoder.h
@@ -38,16 +38,21 @@ public:
    */
   void InitSharedDecoder(uint8_t* imageData, uint32_t imageDataLength,
                          uint32_t* colormap, uint32_t colormapSize,
                          imgFrame* currentFrame);
 
   /**
    * Writes data to the decoder.
    *
+   * If aBuffer is null and aCount is 0, Write() flushes any buffered data to
+   * the decoder. Data is buffered if the decoder wasn't able to completely
+   * decode it because it needed a new frame.  If it's necessary to flush data,
+   * NeedsToFlushData() will return true.
+   *
    * @param aBuffer buffer containing the data to be written
    * @param aCount the number of bytes to write
    *
    * Any errors are reported by setting the appropriate state on the decoder.
    *
    * Notifications Sent: TODO
    */
   void Write(const char* aBuffer, uint32_t aCount, DecodeStrategy aStrategy);
@@ -106,16 +111,22 @@ public:
   void SetSizeDecode(bool aSizeDecode)
   {
     NS_ABORT_IF_FALSE(!mInitialized, "Can't set size decode after Init()!");
     mSizeDecode = aSizeDecode;
   }
 
   size_t BytesDecoded() const { return mBytesDecoded; }
 
+  // The amount of time we've spent inside Write() so far for this decoder.
+  TimeDuration DecodeTime() const { return mDecodeTime; }
+
+  // The number of times Write() has been called so far for this decoder.
+  uint32_t ChunkCount() const { return mChunkCount; }
+
   // The number of frames we have, including anything in-progress. Thus, this
   // is only 0 if we haven't begun any frames.
   uint32_t GetFrameCount() { return mFrameCount; }
 
   // The number of complete frames we have (ie, not including anything in-progress).
   uint32_t GetCompleteFrameCount() { return mInFrame ? mFrameCount - 1 : mFrameCount; }
 
   // Error tracking
@@ -161,16 +172,21 @@ public:
   // will be called again with nullptr and 0 as arguments.
   void NeedNewFrame(uint32_t frameNum, uint32_t x_offset, uint32_t y_offset,
                     uint32_t width, uint32_t height,
                     gfx::SurfaceFormat format,
                     uint8_t palette_depth = 0);
 
   virtual bool NeedsNewFrame() const { return mNeedsNewFrame; }
 
+  // Returns true if we may have stored data that we need to flush now that we
+  // have a new frame to decode into. Callers can use Write() to actually
+  // flush the data; see the documentation for that method.
+  bool NeedsToFlushData() const { return mNeedsToFlushData; }
+
   // Try to allocate a frame as described in mNewFrameData and return the
   // status code from that attempt. Clears mNewFrameData.
   virtual nsresult AllocateFrame();
 
   already_AddRefed<imgFrame> GetCurrentFrame() const
   {
     nsRefPtr<imgFrame> frame = mCurrentFrame;
     return frame.forget();
@@ -243,16 +259,20 @@ protected:
   nsIntRect mInvalidRect; // Tracks an invalidation region in the current frame.
   Progress mProgress;
 
   uint8_t* mImageData;       // Pointer to image data in either Cairo or 8bit format
   uint32_t mImageDataLength;
   uint32_t* mColormap;       // Current colormap to be used in Cairo format
   uint32_t mColormapSize;
 
+  // Telemetry data for this decoder.
+  TimeDuration mDecodeTime;
+  uint32_t mChunkCount;
+
   uint32_t mDecodeFlags;
   size_t mBytesDecoded;
   bool mDecodeDone;
   bool mDataError;
 
 private:
   uint32_t mFrameCount; // Number of frames, including anything in-progress
 
@@ -279,16 +299,17 @@ private:
     uint32_t mOffsetY;
     uint32_t mWidth;
     uint32_t mHeight;
     gfx::SurfaceFormat mFormat;
     uint8_t mPaletteDepth;
   };
   NewFrameData mNewFrameData;
   bool mNeedsNewFrame;
+  bool mNeedsToFlushData;
   bool mInitialized;
   bool mSizeDecode;
   bool mInFrame;
   bool mIsAnimated;
 };
 
 } // namespace image
 } // namespace mozilla
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -315,16 +315,17 @@ RasterImage::RasterImage(ProgressTracker
   mLockCount(0),
   mDecodeCount(0),
   mRequestedSampleSize(0),
 #ifdef DEBUG
   mFramesNotified(0),
 #endif
   mDecodingMonitor("RasterImage Decoding Monitor"),
   mDecoder(nullptr),
+  mDecodeStatus(DecodeStatus::INACTIVE),
   mNotifyProgress(NoProgress),
   mNotifying(false),
   mHasSize(false),
   mDecodeOnDraw(false),
   mMultipart(false),
   mDiscardable(false),
   mHasSourceData(false),
   mDecoded(false),
@@ -1660,17 +1661,16 @@ RasterImage::OnImageDataComplete(nsIRequ
   // Give precedence to Necko failure codes.
   if (NS_FAILED(aStatus))
     finalStatus = aStatus;
 
   // We just recorded OnStopRequest; we need to inform our listeners.
   {
     ReentrantMonitorAutoEnter lock(mDecodingMonitor);
     FinishedSomeDecoding(eShutdownIntent_Done,
-                         nullptr,
                          LoadCompleteProgress(aLastPart, mError, finalStatus));
   }
 
   return finalStatus;
 }
 
 nsresult
 RasterImage::OnImageDataAvailable(nsIRequest*,
@@ -1727,17 +1727,17 @@ RasterImage::OnNewSourceData()
   // The decoder was shut down and we didn't flag an error, so we should be decoded
   NS_ABORT_IF_FALSE(mDecoded, "Should be decoded in NewSourceData");
 
   // Reset some flags
   mDecoded = false;
   mHasSourceData = false;
   mHasSize = false;
   mWantFullDecode = true;
-  mDecodeRequest = nullptr;
+  mDecodeStatus = DecodeStatus::INACTIVE;
 
   if (mAnim) {
     mAnim->SetDoneDecoding(false);
   }
 
   // We always need the size first.
   rv = InitDecoder(/* aDoSizeDecode = */ true);
   CONTAINER_ENSURE_SUCCESS(rv);
@@ -1828,17 +1828,17 @@ RasterImage::Discard(bool force)
 
   // Flag that we no longer have decoded frames for this image
   mDecoded = false;
 
   // Notify that we discarded
   if (mProgressTracker)
     mProgressTracker->OnDiscard();
 
-  mDecodeRequest = nullptr;
+  mDecodeStatus = DecodeStatus::INACTIVE;
 
   if (force)
     DiscardTracker::Remove(&mDiscardTrackerNode);
 
   // Log
   PR_LOG(GetCompressedImageAccountingLog(), PR_LOG_DEBUG,
          ("CompressedImageAccounting: discarded uncompressed image "
           "data from RasterImage %p (%s) - %d frames (cached count: %d); "
@@ -1948,19 +1948,16 @@ RasterImage::InitDecoder(bool aDoSizeDec
   // case. Regardless, we need to lock the last frame. Our invariant is that,
   // while we have a decoder open, the last frame is always locked.
   if (GetNumFrames() > 0) {
     nsRefPtr<imgFrame> curframe = mFrameBlender.RawGetFrame(GetNumFrames() - 1);
     curframe->LockImageData();
   }
 
   // Initialize the decoder
-  if (!mDecodeRequest) {
-    mDecodeRequest = new DecodeRequest(this);
-  }
   mDecoder->SetSizeDecode(aDoSizeDecode);
   mDecoder->SetDecodeFlags(mFrameDecodeFlags);
   if (!aDoSizeDecode) {
     // We already have the size; tell the decoder so it can preallocate a
     // frame.  By default, we create an ARGB frame with no offset. If decoders
     // need a different type, they need to ask for it themselves.
     mDecoder->NeedNewFrame(0, 0, 0, mSize.width, mSize.height,
                            SurfaceFormat::B8G8R8A8);
@@ -2163,18 +2160,17 @@ RasterImage::RequestDecodeCore(RequestDe
     // data, so signal that we want a full decode and give up for now.
     if (!mHasSize) {
       mWantFullDecode = true;
       return NS_OK;
     }
   }
 
   // If the image is waiting for decode work to be notified, go ahead and do that.
-  if (mDecodeRequest &&
-      mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE &&
+  if (mDecodeStatus == DecodeStatus::WORK_DONE &&
       aDecodeType == SYNCHRONOUS_NOTIFY) {
     ReentrantMonitorAutoEnter lock(mDecodingMonitor);
     nsresult rv = FinishedSomeDecoding();
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   // If we're fully decoded, we have nothing to do. We need this check after
   // DecodeUntilSizeAvailable and FinishedSomeDecoding because they can result
@@ -2200,19 +2196,17 @@ RasterImage::RequestDecodeCore(RequestDe
   if (mDecoder && mDecoder->BytesDecoded() > mSourceData.Length()) {
     return NS_OK;
   }
 
   // After acquiring the lock we may have finished some more decoding, so
   // we need to repeat the following three checks after getting the lock.
 
   // If the image is waiting for decode work to be notified, go ahead and do that.
-  if (mDecodeRequest &&
-      mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE &&
-      aDecodeType != ASYNCHRONOUS) {
+  if (mDecodeStatus == DecodeStatus::WORK_DONE && aDecodeType != ASYNCHRONOUS) {
     nsresult rv = FinishedSomeDecoding();
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   // If we're fully decoded, we have nothing to do. We need this check after
   // DecodeUntilSizeAvailable and FinishedSomeDecoding because they can result
   // in us finishing an in-progress decode (or kicking off and finishing a
   // synchronous decode if we're already waiting on a full decode).
@@ -2287,22 +2281,20 @@ RasterImage::SyncDecode()
     if (!mHasSize) {
       mWantFullDecode = true;
       return NS_ERROR_NOT_AVAILABLE;
     }
   }
 
   ReentrantMonitorAutoEnter lock(mDecodingMonitor);
 
-  if (mDecodeRequest) {
-    // If the image is waiting for decode work to be notified, go ahead and do that.
-    if (mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE) {
-      nsresult rv = FinishedSomeDecoding();
-      CONTAINER_ENSURE_SUCCESS(rv);
-    }
+  // If the image is waiting for decode work to be notified, go ahead and do that.
+  if (mDecodeStatus == DecodeStatus::WORK_DONE) {
+    nsresult rv = FinishedSomeDecoding();
+    CONTAINER_ENSURE_SUCCESS(rv);
   }
 
   nsresult rv;
 
   // If we're decoded already, or decoding until the size was available
   // finished us as a side-effect, no worries
   if (mDecoded)
     return NS_OK;
@@ -2325,21 +2317,19 @@ RasterImage::SyncDecode()
       // with the new flags. If we can't discard then there isn't
       // anything we can do.
       if (!CanForciblyDiscardAndRedecode())
         return NS_ERROR_NOT_AVAILABLE;
       ForceDiscard();
     }
   }
 
-  // If we're currently waiting on a new frame for this image, we have to create
-  // it now.
+  // If we're currently waiting on a new frame for this image, create it now.
   if (mDecoder && mDecoder->NeedsNewFrame()) {
     mDecoder->AllocateFrame();
-    mDecodeRequest->mAllocatedNewFrame = true;
   }
 
   // If we don't have a decoder, create one
   if (!mDecoder) {
     rv = InitDecoder(/* aDoSizeDecode = */ false);
     CONTAINER_ENSURE_SUCCESS(rv);
   }
 
@@ -2695,18 +2685,17 @@ RasterImage::DecodeSomeData(size_t aMaxB
 {
   MOZ_ASSERT(mDecoder, "Should have a decoder");
 
   mDecodingMonitor.AssertCurrentThreadIn();
 
   // First, if we've just been called because we allocated a frame on the main
   // thread, let the decoder deal with the data it set aside at that time by
   // passing it a null buffer.
-  if (mDecodeRequest->mAllocatedNewFrame) {
-    mDecodeRequest->mAllocatedNewFrame = false;
+  if (mDecoder->NeedsToFlushData()) {
     nsresult rv = WriteToDecoder(nullptr, 0, aStrategy);
     if (NS_FAILED(rv) || mDecoder->NeedsNewFrame()) {
       return rv;
     }
   }
 
   // If we have nothing else to decode, return.
   if (mDecoder->BytesDecoded() == mSourceData.Length()) {
@@ -2742,18 +2731,17 @@ RasterImage::IsDecodeFinished()
     }
   } else if (mDecoder->GetDecodeDone()) {
     return true;
   }
 
   // If the decoder returned because it needed a new frame and we haven't
   // written to it since then, the decoder may be storing data that it hasn't
   // decoded yet.
-  if (mDecoder->NeedsNewFrame() ||
-      (mDecodeRequest && mDecodeRequest->mAllocatedNewFrame)) {
+  if (mDecoder->NeedsNewFrame() || mDecoder->NeedsToFlushData()) {
     return false;
   }
 
   // Otherwise, if we have all the source data and wrote all the source data,
   // we're done.
   //
   // (NB - This can be the case even for non-erroneous images because
   // Decoder::GetDecodeDone() might not return true until after we call
@@ -2893,46 +2881,39 @@ RasterImage::RequestDecodeIfNeeded(nsres
   }
 
   // We don't need a full decode right now, so just return the existing status.
   return aStatus;
 }
 
 nsresult
 RasterImage::FinishedSomeDecoding(eShutdownIntent aIntent /* = eShutdownIntent_Done */,
-                                  DecodeRequest* aRequest /* = nullptr */,
                                   Progress aProgress /* = NoProgress */)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   mDecodingMonitor.AssertCurrentThreadIn();
 
-  nsRefPtr<DecodeRequest> request;
-  if (aRequest) {
-    request = aRequest;
-  } else {
-    request = mDecodeRequest;
-  }
-
   // Ensure that, if the decoder is the last reference to the image, we don't
   // destroy it by destroying the decoder.
   nsRefPtr<RasterImage> image(this);
 
   bool done = false;
   bool wasSize = false;
   nsIntRect invalidRect;
   nsresult rv = NS_OK;
   Progress progress = aProgress;
 
   if (image->mDecoder) {
     invalidRect = image->mDecoder->TakeInvalidRect();
     progress |= image->mDecoder->TakeProgress();
 
-    if (request && request->mChunkCount && !image->mDecoder->IsSizeDecode()) {
-      Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, request->mChunkCount);
+    if (!image->mDecoder->IsSizeDecode() && image->mDecoder->ChunkCount()) {
+      Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS,
+                            image->mDecoder->ChunkCount());
     }
 
     if (!image->mHasSize && image->mDecoder->HasSize()) {
       image->mDecoder->SetSizeOnImage();
     }
 
     // If the decode finished, or we're specifically being told to shut down,
     // tell the image and shut down the decoder.
@@ -2940,26 +2921,26 @@ RasterImage::FinishedSomeDecoding(eShutd
       done = true;
 
       // Hold on to a reference to the decoder until we're done with it
       nsRefPtr<Decoder> decoder = image->mDecoder;
 
       wasSize = decoder->IsSizeDecode();
 
       // Do some telemetry if this isn't a size decode.
-      if (request && !wasSize) {
+      if (!wasSize) {
         Telemetry::Accumulate(Telemetry::IMAGE_DECODE_TIME,
-                              int32_t(request->mDecodeTime.ToMicroseconds()));
+                              int32_t(decoder->DecodeTime().ToMicroseconds()));
 
         // We record the speed for only some decoders. The rest have
         // SpeedHistogram return HistogramCount.
         Telemetry::ID id = decoder->SpeedHistogram();
         if (id < Telemetry::HistogramCount) {
           int32_t KBps = int32_t(decoder->BytesDecoded() /
-                                 (1024 * request->mDecodeTime.ToSeconds()));
+                                 (1024 * decoder->DecodeTime().ToSeconds()));
           Telemetry::Accumulate(id, KBps);
         }
       }
 
       // We need to shut down the decoder first, in order to ensure all
       // decoding routines have been finished.
       rv = image->ShutdownDecoder(aIntent);
       if (NS_FAILED(rv)) {
@@ -3138,51 +3119,44 @@ void
 RasterImage::DecodePool::RequestDecode(RasterImage* aImg)
 {
   MOZ_ASSERT(aImg->mDecoder);
   aImg->mDecodingMonitor.AssertCurrentThreadIn();
 
   // If we're currently waiting on a new frame for this image, we can't do any
   // decoding.
   if (!aImg->mDecoder->NeedsNewFrame()) {
-    // No matter whether this is currently being decoded, we need to update the
-    // number of bytes we want it to decode.
-    aImg->mDecodeRequest->mBytesToDecode =
-      aImg->mSourceData.Length() - aImg->mDecoder->BytesDecoded();
-
-    if (aImg->mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_PENDING ||
-        aImg->mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_ACTIVE) {
+    if (aImg->mDecodeStatus == DecodeStatus::PENDING ||
+        aImg->mDecodeStatus == DecodeStatus::ACTIVE) {
       // The image is already in our list of images to decode, or currently being
       // decoded, so we don't have to do anything else.
       return;
     }
 
-    aImg->mDecodeRequest->mRequestStatus = DecodeRequest::REQUEST_PENDING;
-    nsRefPtr<DecodeJob> job = new DecodeJob(aImg->mDecodeRequest, aImg);
+    aImg->mDecodeStatus = DecodeStatus::PENDING;
+    nsRefPtr<DecodeJob> job = new DecodeJob(aImg);
 
     MutexAutoLock threadPoolLock(mThreadPoolMutex);
     if (!gfxPrefs::ImageMTDecodingEnabled() || !mThreadPool) {
       NS_DispatchToMainThread(job);
     } else {
       mThreadPool->Dispatch(job, nsIEventTarget::DISPATCH_NORMAL);
     }
   }
 }
 
 void
 RasterImage::DecodePool::DecodeABitOf(RasterImage* aImg, DecodeStrategy aStrategy)
 {
   MOZ_ASSERT(NS_IsMainThread());
   aImg->mDecodingMonitor.AssertCurrentThreadIn();
 
-  if (aImg->mDecodeRequest) {
-    // If the image is waiting for decode work to be notified, go ahead and do that.
-    if (aImg->mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE) {
-      aImg->FinishedSomeDecoding();
-    }
+  // If the image is waiting for decode work to be notified, go ahead and do that.
+  if (aImg->mDecodeStatus == DecodeStatus::WORK_DONE) {
+    aImg->FinishedSomeDecoding();
   }
 
   DecodeSomeOfImage(aImg, aStrategy);
 
   aImg->FinishedSomeDecoding();
 
   // If the decoder needs a new frame, enqueue an event to get it; that event
   // will enqueue another decode request when it's done.
@@ -3202,80 +3176,81 @@ RasterImage::DecodePool::DecodeABitOf(Ra
 
 /* static */ void
 RasterImage::DecodePool::StopDecoding(RasterImage* aImg)
 {
   aImg->mDecodingMonitor.AssertCurrentThreadIn();
 
   // If we haven't got a decode request, we're not currently decoding. (Having
   // a decode request doesn't imply we *are* decoding, though.)
-  if (aImg->mDecodeRequest) {
-    aImg->mDecodeRequest->mRequestStatus = DecodeRequest::REQUEST_STOPPED;
-  }
+  aImg->mDecodeStatus = DecodeStatus::STOPPED;
 }
 
 NS_IMETHODIMP
 RasterImage::DecodePool::DecodeJob::Run()
 {
   ReentrantMonitorAutoEnter lock(mImage->mDecodingMonitor);
 
   // If we were interrupted, we shouldn't do any work.
-  if (mRequest->mRequestStatus == DecodeRequest::REQUEST_STOPPED) {
-    DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage, mRequest);
+  if (mImage->mDecodeStatus == DecodeStatus::STOPPED) {
+    DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage);
     return NS_OK;
   }
 
   // If someone came along and synchronously decoded us, there's nothing for us to do.
   if (!mImage->mDecoder || mImage->IsDecodeFinished()) {
-    DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage, mRequest);
+    DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage);
     return NS_OK;
   }
 
   // If we're a decode job that's been enqueued since a previous decode that
   // still needs a new frame, we can't do anything. Wait until the
   // FrameNeededWorker enqueues another frame.
   if (mImage->mDecoder->NeedsNewFrame()) {
     return NS_OK;
   }
 
-  mRequest->mRequestStatus = DecodeRequest::REQUEST_ACTIVE;
+  mImage->mDecodeStatus = DecodeStatus::ACTIVE;
 
   size_t oldByteCount = mImage->mDecoder->BytesDecoded();
 
   DecodeType type = DECODE_TYPE_UNTIL_DONE_BYTES;
 
   // Multithreaded decoding can be disabled. If we've done so, we don't want to
   // monopolize the main thread, and will allow a timeout in DecodeSomeOfImage.
   if (NS_IsMainThread()) {
     type = DECODE_TYPE_UNTIL_TIME;
   }
 
-  DecodePool::Singleton()->DecodeSomeOfImage(mImage, DECODE_ASYNC, type, mRequest->mBytesToDecode);
+  size_t maxBytes = mImage->mSourceData.Length() -
+                    mImage->mDecoder->BytesDecoded();
+  DecodePool::Singleton()->DecodeSomeOfImage(mImage, DECODE_ASYNC,
+                                             type, maxBytes);
 
   size_t bytesDecoded = mImage->mDecoder->BytesDecoded() - oldByteCount;
 
-  mRequest->mRequestStatus = DecodeRequest::REQUEST_WORK_DONE;
+  mImage->mDecodeStatus = DecodeStatus::WORK_DONE;
 
   // If the decoder needs a new frame, enqueue an event to get it; that event
   // will enqueue another decode request when it's done.
   if (mImage->mDecoder && mImage->mDecoder->NeedsNewFrame()) {
     FrameNeededWorker::GetNewFrame(mImage);
   }
   // If we aren't yet finished decoding and we have more data in hand, add
   // this request to the back of the list.
   else if (mImage->mDecoder &&
            !mImage->mError &&
            !mImage->mPendingError &&
            !mImage->IsDecodeFinished() &&
-           bytesDecoded < mRequest->mBytesToDecode &&
+           bytesDecoded < maxBytes &&
            bytesDecoded > 0) {
     DecodePool::Singleton()->RequestDecode(mImage);
   } else {
     // Nothing more for us to do - let everyone know what happened.
-    DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage, mRequest);
+    DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage);
   }
 
   return NS_OK;
 }
 
 RasterImage::DecodePool::DecodeJob::~DecodeJob()
 {
   if (gfxPrefs::ImageMTDecodingEnabled()) {
@@ -3293,24 +3268,22 @@ RasterImage::DecodePool::DecodeJob::~Dec
 }
 
 nsresult
 RasterImage::DecodePool::DecodeUntilSizeAvailable(RasterImage* aImg)
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter lock(aImg->mDecodingMonitor);
 
-  if (aImg->mDecodeRequest) {
-    // If the image is waiting for decode work to be notified, go ahead and do that.
-    if (aImg->mDecodeRequest->mRequestStatus == DecodeRequest::REQUEST_WORK_DONE) {
-      nsresult rv = aImg->FinishedSomeDecoding();
-      if (NS_FAILED(rv)) {
-        aImg->DoError();
-        return rv;
-      }
+  // If the image is waiting for decode work to be notified, go ahead and do that.
+  if (aImg->mDecodeStatus == DecodeStatus::WORK_DONE) {
+    nsresult rv = aImg->FinishedSomeDecoding();
+    if (NS_FAILED(rv)) {
+      aImg->DoError();
+      return rv;
     }
   }
 
   // We use DECODE_ASYNC here because we just want to get the size information
   // here and defer the rest of the work.
   nsresult rv = DecodeSomeOfImage(aImg, DECODE_ASYNC, DECODE_TYPE_UNTIL_SIZE);
   if (NS_FAILED(rv)) {
     return rv;
@@ -3351,19 +3324,17 @@ RasterImage::DecodePool::DecodeSomeOfIma
   // example, a synchronous decode request came while the worker was pending).
   if (!aImg->mDecoder || aImg->mDecoded)
     return NS_OK;
 
   // If we're doing synchronous decodes, and we're waiting on a new frame for
   // this image, get it now.
   if (aStrategy == DECODE_SYNC && aImg->mDecoder->NeedsNewFrame()) {
     MOZ_ASSERT(NS_IsMainThread());
-
     aImg->mDecoder->AllocateFrame();
-    aImg->mDecodeRequest->mAllocatedNewFrame = true;
   }
 
   // If we're not synchronous, we can't allocate a frame right now.
   else if (aImg->mDecoder->NeedsNewFrame()) {
     return NS_OK;
   }
 
   nsRefPtr<Decoder> decoderKungFuDeathGrip = aImg->mDecoder;
@@ -3379,78 +3350,70 @@ RasterImage::DecodePool::DecodeSomeOfIma
     // to read the size from most images.
     maxBytes = gfxPrefs::ImageMemDecodeBytesAtATime();
   }
 
   if (bytesToDecode == 0) {
     bytesToDecode = aImg->mSourceData.Length() - aImg->mDecoder->BytesDecoded();
   }
 
-  int32_t chunkCount = 0;
-  TimeStamp start = TimeStamp::Now();
-  TimeStamp deadline = start + TimeDuration::FromMilliseconds(gfxPrefs::ImageMemMaxMSBeforeYield());
+  TimeStamp deadline = TimeStamp::Now() +
+                       TimeDuration::FromMilliseconds(gfxPrefs::ImageMemMaxMSBeforeYield());
 
   // We keep decoding chunks until:
   //  * we don't have any data left to decode,
   //  * the decode completes,
   //  * we're an UNTIL_SIZE decode and we get the size, or
   //  * we run out of time.
   // We also try to decode at least one "chunk" if we've allocated a new frame,
   // even if we have no more data to send to the decoder.
   while ((aImg->mSourceData.Length() > aImg->mDecoder->BytesDecoded() &&
           bytesToDecode > 0 &&
           !aImg->IsDecodeFinished() &&
           !(aDecodeType == DECODE_TYPE_UNTIL_SIZE && aImg->mHasSize) &&
           !aImg->mDecoder->NeedsNewFrame()) ||
-         (aImg->mDecodeRequest && aImg->mDecodeRequest->mAllocatedNewFrame)) {
-    chunkCount++;
+         aImg->mDecoder->NeedsToFlushData()) {
     uint32_t chunkSize = std::min(bytesToDecode, maxBytes);
     nsresult rv = aImg->DecodeSomeData(chunkSize, aStrategy);
     if (NS_FAILED(rv)) {
       aImg->DoError();
       return rv;
     }
 
     bytesToDecode -= chunkSize;
 
     // Yield if we've been decoding for too long. We check this _after_ decoding
     // a chunk to ensure that we don't yield without doing any decoding.
     if (aDecodeType == DECODE_TYPE_UNTIL_TIME && TimeStamp::Now() >= deadline)
       break;
   }
 
-  if (aImg->mDecodeRequest) {
-    aImg->mDecodeRequest->mDecodeTime += (TimeStamp::Now() - start);
-    aImg->mDecodeRequest->mChunkCount += chunkCount;
-  }
-
   return NS_OK;
 }
 
-RasterImage::DecodeDoneWorker::DecodeDoneWorker(RasterImage* image, DecodeRequest* request)
- : mImage(image)
- , mRequest(request)
-{}
+RasterImage::DecodeDoneWorker::DecodeDoneWorker(RasterImage* aImage)
+ : mImage(aImage)
+{ }
 
 void
-RasterImage::DecodeDoneWorker::NotifyFinishedSomeDecoding(RasterImage* image, DecodeRequest* request)
+RasterImage::DecodeDoneWorker::NotifyFinishedSomeDecoding(RasterImage* aImage)
 {
-  image->mDecodingMonitor.AssertCurrentThreadIn();
-
-  nsCOMPtr<nsIRunnable> worker = new DecodeDoneWorker(image, request);
+  aImage->mDecodingMonitor.AssertCurrentThreadIn();
+
+  nsCOMPtr<nsIRunnable> worker = new DecodeDoneWorker(aImage);
   NS_DispatchToMainThread(worker);
 }
 
 NS_IMETHODIMP
 RasterImage::DecodeDoneWorker::Run()
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter lock(mImage->mDecodingMonitor);
 
-  mImage->FinishedSomeDecoding(eShutdownIntent_Done, mRequest);
+  mImage->FinishedSomeDecoding(eShutdownIntent_Done);
 
   return NS_OK;
 }
 
 RasterImage::FrameNeededWorker::FrameNeededWorker(RasterImage* image)
  : mImage(image)
 {}
 
@@ -3467,17 +3430,16 @@ RasterImage::FrameNeededWorker::Run()
 {
   ReentrantMonitorAutoEnter lock(mImage->mDecodingMonitor);
   nsresult rv = NS_OK;
 
   // If we got a synchronous decode in the mean time, we don't need to do
   // anything.
   if (mImage->mDecoder && mImage->mDecoder->NeedsNewFrame()) {
     rv = mImage->mDecoder->AllocateFrame();
-    mImage->mDecodeRequest->mAllocatedNewFrame = true;
   }
 
   if (NS_SUCCEEDED(rv) && mImage->mDecoder) {
     // By definition, we're not done decoding, so enqueue us for more decoding.
     DecodePool::Singleton()->RequestDecode(mImage);
   }
 
   return NS_OK;
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -28,16 +28,17 @@
 #include "DecodeStrategy.h"
 #include "DiscardTracker.h"
 #include "Orientation.h"
 #include "nsIObserver.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/TimeStamp.h"
+#include "mozilla/TypedEnum.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/UniquePtr.h"
 #ifdef DEBUG
   #include "imgIContainerDebug.h"
 #endif
 
 class nsIInputStream;
@@ -131,16 +132,24 @@ class Image;
 }
 
 namespace image {
 
 class Decoder;
 class FrameAnimator;
 class ScaleRunner;
 
+MOZ_BEGIN_ENUM_CLASS(DecodeStatus, uint8_t)
+  INACTIVE,
+  PENDING,
+  ACTIVE,
+  WORK_DONE,
+  STOPPED
+MOZ_END_ENUM_CLASS(DecodeStatus)
+
 class RasterImage MOZ_FINAL : public ImageResource
                             , public nsIProperties
                             , public SupportsWeakPtr<RasterImage>
 #ifdef DEBUG
                             , public imgIContainerDebug
 #endif
 {
   // (no public constructor - use ImageFactory)
@@ -301,65 +310,17 @@ public:
   // Decoder shutdown
   enum eShutdownIntent {
     eShutdownIntent_Done        = 0,
     eShutdownIntent_NotNeeded   = 1,
     eShutdownIntent_Error       = 2,
     eShutdownIntent_AllCount    = 3
   };
 
-  // Decode strategy
-
 private:
-  nsresult OnImageDataCompleteCore(nsIRequest* aRequest, nsISupports*, nsresult aStatus);
-
-  /**
-   * Each RasterImage has a pointer to one or zero heap-allocated
-   * DecodeRequests.
-   */
-  struct DecodeRequest
-  {
-    explicit DecodeRequest(RasterImage* aImage)
-      : mImage(aImage)
-      , mBytesToDecode(0)
-      , mRequestStatus(REQUEST_INACTIVE)
-      , mChunkCount(0)
-      , mAllocatedNewFrame(false)
-    { }
-
-    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DecodeRequest)
-
-    RasterImage* mImage;
-
-    size_t mBytesToDecode;
-
-    enum DecodeRequestStatus
-    {
-      REQUEST_INACTIVE,
-      REQUEST_PENDING,
-      REQUEST_ACTIVE,
-      REQUEST_WORK_DONE,
-      REQUEST_STOPPED
-    } mRequestStatus;
-
-    /* Keeps track of how much time we've burned decoding this particular decode
-     * request. */
-    TimeDuration mDecodeTime;
-
-    /* The number of chunks it took to decode this image. */
-    int32_t mChunkCount;
-
-    /* True if a new frame has been allocated, but DecodeSomeData hasn't yet
-     * been called to flush data to it */
-    bool mAllocatedNewFrame;
-
-  private:
-    ~DecodeRequest() {}
-  };
-
   /*
    * DecodePool is a singleton class we use when decoding large images.
    *
    * When we wish to decode an image larger than
    * image.mem.max_bytes_for_sync_decode, we call DecodePool::RequestDecode()
    * for the image.  This adds the image to a queue of pending requests and posts
    * the DecodePool singleton to the event queue, if it's not already pending
    * there.
@@ -437,28 +398,24 @@ private:
                                DecodeType aDecodeType = DECODE_TYPE_UNTIL_TIME,
                                uint32_t bytesToDecode = 0);
 
     /* A decode job dispatched to a thread pool by DecodePool.
      */
     class DecodeJob : public nsRunnable
     {
     public:
-      DecodeJob(DecodeRequest* aRequest, RasterImage* aImg)
-        : mRequest(aRequest)
-        , mImage(aImg)
-      {}
+      DecodeJob(RasterImage* aImage) : mImage(aImage) { }
 
-      NS_IMETHOD Run();
+      NS_IMETHOD Run() MOZ_OVERRIDE;
 
     protected:
       virtual ~DecodeJob();
 
     private:
-      nsRefPtr<DecodeRequest> mRequest;
       nsRefPtr<RasterImage> mImage;
     };
 
   private: /* members */
 
     // mThreadPoolMutex protects mThreadPool. For all RasterImages R,
     // R::mDecodingMonitor must be acquired before mThreadPoolMutex
     // if both are acquired; the other order may cause deadlock.
@@ -471,53 +428,49 @@ private:
   public:
     /**
      * Called by the DecodePool with an image when it's done some significant
      * portion of decoding that needs to be notified about.
      *
      * Ensures the decode state accumulated by the decoding process gets
      * applied to the image.
      */
-    static void NotifyFinishedSomeDecoding(RasterImage* image, DecodeRequest* request);
+    static void NotifyFinishedSomeDecoding(RasterImage* aImage);
 
     NS_IMETHOD Run();
 
-  private: /* methods */
-    DecodeDoneWorker(RasterImage* image, DecodeRequest* request);
-
-  private: /* members */
+  private:
+    DecodeDoneWorker(RasterImage* aImage);
 
     nsRefPtr<RasterImage> mImage;
-    nsRefPtr<DecodeRequest> mRequest;
   };
 
   class FrameNeededWorker : public nsRunnable
   {
   public:
     /**
      * Called by the DecodeJob with an image when it's been told by the
      * decoder that it needs a new frame to be allocated on the main thread.
      *
      * Dispatches an event to do so, which will further dispatch a
-     * DecodeRequest event to continue decoding.
+     * RequestDecode event to continue decoding.
      */
     static void GetNewFrame(RasterImage* image);
 
     NS_IMETHOD Run();
 
   private: /* methods */
     explicit FrameNeededWorker(RasterImage* image);
 
   private: /* members */
 
     nsRefPtr<RasterImage> mImage;
   };
 
   nsresult FinishedSomeDecoding(eShutdownIntent intent = eShutdownIntent_Done,
-                                DecodeRequest* request = nullptr,
                                 Progress aProgress = NoProgress);
 
   void DrawWithPreDownscaleIfNeeded(DrawableFrameRef&& aFrameRef,
                                     gfxContext* aContext,
                                     const nsIntSize& aSize,
                                     const ImageRegion& aRegion,
                                     GraphicsFilter aFilter,
                                     uint32_t aFlags);
@@ -632,17 +585,17 @@ private: // data
 
   // BEGIN LOCKED MEMBER VARIABLES
   ReentrantMonitor           mDecodingMonitor;
 
   FallibleTArray<char>       mSourceData;
 
   // Decoder and friends
   nsRefPtr<Decoder>          mDecoder;
-  nsRefPtr<DecodeRequest>    mDecodeRequest;
+  DecodeStatus               mDecodeStatus;
   // END LOCKED MEMBER VARIABLES
 
   // Notification state. Used to avoid recursive notifications.
   Progress                   mNotifyProgress;
   nsIntRect                  mNotifyInvalidRect;
   bool                       mNotifying:1;
 
   // Boolean flags (clustered together to conserve space):
--- a/image/src/imgLoader.cpp
+++ b/image/src/imgLoader.cpp
@@ -43,16 +43,17 @@
 // so we can associate the document URI with the load group.
 // until this point, we have an evil hack:
 #include "nsIHttpChannelInternal.h"
 #include "nsILoadContext.h"
 #include "nsILoadGroupChild.h"
 
 using namespace mozilla;
 using namespace mozilla::image;
+using namespace mozilla::net;
 
 MOZ_DEFINE_MALLOC_SIZE_OF(ImagesMallocSizeOf)
 
 class imgMemoryReporter MOZ_FINAL : public nsIMemoryReporter
 {
   ~imgMemoryReporter() {}
 
 public:
@@ -585,21 +586,28 @@ static bool ShouldRevalidateEntry(imgCac
     }
   }
 
   return bValidateEntry;
 }
 
 // Returns true if this request is compatible with the given CORS mode on the
 // given loading principal, and false if the request may not be reused due
-// to CORS.
+// to CORS.  Also checks the Referrer Policy, since requests with different
+// referrers/policies may generate different responses.
 static bool
-ValidateCORSAndPrincipal(imgRequest* request, bool forcePrincipalCheck,
-                         int32_t corsmode, nsIPrincipal* loadingPrincipal)
+ValidateSecurityInfo(imgRequest* request, bool forcePrincipalCheck,
+                     int32_t corsmode, nsIPrincipal* loadingPrincipal,
+                     ReferrerPolicy referrerPolicy)
 {
+  // If the entry's Referrer Policy doesn't match, we can't use this request.
+  if (referrerPolicy != request->GetReferrerPolicy()) {
+    return false;
+  }
+
   // If the entry's CORS mode doesn't match, or the CORS mode matches but the
   // document principal isn't the same, we can't use this request.
   if (request->GetCORSMode() != corsmode) {
     return false;
   } else if (request->GetCORSMode() != imgIRequest::CORS_NONE ||
              forcePrincipalCheck) {
     nsCOMPtr<nsIPrincipal> otherprincipal = request->GetLoadingPrincipal();
 
@@ -627,16 +635,17 @@ static nsresult NewImageChannel(nsIChann
                                 // create for this channel.  This is an out
                                 // param that should be set to true if this
                                 // channel ends up depending on
                                 // aLoadingPrincipal and false otherwise.
                                 bool *aForcePrincipalCheckForCacheEntry,
                                 nsIURI *aURI,
                                 nsIURI *aInitialDocumentURI,
                                 nsIURI *aReferringURI,
+                                ReferrerPolicy aReferrerPolicy,
                                 nsILoadGroup *aLoadGroup,
                                 const nsCString& aAcceptHeader,
                                 nsLoadFlags aLoadFlags,
                                 nsContentPolicyType aPolicyType,
                                 nsIPrincipal *aLoadingPrincipal,
                                 nsISupports *aRequestingContext)
 {
   nsresult rv;
@@ -723,17 +732,17 @@ static nsresult NewImageChannel(nsIChann
   if (newHttpChannel) {
     newHttpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                      aAcceptHeader,
                                      false);
 
     nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal = do_QueryInterface(newHttpChannel);
     NS_ENSURE_TRUE(httpChannelInternal, NS_ERROR_UNEXPECTED);
     httpChannelInternal->SetDocumentURI(aInitialDocumentURI);
-    newHttpChannel->SetReferrer(aReferringURI);
+    newHttpChannel->SetReferrerWithPolicy(aReferringURI, aReferrerPolicy);
   }
 
   // Image channels are loaded by default with reduced priority.
   nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(*aResult);
   if (p) {
     uint32_t priority = nsISupportsPriority::PRIORITY_LOW;
 
     if (aLoadFlags & nsIRequest::LOAD_BACKGROUND)
@@ -1452,16 +1461,17 @@ void imgLoader::CheckCacheLimits(imgCach
       RemoveFromCache(entry);
   }
 }
 
 bool imgLoader::ValidateRequestWithNewChannel(imgRequest *request,
                                                 nsIURI *aURI,
                                                 nsIURI *aInitialDocumentURI,
                                                 nsIURI *aReferrerURI,
+                                                ReferrerPolicy aReferrerPolicy,
                                                 nsILoadGroup *aLoadGroup,
                                                 imgINotificationObserver *aObserver,
                                                 nsISupports *aCX,
                                                 nsLoadFlags aLoadFlags,
                                                 nsContentPolicyType aLoadPolicyType,
                                                 imgRequestProxy **aProxyRequest,
                                                 nsIPrincipal* aLoadingPrincipal,
                                                 int32_t aCORSMode)
@@ -1502,16 +1512,17 @@ bool imgLoader::ValidateRequestWithNewCh
     // cache.
     nsCOMPtr<nsIChannel> newChannel;
     bool forcePrincipalCheck;
     rv = NewImageChannel(getter_AddRefs(newChannel),
                          &forcePrincipalCheck,
                          aURI,
                          aInitialDocumentURI,
                          aReferrerURI,
+                         aReferrerPolicy,
                          aLoadGroup,
                          mAcceptHeader,
                          aLoadFlags,
                          aLoadPolicyType,
                          aLoadingPrincipal,
                          aCX);
     if (NS_FAILED(rv)) {
       return false;
@@ -1579,16 +1590,17 @@ bool imgLoader::ValidateRequestWithNewCh
     return NS_SUCCEEDED(rv);
   }
 }
 
 bool imgLoader::ValidateEntry(imgCacheEntry *aEntry,
                                 nsIURI *aURI,
                                 nsIURI *aInitialDocumentURI,
                                 nsIURI *aReferrerURI,
+                                ReferrerPolicy aReferrerPolicy,
                                 nsILoadGroup *aLoadGroup,
                                 imgINotificationObserver *aObserver,
                                 nsISupports *aCX,
                                 nsLoadFlags aLoadFlags,
                                 nsContentPolicyType aLoadPolicyType,
                                 bool aCanMakeNewChannel,
                                 imgRequestProxy **aProxyRequest,
                                 nsIPrincipal* aLoadingPrincipal,
@@ -1624,18 +1636,19 @@ bool imgLoader::ValidateEntry(imgCacheEn
     }
   }
 
   nsRefPtr<imgRequest> request(aEntry->GetRequest());
 
   if (!request)
     return false;
 
-  if (!ValidateCORSAndPrincipal(request, aEntry->ForcePrincipalCheck(),
-                                aCORSMode, aLoadingPrincipal))
+  if (!ValidateSecurityInfo(request, aEntry->ForcePrincipalCheck(),
+                            aCORSMode, aLoadingPrincipal,
+                            aReferrerPolicy))
     return false;
 
   // data URIs are immutable and by their nature can't leak data, so we can
   // just return true in that case.  Doing so would mean that shift-reload
   // doesn't reload data URI documents/images though (which is handy for
   // debugging during gecko development) so we make an exception in that case.
   nsAutoCString scheme;
   aURI->GetScheme(scheme);
@@ -1694,17 +1707,18 @@ bool imgLoader::ValidateEntry(imgCacheEn
             address_of(request)));
     return false;
   }
 
   if (validateRequest && aCanMakeNewChannel) {
     LOG_SCOPE(GetImgLog(), "imgLoader::ValidateRequest |cache hit| must validate");
 
     return ValidateRequestWithNewChannel(request, aURI, aInitialDocumentURI,
-                                         aReferrerURI, aLoadGroup, aObserver,
+                                         aReferrerURI, aReferrerPolicy,
+                                         aLoadGroup, aObserver,
                                          aCX, aLoadFlags, aLoadPolicyType,
                                          aProxyRequest, aLoadingPrincipal,
                                          aCORSMode);
   }
 
   return !validateRequest;
 }
 
@@ -1865,58 +1879,62 @@ void imgLoader::RemoveFromUncachedImages
 
 #define LOAD_FLAGS_VALIDATE_MASK (nsIRequest::VALIDATE_ALWAYS |   \
                                   nsIRequest::VALIDATE_NEVER |    \
                                   nsIRequest::VALIDATE_ONCE_PER_SESSION)
 
 NS_IMETHODIMP imgLoader::LoadImageXPCOM(nsIURI *aURI,
                                    nsIURI *aInitialDocumentURI,
                                    nsIURI *aReferrerURI,
+                                   const nsAString& aReferrerPolicy,
                                    nsIPrincipal* aLoadingPrincipal,
                                    nsILoadGroup *aLoadGroup,
                                    imgINotificationObserver *aObserver,
                                    nsISupports *aCX,
                                    nsLoadFlags aLoadFlags,
                                    nsISupports *aCacheKey,
                                    nsContentPolicyType aContentPolicyType,
                                    imgIRequest **_retval)
 {
     // Optional parameter, so defaults to 0 (== TYPE_INVALID)
     if (!aContentPolicyType) {
       aContentPolicyType = nsIContentPolicy::TYPE_IMAGE;
     }
     imgRequestProxy *proxy;
-    nsresult result = LoadImage(aURI,
-                                aInitialDocumentURI,
-                                aReferrerURI,
-                                aLoadingPrincipal,
-                                aLoadGroup,
-                                aObserver,
-                                aCX,
-                                aLoadFlags,
-                                aCacheKey,
-                                aContentPolicyType,
-                                EmptyString(),
-                                &proxy);
+    ReferrerPolicy refpol = ReferrerPolicyFromString(aReferrerPolicy);
+    nsresult rv = LoadImage(aURI,
+                            aInitialDocumentURI,
+                            aReferrerURI,
+                            refpol,
+                            aLoadingPrincipal,
+                            aLoadGroup,
+                            aObserver,
+                            aCX,
+                            aLoadFlags,
+                            aCacheKey,
+                            aContentPolicyType,
+                            EmptyString(),
+                            &proxy);
     *_retval = proxy;
-    return result;
+    return rv;
 }
 
 // imgIRequest loadImage(in nsIURI aURI,
 //                       in nsIURI aInitialDocumentURL,
 //                       in nsIURI aReferrerURI,
 //                       in nsIPrincipal aLoadingPrincipal,
 //                       in nsILoadGroup aLoadGroup,
 //                       in imgINotificationObserver aObserver,
 //                       in nsISupports aCX,
 //                       in nsLoadFlags aLoadFlags,
 //                       in nsISupports cacheKey);
 nsresult imgLoader::LoadImage(nsIURI *aURI,
                               nsIURI *aInitialDocumentURI,
                               nsIURI *aReferrerURI,
+                              ReferrerPolicy aReferrerPolicy,
                               nsIPrincipal* aLoadingPrincipal,
                               nsILoadGroup *aLoadGroup,
                               imgINotificationObserver *aObserver,
                               nsISupports *aCX,
                               nsLoadFlags aLoadFlags,
                               nsISupports *aCacheKey,
                               nsContentPolicyType aContentPolicyType,
                               const nsAString& initiatorType,
@@ -1992,18 +2010,18 @@ nsresult imgLoader::LoadImage(nsIURI *aU
   // Look in the cache for our URI, and then validate it.
   // XXX For now ignore aCacheKey. We will need it in the future
   // for correctly dealing with image load requests that are a result
   // of post data.
   imgCacheTable &cache = GetCache(aURI);
 
   if (cache.Get(spec, getter_AddRefs(entry)) && entry) {
     if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerURI,
-                      aLoadGroup, aObserver, aCX, requestFlags,
-                      aContentPolicyType, true, _retval,
+                      aReferrerPolicy, aLoadGroup, aObserver, aCX,
+                      requestFlags, aContentPolicyType, true, _retval,
                       aLoadingPrincipal, corsmode)) {
       request = entry->GetRequest();
 
       // If this entry has no proxies, its request has no reference to the entry.
       if (entry->HasNoProxies()) {
         LOG_FUNC_WITH_PARAM(GetImgLog(), "imgLoader::LoadImage() adding proxyless entry", "uri", spec.get());
         NS_ABORT_IF_FALSE(!request->HasCacheEntry(), "Proxyless entry's request has cache entry!");
         request->SetCacheEntry(entry);
@@ -2033,16 +2051,17 @@ nsresult imgLoader::LoadImage(nsIURI *aU
     LOG_SCOPE(GetImgLog(), "imgLoader::LoadImage |cache miss|");
 
     bool forcePrincipalCheck;
     rv = NewImageChannel(getter_AddRefs(newChannel),
                          &forcePrincipalCheck,
                          aURI,
                          aInitialDocumentURI,
                          aReferrerURI,
+                         aReferrerPolicy,
                          aLoadGroup,
                          mAcceptHeader,
                          requestFlags,
                          aContentPolicyType,
                          aLoadingPrincipal,
                          aCX);
     if (NS_FAILED(rv))
       return NS_ERROR_FAILURE;
@@ -2052,17 +2071,17 @@ nsresult imgLoader::LoadImage(nsIURI *aU
     NewRequestAndEntry(forcePrincipalCheck, this, getter_AddRefs(request), getter_AddRefs(entry));
 
     PR_LOG(GetImgLog(), PR_LOG_DEBUG,
            ("[this=%p] imgLoader::LoadImage -- Created new imgRequest [request=%p]\n", this, request.get()));
 
     nsCOMPtr<nsILoadGroup> channelLoadGroup;
     newChannel->GetLoadGroup(getter_AddRefs(channelLoadGroup));
     request->Init(aURI, aURI, channelLoadGroup, newChannel, entry, aCX,
-                  aLoadingPrincipal, corsmode);
+                  aLoadingPrincipal, corsmode, aReferrerPolicy);
 
     // Add the initiator type for this image load
     nsCOMPtr<nsITimedChannel> timedChannel = do_QueryInterface(newChannel);
     if (timedChannel) {
       timedChannel->SetInitiatorType(initiatorType);
     }
 
     // Pass the inner window ID of the loading document, if possible.
@@ -2222,18 +2241,18 @@ nsresult imgLoader::LoadImageWithChannel
       // it says that the entry isn't valid any more, we'll only use the entry
       // we're getting if the channel is loading from the cache anyways.
       //
       // XXX -- should this be changed? it's pretty much verbatim from the old
       // code, but seems nonsensical.
       //
       // Since aCanMakeNewChannel == false, we don't need to pass content policy
       // type/principal/etc
-      if (ValidateEntry(entry, uri, nullptr, nullptr, nullptr,
-                        aObserver, aCX, requestFlags,
+      if (ValidateEntry(entry, uri, nullptr, nullptr, RP_Default,
+                        nullptr, aObserver, aCX, requestFlags,
                         nsIContentPolicy::TYPE_INVALID, false, nullptr,
                         nullptr, imgIRequest::CORS_NONE)) {
         request = entry->GetRequest();
       } else {
         nsCOMPtr<nsICachingChannel> cacheChan(do_QueryInterface(channel));
         bool bUseCacheCopy;
 
         if (cacheChan)
@@ -2286,17 +2305,17 @@ nsresult imgLoader::LoadImageWithChannel
     NewRequestAndEntry(true, this, getter_AddRefs(request), getter_AddRefs(entry));
 
     // We use originalURI here to fulfil the imgIRequest contract on GetURI.
     nsCOMPtr<nsIURI> originalURI;
     channel->GetOriginalURI(getter_AddRefs(originalURI));
 
     // No principal specified here, because we're not passed one.
     request->Init(originalURI, uri, channel, channel, entry,
-                  aCX, nullptr, imgIRequest::CORS_NONE);
+                  aCX, nullptr, imgIRequest::CORS_NONE, RP_Default);
 
     ProxyListener *pl = new ProxyListener(static_cast<nsIStreamListener *>(request.get()));
     NS_ADDREF(pl);
 
     *listener = static_cast<nsIStreamListener*>(pl);
     NS_ADDREF(*listener);
 
     NS_RELEASE(pl);
@@ -2607,30 +2626,31 @@ NS_IMETHODIMP imgCacheValidator::OnStart
 
 #if defined(PR_LOGGING)
   nsAutoCString spec;
   uri->GetSpec(spec);
   LOG_MSG_WITH_PARAM(GetImgLog(), "imgCacheValidator::OnStartRequest creating new request", "uri", spec.get());
 #endif
 
   int32_t corsmode = mRequest->GetCORSMode();
+  ReferrerPolicy refpol = mRequest->GetReferrerPolicy();
   nsCOMPtr<nsIPrincipal> loadingPrincipal = mRequest->GetLoadingPrincipal();
 
   // Doom the old request's cache entry
   mRequest->RemoveFromCache();
 
   mRequest->mValidator = nullptr;
   mRequest = nullptr;
 
   // We use originalURI here to fulfil the imgIRequest contract on GetURI.
   nsCOMPtr<nsIURI> originalURI;
   channel->GetOriginalURI(getter_AddRefs(originalURI));
   mNewRequest->Init(originalURI, uri, aRequest, channel, mNewEntry,
                     mContext, loadingPrincipal,
-                    corsmode);
+                    corsmode, refpol);
 
   mDestListener = new ProxyListener(mNewRequest);
 
   // Try to add the new request into the cache. Note that the entry must be in
   // the cache before the proxies' ownership changes, because adding a proxy
   // changes the caching behaviour for imgRequests.
   mImgLoader->PutIntoCache(originalURI, mNewEntry);
 
--- a/image/src/imgLoader.h
+++ b/image/src/imgLoader.h
@@ -17,16 +17,17 @@
 #include "nsRefPtrHashtable.h"
 #include "nsExpirationTracker.h"
 #include "nsAutoPtr.h"
 #include "imgRequest.h"
 #include "nsIProgressEventSink.h"
 #include "nsIChannel.h"
 #include "nsIThreadRetargetableStreamListener.h"
 #include "imgIRequest.h"
+#include "mozilla/net/ReferrerPolicy.h"
 
 class imgLoader;
 class imgRequestProxy;
 class imgINotificationObserver;
 class nsILoadGroup;
 class imgCacheExpirationTracker;
 class imgMemoryReporter;
 
@@ -212,16 +213,17 @@ class imgLoader MOZ_FINAL : public imgIL
                             public nsIObserver
 {
   virtual ~imgLoader();
 
 public:
   typedef mozilla::image::ImageURL ImageURL;
   typedef nsRefPtrHashtable<nsCStringHashKey, imgCacheEntry> imgCacheTable;
   typedef nsTHashtable<nsPtrHashKey<imgRequest>> imgSet;
+  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
   typedef mozilla::Mutex Mutex;
 
   NS_DECL_ISUPPORTS
   NS_DECL_IMGILOADER
   NS_DECL_NSICONTENTSNIFFER
   NS_DECL_IMGICACHE
   NS_DECL_NSIOBSERVER
 
@@ -246,16 +248,17 @@ public:
       return static_cast<imgLoader*>(loader);
   }
 
   static already_AddRefed<imgLoader> GetInstance();
 
   nsresult LoadImage(nsIURI *aURI,
                      nsIURI *aInitialDocumentURI,
                      nsIURI *aReferrerURI,
+                     ReferrerPolicy aReferrerPolicy,
                      nsIPrincipal* aLoadingPrincipal,
                      nsILoadGroup *aLoadGroup,
                      imgINotificationObserver *aObserver,
                      nsISupports *aCX,
                      nsLoadFlags aLoadFlags,
                      nsISupports *aCacheKey,
                      nsContentPolicyType aContentPolicyType,
                      const nsAString& initiatorType,
@@ -331,28 +334,30 @@ public:
   // observers is re-requested.
   bool SetHasNoProxies(imgRequest *aRequest, imgCacheEntry *aEntry);
   bool SetHasProxies(imgRequest *aRequest);
 
 private: // methods
 
   bool ValidateEntry(imgCacheEntry *aEntry, nsIURI *aKey,
                        nsIURI *aInitialDocumentURI, nsIURI *aReferrerURI,
+                       ReferrerPolicy aReferrerPolicy,
                        nsILoadGroup *aLoadGroup,
                        imgINotificationObserver *aObserver, nsISupports *aCX,
                        nsLoadFlags aLoadFlags,
                        nsContentPolicyType aContentPolicyType,
                        bool aCanMakeNewChannel,
                        imgRequestProxy **aProxyRequest,
                        nsIPrincipal* aLoadingPrincipal,
                        int32_t aCORSMode);
 
   bool ValidateRequestWithNewChannel(imgRequest *request, nsIURI *aURI,
                                        nsIURI *aInitialDocumentURI,
                                        nsIURI *aReferrerURI,
+                                       ReferrerPolicy aReferrerPolicy,
                                        nsILoadGroup *aLoadGroup,
                                        imgINotificationObserver *aObserver,
                                        nsISupports *aCX, nsLoadFlags aLoadFlags,
                                        nsContentPolicyType aContentPolicyType,
                                        imgRequestProxy **aProxyRequest,
                                        nsIPrincipal* aLoadingPrincipal,
                                        int32_t aCORSMode);
 
--- a/image/src/imgRequest.cpp
+++ b/image/src/imgRequest.cpp
@@ -61,16 +61,17 @@ NS_IMPL_ISUPPORTS(imgRequest,
                   nsIAsyncVerifyRedirectCallback)
 
 imgRequest::imgRequest(imgLoader* aLoader)
  : mLoader(aLoader)
  , mProgressTracker(new ProgressTracker(nullptr))
  , mValidator(nullptr)
  , mInnerWindowId(0)
  , mCORSMode(imgIRequest::CORS_NONE)
+ , mReferrerPolicy(mozilla::net::RP_Default)
  , mImageErrorCode(NS_OK)
  , mDecodeRequested(false)
  , mIsMultiPartChannel(false)
  , mGotData(false)
  , mIsInCache(false)
  , mResniffMimeType(false)
 { }
 
@@ -89,17 +90,18 @@ imgRequest::~imgRequest()
 
 nsresult imgRequest::Init(nsIURI *aURI,
                           nsIURI *aCurrentURI,
                           nsIRequest *aRequest,
                           nsIChannel *aChannel,
                           imgCacheEntry *aCacheEntry,
                           void *aLoadId,
                           nsIPrincipal* aLoadingPrincipal,
-                          int32_t aCORSMode)
+                          int32_t aCORSMode,
+                          ReferrerPolicy aReferrerPolicy)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Cannot use nsIURI off main thread!");
 
   LOG_FUNC(GetImgLog(), "imgRequest::Init");
 
   NS_ABORT_IF_FALSE(!mImage, "Multiple calls to init");
   NS_ABORT_IF_FALSE(aURI, "No uri");
   NS_ABORT_IF_FALSE(aCurrentURI, "No current uri");
@@ -112,16 +114,17 @@ nsresult imgRequest::Init(nsIURI *aURI,
   mURI = new ImageURL(aURI);
   mCurrentURI = aCurrentURI;
   mRequest = aRequest;
   mChannel = aChannel;
   mTimedChannel = do_QueryInterface(mChannel);
 
   mLoadingPrincipal = aLoadingPrincipal;
   mCORSMode = aCORSMode;
+  mReferrerPolicy = aReferrerPolicy;
 
   mChannel->GetNotificationCallbacks(getter_AddRefs(mPrevChannelSink));
 
   NS_ASSERTION(mPrevChannelSink != this,
                "Initializing with a channel that already calls back to us!");
 
   mChannel->SetNotificationCallbacks(this);
 
--- a/image/src/imgRequest.h
+++ b/image/src/imgRequest.h
@@ -14,16 +14,17 @@
 #include "nsIPrincipal.h"
 
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsProxyRelease.h"
 #include "nsStringGlue.h"
 #include "nsError.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
+#include "mozilla/net/ReferrerPolicy.h"
 
 class imgCacheValidator;
 class imgLoader;
 class imgRequestProxy;
 class imgCacheEntry;
 class imgMemoryReporter;
 class imgRequestNotifyRunnable;
 class nsIApplicationCache;
@@ -47,29 +48,31 @@ class imgRequest MOZ_FINAL : public nsIS
                              public nsIAsyncVerifyRedirectCallback
 {
   virtual ~imgRequest();
 
 public:
   typedef mozilla::image::Image Image;
   typedef mozilla::image::ImageURL ImageURL;
   typedef mozilla::image::ProgressTracker ProgressTracker;
+  typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
 
   explicit imgRequest(imgLoader* aLoader);
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
   nsresult Init(nsIURI *aURI,
                 nsIURI *aCurrentURI,
                 nsIRequest *aRequest,
                 nsIChannel *aChannel,
                 imgCacheEntry *aCacheEntry,
                 void *aLoadId,
                 nsIPrincipal* aLoadingPrincipal,
-                int32_t aCORSMode);
+                int32_t aCORSMode,
+                ReferrerPolicy aReferrerPolicy);
 
   void ClearLoader();
 
   // Callers must call imgRequestProxy::Notify later.
   void AddProxy(imgRequestProxy *proxy);
 
   nsresult RemoveProxy(imgRequestProxy *proxy, nsresult aStatus);
 
@@ -111,16 +114,19 @@ public:
   // HTTP cache may contain a different data then app cache.
   bool CacheChanged(nsIRequest* aNewRequest);
 
   bool GetMultipart() const { return mIsMultiPartChannel; }
 
   // The CORS mode for which we loaded this image.
   int32_t GetCORSMode() const { return mCORSMode; }
 
+  // The Referrer Policy in effect when loading this image.
+  ReferrerPolicy GetReferrerPolicy() const { return mReferrerPolicy; }
+
   // The principal for the document that loaded this image. Used when trying to
   // validate a CORS image load.
   already_AddRefed<nsIPrincipal> GetLoadingPrincipal() const
   {
     nsCOMPtr<nsIPrincipal> principal = mLoadingPrincipal;
     return principal.forget();
   }
 
@@ -248,16 +254,19 @@ private:
 
   // The ID of the inner window origin, used for error reporting.
   uint64_t mInnerWindowId;
 
   // The CORS mode (defined in imgIRequest) this image was loaded with. By
   // default, imgIRequest::CORS_NONE.
   int32_t mCORSMode;
 
+  // The Referrer Policy (defined in ReferrerPolicy.h) used for this image.
+  ReferrerPolicy mReferrerPolicy;
+
   nsresult mImageErrorCode;
 
   // Sometimes consumers want to do things before the image is ready. Let them,
   // and apply the action when the image becomes available.
   bool mDecodeRequested : 1;
 
   bool mIsMultiPartChannel : 1;
   bool mGotData : 1;
--- a/image/test/unit/async_load_tests.js
+++ b/image/test/unit/async_load_tests.js
@@ -91,17 +91,17 @@ function secondLoadDone(oldlistener, aRe
 // therefore would be at most risk of being served synchronously.
 function checkSecondLoad()
 {
   do_test_pending();
 
   var listener = new ImageListener(checkClone, secondLoadDone);
   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
                 .createScriptedObserver(listener);
-  requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, null, null, outer, null, 0, null));
+  requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null));
   listener.synchronous = false;
 }
 
 function firstLoadDone(oldlistener, aRequest)
 {
   checkSecondLoad(uri);
 
   do_test_finished();
@@ -189,17 +189,17 @@ function startImageCallback(otherCb)
 {
   return function(listener, request)
   {
     // Make sure we can load the same image immediately out of the cache.
     do_test_pending();
     var listener2 = new ImageListener(null, function(foo, bar) { do_test_finished(); });
     var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
                   .createScriptedObserver(listener2);
-    requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, null, null, outer, null, 0, null));
+    requests.push(gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null));
     listener2.synchronous = false;
 
     // Now that we've started another load, chain to the callback.
     otherCb(listener, request);
   }
 }
 
 var gCurrentLoader;
@@ -216,16 +216,16 @@ function run_test()
   do_register_cleanup(cleanup);
 
   gCurrentLoader = Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader);
 
   do_test_pending();
   var listener = new ImageListener(startImageCallback(checkClone), firstLoadDone);
   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
                 .createScriptedObserver(listener);
-  var req = gCurrentLoader.loadImageXPCOM(uri, null, null, null, null, outer, null, 0, null);
+  var req = gCurrentLoader.loadImageXPCOM(uri, null, null, "default", null, null, outer, null, 0, null);
   requests.push(req);
 
   // Ensure that we don't cause any mayhem when we lock an image.
   req.lockImage();
 
   listener.synchronous = false;
 }
--- a/image/test/unit/test_private_channel.js
+++ b/image/test/unit/test_private_channel.js
@@ -72,17 +72,17 @@ function setup_chan(path, isPrivate, cal
 function loadImage(isPrivate, callback) {
   var listener = new ImageListener(null, callback);
   var outer = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools)
                 .createScriptedObserver(listener);
   var uri = gIoService.newURI(gImgPath, null, null);
   var loadGroup = Cc["@mozilla.org/network/load-group;1"].createInstance(Ci.nsILoadGroup);
   loadGroup.notificationCallbacks = new NotificationCallbacks(isPrivate);
   var loader = isPrivate ? gPrivateLoader : gPublicLoader;
-  requests.push(loader.loadImageXPCOM(uri, null, null, null, loadGroup, outer, null, 0, null));
+  requests.push(loader.loadImageXPCOM(uri, null, null, "default", null, loadGroup, outer, null, 0, null));
   listener.synchronous = false;
 }
 
 function run_loadImage_tests() {
   function observer() {
     Services.obs.removeObserver(observer, "cacheservice:empty-cache");
     gHits = 0;
     loadImage(false, function() {
--- a/js/src/asmjs/AsmJSModule.cpp
+++ b/js/src/asmjs/AsmJSModule.cpp
@@ -1587,16 +1587,19 @@ AsmJSModule::changeHeap(Handle<ArrayBuff
 
     // Content JS should not be able to run (and change heap) from within an
     // interrupt callback, but in case it does, fail to change heap. Otherwise,
     // the heap can change at every single instruction which would prevent
     // future optimizations like heap-base hoisting.
     if (interrupted_)
         return false;
 
+    AutoFlushICache afc("AsmJSModule::changeHeap");
+    setAutoFlushICacheRange();
+
     restoreHeapToInitialState(maybeHeap_);
     initHeap(newHeap, cx);
     return true;
 }
 
 void
 AsmJSModule::setProfilingEnabled(bool enabled, JSContext *cx)
 {
--- a/js/src/builtin/String.js
+++ b/js/src/builtin/String.js
@@ -1,14 +1,134 @@
 /* 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/. */
 
 /*global intl_Collator: false, */
 
+/* ES6 Draft Oct 14, 2014 21.1.3.19 */
+function String_substring(start, end) {
+    // Steps 1-3.
+    CheckObjectCoercible(this);
+    var str = ToString(this);
+
+    // Step 4.
+    var len = str.length;
+
+    // Step 5.
+    var intStart = ToInteger(start);
+
+    // Step 6.
+    var intEnd = (end === undefined) ? len : ToInteger(end);
+
+    // Step 7.
+    var finalStart = std_Math_min(std_Math_max(intStart, 0), len);
+
+    // Step 8.
+    var finalEnd = std_Math_min(std_Math_max(intEnd, 0), len);
+
+    // Steps 9-10.
+    var from, to;
+    if (finalStart < finalEnd) {
+        from = finalStart;
+        to = finalEnd;
+    } else {
+        from = finalEnd;
+        to = finalStart;
+    }
+
+    // Step 11.
+    // While |from| and |to - from| are bounded to the length of |str| and this
+    // and thus definitely in the int32 range, they can still be typed as
+    // double. Eagerly truncate since SubstringKernel only accepts int32.
+    return SubstringKernel(str, from | 0, (to - from) | 0);
+}
+
+function String_static_substring(string, start, end) {
+    if (arguments.length < 1)
+        ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'String.substring');
+    return callFunction(String_substring, string, start, end);
+}
+
+/* ES6 Draft Oct 14, 2014 B.2.3.1 */
+function String_substr(start, length) {
+    // Steps 1-2.
+    CheckObjectCoercible(this);
+    var str = ToString(this);
+
+    // Steps 3-4.
+    var intStart = ToInteger(start);
+
+    // Steps 5-7.
+    var size = str.length;
+    // Use |size| instead of +Infinity to avoid performing calculations with
+    // doubles. (The result is the same either way.)
+    var end = (length === undefined) ? size : ToInteger(length);
+
+    // Step 8.
+    if (intStart < 0)
+        intStart = std_Math_max(intStart + size, 0);
+
+    // Step 9.
+    var resultLength = std_Math_min(std_Math_max(end, 0), size - intStart)
+
+    // Step 10.
+    if (resultLength <= 0)
+        return "";
+
+    // Step 11.
+    // While |intStart| and |resultLength| are bounded to the length of |str|
+    // and thus definitely in the int32 range, they can still be typed as
+    // double. Eagerly truncate since SubstringKernel only accepts int32.
+    return SubstringKernel(str, intStart | 0, resultLength | 0);
+}
+
+function String_static_substr(string, start, length) {
+    if (arguments.length < 1)
+        ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'String.substr');
+    return callFunction(String_substr, string, start, length);
+}
+
+/* ES6 Draft Oct 14, 2014 21.1.3.16 */
+function String_slice(start, end) {
+    // Steps 1-3.
+    CheckObjectCoercible(this);
+    var str = ToString(this);
+
+    // Step 4.
+    var len = str.length;
+
+    // Step 5.
+    var intStart = ToInteger(start);
+
+    // Step 6.
+    var intEnd = (end === undefined) ? len : ToInteger(end);
+
+    // Step 7.
+    var from = (intStart < 0) ? std_Math_max(len + intStart, 0) : std_Math_min(intStart, len);
+
+    // Step 8.
+    var to = (intEnd < 0) ? std_Math_max(len + intEnd, 0) : std_Math_min(intEnd, len);
+
+    // Step 9.
+    var span = std_Math_max(to - from, 0);
+
+    // Step 10.
+    // While |from| and |span| are bounded to the length of |str|
+    // and thus definitely in the int32 range, they can still be typed as
+    // double. Eagerly truncate since SubstringKernel only accepts int32.
+    return SubstringKernel(str, from | 0, span | 0);
+}
+
+function String_static_slice(string, start, end) {
+    if (arguments.length < 1)
+        ThrowError(JSMSG_MISSING_FUN_ARG, 0, 'String.slice');
+    return callFunction(String_slice, string, start, end);
+}
+
 /* ES6 Draft September 5, 2013 21.1.3.3 */
 function String_codePointAt(pos) {
     // Steps 1-3.
     CheckObjectCoercible(this);
     var S = ToString(this);
 
     // Steps 4-5.
     var position = ToInteger(pos);
--- a/js/src/builtin/TypedObject.h
+++ b/js/src/builtin/TypedObject.h
@@ -720,17 +720,21 @@ class InlineTypedObject : public TypedOb
   public:
     static const size_t MaximumSize =
         sizeof(NativeObject) - sizeof(TypedObject) + NativeObject::MAX_FIXED_SLOTS * sizeof(Value);
 
     static gc::AllocKind allocKindForTypeDescriptor(TypeDescr *descr) {
         size_t nbytes = descr->size();
         MOZ_ASSERT(nbytes <= MaximumSize);
 
-        size_t dataSlots = AlignBytes(nbytes, sizeof(Value) / sizeof(Value));
+        if (nbytes <= sizeof(NativeObject) - sizeof(TypedObject))
+            return gc::FINALIZE_OBJECT0;
+        nbytes -= sizeof(NativeObject) - sizeof(TypedObject);
+
+        size_t dataSlots = AlignBytes(nbytes, sizeof(Value)) / sizeof(Value);
         MOZ_ASSERT(nbytes <= dataSlots * sizeof(Value));
         return gc::GetGCObjectKind(dataSlots);
     }
 
     uint8_t *inlineTypedMem() const {
         static_assert(offsetof(InlineTypedObject, data_) == sizeof(JSObject),
                       "The data for an inline typed object must follow the shape and type.");
         return (uint8_t *) &data_;
@@ -979,16 +983,30 @@ IsTypedObjectClass(const Class *class_)
 
 inline bool
 IsOpaqueTypedObjectClass(const Class *class_)
 {
     return class_ == &OutlineOpaqueTypedObject::class_ ||
            class_ == &InlineOpaqueTypedObject::class_;
 }
 
+inline bool
+IsOutlineTypedObjectClass(const Class *class_)
+{
+    return class_ == &OutlineOpaqueTypedObject::class_ ||
+           class_ == &OutlineTransparentTypedObject::class_;
+}
+
+inline bool
+IsInlineTypedObjectClass(const Class *class_)
+{
+    return class_ == &InlineOpaqueTypedObject::class_ ||
+           class_ == &InlineTransparentTypedObject::class_;
+}
+
 inline const Class *
 GetOutlineTypedObjectClass(bool opaque)
 {
     return opaque ? &OutlineOpaqueTypedObject::class_ : &OutlineTransparentTypedObject::class_;
 }
 
 inline bool
 IsSimpleTypeDescrClass(const Class* clasp)
--- a/js/src/builtin/TypedObject.js
+++ b/js/src/builtin/TypedObject.js
@@ -786,17 +786,17 @@ function BuildTypedSeqImpl(arrayType, le
     // RangeError("bad depth")
     ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
 
   // For example, if we have as input
   //    ArrayType(ArrayType(T, 4), 5)
   // and a depth of 2, we get
   //    grainType = T
   //    iterationSpace = [5, 4]
-  var [iterationSpace, grainType, totalLength] =
+  var {iterationSpace, grainType, totalLength} =
     ComputeIterationSpace(arrayType, depth, len);
 
   // Create a zeroed instance with no data
   var result = new arrayType();
 
   var indices = NewDenseArray(depth);
   for (var i = 0; i < depth; i++) {
     indices[i] = 0;
@@ -840,17 +840,19 @@ function ComputeIterationSpace(arrayType
       iterationSpace[i] = grainLen;
       totalLength *= grainLen;
       grainType = grainType.elementType;
     } else {
       // RangeError("Depth "+depth+" too high");
       ThrowError(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS);
     }
   }
-  return [iterationSpace, grainType, totalLength];
+  return { iterationSpace: iterationSpace,
+           grainType: grainType,
+           totalLength: totalLength };
 }
 
 function IncrementIterationSpace(indices, iterationSpace) {
   // Increment something like
   //     [5, 5, 7, 8]
   // in an iteration space of
   //     [9, 9, 9, 9]
   // to
@@ -932,21 +934,21 @@ function MapTypedSeqImpl(inArray, depth,
   assert(IsObject(inArray) && ObjectIsTypedObject(inArray), "Map/From called on non-object or untyped input array.");
   assert(TypeDescrIsArrayType(outputType), "Map/From called on non array-type outputType");
 
   if (depth <= 0 || TO_INT32(depth) !== depth)
     ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
 
   // Compute iteration space for input and output and check for compatibility.
   var inputType = TypeOfTypedObject(inArray);
-  var [inIterationSpace, inGrainType, _] =
+  var {iterationSpace:inIterationSpace, grainType:inGrainType} =
     ComputeIterationSpace(inputType, depth, inArray.length);
   if (!IsObject(inGrainType) || !ObjectIsTypeDescr(inGrainType))
     ThrowError(JSMSG_TYPEDOBJECT_BAD_ARGS);
-  var [iterationSpace, outGrainType, totalLength] =
+  var {iterationSpace, grainType:outGrainType, totalLength} =
     ComputeIterationSpace(outputType, depth, outputType.length);
   for (var i = 0; i < depth; i++)
     if (inIterationSpace[i] !== iterationSpace[i])
       // TypeError("Incompatible iteration space in input and output type");
       ThrowError(JSMSG_TYPEDOBJECT_ARRAYTYPE_BAD_ARGS);
 
   // Create a zeroed instance with no data
   var result = new outputType();
--- a/js/src/builtin/Utilities.js
+++ b/js/src/builtin/Utilities.js
@@ -27,16 +27,17 @@
 
 // All C++-implemented standard builtins library functions used in self-hosted
 // code are installed via the std_functions JSFunctionSpec[] in
 // SelfHosting.cpp.
 //
 // The few items below here are either self-hosted or installing them under a
 // std_Foo name would require ugly contortions, so they just get aliased here.
 var std_Array_indexOf = ArrayIndexOf;
+var std_String_substring = String_substring;
 // WeakMap is a bare constructor without properties or methods.
 var std_WeakMap = WeakMap;
 // StopIteration is a bare constructor without properties or methods.
 var std_StopIteration = StopIteration;
 
 
 /********** List specification type **********/
 
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -3420,16 +3420,20 @@ static bool EmitIterator(ExclusiveContex
 
 /**
  * EmitIteratorNext will pop iterator from the top of the stack.
  * It will push the result of |.next()| onto the stack.
  */
 static bool
 EmitIteratorNext(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn=nullptr)
 {
+    MOZ_ASSERT(bce->emitterMode != BytecodeEmitter::SelfHosting,
+               ".next() iteration is prohibited in self-hosted code because it "
+               "can run user-modifiable iteration code");
+
     if (Emit1(cx, bce, JSOP_DUP) < 0)                          // ... ITER ITER
         return false;
     if (!EmitAtomOp(cx, cx->names().next, JSOP_CALLPROP, bce)) // ... ITER NEXT
         return false;
     if (Emit1(cx, bce, JSOP_SWAP) < 0)                         // ... NEXT ITER
         return false;
     if (EmitCall(cx, bce, JSOP_CALL, 0, pn) < 0)               // ... RESULT
         return false;
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -302,16 +302,17 @@ class GCRuntime
     };
     void markRuntime(JSTracer *trc,
                      TraceOrMarkRuntime traceOrMark = TraceRuntime,
                      TraceRootsOrUsedSaved rootsSource = TraceRoots);
 
     void notifyDidPaint();
     void shrinkBuffers();
     void onOutOfMallocMemory();
+    void onOutOfMallocMemory(const AutoLockGC &lock);
 
 #ifdef JS_GC_ZEAL
     const void *addressOfZealMode() { return &zealMode; }
     void setZeal(uint8_t zeal, uint32_t frequency);
     void setNextScheduled(uint32_t count);
     void verifyPreBarriers();
     void verifyPostBarriers();
     void maybeVerifyPreBarriers(bool always);
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -947,17 +947,19 @@ struct Chunk
 
     inline void addToAvailableList(JSRuntime *rt);
     inline void insertToAvailableList(Chunk **insertPoint);
     inline void removeFromAvailableList();
 
     ArenaHeader *allocateArena(JSRuntime *rt, JS::Zone *zone, AllocKind kind,
                                const AutoLockGC &lock);
 
-    void releaseArena(JSRuntime *rt, ArenaHeader *aheader, const AutoLockGC &lock);
+    enum ArenaDecommitState { IsCommitted = false, IsDecommitted = true };
+    void releaseArena(JSRuntime *rt, ArenaHeader *aheader, const AutoLockGC &lock,
+                      ArenaDecommitState state = IsCommitted);
     void recycleArena(ArenaHeader *aheader, SortedArenaList &dest, AllocKind thingKind,
                       size_t thingsPerArena);
 
     static Chunk *allocate(JSRuntime *rt);
 
     void decommitAllArenas(JSRuntime *rt);
 
     /*
@@ -978,21 +980,22 @@ struct Chunk
 
   private:
     inline void init(JSRuntime *rt);
 
     /* Search for a decommitted arena to allocate. */
     unsigned findDecommittedArenaOffset();
     ArenaHeader* fetchNextDecommittedArena();
 
+    void addArenaToFreeList(JSRuntime *rt, ArenaHeader *aheader);
+    void addArenaToDecommittedList(JSRuntime *rt, const ArenaHeader *aheader);
+
   public:
     /* Unlink and return the freeArenasHead. */
     inline ArenaHeader* fetchNextFreeArena(JSRuntime *rt);
-
-    inline void addArenaToFreeList(JSRuntime *rt, ArenaHeader *aheader);
 };
 
 static_assert(sizeof(Chunk) == ChunkSize,
               "Ensure the hardcoded chunk size definition actually matches the struct.");
 static_assert(js::gc::ChunkMarkBitmapOffset == offsetof(Chunk, bitmap),
               "The hardcoded API bitmap offset must match the actual offset.");
 static_assert(js::gc::ChunkRuntimeOffset == offsetof(Chunk, info) +
                                             offsetof(ChunkInfo, trailer) +
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -436,24 +436,25 @@ js::Nursery::setSlotsForwardingPointer(H
     MOZ_ASSERT(!isInside(newSlots));
     *reinterpret_cast<HeapSlot **>(oldSlots) = newSlots;
 }
 
 void
 js::Nursery::setElementsForwardingPointer(ObjectElements *oldHeader, ObjectElements *newHeader,
                                           uint32_t nelems)
 {
-    /*
-     * If the JIT has hoisted a zero length pointer, then we do not need to
-     * relocate it because reads and writes to/from this pointer are invalid.
-     */
-    if (nelems - ObjectElements::VALUES_PER_HEADER < 1)
-        return;
     MOZ_ASSERT(isInside(oldHeader));
     MOZ_ASSERT(!isInside(newHeader));
+    if (nelems - ObjectElements::VALUES_PER_HEADER < 1) {
+        if (!forwardedBuffers.initialized() && !forwardedBuffers.init())
+            CrashAtUnhandlableOOM("Nursery::setElementsForwardingPointer");
+        if (!forwardedBuffers.put(oldHeader->elements(), newHeader->elements()))
+            CrashAtUnhandlableOOM("Nursery::setElementsForwardingPointer");
+        return;
+    }
     *reinterpret_cast<HeapSlot **>(oldHeader->elements()) = newHeader->elements();
 }
 
 #ifdef DEBUG
 static bool IsWriteableAddress(void *ptr)
 {
     volatile uint64_t *vPtr = reinterpret_cast<volatile uint64_t *>(ptr);
     *vPtr = *vPtr;
@@ -464,25 +465,29 @@ static bool IsWriteableAddress(void *ptr
 void
 js::Nursery::forwardBufferPointer(HeapSlot **pSlotsElems)
 {
     HeapSlot *old = *pSlotsElems;
 
     if (!isInside(old))
         return;
 
-    /*
-     * If the elements buffer is zero length, the "first" item could be inside
-     * of the next object or past the end of the allocable area.  However,
-     * since we always store the runtime as the last word in the nursery,
-     * isInside will still be true, even if this zero-size allocation abuts the
-     * end of the allocable area. Thus, it is always safe to read the first
-     * word of |old| here.
-     */
-    *pSlotsElems = *reinterpret_cast<HeapSlot **>(old);
+    // The new location for this buffer is either stored inline with it or in
+    // the forwardedBuffers table.
+    do {
+        if (forwardedBuffers.initialized()) {
+            if (ForwardedBufferMap::Ptr p = forwardedBuffers.lookup(old)) {
+                *pSlotsElems = reinterpret_cast<HeapSlot *>(p->value());
+                break;
+            }
+        }
+
+        *pSlotsElems = *reinterpret_cast<HeapSlot **>(old);
+    } while (false);
+
     MOZ_ASSERT(!isInside(*pSlotsElems));
     MOZ_ASSERT(IsWriteableAddress(*pSlotsElems));
 }
 
 // Structure for counting how many times objects of a particular type have been
 // tenured during a minor collection.
 struct TenureCount
 {
@@ -840,16 +845,17 @@ js::Nursery::collect(JSRuntime *rt, JS::
         if (c->innerViews.needsSweepAfterMinorGC())
             c->innerViews.sweepAfterMinorGC(rt);
     }
     TIME_END(sweepArrayBufferViewList);
 
     // Update any slot or element pointers whose destination has been tenured.
     TIME_START(updateJitActivations);
     js::jit::UpdateJitActivationsForMinorGC<Nursery>(&rt->mainThread, &trc);
+    forwardedBuffers.finish();
     TIME_END(updateJitActivations);
 
     // Resize the nursery.
     TIME_START(resize);
     double promotionRate = trc.tenuredSize / double(allocationEnd() - start());
     if (promotionRate > 0.05)
         growAllocableSpace();
     else if (promotionRate < 0.01)
--- a/js/src/gc/Nursery.h
+++ b/js/src/gc/Nursery.h
@@ -201,16 +201,26 @@ class Nursery
     /*
      * The set of externally malloced slots potentially kept live by objects
      * stored in the nursery. Any external slots that do not belong to a
      * tenured thing at the end of a minor GC must be freed.
      */
     typedef HashSet<HeapSlot *, PointerHasher<HeapSlot *, 3>, SystemAllocPolicy> HugeSlotsSet;
     HugeSlotsSet hugeSlots;
 
+    /*
+     * During a collection most hoisted slot and element buffers indicate their
+     * new location with a forwarding pointer at the base. This does not work
+     * for buffers whose length is less than pointer width, or when different
+     * buffers might overlap each other. For these, an entry in the following
+     * table is used.
+     */
+    typedef HashMap<void *, void *, PointerHasher<void *, 1>, SystemAllocPolicy> ForwardedBufferMap;
+    ForwardedBufferMap forwardedBuffers;
+
     /* The maximum number of slots allowed to reside inline in the nursery. */
     static const size_t MaxNurserySlots = 128;
 
     /* The amount of space in the mapped nursery available to allocations. */
     static const size_t NurseryChunkUsableSize = gc::ChunkSize - sizeof(gc::ChunkTrailer);
 
     struct NurseryChunkLayout {
         char data[NurseryChunkUsableSize];
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/TypedObject/bug1098961.js
@@ -0,0 +1,9 @@
+if (!this.hasOwnProperty("TypedObject"))
+    quit();
+
+Array.prototype[Symbol.iterator] = function() {
+    for (var i = 3; --i >= 0;) {
+        yield this[i]
+    }
+}
+new TypedObject.ArrayType(TypedObject.int32, 0).build(1, x => 1)
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/TypedObject/bug1100202.js
@@ -0,0 +1,15 @@
+if (typeof TypedObject === "undefined")
+  quit();
+
+(function() {
+    Object
+})()
+var {
+    Object
+} = TypedObject
+function f() {
+    Object(Symbol)
+}
+for (var i = 0; i < 1; i++) {
+    f()
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/asm.js/testBug1100237.js
@@ -0,0 +1,33 @@
+load(libdir + "asm.js");
+
+var byteLength = Function.prototype.call.bind(
+    Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength").get
+);
+var m = asmCompile("glob", "s", "b", `
+    "use asm";
+    var I32 = glob.Int32Array;
+    var i32 = new I32(b);
+    var len = glob.byteLength;
+    function ch(b2) {
+        if (len(b2) & 0xffffff || len(b2) <= 0xffffff || len(b2) > 80000000) {
+            return false;
+        }
+        i32 = new I32(b2);
+        b = b2;
+        return true
+    }
+    function get(i) {
+        i = i | 0;
+        return i32[i >> 2] | 0
+    }
+    return {
+        get: get,
+        changeHeap: ch
+    }
+`);
+var buf1 = new ArrayBuffer(16777216)
+var { get, changeHeap } = asmLink(m, this, null, buf1)
+assertEq(changeHeap(new ArrayBuffer(33554432)), true)
+assertEq(get(), 0)
+assertEq(changeHeap(buf1), true);
+get();
--- a/js/src/jit-test/tests/ion/dce-with-rinstructions.js
+++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js
@@ -981,16 +981,38 @@ function rtofloat32_object(i) {
     var o = { valueOf: function () { return t; } };
     var x = Math.fround(o);
     t = 1000.1111111111;
     if (uceFault_tofloat32_object(i) || uceFault_tofloat32_object(i))
         assertEq(x, Math.fround(99.1111111111));
     return i;
 }
 
+var uceFault_hypot_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_hypot_number'));
+function rhypot_number(i) {
+    var x = Math.hypot(i, i + 1);
+    if (uceFault_hypot_number(i) || uceFault_hypot_number(i))
+        assertEq(x, Math.sqrt(i * i + (i + 1) * (i + 1)));
+    return i;
+}
+
+var uceFault_hypot_object = eval(uneval(uceFault).replace('uceFault', 'uceFault_hypot_object'));
+function rhypot_object(i) {
+    var t0 = i;
+    var t1 = i + 1;
+    var o0 = { valueOf: function () { return t0; } };
+    var o1 = { valueOf: function () { return t1; } };
+    var x = Math.hypot(o0, o1);
+    t0 = 1000;
+    t1 = 2000;
+    if (uceFault_hypot_object(i) || uceFault_hypot_object(i) )
+        assertEq(x, Math.sqrt(i * i + (i + 1) * (i + 1)));
+    return i;
+}
+
 for (i = 0; i < 100; i++) {
     rbitnot_number(i);
     rbitnot_object(i);
     rbitand_number(i);
     rbitand_object(i);
     rbitor_number(i);
     rbitor_object(i);
     rbitxor_number(i);
@@ -1076,16 +1098,18 @@ for (i = 0; i < 100; i++) {
     rregexp_i_literal_replace(i);
     rregexp_m_replace(i);
     rregexp_m_literal_replace(i);
     rtypeof(i);
     rtodouble_value(i);
     rtodouble_number(i);
     rtofloat32_number(i);