merge mozilla-inbound to mozilla-central. r=merge a=merge
authorSebastian Hengst <archaeopteryx@coole-files.de>
Thu, 09 Nov 2017 11:53:05 +0200
changeset 444150 d16b52f5d1955192c42c7b5c5da4e05a7dffef27
parent 444142 bda35e3d8ce4e6fbdc416b427f2200110ce52ff4 (current diff)
parent 444149 e368fe33afd342ed8540df982ce4ef0d37617940 (diff)
child 444151 2203d23429f61f879753234b275ff141c50c11f0
child 444190 5da4fb949bd215e7bca4b63acd76884e0b0208c0
child 444200 176a739c66b9ebd4098131339c0ed12a192c7dc9
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge, merge
milestone58.0a1
first release with
nightly linux32
d16b52f5d195 / 58.0a1 / 20171109100107 / files
nightly linux64
d16b52f5d195 / 58.0a1 / 20171109100107 / files
nightly mac
d16b52f5d195 / 58.0a1 / 20171109100107 / files
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
merge mozilla-inbound to mozilla-central. r=merge a=merge
layout/forms/nsListControlFrame.cpp
layout/painting/nsDisplayList.cpp
--- a/accessible/base/nsAccessibilityService.cpp
+++ b/accessible/base/nsAccessibilityService.cpp
@@ -692,17 +692,17 @@ nsAccessibilityService::UpdateListBullet
         listItem->UpdateBullet(aHasBullet);
     }
   }
 }
 
 void
 nsAccessibilityService::UpdateImageMap(nsImageFrame* aImageFrame)
 {
-  nsIPresShell* presShell = aImageFrame->PresContext()->PresShell();
+  nsIPresShell* presShell = aImageFrame->PresShell();
   DocAccessible* document = GetDocAccessible(presShell);
   if (document) {
     Accessible* accessible =
       document->GetAccessible(aImageFrame->GetContent());
     if (accessible) {
       HTMLImageMapAccessible* imageMap = accessible->AsImageMap();
       if (imageMap) {
         imageMap->UpdateChildAreas();
new file mode 100644
--- /dev/null
+++ b/accessible/tests/crashtests/890760.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+
+function boom()
+{
+    window.getSelection().collapse(document.createTextNode("."), 0);
+}
+
+</script>
+</head>
+<body onload="setTimeout(boom, 0);"></body>
+</html>
--- a/accessible/tests/crashtests/crashtests.list
+++ b/accessible/tests/crashtests/crashtests.list
@@ -1,9 +1,10 @@
 load 448064.xhtml # This test instantiates a11y, so be careful about adding tests before it
 load 471493.xul
 asserts-if(!browserIsRemote,2) load 884202.html
+load 890760.html
 load 893515.html
 load 1072792.xhtml
 
 # last_test_to_unload_testsuite.xul MUST be the last test in the list because it
 # is responsible for shutting down accessibility service affecting later tests.
 load last_test_to_unload_testsuite.xul
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -946,17 +946,18 @@ nsContextMenu.prototype = {
                                  referrerURI,
                                  triggeringPrincipal: systemPrincipal});
       }, Cu.reportError);
     } else {
       urlSecurityCheck(this.mediaURL,
                        this.browser.contentPrincipal,
                        Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
       openUILink(this.mediaURL, e, { disallowInheritPrincipal: true,
-                                     referrerURI });
+                                     referrerURI,
+                                     forceAllowDataURI: true });
     }
   },
 
   saveVideoFrameAsImage() {
     let mm = this.browser.messageManager;
     let isPrivate = PrivateBrowsingUtils.isBrowserPrivate(this.browser);
 
     let name = "";
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -202,31 +202,33 @@ function openUILinkIn(url, where, aAllow
     };
   }
 
   params.fromChrome = true;
 
   openLinkIn(url, where, params);
 }
 
+/* eslint-disable complexity */
 function openLinkIn(url, where, params) {
   if (!where || !url)
     return;
   const Cc = Components.classes;
   const Ci = Components.interfaces;
 
   var aFromChrome           = params.fromChrome;
   var aAllowThirdPartyFixup = params.allowThirdPartyFixup;
   var aPostData             = params.postData;
   var aCharset              = params.charset;
   var aReferrerURI          = params.referrerURI;
   var aReferrerPolicy       = ("referrerPolicy" in params ?
       params.referrerPolicy : Ci.nsIHttpChannel.REFERRER_POLICY_UNSET);
   var aRelatedToCurrent     = params.relatedToCurrent;
   var aAllowMixedContent    = params.allowMixedContent;
+  var aForceAllowDataURI    = params.forceAllowDataURI;
   var aInBackground         = params.inBackground;
   var aDisallowInheritPrincipal = params.disallowInheritPrincipal;
   var aInitiatingDoc        = params.initiatingDoc;
   var aIsPrivate            = params.private;
   var aSkipTabAnimation     = params.skipTabAnimation;
   var aAllowPinnedTabHostChange = !!params.allowPinnedTabHostChange;
   var aNoReferrer           = params.noReferrer;
   var aAllowPopups          = !!params.allowPopups;
@@ -428,16 +430,19 @@ function openLinkIn(url, where, params) 
     }
 
     if (aAllowPopups) {
       flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_POPUPS;
     }
     if (aIndicateErrorPageLoad) {
       flags |= Ci.nsIWebNavigation.LOAD_FLAGS_ERROR_LOAD_CHANGES_RV;
     }
+    if (aForceAllowDataURI) {
+      flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
+    }
 
     let {URI_INHERITS_SECURITY_CONTEXT} = Ci.nsIProtocolHandler;
     if (aForceAboutBlankViewerInCurrent &&
         (!uriObj ||
          (doGetProtocolFlags(uriObj) & URI_INHERITS_SECURITY_CONTEXT))) {
       // Unless we know for sure we're not inheriting principals,
       // force the about:blank viewer to have the right principal:
       targetBrowser.createAboutBlankContentViewer(aPrincipal);
--- a/browser/installer/windows/nsis/installer.nsi
+++ b/browser/installer/windows/nsis/installer.nsi
@@ -490,27 +490,45 @@ Section "-Application" APP_IDX
     UAC::ExecCodeSegment $0
   ${EndUnless}
 
   ; UAC only allows elevating to an Admin account so there is no need to add
   ; the Start Menu or Desktop shortcuts from the original unelevated process
   ; since this will either add it for the user if unelevated or All Users if
   ; elevated.
   ${If} $AddStartMenuSC == 1
-    CreateShortCut "$SMPROGRAMS\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
-    ${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
-      ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandShortName}.lnk" \
-                                           "$INSTDIR"
-      ${If} ${AtLeastWin7}
-      ${AndIf} "$AppUserModelID" != ""
-        ApplicationID::Set "$SMPROGRAMS\${BrandShortName}.lnk" "$AppUserModelID" "true"
+    ; See if there's an existing shortcut for this installation using the old
+    ; name that we should just rename, instead of creating a new shortcut.
+    ; We could do this renaming even when $AddStartMenuSC is false; the idea
+    ; behind not doing that is to interpret "false" as "don't do anything
+    ; involving start menu shortcuts at all." We could also try to do this for
+    ; both shell contexts, but that won't typically accomplish anything.
+    ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
+      ShellLink::GetShortCutTarget "$SMPROGRAMS\${BrandFullName}.lnk"
+      Pop $0
+      ${GetLongPath} "$0" $0
+      ${If} $0 == "$INSTDIR\${FileMainEXE}"
+      ${AndIfNot} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
+        Rename "$SMPROGRAMS\${BrandFullName}.lnk" \
+               "$SMPROGRAMS\${BrandShortName}.lnk"
+        ${LogMsg} "Renamed existing shortcut to $SMPROGRAMS\${BrandShortName}.lnk"
       ${EndIf}
-      ${LogMsg} "Added Shortcut: $SMPROGRAMS\${BrandShortName}.lnk"
     ${Else}
-      ${LogMsg} "** ERROR Adding Shortcut: $SMPROGRAMS\${BrandShortName}.lnk"
+      CreateShortCut "$SMPROGRAMS\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
+      ${If} ${FileExists} "$SMPROGRAMS\${BrandShortName}.lnk"
+        ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandShortName}.lnk" \
+                                               "$INSTDIR"
+        ${If} "$AppUserModelID" != ""
+          ApplicationID::Set "$SMPROGRAMS\${BrandShortName}.lnk" \
+                             "$AppUserModelID" "true"
+        ${EndIf}
+        ${LogMsg} "Added Shortcut: $SMPROGRAMS\${BrandShortName}.lnk"
+      ${Else}
+        ${LogMsg} "** ERROR Adding Shortcut: $SMPROGRAMS\${BrandShortName}.lnk"
+      ${EndIf}
     ${EndIf}
   ${EndIf}
 
   ; Update lastwritetime of the Start Menu shortcut to clear the tile cache.
   ; Do this for both shell contexts in case the user has shortcuts in multiple
   ; locations, then restore the previous context at the end.
   ${If} ${AtLeastWin8}
     SetShellVarContext all
@@ -520,27 +538,38 @@ Section "-Application" APP_IDX
     ${If} $TmpVal == "HKLM"
       SetShellVarContext all
     ${ElseIf} $TmpVal == "HKCU"
       SetShellVarContext current
     ${EndIf}
   ${EndIf}
 
   ${If} $AddDesktopSC == 1
-    CreateShortCut "$DESKTOP\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
-    ${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
-      ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandShortName}.lnk" \
-                                             "$INSTDIR"
-      ${If} ${AtLeastWin7}
-      ${AndIf} "$AppUserModelID" != ""
-        ApplicationID::Set "$DESKTOP\${BrandShortName}.lnk" "$AppUserModelID"  "true"
+    ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
+      ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk"
+      Pop $0
+      ${GetLongPath} "$0" $0
+      ${If} $0 == "$INSTDIR\${FileMainEXE}"
+      ${AndIfNot} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
+        Rename "$DESKTOP\${BrandFullName}.lnk" "$DESKTOP\${BrandShortName}.lnk"
+        ${LogMsg} "Renamed existing shortcut to $DESKTOP\${BrandShortName}.lnk"
       ${EndIf}
-      ${LogMsg} "Added Shortcut: $DESKTOP\${BrandShortName}.lnk"
     ${Else}
-      ${LogMsg} "** ERROR Adding Shortcut: $DESKTOP\${BrandShortName}.lnk"
+      CreateShortCut "$DESKTOP\${BrandShortName}.lnk" "$INSTDIR\${FileMainEXE}"
+      ${If} ${FileExists} "$DESKTOP\${BrandShortName}.lnk"
+        ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandShortName}.lnk" \
+                                               "$INSTDIR"
+        ${If} "$AppUserModelID" != ""
+          ApplicationID::Set "$DESKTOP\${BrandShortName}.lnk" \
+                             "$AppUserModelID" "true"
+        ${EndIf}
+        ${LogMsg} "Added Shortcut: $DESKTOP\${BrandShortName}.lnk"
+      ${Else}
+        ${LogMsg} "** ERROR Adding Shortcut: $DESKTOP\${BrandShortName}.lnk"
+      ${EndIf}
     ${EndIf}
   ${EndIf}
 
   ; If elevated the Quick Launch shortcut must be added from the unelevated
   ; original process.
   ${If} $AddQuickLaunchSC == 1
     ${Unless} ${AtLeastWin7}
       ClearErrors
--- a/browser/installer/windows/nsis/shared.nsh
+++ b/browser/installer/windows/nsis/shared.nsh
@@ -67,23 +67,23 @@
   ; Adds a pinned Task Bar shortcut (see MigrateTaskBarShortcut for details).
   ${MigrateTaskBarShortcut}
 
   ; Update the name/icon/AppModelID of our shortcuts as needed, then update the
   ; lastwritetime of the Start Menu shortcut to clear the tile icon cache.
   ; Do this for both shell contexts in case the user has shortcuts in multiple
   ; locations, then restore the previous context at the end.
   SetShellVarContext all
-  ${UpdateShortcutBranding}
+  ${UpdateShortcutsBranding}
   ${If} ${AtLeastWin8}
     ${TouchStartMenuShortcut}
   ${EndIf}
   Call FixShortcutAppModelIDs
   SetShellVarContext current
-  ${UpdateShortcutBranding}
+  ${UpdateShortcutsBranding}
   ${If} ${AtLeastWin8}
     ${TouchStartMenuShortcut}
   ${EndIf}
   Call FixShortcutAppModelIDs
   ${If} $TmpVal == "HKLM"
     SetShellVarContext all
   ${ElseIf} $TmpVal == "HKCU"
     SetShellVarContext current
@@ -334,140 +334,61 @@
     ${If} ${FileExists} "$QUICKLAUNCH\${BrandShortName}.lnk"
       ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandShortName}.lnk" \
                                              "$INSTDIR"
     ${EndIf}
   ${EndUnless}
 !macroend
 !define ShowShortcuts "!insertmacro ShowShortcuts"
 
-; Update the branding information on all shortcuts our installer created,
+; Update the branding name on all shortcuts our installer created
 ; to convert from BrandFullName (which is what we used to name shortcuts)
-; to BrandShortName (which is what we now name shortcuts). Also update the
-; icon if it's been changed.
-; This should only be called sometime after both MigrateStartMenuShortcut
-; and MigrateTaskBarShurtcut, and it assumes SHCTX is set correctly.
-!macro UpdateShortcutBranding
+; to BrandShortName (which is what we now name shortcuts). We only rename
+; desktop and start menu shortcuts, because touching taskbar pins often
+; (but inconsistently) triggers various broken behaviors in the shell.
+; This should only be called sometime after MigrateStartMenuShortcut,
+; and it assumes SHCTX is set correctly.
+!macro UpdateShortcutsBranding
+  ${UpdateOneShortcutBranding} "STARTMENU" "$SMPROGRAMS"
+  ${UpdateOneShortcutBranding} "DESKTOP" "$DESKTOP"
+!macroend
+!define UpdateShortcutsBranding "!insertmacro UpdateShortcutsBranding"
+
+!macro UpdateOneShortcutBranding LOG_SECTION SHORTCUT_DIR
+  ; Only try to rename the shortcuts found in the shortcuts log, to avoid
+  ; blowing away a name that the user created.
   ${GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R9
   ${If} ${FileExists} "$R9"
     ClearErrors
-    ; The entries in the shortcut log are numbered, but we never actually
-    ; create more than one shortcut (or log entry) in each location.
-    ReadINIStr $R8 "$R9" "STARTMENU" "Shortcut0"
+    ; The shortcuts log contains a numbered list of entries for each section,
+    ; but we never actually create more than one.
+    ReadINIStr $R8 "$R9" "${LOG_SECTION}" "Shortcut0"
     ${IfNot} ${Errors}
-      ${If} ${FileExists} "$SMPROGRAMS\$R8"
-        ShellLink::GetShortCutTarget "$SMPROGRAMS\$R8"
-        Pop $R7
-        ${GetLongPath} "$R7" $R7
-        ${If} $R7 == "$INSTDIR\${FileMainEXE}"
-          ShellLink::GetShortCutIconLocation "$SMPROGRAMS\$R8"
-          Pop $R6
-          ${GetLongPath} "$R6" $R6
-          ${If} $R6 != "$INSTDIR\firefox.ico"
-          ${AndIf} ${FileExists} "$INSTDIR\firefox.ico"
-            StrCpy $R5 "1"
-          ${ElseIf} $R6 == "$INSTDIR\firefox.ico"
-          ${AndIfNot} ${FileExists} "$INSTDIR\firefox.ico"
-            StrCpy $R5 "1"
-          ${Else}
-            StrCpy $R5 "0"
-          ${EndIf}
-
-          ${If} $R5 == "1"
-          ${OrIf} $R8 != "${BrandShortName}.lnk"
-            Delete "$SMPROGRAMS\$R8"
-            ${If} ${FileExists} "$INSTDIR\firefox.ico"
-              CreateShortcut "$SMPROGRAMS\${BrandShortName}.lnk" \
-                             "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\firefox.ico"
-            ${Else}
-              CreateShortcut "$SMPROGRAMS\${BrandShortName}.lnk" \
-                             "$INSTDIR\${FileMainEXE}"
-            ${EndIf}
-            WriteINIStr "$R9" "STARTMENU" "Shortcut0" "${BrandShortName}.lnk"
-          ${EndIf}
-        ${EndIf}
-      ${EndIf}
-    ${EndIf}
-
-    ClearErrors
-    ReadINIStr $R8 "$R9" "DESKTOP" "Shortcut0"
-    ${IfNot} ${Errors}
-      ${If} ${FileExists} "$DESKTOP\$R8"
-        ShellLink::GetShortCutTarget "$DESKTOP\$R8"
+      ${If} ${FileExists} "${SHORTCUT_DIR}\$R8"
+        ShellLink::GetShortCutTarget "${SHORTCUT_DIR}\$R8"
         Pop $R7
         ${GetLongPath} "$R7" $R7
         ${If} $R7 == "$INSTDIR\${FileMainEXE}"
-          ShellLink::GetShortCutIconLocation "$DESKTOP\$R8"
-          Pop $R6
-          ${GetLongPath} "$R6" $R6
-          ${If} $R6 != "$INSTDIR\firefox.ico"
-          ${AndIf} ${FileExists} "$INSTDIR\firefox.ico"
-            StrCpy $R5 "1"
-          ${ElseIf} $R6 == "$INSTDIR\firefox.ico"
-          ${AndIfNot} ${FileExists} "$INSTDIR\firefox.ico"
-            StrCpy $R5 "1"
-          ${Else}
-            StrCpy $R5 "0"
-          ${EndIf}
-
-          ${If} $R5 == "1"
-          ${OrIf} $R8 != "${BrandShortName}.lnk"
-            Delete "$DESKTOP\$R8"
-            ${If} ${FileExists} "$INSTDIR\firefox.ico"
-              CreateShortcut "$DESKTOP\${BrandShortName}.lnk" \
-                             "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\firefox.ico"
-            ${Else}
-              CreateShortcut "$DESKTOP\${BrandShortName}.lnk" \
-                             "$INSTDIR\${FileMainEXE}"
-            ${EndIf}
-            WriteINIStr "$R9" "DESKTOP" "Shortcut0" "${BrandShortName}.lnk"
-          ${EndIf}
-        ${EndIf}
-      ${EndIf}
-    ${EndIf}
-
-    ClearErrors
-    ReadINIStr $R8 "$R9" "QUICKLAUNCH" "Shortcut0"
-    ${IfNot} ${Errors}
-      ; "QUICKLAUNCH" actually means a taskbar pin.
-      ; We can't simultaneously rename and change the icon for a taskbar pin
-      ; without the icon breaking, and the icon is more important than the name,
-      ; so we'll forget about changing the name and just overwrite the icon.
-      ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R8"
-        ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\TaskBar\$R8"
-        Pop $R7
-        ${GetLongPath} "$R7" $R7
-        ${If} "$INSTDIR\${FileMainEXE}" == "$R7"
-          ShellLink::GetShortCutIconLocation "$QUICKLAUNCH\User Pinned\TaskBar\$R8"
-          Pop $R6
-          ${GetLongPath} "$R6" $R6
-          ${If} $R6 != "$INSTDIR\firefox.ico"
-          ${AndIf} ${FileExists} "$INSTDIR\firefox.ico"
-            StrCpy $R5 "1"
-          ${ElseIf} $R6 == "$INSTDIR\firefox.ico"
-          ${AndIfNot} ${FileExists} "$INSTDIR\firefox.ico"
-            StrCpy $R5 "1"
-          ${Else}
-            StrCpy $R5 "0"
-          ${EndIf}
-
-          ${If} $R5 == "1"
-            ${If} ${FileExists} "$INSTDIR\firefox.ico"
-              CreateShortcut "$QUICKLAUNCH\User Pinned\TaskBar\$R8" "$R7" "" \
-                             "$INSTDIR\firefox.ico"
-            ${Else}
-              CreateShortcut "$QUICKLAUNCH\User Pinned\TaskBar\$R8" "$R7"
-            ${EndIf}
+        ${AndIf} $R8 != "${BrandShortName}.lnk"
+        ${AndIfNot} ${FileExists} "${SHORTCUT_DIR}\${BrandShortName}.lnk"
+          ClearErrors
+          Rename "${SHORTCUT_DIR}\$R8" "${SHORTCUT_DIR}\${BrandShortName}.lnk"
+          ${IfNot} ${Errors}
+            ; Update the shortcut log manually instead of calling LogShortcut
+            ; because it would add a Shortcut1 entry, and we really do want to
+            ; overwrite the existing entry 0, since we just renamed the file.
+            WriteINIStr "$R9" "${LOG_SECTION}" "Shortcut0" \
+                        "${BrandShortName}.lnk"
           ${EndIf}
         ${EndIf}
       ${EndIf}
     ${EndIf}
   ${EndIf}
 !macroend
-!define UpdateShortcutBranding "!insertmacro UpdateShortcutBranding"
+!define UpdateOneShortcutBranding "!insertmacro UpdateOneShortcutBranding"
 
 !macro AddAssociationIfNoneExist FILE_TYPE KEY
   ClearErrors
   EnumRegKey $7 HKCR "${FILE_TYPE}" 0
   ${If} ${Errors}
     WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}"  "" ${KEY}
   ${EndIf}
   WriteRegStr SHCTX "SOFTWARE\Classes\${FILE_TYPE}\OpenWithProgids" ${KEY} ""
--- a/build/build-clang/build-clang.py
+++ b/build/build-clang/build-clang.py
@@ -451,25 +451,25 @@ if __name__ == "__main__":
     checkout_or_update(libcxx_repo, libcxx_source_dir)
     if libcxxabi_repo:
         checkout_or_update(libcxxabi_repo, libcxxabi_source_dir)
     if extra_repo:
         checkout_or_update(extra_repo, extra_source_dir)
     for p in config.get("patches", []):
         patch(p, source_dir)
 
-    symlinks = [(source_dir + "/clang",
+    symlinks = [(clang_source_dir,
                  llvm_source_dir + "/tools/clang"),
-                (source_dir + "/extra",
+                (extra_source_dir,
                  llvm_source_dir + "/tools/clang/tools/extra"),
-                (source_dir + "/compiler-rt",
+                (compiler_rt_source_dir,
                  llvm_source_dir + "/projects/compiler-rt"),
-                (source_dir + "/libcxx",
+                (libcxx_source_dir,
                  llvm_source_dir + "/projects/libcxx"),
-                (source_dir + "/libcxxabi",
+                (libcxxabi_source_dir,
                  llvm_source_dir + "/projects/libcxxabi")]
     for l in symlinks:
         # On Windows, we have to re-copy the whole directory every time.
         if not is_windows() and os.path.islink(l[1]):
             continue
         delete(l[1])
         if os.path.exists(l[0]):
             symlink(l[0], l[1])
--- a/build/build-clang/clang-win32.json
+++ b/build/build-clang/clang-win32.json
@@ -7,12 +7,12 @@
     "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/trunk",
     "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
     "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
     "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
     "patches": [
-      "build/src/build/build-clang/msvc-host-x64.patch",
-      "build/src/build/build-clang/loosen-msvc-detection.patch"
+      "msvc-host-x64.patch",
+      "loosen-msvc-detection.patch"
     ]
 }
--- a/build/build-clang/clang-win64.json
+++ b/build/build-clang/clang-win64.json
@@ -8,11 +8,11 @@
     "clang_repo": "https://llvm.org/svn/llvm-project/cfe/trunk",
     "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/trunk",
     "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/trunk",
     "python_path": "c:/mozilla-build/python/python.exe",
     "cc": "cl.exe",
     "cxx": "cl.exe",
     "ml": "ml64.exe",
     "patches": [
-      "build/src/build/build-clang/loosen-msvc-detection.patch"
+      "loosen-msvc-detection.patch"
     ]
 }
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -1305,16 +1305,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
   bool inheritPrincipal = false;
   bool principalIsExplicit = false;
   bool sendReferrer = true;
   uint32_t referrerPolicy = mozilla::net::RP_Unset;
   bool isSrcdoc = false;
   nsCOMPtr<nsISHEntry> shEntry;
   nsString target;
   nsAutoString srcdoc;
+  bool forceAllowDataURI = false;
   nsCOMPtr<nsIDocShell> sourceDocShell;
   nsCOMPtr<nsIURI> baseURI;
 
   uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags);
 
   NS_ENSURE_ARG(aURI);
 
   if (!StartupTimeline::HasRecord(StartupTimeline::FIRST_LOAD_URI) &&
@@ -1341,16 +1342,17 @@ nsDocShell::LoadURI(nsIURI* aURI,
     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));
+    aLoadInfo->GetForceAllowDataURI(&forceAllowDataURI);
   }
 
   MOZ_LOG(gDocShellLeakLog, LogLevel::Debug,
           ("nsDocShell[%p]: loading %s with flags 0x%08x",
            this, aURI->GetSpecOrDefault().get(), aLoadFlags));
 
   if (!shEntry &&
       !LOAD_TYPE_HAS_FLAGS(loadType, LOAD_FLAGS_REPLACE_HISTORY)) {
@@ -1604,16 +1606,20 @@ 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;
   }
 
+  if (forceAllowDataURI) {
+    flags |= INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
+  }
+
   return InternalLoad(aURI,
                       originalURI,
                       resultPrincipalURI,
                       loadReplace,
                       referrer,
                       referrerPolicy,
                       triggeringPrincipal,
                       principalToInherit,
@@ -4912,16 +4918,19 @@ nsDocShell::LoadURIWithOptions(const cha
   if (aLoadFlags & LOAD_FLAGS_ALLOW_POPUPS) {
     popupState = openAllowed;
     aLoadFlags &= ~LOAD_FLAGS_ALLOW_POPUPS;
   } else {
     popupState = openOverridden;
   }
   nsAutoPopupStatePusher statePusher(popupState);
 
+  bool forceAllowDataURI =
+    aLoadFlags & LOAD_FLAGS_FORCE_ALLOW_DATA_URI;
+
   // Don't pass certain flags that aren't needed and end up confusing
   // ConvertLoadTypeToDocShellLoadInfo.  We do need to ensure that they are
   // passed to LoadURI though, since it uses them.
   uint32_t extraFlags = (aLoadFlags & EXTRA_LOAD_FLAGS);
   aLoadFlags &= ~EXTRA_LOAD_FLAGS;
 
   nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
   rv = CreateLoadInfo(getter_AddRefs(loadInfo));
@@ -4942,16 +4951,17 @@ nsDocShell::LoadURIWithOptions(const cha
 
   loadInfo->SetLoadType(ConvertLoadTypeToDocShellLoadInfo(loadType));
   loadInfo->SetPostDataStream(postStream);
   loadInfo->SetReferrer(aReferringURI);
   loadInfo->SetReferrerPolicy(aReferrerPolicy);
   loadInfo->SetHeadersStream(aHeaderStream);
   loadInfo->SetBaseURI(aBaseURI);
   loadInfo->SetTriggeringPrincipal(aTriggeringPrincipal);
+  loadInfo->SetForceAllowDataURI(forceAllowDataURI);
 
   if (fixupInfo) {
     nsAutoString searchProvider, keyword;
     fixupInfo->GetKeywordProviderName(searchProvider);
     fixupInfo->GetKeywordAsSent(keyword);
     MaybeNotifyKeywordSearchLoading(searchProvider, keyword);
   }
 
@@ -8845,17 +8855,17 @@ nsDocShell::RestoreFromHistory()
   nsCOMPtr<nsIDocument> sibling;
   if (rootViewParent && rootViewParent->GetParent()) {
     nsIFrame* frame = rootViewParent->GetParent()->GetFrame();
     container = frame ? frame->GetContent() : nullptr;
   }
   if (rootViewSibling) {
     nsIFrame* frame = rootViewSibling->GetFrame();
     sibling =
-      frame ? frame->PresContext()->PresShell()->GetDocument() : nullptr;
+      frame ? frame->PresShell()->GetDocument() : nullptr;
   }
 
   // Transfer ownership to mContentViewer.  By ensuring that either the
   // docshell or the session history, but not both, have references to the
   // content viewer, we prevent the viewer from being torn down after
   // Destroy() is called.
 
   if (mContentViewer) {
@@ -10184,16 +10194,17 @@ nsDocShell::InternalLoad(nsIURI* aURI,
         loadInfo->SetLoadReplace(aLoadReplace);
         loadInfo->SetTriggeringPrincipal(aTriggeringPrincipal);
         loadInfo->SetInheritPrincipal(
           aFlags & INTERNAL_LOAD_FLAGS_INHERIT_PRINCIPAL);
         // Explicit principal because we do not want any guesses as to what the
         // principal to inherit is: it should be aTriggeringPrincipal.
         loadInfo->SetPrincipalIsExplicit(true);
         loadInfo->SetLoadType(ConvertLoadTypeToDocShellLoadInfo(LOAD_LINK));
+        loadInfo->SetForceAllowDataURI(aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI);
 
         rv = win->Open(NS_ConvertUTF8toUTF16(spec),
                        aWindowTarget, // window name
                        EmptyString(), // Features
                        loadInfo,
                        true, // aForceNoOpener
                        getter_AddRefs(newWin));
         MOZ_ASSERT(!newWin);
@@ -10861,17 +10872,19 @@ nsDocShell::InternalLoad(nsIURI* aURI,
 
   net::PredictorLearn(aURI, nullptr,
                       nsINetworkPredictor::LEARN_LOAD_TOPLEVEL, attrs);
   net::PredictorPredict(aURI, nullptr,
                         nsINetworkPredictor::PREDICT_LOAD, attrs, nullptr);
 
   nsCOMPtr<nsIRequest> req;
   rv = DoURILoad(aURI, aOriginalURI, aResultPrincipalURI, aLoadReplace,
-                 loadFromExternal, aReferrer,
+                 loadFromExternal,
+                 (aFlags & INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI),
+                 aReferrer,
                  !(aFlags & INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER),
                  aReferrerPolicy,
                  aTriggeringPrincipal, principalToInherit, aTypeHint,
                  aFileName, aPostData, aPostDataLength, 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,
@@ -10999,16 +11012,17 @@ IsConsideredSameOriginForUIR(nsIPrincipa
 }
 
 nsresult
 nsDocShell::DoURILoad(nsIURI* aURI,
                       nsIURI* aOriginalURI,
                       Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
                       bool aLoadReplace,
                       bool aLoadFromExternal,
+                      bool aForceAllowDataURI,
                       nsIURI* aReferrerURI,
                       bool aSendReferrer,
                       uint32_t aReferrerPolicy,
                       nsIPrincipal* aTriggeringPrincipal,
                       nsIPrincipal* aPrincipalToInherit,
                       const char* aTypeHint,
                       const nsAString& aFileName,
                       nsIInputStream* aPostData,
@@ -11179,16 +11193,17 @@ nsDocShell::DoURILoad(nsIURI* aURI,
                    securityFlags) :
       new LoadInfo(loadingPrincipal, aTriggeringPrincipal, loadingNode,
                    securityFlags, aContentPolicyType);
 
   if (aPrincipalToInherit) {
     loadInfo->SetPrincipalToInherit(aPrincipalToInherit);
   }
   loadInfo->SetLoadTriggeredFromExternal(aLoadFromExternal);
+  loadInfo->SetForceAllowDataURI(aForceAllowDataURI);
 
   // We have to do this in case our OriginAttributes are different from the
   // OriginAttributes of the parent document. Or in case there isn't a
   // parent document.
   bool isTopLevelDoc = mItemType == typeContent &&
                        (aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
                         GetIsMozBrowser());
 
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -447,16 +447,17 @@ protected:
   // aOriginalURI will be set as the originalURI on the channel that does the
   // load. If aOriginalURI is null, aURI will be set as the originalURI.
   // If aLoadReplace is true, LOAD_REPLACE flag will be set to the nsIChannel.
   nsresult DoURILoad(nsIURI* aURI,
                      nsIURI* aOriginalURI,
                      mozilla::Maybe<nsCOMPtr<nsIURI>> const& aResultPrincipalURI,
                      bool aLoadReplace,
                      bool aLoadFromExternal,
+                     bool aForceAllowDataURI,
                      nsIURI* aReferrer,
                      bool aSendReferrer,
                      uint32_t aReferrerPolicy,
                      nsIPrincipal* aTriggeringPrincipal,
                      nsIPrincipal* aPrincipalToInherit,
                      const char* aTypeHint,
                      const nsAString& aFileName,
                      nsIInputStream* aPostData,
--- a/docshell/base/nsDocShellLoadInfo.cpp
+++ b/docshell/base/nsDocShellLoadInfo.cpp
@@ -62,16 +62,17 @@ SetMaybeResultPrincipalURI(nsIDocShellLo
 
 } // mozilla
 
 nsDocShellLoadInfo::nsDocShellLoadInfo()
   : mResultPrincipalURIIsSome(false)
   , mLoadReplace(false)
   , mInheritPrincipal(false)
   , mPrincipalIsExplicit(false)
+  , mForceAllowDataURI(false)
   , mSendReferrer(true)
   , mReferrerPolicy(mozilla::net::RP_Unset)
   , mLoadType(nsIDocShellLoadInfo::loadNormal)
   , mIsSrcdocLoad(false)
 {
 }
 
 nsDocShellLoadInfo::~nsDocShellLoadInfo()
@@ -205,16 +206,30 @@ nsDocShellLoadInfo::GetPrincipalIsExplic
 NS_IMETHODIMP
 nsDocShellLoadInfo::SetPrincipalIsExplicit(bool aPrincipalIsExplicit)
 {
   mPrincipalIsExplicit = aPrincipalIsExplicit;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsDocShellLoadInfo::GetForceAllowDataURI(bool* aForceAllowDataURI)
+{
+  *aForceAllowDataURI = mForceAllowDataURI;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDocShellLoadInfo::SetForceAllowDataURI(bool aForceAllowDataURI)
+{
+  mForceAllowDataURI = aForceAllowDataURI;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 nsDocShellLoadInfo::GetLoadType(nsDocShellInfoLoadType* aLoadType)
 {
   NS_ENSURE_ARG_POINTER(aLoadType);
 
   *aLoadType = mLoadType;
   return NS_OK;
 }
 
--- a/docshell/base/nsDocShellLoadInfo.h
+++ b/docshell/base/nsDocShellLoadInfo.h
@@ -34,16 +34,17 @@ protected:
   nsCOMPtr<nsIURI> mReferrer;
   nsCOMPtr<nsIURI> mOriginalURI;
   nsCOMPtr<nsIURI> mResultPrincipalURI;
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
   bool mResultPrincipalURIIsSome;
   bool mLoadReplace;
   bool mInheritPrincipal;
   bool mPrincipalIsExplicit;
+  bool mForceAllowDataURI;
   bool mSendReferrer;
   nsDocShellInfoReferrerPolicy mReferrerPolicy;
   nsDocShellInfoLoadType mLoadType;
   nsCOMPtr<nsISHEntry> mSHEntry;
   nsString mTarget;
   nsCOMPtr<nsIInputStream> mPostDataStream;
   nsCOMPtr<nsIInputStream> mHeadersStream;
   bool mIsSrcdocLoad;
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -122,16 +122,19 @@ interface nsIDocShell : nsIDocShellTreeI
   const long INTERNAL_LOAD_FLAGS_BYPASS_CLASSIFIER       = 0x10;
   const long INTERNAL_LOAD_FLAGS_FORCE_ALLOW_COOKIES     = 0x20;
 
   // Whether the load should be treated as srcdoc load, rather than a URI one.
   const long INTERNAL_LOAD_FLAGS_IS_SRCDOC               = 0x40;
 
   const long INTERNAL_LOAD_FLAGS_NO_OPENER               = 0x100;
 
+  // Whether a top-level data URI navigation is allowed for that load
+  const long INTERNAL_LOAD_FLAGS_FORCE_ALLOW_DATA_URI    = 0x200;
+
   // NB: 0x80 is available.
 
   /**
    * 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.
--- a/docshell/base/nsIDocShellLoadInfo.idl
+++ b/docshell/base/nsIDocShellLoadInfo.idl
@@ -60,16 +60,22 @@ interface nsIDocShellLoadInfo : nsISuppo
     /** If this attribute is true only ever use the principal specified
      *  by the triggeringPrincipal and inheritPrincipal attributes.
      *  If there are security reasons for why this is unsafe, such
      *  as trying to use a systemprincipal as the triggeringPrincipal
      *  for a content docshell the load fails.
      */
     attribute boolean principalIsExplicit;
 
+    /**
+     * If this attribute is true, then a top-level navigation
+     * to a data URI will be allowed.
+     */
+    attribute boolean forceAllowDataURI;
+
     /* these are load type enums... */
     const long loadNormal = 0;                     // Normal Load
     const long loadNormalReplace = 1;              // Normal Load but replaces current history slot
     const long loadHistory = 2;                    // Load from history
     const long loadReloadNormal = 3;               // Reload
     const long loadReloadBypassCache = 4;
     const long loadReloadBypassProxy = 5;
     const long loadReloadBypassProxyAndCache = 6;
--- a/docshell/base/nsIWebNavigation.idl
+++ b/docshell/base/nsIWebNavigation.idl
@@ -202,16 +202,22 @@ interface nsIWebNavigation : nsISupports
   const unsigned long LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP = 0x100000;
 
   /**
    * This flag specifies that common scheme typos should be corrected.
    */
   const unsigned long LOAD_FLAGS_FIXUP_SCHEME_TYPOS = 0x200000;
 
   /**
+   * Allows a top-level data: navigation to occur. E.g. view-image
+   * is an explicit user action which should be allowed.
+   */
+  const unsigned long LOAD_FLAGS_FORCE_ALLOW_DATA_URI = 0x400000;
+
+  /**
    * 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 URI dispatcher will go through its normal process of content
    * loading.
    *
    * @param aURI
    *        The URI string to load.  For HTTP and FTP URLs and possibly others,
    *        characters above U+007F will be converted to UTF-8 and then URL-
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -778,53 +778,65 @@ CustomElementRegistry::Define(const nsAS
        *       "attributeChangedCallback" is not null, then:
        *       1. Let observedAttributesIterable be Get(constructor,
        *          "observedAttributes"). Rethrow any exceptions.
        *       2. If observedAttributesIterable is not undefined, then set
        *          observedAttributes to the result of converting
        *          observedAttributesIterable to a sequence<DOMString>. Rethrow
        *          any exceptions from the conversion.
        */
-      // TODO: Bug 1293921 - Implement connected/disconnected/adopted/attributeChanged lifecycle callbacks for custom elements
       if (callbacksHolder->mAttributeChangedCallback.WasPassed()) {
         // Enter constructor's compartment.
         JSAutoCompartment ac(cx, constructor);
         JS::Rooted<JS::Value> observedAttributesIterable(cx);
 
         if (!JS_GetProperty(cx, constructor, "observedAttributes",
                             &observedAttributesIterable)) {
           aRv.StealExceptionFromJSContext(cx);
           return;
         }
 
         if (!observedAttributesIterable.isUndefined()) {
+          if (!observedAttributesIterable.isObject()) {
+            aRv.ThrowTypeError<MSG_NOT_SEQUENCE>(NS_LITERAL_STRING("observedAttributes"));
+            return;
+          }
+
           JS::ForOfIterator iter(cx);
-          if (!iter.init(observedAttributesIterable)) {
+          if (!iter.init(observedAttributesIterable, JS::ForOfIterator::AllowNonIterable)) {
             aRv.StealExceptionFromJSContext(cx);
             return;
           }
 
+          if (!iter.valueIsIterable()) {
+            aRv.ThrowTypeError<MSG_NOT_SEQUENCE>(NS_LITERAL_STRING("observedAttributes"));
+            return;
+          }
+
           JS::Rooted<JS::Value> attribute(cx);
           while (true) {
             bool done;
             if (!iter.next(&attribute, &done)) {
               aRv.StealExceptionFromJSContext(cx);
               return;
             }
             if (done) {
               break;
             }
 
-            JSString *attrJSStr = attribute.toString();
-            nsAutoJSString attrStr;
-            if (!attrStr.init(cx, attrJSStr)) {
+            nsAutoString attrStr;
+            if (!ConvertJSValueToString(cx, attribute, eStringify, eStringify, attrStr)) {
               aRv.StealExceptionFromJSContext(cx);
               return;
             }
-            observedAttributes.AppendElement(NS_Atomize(attrStr));
+
+            if (!observedAttributes.AppendElement(NS_Atomize(attrStr))) {
+              aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
+              return;
+            }
           }
         }
       } // Leave constructor's compartment.
     } // Leave constructorProtoUnwrapped's compartment.
   } // Unset mIsCustomDefinitionRunning
 
   /**
    * 11. Let definition be a new custom element definition with name name,
new file mode 100644
--- /dev/null
+++ b/dom/base/crashtests/1413815.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script type="text/javascript">
+class XFoo extends HTMLElement {
+  constructor() {
+    super();
+  }
+
+  static get observedAttributes() {
+    return [3.76277868767527e-310, Symbol("Ashitaka"), {}];
+  }
+
+  attributeChangedCallback(aName, aOldValue, aNewValue) {
+  }
+}
+
+customElements.define('x-foo', XFoo);
+</script>
+</html>
--- a/dom/base/crashtests/crashtests.list
+++ b/dom/base/crashtests/crashtests.list
@@ -229,8 +229,9 @@ load 1383780.html
 pref(clipboard.autocopy,true) load 1385272-1.html
 load 1393806.html
 load 1396466.html
 load 1400701.html
 load 1403377.html
 load 1405771.html
 load 1406109-1.html
 pref(dom.webcomponents.enabled,true) load 1324463.html
+pref(dom.webcomponents.customelements.enabled,true) load 1413815.html
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -3025,26 +3025,26 @@ nsFrameLoader::GetClipSubdocument(bool* 
 
 NS_IMETHODIMP
 nsFrameLoader::SetClipSubdocument(bool aClip)
 {
   mClipSubdocument = aClip;
   nsIFrame* frame = GetPrimaryFrameOfOwningContent();
   if (frame) {
     frame->InvalidateFrame();
-    frame->PresContext()->PresShell()->
+    frame->PresShell()->
       FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
     nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
     if (subdocFrame) {
       nsIFrame* subdocRootFrame = subdocFrame->GetSubdocumentRootFrame();
       if (subdocRootFrame) {
-        nsIFrame* subdocRootScrollFrame = subdocRootFrame->PresContext()->PresShell()->
+        nsIFrame* subdocRootScrollFrame = subdocRootFrame->PresShell()->
           GetRootScrollFrame();
         if (subdocRootScrollFrame) {
-          frame->PresContext()->PresShell()->
+          frame->PresShell()->
             FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
         }
       }
     }
   }
   return NS_OK;
 }
 
@@ -3062,17 +3062,17 @@ nsFrameLoader::SetClampScrollPosition(bo
 
   // When turning clamping on, make sure the current position is clamped.
   if (aClamp) {
     nsIFrame* frame = GetPrimaryFrameOfOwningContent();
     nsSubDocumentFrame* subdocFrame = do_QueryFrame(frame);
     if (subdocFrame) {
       nsIFrame* subdocRootFrame = subdocFrame->GetSubdocumentRootFrame();
       if (subdocRootFrame) {
-        nsIScrollableFrame* subdocRootScrollFrame = subdocRootFrame->PresContext()->PresShell()->
+        nsIScrollableFrame* subdocRootScrollFrame = subdocRootFrame->PresShell()->
           GetRootScrollFrameAsScrollable();
         if (subdocRootScrollFrame) {
           subdocRootScrollFrame->ScrollTo(subdocRootScrollFrame->GetScrollPosition(), nsIScrollableFrame::INSTANT);
         }
       }
     }
   }
   return NS_OK;
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -3245,17 +3245,17 @@ ContentEventHandler::FrameRelativeRect::
   if (NS_WARN_IF(aDestFrame->PresContext() != mBaseFrame->PresContext())) {
     return nsRect();
   }
 
   if (aDestFrame == mBaseFrame) {
     return mRect;
   }
 
-  nsIFrame* rootFrame = mBaseFrame->PresContext()->PresShell()->GetRootFrame();
+  nsIFrame* rootFrame = mBaseFrame->PresShell()->GetRootFrame();
   nsRect baseFrameRectInRootFrame =
     nsLayoutUtils::TransformFrameRectToAncestor(mBaseFrame, nsRect(),
                                                 rootFrame);
   nsRect destFrameRectInRootFrame =
     nsLayoutUtils::TransformFrameRectToAncestor(aDestFrame, nsRect(),
                                                 rootFrame);
   nsPoint difference =
     destFrameRectInRootFrame.TopLeft() - baseFrameRectInRootFrame.TopLeft();
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3305,17 +3305,17 @@ EventStateManager::PostHandleEvent(nsPre
               (!wheelEvent->mDeltaX && !wheelEvent->mDeltaY)) {
             break;
           }
 
           nsIScrollableFrame* scrollTarget = do_QueryFrame(frameToScroll);
           ScrollbarsForWheel::SetActiveScrollTarget(scrollTarget);
 
           nsIFrame* rootScrollFrame = !mCurrentTarget ? nullptr :
-            mCurrentTarget->PresContext()->PresShell()->GetRootScrollFrame();
+            mCurrentTarget->PresShell()->GetRootScrollFrame();
           nsIScrollableFrame* rootScrollableFrame = nullptr;
           if (rootScrollFrame) {
             rootScrollableFrame = do_QueryFrame(rootScrollFrame);
           }
           if (!scrollTarget || scrollTarget == rootScrollableFrame) {
             wheelEvent->mViewPortIsOverscrolled = true;
           }
           wheelEvent->mOverflowDeltaX = wheelEvent->mDeltaX;
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -4127,19 +4127,18 @@ void HTMLMediaElement::SetPlayedOrSeeked
 
   mHasPlayedOrSeeked = aValue;
 
   // Force a reflow so that the poster frame hides or shows immediately.
   nsIFrame* frame = GetPrimaryFrame();
   if (!frame) {
     return;
   }
-  frame->PresContext()->PresShell()->FrameNeedsReflow(frame,
-                                                      nsIPresShell::eTreeChange,
-                                                      NS_FRAME_IS_DIRTY);
+  frame->PresShell()->FrameNeedsReflow(frame, nsIPresShell::eTreeChange,
+                                       NS_FRAME_IS_DIRTY);
 }
 
 void
 HTMLMediaElement::NotifyXPCOMShutdown()
 {
   ShutdownDecoder();
 }
 
--- a/dom/indexedDB/IDBFactory.cpp
+++ b/dom/indexedDB/IDBFactory.cpp
@@ -270,18 +270,17 @@ IDBFactory::CreateForJSInternal(JSContex
     *aFactory = nullptr;
     return NS_OK;
   }
 
   RefPtr<IDBFactory> factory = new IDBFactory();
   factory->mPrincipalInfo = aPrincipalInfo.forget();
   factory->mOwningObject = aOwningObject;
   mozilla::HoldJSObjects(factory.get());
-  factory->mEventTarget = NS_IsMainThread() ?
-    SystemGroup::EventTargetFor(TaskCategory::Other) : GetCurrentThreadEventTarget();
+  factory->mEventTarget = GetCurrentThreadEventTarget();
   factory->mInnerWindowID = aInnerWindowID;
 
   factory.forget(aFactory);
   return NS_OK;
 }
 
 // static
 bool
--- a/dom/indexedDB/IDBFactory.h
+++ b/dom/indexedDB/IDBFactory.h
@@ -66,19 +66,18 @@ class IDBFactory final
   JS::Heap<JSObject*> mOwningObject;
 
   // This will only be set if the factory belongs to a window in a child
   // process.
   RefPtr<TabChild> mTabChild;
 
   indexedDB::BackgroundFactoryChild* mBackgroundActor;
 
-  // A DocGroup-specific EventTarget if created by CreateForWindow().
-  // Otherwise, it must either be set to SystemGroup on main thread or
-  // NS_GetCurrentThread() off main thread.
+  // It is either set to a DocGroup-specific EventTarget if created by
+  // CreateForWindow() or set to GetCurrentThreadEventTarget() otherwise.
   nsCOMPtr<nsIEventTarget> mEventTarget;
 
   uint64_t mInnerWindowID;
 
   bool mBackgroundActorFailed;
   bool mPrivateBrowsingMode;
 
 public:
--- a/dom/media/mediasource/AutoTaskQueue.h
+++ b/dom/media/mediasource/AutoTaskQueue.h
@@ -31,21 +31,21 @@ public:
   , mTaskQueue(new TaskQueue(Move(aPool), aName, aSupportsTailDispatch))
   {}
 
   TaskDispatcher& TailDispatcher() override
   {
     return mTaskQueue->TailDispatcher();
   }
 
-  void Dispatch(already_AddRefed<nsIRunnable> aRunnable,
-                DispatchFailureHandling aFailureHandling = AssertDispatchSuccess,
-                DispatchReason aReason = NormalDispatch) override
+  nsresult Dispatch(already_AddRefed<nsIRunnable> aRunnable,
+                    DispatchFailureHandling aFailureHandling = AssertDispatchSuccess,
+                    DispatchReason aReason = NormalDispatch) override
   {
-    mTaskQueue->Dispatch(Move(aRunnable), aFailureHandling, aReason);
+    return mTaskQueue->Dispatch(Move(aRunnable), aFailureHandling, aReason);
   }
 
   // Prevent a GCC warning about the other overload of Dispatch being hidden.
   using AbstractThread::Dispatch;
 
   // Blocks until all tasks finish executing.
   void AwaitIdle() { mTaskQueue->AwaitIdle(); }
 
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -43,16 +43,20 @@ nsContentSecurityManager::AllowTopLevelN
   }
   nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
   if (!loadInfo) {
     return true;
   }
   if (loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_DOCUMENT) {
     return true;
   }
+  if (loadInfo->GetForceAllowDataURI()) {
+    // if the loadinfo explicitly allows the data URI navigation, let's allow it now
+    return true;
+  }
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, true);
   bool isDataURI =
     (NS_SUCCEEDED(uri->SchemeIs("data", &isDataURI)) && isDataURI);
   if (!isDataURI) {
     return true;
   }
--- a/dom/security/test/general/browser.ini
+++ b/dom/security/test/general/browser.ini
@@ -4,8 +4,11 @@ support-files =
   file_toplevel_data_navigations.sjs
   file_toplevel_data_meta_redirect.html
 [browser_test_data_download.js]
 support-files =
   file_data_download.html
 [browser_test_data_text_csv.js]
 support-files =
   file_data_text_csv.html
+[browser_test_view_image_data_navigation.js]
+support-files =
+  file_view_image_data_navigation.html
new file mode 100644
--- /dev/null
+++ b/dom/security/test/general/browser_test_view_image_data_navigation.js
@@ -0,0 +1,30 @@
+"use strict";
+
+const TEST_PAGE = getRootDirectory(gTestPath) + "file_view_image_data_navigation.html";
+
+add_task(async function test_principal_right_click_open_link_in_new_tab() {
+  await SpecialPowers.pushPrefEnv({
+    "set": [["security.data_uri.block_toplevel_data_uri_navigations", true]],
+  });
+
+  await BrowserTestUtils.withNewTab(TEST_PAGE, async function(browser) {
+    let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser, true);
+
+    // simulate right-click->view-image
+    BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
+      // These are operations that must be executed synchronously with the event.
+      document.getElementById("context-viewimage").doCommand();
+      event.target.hidePopup();
+      return true;
+    });
+    BrowserTestUtils.synthesizeMouseAtCenter("#testimage",
+                                             { type: "contextmenu", button: 2 },
+                                             gBrowser.selectedBrowser);
+    await loadPromise;
+
+    await ContentTask.spawn(gBrowser.selectedBrowser, {}, async function() {
+      ok(content.document.location.toString().startsWith("data:image/svg+xml;"),
+         "data:image/svg navigation allowed through right-click view-image")
+    });
+  });
+});
new file mode 100644
--- /dev/null
+++ b/dom/security/test/general/file_view_image_data_navigation.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Bug 1407891: Test navigation for right-click view-image on data:image/svg</title>
+</head>
+<body>
+
+<img id="testimage" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgdmlld0JveD0iMCAwIDE2IDE2Ij4KICA8cGF0aCBkPSJNOCwxMkwzLDcsNCw2bDQsNCw0LTQsMSwxWiIgZmlsbD0iIzZBNkE2QSIgLz4KPC9zdmc+Cg=="></img>
+
+</body>
+</html>
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -45,16 +45,18 @@
 #include "ScaledFontMac.h"
 #include "CGTextDrawing.h"
 #endif
 
 #ifdef XP_WIN
 #include "ScaledFontDWrite.h"
 #endif
 
+using namespace std;
+
 namespace mozilla {
 namespace gfx {
 
 class GradientStopsSkia : public GradientStops
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(GradientStopsSkia)
   GradientStopsSkia(const std::vector<GradientStop>& aStops, uint32_t aNumStops, ExtendMode aExtendMode)
@@ -271,16 +273,17 @@ GetSkImageForSurface(SourceSurface* aSur
   MOZ_ASSERT(VerifyRGBXCorners(surf->GetData(), surf->GetSize(),
                                surf->Stride(), surf->GetFormat(),
                                aBounds, aMatrix));
   return image;
 }
 
 DrawTargetSkia::DrawTargetSkia()
   : mSnapshot(nullptr)
+  , mSnapshotLock{make_shared<Mutex>("DrawTargetSkia::mSnapshotLock")}
 #ifdef MOZ_WIDGET_COCOA
   , mCG(nullptr)
   , mColorSpace(nullptr)
   , mCanvasData(nullptr)
   , mCGSize(0, 0)
   , mNeedLayer(false)
 #endif
 {
@@ -311,17 +314,17 @@ DrawTargetSkia::Snapshot()
     // If the surface is raster, making a snapshot may trigger a pixel copy.
     // Instead, try to directly make a raster image referencing the surface pixels.
     SkPixmap pixmap;
     if (mSurface->peekPixels(&pixmap)) {
       image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
     } else {
       image = mSurface->makeImageSnapshot();
     }
-    if (!snapshot->InitFromImage(image, mFormat, this)) {
+    if (!snapshot->InitFromImage(image, mFormat, this, mSnapshotLock)) {
       return nullptr;
     }
     mSnapshot = snapshot;
   }
 
   return snapshot.forget();
 }
 
@@ -2209,16 +2212,17 @@ already_AddRefed<FilterNode>
 DrawTargetSkia::CreateFilter(FilterType aType)
 {
   return FilterNodeSoftware::Create(aType);
 }
 
 void
 DrawTargetSkia::MarkChanged()
 {
+  MutexAutoLock lock(*mSnapshotLock);
   if (mSnapshot) {
     mSnapshot->DrawTargetWillChange();
     mSnapshot = nullptr;
 
     // Handle copying of any image snapshots bound to the surface.
     if (mSurface) {
       mSurface->notifyContentWillChange(SkSurface::kRetain_ContentChangeMode);
     }
--- a/gfx/2d/DrawTargetSkia.h
+++ b/gfx/2d/DrawTargetSkia.h
@@ -201,16 +201,17 @@ private:
 #ifdef USE_SKIA_GPU
   sk_sp<GrContext> mGrContext;
 #endif
 
   IntSize mSize;
   sk_sp<SkSurface> mSurface;
   SkCanvas* mCanvas;
   SourceSurfaceSkia* mSnapshot;
+  std::shared_ptr<Mutex> mSnapshotLock;
 
 #ifdef MOZ_WIDGET_COCOA
   friend class BorrowedCGContext;
 
   CGContextRef BorrowCGContext(const DrawOptions &aOptions);
   void ReturnCGContext(CGContextRef);
   bool FillGlyphsWithCG(ScaledFont* aFont,
                         const GlyphBuffer& aBuffer,
--- a/gfx/2d/Filters.h
+++ b/gfx/2d/Filters.h
@@ -470,17 +470,17 @@ enum PremultiplyInputs
   IN_PREMULTIPLY_IN = 0
 };
 
 enum UnpremultiplyInputs
 {
   IN_UNPREMULTIPLY_IN = 0
 };
 
-class FilterNode : public RefCounted<FilterNode>
+class FilterNode : public external::AtomicRefCounted<FilterNode>
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNode)
   virtual ~FilterNode() {}
 
   virtual FilterBackend GetBackendType() = 0;
 
   virtual void SetInput(uint32_t aIndex, SourceSurface *aSurface) { MOZ_CRASH("GFX: FilterNode"); }
--- a/gfx/2d/SourceSurfaceSkia.cpp
+++ b/gfx/2d/SourceSurfaceSkia.cpp
@@ -8,30 +8,35 @@
 #include "Logging.h"
 #include "SourceSurfaceSkia.h"
 #include "HelpersSkia.h"
 #include "DrawTargetSkia.h"
 #include "DataSurfaceHelpers.h"
 #include "skia/include/core/SkData.h"
 #include "mozilla/CheckedInt.h"
 
+using namespace std;
+
 namespace mozilla {
 namespace gfx {
 
 SourceSurfaceSkia::SourceSurfaceSkia()
   : mDrawTarget(nullptr)
   , mChangeMutex("SourceSurfaceSkia::mChangeMutex")
 {
 }
 
 SourceSurfaceSkia::~SourceSurfaceSkia()
 {
-  if (mDrawTarget) {
-    mDrawTarget->SnapshotDestroyed();
-    mDrawTarget = nullptr;
+  if (mSnapshotLock) {
+    MutexAutoLock lock{*mSnapshotLock};
+    if (mDrawTarget) {
+      mDrawTarget->SnapshotDestroyed();
+      mDrawTarget = nullptr;
+    }
   }
 }
 
 IntSize
 SourceSurfaceSkia::GetSize() const
 {
   return mSize;
 }
@@ -99,17 +104,18 @@ SourceSurfaceSkia::InitFromData(unsigned
   mFormat = aFormat;
   mStride = aStride;
   return true;
 }
 
 bool
 SourceSurfaceSkia::InitFromImage(const sk_sp<SkImage>& aImage,
                                  SurfaceFormat aFormat,
-                                 DrawTargetSkia* aOwner)
+                                 DrawTargetSkia* aOwner,
+                                 shared_ptr<Mutex> aSnapshotLock)
 {
   if (!aImage) {
     return false;
   }
 
   mSize = IntSize(aImage->width(), aImage->height());
 
   // For the raster image case, we want to use the format and stride
@@ -132,16 +138,18 @@ SourceSurfaceSkia::InitFromImage(const s
     mStride = SkAlign4(info.minRowBytes());
   } else {
     return false;
   }
 
   mImage = aImage;
 
   if (aOwner) {
+    MOZ_ASSERT(aSnapshotLock);
+    mSnapshotLock = move(aSnapshotLock);
     mDrawTarget = aOwner;
   }
 
   return true;
 }
 
 uint8_t*
 SourceSurfaceSkia::GetData()
@@ -181,16 +189,20 @@ SourceSurfaceSkia::Unmap()
   mChangeMutex.Unlock();
   MOZ_ASSERT(mIsMapped);
   mIsMapped = false;
 }
 
 void
 SourceSurfaceSkia::DrawTargetWillChange()
 {
+  // In this case synchronisation on destroy should be guaranteed!
+  MOZ_ASSERT(mSnapshotLock);
+  mSnapshotLock->AssertCurrentThreadOwns();
+
   MutexAutoLock lock(mChangeMutex);
   if (mDrawTarget) {
     // Raster snapshots do not use Skia's internal copy-on-write mechanism,
     // so we need to do an explicit copy here.
     // GPU snapshots, for which peekPixels is false, will already be dealt
     // with automatically via the internal copy-on-write mechanism, so we
     // don't need to do anything for them here.
     SkPixmap pixmap;
--- a/gfx/2d/SourceSurfaceSkia.h
+++ b/gfx/2d/SourceSurfaceSkia.h
@@ -13,16 +13,17 @@
 #include "skia/include/core/SkCanvas.h"
 #include "skia/include/core/SkImage.h"
 
 namespace mozilla {
 
 namespace gfx {
 
 class DrawTargetSkia;
+class SnapshotLock;
 
 class SourceSurfaceSkia : public DataSourceSurface
 {
 public:
   MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceSkia)
   SourceSurfaceSkia();
   ~SourceSurfaceSkia();
 
@@ -34,17 +35,18 @@ public:
 
   bool InitFromData(unsigned char* aData,
                     const IntSize &aSize,
                     int32_t aStride,
                     SurfaceFormat aFormat);
 
   bool InitFromImage(const sk_sp<SkImage>& aImage,
                      SurfaceFormat aFormat = SurfaceFormat::UNKNOWN,
-                     DrawTargetSkia* aOwner = nullptr);
+                     DrawTargetSkia* aOwner = nullptr,
+                     std::shared_ptr<Mutex> aSnapshotLock = std::shared_ptr<Mutex>{});
 
   virtual uint8_t* GetData();
 
   /**
    * The caller is responsible for ensuring aMappedSurface is not null.
    */
   virtual bool Map(MapType, MappedSurface *aMappedSurface);
 
@@ -57,15 +59,16 @@ private:
 
   void DrawTargetWillChange();
 
   sk_sp<SkImage> mImage;
   SurfaceFormat mFormat;
   IntSize mSize;
   int32_t mStride;
   RefPtr<DrawTargetSkia> mDrawTarget;
+  std::shared_ptr<Mutex> mSnapshotLock;
   Mutex mChangeMutex;
 };
 
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_SOURCESURFACESKIA_H_ */
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -208,16 +208,25 @@ GPUParent::RecvInit(nsTArray<GfxPrefSett
       display_name,
       nullptr
     };
     char** argvp = argv;
     gtk_init(&argc, &argvp);
   } else {
     gtk_init(nullptr, nullptr);
   }
+
+  // Ensure we have an FT library for font instantiation.
+  // This would normally be set by gfxPlatform::Init().
+  // Since we bypass that, we must do it here instead.
+  if (gfxVars::UseWebRender()) {
+    FT_Library library = Factory::NewFTLibrary();
+    MOZ_ASSERT(library);
+    Factory::SetFTLibrary(library);
+  }
 #endif
 
   // Make sure to do this *after* we update gfxVars above.
   if (gfxVars::UseWebRender()) {
     wr::RenderThread::Start();
   }
 
   VRManager::ManagerInit();
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -608,17 +608,17 @@ GetRootDocumentElementFor(nsIWidget* aWi
 
 static nsIFrame*
 UpdateRootFrameForTouchTargetDocument(nsIFrame* aRootFrame)
 {
 #if defined(MOZ_WIDGET_ANDROID)
   // Re-target so that the hit test is performed relative to the frame for the
   // Root Content Document instead of the Root Document which are different in
   // Android. See bug 1229752 comment 16 for an explanation of why this is necessary.
-  if (nsIDocument* doc = aRootFrame->PresContext()->PresShell()->GetPrimaryContentDocument()) {
+  if (nsIDocument* doc = aRootFrame->PresShell()->GetPrimaryContentDocument()) {
     if (nsIPresShell* shell = doc->GetShell()) {
       if (nsIFrame* frame = shell->GetRootFrame()) {
         return frame;
       }
     }
   }
 #endif
   return aRootFrame;
@@ -643,17 +643,17 @@ PrepareForSetTargetAPZCNotification(nsIW
   // when zoomed out. On desktop, don't use it because it interferes with
   // hit testing for some purposes such as scrollbar dragging.
   flags = nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME;
 #endif
   nsIFrame* target =
     nsLayoutUtils::GetFrameForPoint(aRootFrame, point, flags);
   nsIScrollableFrame* scrollAncestor = target
     ? nsLayoutUtils::GetAsyncScrollableAncestorFrame(target)
-    : aRootFrame->PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
+    : aRootFrame->PresShell()->GetRootScrollFrameAsScrollable();
 
   // Assuming that if there's no scrollAncestor, there's already a displayPort.
   nsCOMPtr<dom::Element> dpElement = scrollAncestor
     ? GetDisplayportElementFor(scrollAncestor)
     : GetRootDocumentElementFor(aWidget);
 
 #ifdef APZCCH_LOGGING
   nsAutoString dpElementDesc;
@@ -680,17 +680,17 @@ PrepareForSetTargetAPZCNotification(nsIW
     // reach this point...
     // If we get here, the document element is non-null, valid, but doesn't have
     // a displayport. It's possible that the init code in ChromeProcessController
     // failed for some reason, or the document element got swapped out at some
     // later time. In this case let's try to set a displayport on the document
     // element again and bail out on this operation.
     APZCCH_LOG("Widget %p's document element %p didn't have a displayport\n",
         aWidget, dpElement.get());
-    APZCCallbackHelper::InitializeRootDisplayport(aRootFrame->PresContext()->PresShell());
+    APZCCallbackHelper::InitializeRootDisplayport(aRootFrame->PresShell());
     return false;
   }
 
   APZCCH_LOG("%p didn't have a displayport, so setting one...\n", dpElement.get());
   bool activated = nsLayoutUtils::CalculateAndSetDisplayPortMargins(
       scrollAncestor, nsLayoutUtils::RepaintMode::Repaint);
   if (!activated) {
     return false;
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -263,17 +263,17 @@ public:
     return ret.forget();
   }
 };
 
 static already_AddRefed<TextureClient>
 TexClientFromReadback(SharedSurface* src, CompositableForwarder* allocator,
                       TextureFlags baseFlags, LayersBackend layersBackend)
 {
-  auto backendType = gfx::BackendType::CAIRO;
+  auto backendType = gfx::BackendType::SKIA;
   TexClientFactory factory(allocator, src->mHasAlpha, src->mSize, backendType,
                            baseFlags, layersBackend);
 
   RefPtr<TextureClient> texClient;
 
   {
     gl::ScopedReadbackFB autoReadback(src);
 
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -1136,21 +1136,16 @@ TextureClient::CreateForDrawing(TextureF
     data = AndroidNativeWindowTextureData::Create(aSize, aFormat);
   }
 #endif
 
   if (data) {
     return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
   }
 
-  if (moz2DBackend == BackendType::SKIA && aFormat == SurfaceFormat::B8G8R8X8) {
-    // Skia doesn't support RGBX, so ensure we clear the buffer for the proper alpha values.
-    aAllocFlags = TextureAllocationFlags(aAllocFlags | ALLOC_CLEAR_BUFFER);
-  }
-
   // Can't do any better than a buffer texture client.
   return TextureClient::CreateForRawBufferAccess(aAllocator, aFormat, aSize,
                                                  moz2DBackend, aLayersBackend,
                                                  aTextureFlags, aAllocFlags);
 }
 
 // static
 already_AddRefed<TextureClient>
@@ -1245,23 +1240,30 @@ TextureClient::CreateForRawBufferAccess(
   if (aAllocFlags & ALLOC_DISALLOW_BUFFERTEXTURECLIENT) {
     return nullptr;
   }
 
   if (!gfx::Factory::AllowedSurfaceSize(aSize)) {
     return nullptr;
   }
 
-  // D2D backend does not support CreateDrawTargetForData(). Use CAIRO instead.
-  if (aMoz2DBackend == gfx::BackendType::DIRECT2D ||
-      aMoz2DBackend == gfx::BackendType::DIRECT2D1_1) {
-    aMoz2DBackend = gfx::BackendType::CAIRO;
+  if (aFormat == SurfaceFormat::B8G8R8X8) {
+    // Skia doesn't support RGBX, so ensure we clear the buffer for the proper alpha values.
+    aAllocFlags = TextureAllocationFlags(aAllocFlags | ALLOC_CLEAR_BUFFER);
   }
 
-  TextureData* texData = BufferTextureData::Create(aSize, aFormat, aMoz2DBackend,
+  // Note that we ignore the backend type if we get here. It should only be D2D
+  // or Skia, and D2D does not support data surfaces. Therefore it is safe to
+  // force the buffer to be Skia.
+  NS_WARNING_ASSERTION(aMoz2DBackend != gfx::BackendType::SKIA &&
+                       aMoz2DBackend != gfx::BackendType::DIRECT2D &&
+                       aMoz2DBackend != gfx::BackendType::DIRECT2D1_1,
+                       "Unsupported TextureClient backend type");
+
+  TextureData* texData = BufferTextureData::Create(aSize, aFormat, gfx::BackendType::SKIA,
                                                    aLayersBackend, aTextureFlags,
                                                    aAllocFlags, aAllocator);
   if (!texData) {
     return nullptr;
   }
 
   return MakeAndAddRef<TextureClient>(texData, aTextureFlags, aAllocator);
 }
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -76,17 +76,17 @@ WebRenderCommandBuilder::BuildWebRenderC
       CreateWebRenderCommandsFromDisplayList(aDisplayList, aDisplayListBuilder,
                                              pageRootSc, aBuilder, aResourceUpdates);
     }
 
     // Make a "root" layer data that has everything else as descendants
     mLayerScrollData.emplace_back();
     mLayerScrollData.back().InitializeRoot(mLayerScrollData.size() - 1);
     if (aDisplayListBuilder->IsBuildingLayerEventRegions()) {
-      nsIPresShell* shell = aDisplayListBuilder->RootReferenceFrame()->PresContext()->PresShell();
+      nsIPresShell* shell = aDisplayListBuilder->RootReferenceFrame()->PresShell();
       if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(shell)) {
         mLayerScrollData.back().SetEventRegionsOverride(EventRegionsOverride::ForceDispatchToContent);
       }
     }
     auto callback = [&aScrollData](FrameMetrics::ViewID aScrollId) -> bool {
       return aScrollData.HasMetadataFor(aScrollId);
     };
     if (Maybe<ScrollMetadata> rootMetadata = nsLayoutUtils::GetRootMetadata(
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -89,17 +89,17 @@ protected:
 
   virtual void OnRenderingChange() override
   {
     Element* elem = GetTarget();
     MOZ_ASSERT(elem, "missing root SVG node");
 
     if (mHonoringInvalidations && !mDocWrapper->ShouldIgnoreInvalidation()) {
       nsIFrame* frame = elem->GetPrimaryFrame();
-      if (!frame || frame->PresContext()->PresShell()->IsDestroying()) {
+      if (!frame || frame->PresShell()->IsDestroying()) {
         // We're being destroyed. Bail out.
         return;
       }
 
       // Ignore further invalidations until we draw.
       mHonoringInvalidations = false;
 
       mVectorImage->InvalidateObserversOnNextRefreshDriverTick();
--- a/ipc/glue/BackgroundUtils.cpp
+++ b/ipc/glue/BackgroundUtils.cpp
@@ -382,16 +382,17 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoa
       sandboxedLoadingPrincipalInfo,
       optionalResultPrincipalURI,
       aLoadInfo->GetSecurityFlags(),
       aLoadInfo->InternalContentPolicyType(),
       static_cast<uint32_t>(aLoadInfo->GetTainting()),
       aLoadInfo->GetUpgradeInsecureRequests(),
       aLoadInfo->GetVerifySignedContent(),
       aLoadInfo->GetEnforceSRI(),
+      aLoadInfo->GetForceAllowDataURI(),
       aLoadInfo->GetForceInheritPrincipalDropped(),
       aLoadInfo->GetInnerWindowID(),
       aLoadInfo->GetOuterWindowID(),
       aLoadInfo->GetParentOuterWindowID(),
       aLoadInfo->GetTopOuterWindowID(),
       aLoadInfo->GetFrameOuterWindowID(),
       aLoadInfo->GetEnforceSecurity(),
       aLoadInfo->GetInitialSecurityCheckDone(),
@@ -490,16 +491,17 @@ LoadInfoArgsToLoadInfo(const OptionalLoa
                           sandboxedLoadingPrincipal,
                           resultPrincipalURI,
                           loadInfoArgs.securityFlags(),
                           loadInfoArgs.contentPolicyType(),
                           static_cast<LoadTainting>(loadInfoArgs.tainting()),
                           loadInfoArgs.upgradeInsecureRequests(),
                           loadInfoArgs.verifySignedContent(),
                           loadInfoArgs.enforceSRI(),
+                          loadInfoArgs.forceAllowDataURI(),
                           loadInfoArgs.forceInheritPrincipalDropped(),
                           loadInfoArgs.innerWindowID(),
                           loadInfoArgs.outerWindowID(),
                           loadInfoArgs.parentOuterWindowID(),
                           loadInfoArgs.topOuterWindowID(),
                           loadInfoArgs.frameOuterWindowID(),
                           loadInfoArgs.enforceSecurity(),
                           loadInfoArgs.initialSecurityCheckDone(),
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -3125,18 +3125,27 @@ Parser<ParseHandler, CharT>::functionArg
               }
             }
 
             if (positionalFormals.length() >= ARGNO_LIMIT) {
                 error(JSMSG_TOO_MANY_FUN_ARGS);
                 return false;
             }
 
+            // The next step is to detect arguments with default expressions,
+            // e.g. |function parseInt(str, radix = 10) {}|.  But if we have a
+            // parentheses-free arrow function, |a => ...|, the '=' necessary
+            // for a default expression would really be an assignment operator:
+            // that is, |a = b => 42;| would parse as |a = (b => 42);|.  So we
+            // should stop parsing arguments here.
+            if (parenFreeArrow)
+                break;
+
             bool matched;
-            if (!tokenStream.matchToken(&matched, TOK_ASSIGN))
+            if (!tokenStream.matchToken(&matched, TOK_ASSIGN, TokenStream::Operand))
                 return false;
             if (matched) {
                 // A default argument without parentheses would look like:
                 // a = expr => body, but both operators are right-associative, so
                 // that would have been parsed as a = (expr => body) instead.
                 // Therefore it's impossible to get here with parenFreeArrow.
                 MOZ_ASSERT(!parenFreeArrow);
 
@@ -3161,37 +3170,36 @@ Parser<ParseHandler, CharT>::functionArg
 
                 Node def_expr = assignExprWithoutYieldOrAwait(yieldHandling);
                 if (!def_expr)
                     return false;
                 if (!handler.setLastFunctionFormalParameterDefault(funcpn, def_expr))
                     return false;
             }
 
-            if (parenFreeArrow || IsSetterKind(kind))
+            // Setter syntax uniquely requires exactly one argument.
+            if (IsSetterKind(kind))
                 break;
 
-            if (!tokenStream.matchToken(&matched, TOK_COMMA))
+            if (!tokenStream.matchToken(&matched, TOK_COMMA, TokenStream::Operand))
                 return false;
             if (!matched)
                 break;
 
             if (!hasRest) {
                 if (!tokenStream.peekToken(&tt, TokenStream::Operand))
                     return null();
-                if (tt == TOK_RP) {
-                    tokenStream.addModifierException(TokenStream::NoneIsOperand);
+                if (tt == TOK_RP)
                     break;
-                }
             }
         }
 
         if (!parenFreeArrow) {
             TokenKind tt;
-            if (!tokenStream.getToken(&tt))
+            if (!tokenStream.getToken(&tt, TokenStream::Operand))
                 return false;
             if (tt != TOK_RP) {
                 if (IsSetterKind(kind)) {
                     error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
                     return false;
                 }
 
                 error(JSMSG_PAREN_AFTER_FORMAL);
@@ -4438,18 +4446,20 @@ Parser<ParseHandler, CharT>::objectBindi
         return null();
 
     Maybe<DeclarationKind> declKind = Some(kind);
     RootedAtom propAtom(context);
     for (;;) {
         TokenKind tt;
         if (!tokenStream.peekToken(&tt))
             return null();
-        if (tt == TOK_RC)
+        if (tt == TOK_RC) {
+            tokenStream.addModifierException(TokenStream::OperandIsNone);
             break;
+        }
 
         if (tt == TOK_TRIPLEDOT) {
             tokenStream.consumeKnownToken(TOK_TRIPLEDOT);
             uint32_t begin = pos().begin;
 
             TokenKind tt;
             if (!tokenStream.getToken(&tt))
                 return null();
@@ -4479,17 +4489,17 @@ Parser<ParseHandler, CharT>::objectBindi
                 if (!tokenStream.getToken(&tt, TokenStream::Operand))
                     return null();
 
                 Node binding = bindingIdentifierOrPattern(kind, yieldHandling, tt);
                 if (!binding)
                     return null();
 
                 bool hasInitializer;
-                if (!tokenStream.matchToken(&hasInitializer, TOK_ASSIGN))
+                if (!tokenStream.matchToken(&hasInitializer, TOK_ASSIGN, TokenStream::Operand))
                     return null();
 
                 Node bindingExpr = hasInitializer
                                    ? bindingInitializer(binding, kind, yieldHandling)
                                    : binding;
                 if (!bindingExpr)
                     return null();
 
@@ -4525,27 +4535,27 @@ Parser<ParseHandler, CharT>::objectBindi
                     return null();
             } else {
                 errorAt(namePos.begin, JSMSG_NO_VARIABLE_NAME);
                 return null();
             }
         }
 
         bool matched;
-        if (!tokenStream.matchToken(&matched, TOK_COMMA))
+        if (!tokenStream.matchToken(&matched, TOK_COMMA, TokenStream::Operand))
             return null();
         if (!matched)
             break;
         if (tt == TOK_TRIPLEDOT) {
             error(JSMSG_REST_WITH_COMMA);
             return null();
         }
     }
 
-    MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::None,
+    MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::Operand,
                                      reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
                                                           JSMSG_CURLY_OPENED, begin));
 
     handler.setEndPosition(literal, pos().end);
     return literal;
 }
 
 template <class ParseHandler, typename CharT>
@@ -4570,16 +4580,17 @@ Parser<ParseHandler, CharT>::arrayBindin
          }
 
          TokenKind tt;
          if (!tokenStream.getToken(&tt))
              return null();
 
          if (tt == TOK_RB) {
              tokenStream.ungetToken();
+             tokenStream.addModifierException(TokenStream::OperandIsNone);
              break;
          }
 
          if (tt == TOK_COMMA) {
              if (!handler.addElision(literal, pos()))
                  return null();
          } else if (tt == TOK_TRIPLEDOT) {
              uint32_t begin = pos().begin;
@@ -4595,44 +4606,44 @@ Parser<ParseHandler, CharT>::arrayBindin
              if (!handler.addSpreadElement(literal, begin, inner))
                  return null();
          } else {
              Node binding = bindingIdentifierOrPattern(kind, yieldHandling, tt);
              if (!binding)
                  return null();
 
              bool hasInitializer;
-             if (!tokenStream.matchToken(&hasInitializer, TOK_ASSIGN))
+             if (!tokenStream.matchToken(&hasInitializer, TOK_ASSIGN, TokenStream::Operand))
                  return null();
 
              Node element = hasInitializer
                             ? bindingInitializer(binding, kind, yieldHandling)
                             : binding;
              if (!element)
                  return null();
 
              handler.addArrayElement(literal, element);
          }
 
          if (tt != TOK_COMMA) {
              // If we didn't already match TOK_COMMA in above case.
              bool matched;
-             if (!tokenStream.matchToken(&matched, TOK_COMMA))
+             if (!tokenStream.matchToken(&matched, TOK_COMMA, TokenStream::Operand))
                  return null();
              if (!matched)
                  break;
 
              if (tt == TOK_TRIPLEDOT) {
                  error(JSMSG_REST_WITH_COMMA);
                  return null();
              }
          }
      }
 
-     MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RB, TokenStream::None,
+     MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RB, TokenStream::Operand,
                                       reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
                                                            JSMSG_BRACKET_OPENED, begin));
 
     handler.setEndPosition(literal, pos().end);
     return literal;
 }
 
 template <class ParseHandler, typename CharT>
@@ -7926,17 +7937,17 @@ Parser<ParseHandler, CharT>::condExpr(In
         return null();
     if (!matched)
         return condition;
 
     Node thenExpr = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
     if (!thenExpr)
         return null();
 
-    MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND);
+    MUST_MATCH_TOKEN_MOD(TOK_COLON, TokenStream::Operand, JSMSG_COLON_IN_COND);
 
     Node elseExpr = assignExpr(inHandling, yieldHandling, TripledotProhibited);
     if (!elseExpr)
         return null();
 
     return handler.newConditional(condition, thenExpr, elseExpr);
 }
 
@@ -8016,77 +8027,57 @@ Parser<ParseHandler, CharT>::assignExpr(
     // Save the tokenizer state in case we find an arrow function and have to
     // rewind.
     TokenStream::Position start(keepAtoms);
     tokenStream.tell(&start);
 
     PossibleError possibleErrorInner(*this);
     Node lhs;
     TokenKind tokenAfterLHS;
+    bool isArrow;
     if (maybeAsyncArrow) {
         tokenStream.consumeKnownToken(TOK_ASYNC, TokenStream::Operand);
 
         TokenKind tokenAfterAsync;
         if (!tokenStream.getToken(&tokenAfterAsync))
             return null();
         MOZ_ASSERT(TokenKindIsPossibleIdentifier(tokenAfterAsync));
 
         // Check yield validity here.
         RootedPropertyName name(context, bindingIdentifier(yieldHandling));
         if (!name)
             return null();
 
-        if (!tokenStream.getToken(&tokenAfterLHS))
+        if (!tokenStream.peekTokenSameLine(&tokenAfterLHS))
             return null();
         if (tokenAfterLHS != TOK_ARROW) {
             error(JSMSG_UNEXPECTED_TOKEN,
-                  "'=>' after argument list", TokenKindToDesc(tokenAfterLHS));
-            return null();
-        }
+                  "'=>' on the same line after an argument list", TokenKindToDesc(tokenAfterLHS));
+            return null();
+        }
+
+        isArrow = true;
     } else {
         lhs = condExpr(inHandling, yieldHandling, tripledotHandling, &possibleErrorInner, invoked);
         if (!lhs)
             return null();
 
-        if (!tokenStream.getToken(&tokenAfterLHS))
-            return null();
-    }
-
-    ParseNodeKind kind;
-    switch (tokenAfterLHS) {
-      case TOK_ASSIGN:       kind = PNK_ASSIGN;       break;
-      case TOK_ADDASSIGN:    kind = PNK_ADDASSIGN;    break;
-      case TOK_SUBASSIGN:    kind = PNK_SUBASSIGN;    break;
-      case TOK_BITORASSIGN:  kind = PNK_BITORASSIGN;  break;
-      case TOK_BITXORASSIGN: kind = PNK_BITXORASSIGN; break;
-      case TOK_BITANDASSIGN: kind = PNK_BITANDASSIGN; break;
-      case TOK_LSHASSIGN:    kind = PNK_LSHASSIGN;    break;
-      case TOK_RSHASSIGN:    kind = PNK_RSHASSIGN;    break;
-      case TOK_URSHASSIGN:   kind = PNK_URSHASSIGN;   break;
-      case TOK_MULASSIGN:    kind = PNK_MULASSIGN;    break;
-      case TOK_DIVASSIGN:    kind = PNK_DIVASSIGN;    break;
-      case TOK_MODASSIGN:    kind = PNK_MODASSIGN;    break;
-      case TOK_POWASSIGN:    kind = PNK_POWASSIGN;    break;
-
-      case TOK_ARROW: {
-
-        // A line terminator between ArrowParameters and the => should trigger a SyntaxError.
-        tokenStream.ungetToken();
+        // Use Operand here because the ConditionalExpression parsed above
+        // could be the entirety of this AssignmentExpression, and then ASI
+        // permits this token to be a regular expression.
+        if (!tokenStream.peekTokenSameLine(&tokenAfterLHS, TokenStream::Operand))
+            return null();
+
+        isArrow = tokenAfterLHS == TOK_ARROW;
+    }
+
+    if (isArrow) {
+        tokenStream.seek(start);
+
         TokenKind next;
-        if (!tokenStream.peekTokenSameLine(&next))
-            return null();
-        MOZ_ASSERT(next == TOK_ARROW || next == TOK_EOL);
-
-        if (next != TOK_ARROW) {
-            error(JSMSG_LINE_BREAK_BEFORE_ARROW);
-            return null();
-        }
-
-        tokenStream.seek(start);
-
         if (!tokenStream.getToken(&next, TokenStream::Operand))
             return null();
         uint32_t toStringStart = pos().begin;
         tokenStream.ungetToken();
 
         FunctionAsyncKind asyncKind = SyncFunction;
 
         if (next == TOK_ASYNC) {
@@ -8106,29 +8097,46 @@ Parser<ParseHandler, CharT>::assignExpr(
         }
 
         Node pn = handler.newArrowFunction(pos());
         if (!pn)
             return null();
 
         return functionDefinition(pn, toStringStart, inHandling, yieldHandling, nullptr,
                                   Arrow, GeneratorKind::NotGenerator, asyncKind);
-      }
+    }
+
+    MOZ_ALWAYS_TRUE(tokenStream.getToken(&tokenAfterLHS, TokenStream::Operand));
+
+    ParseNodeKind kind;
+    switch (tokenAfterLHS) {
+      case TOK_ASSIGN:       kind = PNK_ASSIGN;       break;
+      case TOK_ADDASSIGN:    kind = PNK_ADDASSIGN;    break;
+      case TOK_SUBASSIGN:    kind = PNK_SUBASSIGN;    break;
+      case TOK_BITORASSIGN:  kind = PNK_BITORASSIGN;  break;
+      case TOK_BITXORASSIGN: kind = PNK_BITXORASSIGN; break;
+      case TOK_BITANDASSIGN: kind = PNK_BITANDASSIGN; break;
+      case TOK_LSHASSIGN:    kind = PNK_LSHASSIGN;    break;
+      case TOK_RSHASSIGN:    kind = PNK_RSHASSIGN;    break;
+      case TOK_URSHASSIGN:   kind = PNK_URSHASSIGN;   break;
+      case TOK_MULASSIGN:    kind = PNK_MULASSIGN;    break;
+      case TOK_DIVASSIGN:    kind = PNK_DIVASSIGN;    break;
+      case TOK_MODASSIGN:    kind = PNK_MODASSIGN;    break;
+      case TOK_POWASSIGN:    kind = PNK_POWASSIGN;    break;
 
       default:
         MOZ_ASSERT(!tokenStream.isCurrentTokenAssignment());
         if (!possibleError) {
             if (!possibleErrorInner.checkForExpressionError())
                 return null();
         } else {
             possibleErrorInner.transferErrorsTo(possibleError);
         }
 
         tokenStream.ungetToken();
-        tokenStream.addModifierException(TokenStream::OperandIsNone);
         return lhs;
     }
 
     // Verify the left-hand side expression doesn't have a forbidden form.
     if (handler.isUnparenthesizedDestructuringPattern(lhs)) {
         if (kind != PNK_ASSIGN) {
             error(JSMSG_BAD_DESTRUCT_ASS);
             return null();
@@ -8706,31 +8714,29 @@ Parser<ParseHandler, CharT>::argumentLis
             argNode = handler.newSpread(begin, argNode);
             if (!argNode)
                 return false;
         }
 
         handler.addList(listNode, argNode);
 
         bool matched;
-        if (!tokenStream.matchToken(&matched, TOK_COMMA))
+        if (!tokenStream.matchToken(&matched, TOK_COMMA, TokenStream::Operand))
             return false;
         if (!matched)
             break;
 
         TokenKind tt;
         if (!tokenStream.peekToken(&tt, TokenStream::Operand))
             return null();
-        if (tt == TOK_RP) {
-            tokenStream.addModifierException(TokenStream::NoneIsOperand);
+        if (tt == TOK_RP)
             break;
-        }
-    }
-
-    MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_ARGS);
+    }
+
+    MUST_MATCH_TOKEN_MOD(TOK_RP, TokenStream::Operand, JSMSG_PAREN_AFTER_ARGS);
 
     handler.setEndPosition(listNode, pos().end);
     return true;
 }
 
 template <class ParseHandler, typename CharT>
 bool
 Parser<ParseHandler, CharT>::checkAndMarkSuperScope()
@@ -9588,25 +9594,28 @@ Parser<ParseHandler, CharT>::propertyNam
 
     if (TokenKindIsPossibleIdentifierName(ltok) &&
         (tt == TOK_COMMA || tt == TOK_RC || tt == TOK_ASSIGN))
     {
         if (isGenerator || isAsync) {
             error(JSMSG_BAD_PROP_ID);
             return null();
         }
+
         tokenStream.ungetToken();
-        *propType = tt == TOK_ASSIGN ?
-                          PropertyType::CoverInitializedName :
-                          PropertyType::Shorthand;
+        tokenStream.addModifierException(TokenStream::OperandIsNone);
+        *propType = tt == TOK_ASSIGN
+                    ? PropertyType::CoverInitializedName
+                    : PropertyType::Shorthand;
         return propName;
     }
 
     if (tt == TOK_LP) {
         tokenStream.ungetToken();
+
         if (isGenerator && isAsync)
             *propType = PropertyType::AsyncGeneratorMethod;
         else if (isGenerator)
             *propType = PropertyType::GeneratorMethod;
         else if (isAsync)
             *propType = PropertyType::AsyncMethod;
         else
             *propType = PropertyType::Method;
@@ -9633,17 +9642,17 @@ Parser<ParseHandler, CharT>::computedPro
     } else {
         handler.setListFlag(literal, PNX_NONCONST);
     }
 
     Node assignNode = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
     if (!assignNode)
         return null();
 
-    MUST_MATCH_TOKEN(TOK_RB, JSMSG_COMP_PROP_UNTERM_EXPR);
+    MUST_MATCH_TOKEN_MOD(TOK_RB, TokenStream::Operand, JSMSG_COMP_PROP_UNTERM_EXPR);
     return handler.newComputedName(assignNode, begin, pos().end);
 }
 
 template <class ParseHandler, typename CharT>
 typename ParseHandler::Node
 Parser<ParseHandler, CharT>::objectLiteral(YieldHandling yieldHandling,
                                            PossibleError* possibleError)
 {
@@ -9658,18 +9667,20 @@ Parser<ParseHandler, CharT>::objectLiter
     bool seenPrototypeMutation = false;
     bool seenCoverInitializedName = false;
     Maybe<DeclarationKind> declKind = Nothing();
     RootedAtom propAtom(context);
     for (;;) {
         TokenKind tt;
         if (!tokenStream.peekToken(&tt))
             return null();
-        if (tt == TOK_RC)
+        if (tt == TOK_RC) {
+            tokenStream.addModifierException(TokenStream::OperandIsNone);
             break;
+        }
 
         if (tt == TOK_TRIPLEDOT) {
             tokenStream.consumeKnownToken(TOK_TRIPLEDOT);
             uint32_t begin = pos().begin;
 
             TokenPos innerPos;
             if (!tokenStream.peekTokenPos(&innerPos, TokenStream::Operand))
                 return null();
@@ -9845,25 +9856,25 @@ Parser<ParseHandler, CharT>::objectLiter
                 if (possibleError) {
                     possibleError->setPendingDestructuringErrorAt(namePos,
                                                                   JSMSG_BAD_DESTRUCT_TARGET);
                 }
             }
         }
 
         bool matched;
-        if (!tokenStream.matchToken(&matched, TOK_COMMA))
+        if (!tokenStream.matchToken(&matched, TOK_COMMA, TokenStream::Operand))
             return null();
         if (!matched)
             break;
         if (tt == TOK_TRIPLEDOT && possibleError)
             possibleError->setPendingDestructuringErrorAt(pos(), JSMSG_REST_WITH_COMMA);
     }
 
-    MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::None,
+    MUST_MATCH_TOKEN_MOD_WITH_REPORT(TOK_RC, TokenStream::Operand,
                                      reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
                                                           JSMSG_CURLY_OPENED, openedPos));
 
     handler.setEndPosition(literal, pos().end);
     return literal;
 }
 
 template <class ParseHandler, typename CharT>
--- a/js/src/jit-test/README
+++ b/js/src/jit-test/README
@@ -1,18 +1,18 @@
 JS Trace Test Suite
 
 * PURPOSE
 
-This is a test suite for testing TraceMonkey. All tests are run in the JS shell
+This is a test suite for testing the SpiderMonkey JIT. All tests are run in the JS shell
 with tracing enabled (-j).
 
 * REQUIREMENTS
 
-Python 2.5. This is already a standard requirement for building our tree.
+Python 2.7. This is already a standard requirement for building our tree.
 
 * RUNNING THE TESTS
 
 Basic usage:
 
     python jit_test.py <path-to-js-shell>
 
 The progress bar shows [#tests passed, #tests failed, #tests run] at the left.
--- a/js/src/tests/README.txt
+++ b/js/src/tests/README.txt
@@ -1,22 +1,22 @@
 JS Test Suite Readme
 ====================
 
 The JS test suite is a fairly extensive collection of correctness and regression
 tests for the Spidermonkey engine. Two harnesses run these tests: the shell test
 harness in this directory and the "reftest" harness built into the browser, used
-by Tinderbox. The browser reftests require additional manifest files; these are
+in continuous integration. The browser reftests require additional manifest files; these are
 generated automatically by the build phase 'package-tests' using the
 '--make-manifests' option to jstests.py.
 
 Creating a test
 ---------------
 For general information, see
-https://developer.mozilla.org/en-US/docs/SpiderMonkey/Creating_JavaScript_tests
+https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Creating_JavaScript_tests
 
 Adding a test
 -------------
     Drop it in an appropriate directory under the tests directory.
 
         <fineprint> Some names are forbidden. Do not name your test browser.js,
         shell.js, template.js, user.js, js-test-driver-begin.js, or
         js-test-driver-end.js.
--- a/js/src/tests/ecma_6/ArrowFunctions/arrow-not-as-end-of-statement.js
+++ b/js/src/tests/ecma_6/ArrowFunctions/arrow-not-as-end-of-statement.js
@@ -3,22 +3,74 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Grab-bag of ArrowFunctions with block bodies appearing in contexts where the
 // subsequent token-examination must use the Operand modifier to avoid an
 // assertion.
 
 assertEq(`x ${a => {}} z`, "x a => {} z");
 
+for (a => {}; ; )
+  break;
+
 for (; a => {}; )
   break;
 
 for (; ; a => {})
   break;
 
+Function.prototype[Symbol.iterator] = function() { return { next() { return { done: true }; } }; };
+for (let m of 0 ? 1 : a => {})
+  assertEq(true, false);
+for (let [m] of 0 ? 1 : a => {})
+  assertEq(true, false);
+delete Function.prototype[Symbol.iterator];
+
+for (let w in 0 ? 1 : a => {})
+  break;
+for (let [w] in 0 ? 1 : a => {})
+  break;
+
+function* stargen()
+{
+  yield a => {}
+  /Q/g;
+
+  var first = true;
+  Function.prototype[Symbol.iterator] = function() {
+    return {
+      next() {
+        var res = { done: true, value: 8675309 };
+        if (first)
+        {
+          res = { value: "fnord", done: false };
+          first = false;
+        }
+
+        return res;
+      }
+    };
+  };
+
+
+  yield* a => {}
+  /Q/g;
+
+  delete Function.prototype[Symbol.iterator];
+
+  yield 99;
+}
+var gen = stargen();
+assertEq(typeof gen.next().value, "function");
+var result = gen.next();
+assertEq(result.value, "fnord");
+assertEq(result.done, false);
+assertEq(gen.next().value, 99);
+assertEq(gen.next().done, true);
+
 switch (1)
 {
   case a => {}:
    break;
 }
 
 try
 {
@@ -48,20 +100,111 @@ else
 
 switch (a => {})
 {
 }
 
 with (a => {});
 
 assertEq(typeof (a => {}), "function");
+assertEq(typeof (a => b => {}), "function");
 
 for (var x in y => {})
   continue;
 
+assertEq(eval("a => {}, 17, 42;"), 42);
+assertEq(eval("42, a => {}, 17;"), 17);
+assertEq(typeof eval("17, 42, a => {};"), "function");
+
+assertEq(eval("1 ? 0 : a => {}, 17, 42;"), 42);
+assertEq(eval("42, 1 ? 0 : a => {}, 17;"), 17);
+assertEq(eval("17, 42, 1 ? 0 : a => {};"), 0);
+
 var z = { x: 0 ? 1 : async a => {} };
 assertEq(typeof z.x, "function");
 
 var q = 0 ? 1 : async () => {};
 assertEq(typeof q, "function");
 
+var m = 0 ? 42 : m = foo => {} // ASI
+/Q/g;
+assertEq(typeof m, "function");
+
+var { q: w = 0 ? 1 : a => {} } = {};
+assertEq(typeof w, "function");
+
+Function.prototype.c = 42;
+var { c } = 0 ? 1 : a => {} // ASI
+/Q/g;
+assertEq(c, 42);
+
+var c = 0 ? 1 : a => {}
+/Q/g;
+assertEq(typeof c, "function");
+delete Function.prototype.c;
+
+assertEq(typeof eval(0 ? 1 : a => {}), "function");
+
+var zoom = 1 ? a => {} : 357;
+assertEq(typeof zoom, "function");
+
+var { b = 0 ? 1 : a => {} } = {};
+assertEq(typeof b, "function");
+
+var [k = 0 ? 1 : a => {}] = [];
+assertEq(typeof k, "function");
+
+assertEq(typeof [0 ? 1 : a => {}][0], "function");
+
+Function.prototype[Symbol.iterator] = function() { return { next() { return { done: true }; } }; };
+assertEq([...0 ? 1 : a => {}].length, 0);
+delete Function.prototype[Symbol.iterator];
+
+var props = Object.getOwnPropertyNames({ ...0 ? 1 : a => {} }).sort();
+assertEq(props.length, 0);
+
+function f1(x = 0 ? 1 : a => {}) { return x; }
+assertEq(typeof f1(), "function");
+assertEq(f1(5), 5);
+
+var g1 = (x = 0 ? 1 : a => {}) => { return x; };
+assertEq(typeof g1(), "function");
+assertEq(g1(5), 5);
+
+var h1 = async (x = 0 ? 1 : a => {}) => { return x; };
+assertEq(typeof h1, "function");
+
+function f2(m, x = 0 ? 1 : a => {}) { return x; }
+assertEq(typeof f2(1), "function");
+assertEq(f2(1, 5), 5);
+
+var g2 = (m, x = 0 ? 1 : a => {}) => { return x; };
+assertEq(typeof g2(1), "function");
+assertEq(g2(1, 5), 5);
+
+var h2 = async (m, x = 0 ? 1 : a => {}) => { return x; };
+assertEq(typeof h2, "function");
+
+function f3(x = 0 ? 1 : a => {}, q) { return x; }
+assertEq(typeof f3(), "function");
+assertEq(f3(5), 5);
+
+var g3 = (x = 0 ? 1 : a => {}, q) => { return x; };
+assertEq(typeof g3(), "function");
+assertEq(g3(5), 5);
+
+var h3 = async (x = 0 ? 1 : a => {}, q) => { return x; };
+assertEq(typeof h3, "function");
+
+var asyncf = async () => {};
+assertEq(typeof asyncf, "function");
+
+var { [0 ? 1 : a => {}]: h } = { "a => {}": "boo-urns!" };
+assertEq(h, "boo-urns!");
+
+var gencomp = (for (prop of [0]) 0 ? 1 : a => {});
+assertEq(typeof gencomp.next().value, "function");
+
+var arrcomp = [for (prop of [0]) 0 ? 1 : a => {}];
+assertEq(typeof arrcomp[0], "function");
+
 if (typeof reportCompare === "function")
   reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/Comprehensions/inside-derived-class.js
@@ -0,0 +1,32 @@
+/*
+ * Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/
+ */
+
+//-----------------------------------------------------------------------------
+var BUGNUMBER = 1299519;
+var summary =
+  "Generator comprehension lambdas in derived constructors shouldn't assert";
+
+print(BUGNUMBER + ": " + summary);
+
+/**************
+ * BEGIN TEST *
+ **************/
+
+class Base {};
+
+class Derived extends Base
+{
+  constructor() {
+    var a = (for (_ of []) _);
+    var b = [for (_ of []) _];
+  }
+};
+
+/******************************************************************************/
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
+
+print("Tests complete");
--- a/layout/base/AccessibleCaret.cpp
+++ b/layout/base/AccessibleCaret.cpp
@@ -264,17 +264,17 @@ AccessibleCaret::RemoveCaretElement(nsID
   CaretElement()->RemoveEventListener(NS_LITERAL_STRING("touchstart"),
                                       mDummyTouchListener, false);
 
   if (nsIFrame* frame = CaretElement()->GetPrimaryFrame()) {
     if (frame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) {
       frame = frame->GetPlaceholderFrame();
     }
     nsAutoScriptBlocker scriptBlocker;
-    nsCSSFrameConstructor* fc = frame->PresContext()->PresShell()->FrameConstructor();
+    nsCSSFrameConstructor* fc = frame->PresShell()->FrameConstructor();
     fc->BeginUpdate();
     frame->GetParent()->RemoveFrame(nsIFrame::kPrincipalList, frame);
     fc->EndUpdate();
   }
 
   ErrorResult rv;
   aDocument->RemoveAnonymousContent(*mCaretElementHolder, rv);
   // It's OK rv is failed since nsCanvasFrame might not exists now.
--- a/layout/base/PositionedEventTargeting.cpp
+++ b/layout/base/PositionedEventTargeting.cpp
@@ -579,17 +579,17 @@ FindFrameTargetedByInputEvent(WidgetGUIE
   }
 
   // If the exact target is non-null, only consider candidate targets in the same
   // document as the exact target. Otherwise, if an ancestor document has
   // a mouse event handler for example, targets that are !GetClickableAncestor can
   // never be targeted --- something nsSubDocumentFrame in an ancestor document
   // would be targeted instead.
   nsIFrame* restrictToDescendants = target ?
-    target->PresContext()->PresShell()->GetRootFrame() : aRootFrame;
+    target->PresShell()->GetRootFrame() : aRootFrame;
 
   nsRect targetRect = GetTargetRect(aRootFrame, aPointRelativeToRootFrame,
                                     restrictToDescendants, prefs, aFlags);
   PET_LOG("Expanded point to target rect %s\n",
     mozilla::layers::Stringify(targetRect).c_str());
   AutoTArray<nsIFrame*,8> candidates;
   nsresult rv = nsLayoutUtils::GetFramesForArea(aRootFrame, targetRect, candidates, flags);
   if (NS_FAILED(rv)) {
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -5272,17 +5272,17 @@ PresShell::AddCanvasBackgroundColorItem(
   // color background behind a scrolled transparent background. Instead,
   // we'll try to move the color background into the scrolled content
   // by making nsDisplayCanvasBackground paint it.
   // If we're only adding an unscrolled item, then pretend that we've
   // already done it.
   bool addedScrollingBackgroundColor = (aFlags & APPEND_UNSCROLLED_ONLY);
   if (!aFrame->GetParent() && !addedScrollingBackgroundColor) {
     nsIScrollableFrame* sf =
-      aFrame->PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
+      aFrame->PresShell()->GetRootScrollFrameAsScrollable();
     if (sf) {
       nsCanvasFrame* canvasFrame = do_QueryFrame(sf->GetScrolledFrame());
       if (canvasFrame && canvasFrame->IsVisibleForPainting(&aBuilder)) {
         addedScrollingBackgroundColor =
           AddCanvasBackgroundColor(aList, canvasFrame, bgcolor, mHasCSSBackgroundColor);
       }
     }
   }
@@ -5561,17 +5561,17 @@ static nsView* FindFloatingViewContainin
 {
   if (aView->GetVisibility() == nsViewVisibility_kHide)
     // No need to look into descendants.
     return nullptr;
 
   nsIFrame* frame = aView->GetFrame();
   if (frame) {
     if (!frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY) ||
-        !frame->PresContext()->PresShell()->IsActive()) {
+        !frame->PresShell()->IsActive()) {
       return nullptr;
     }
   }
 
   for (nsView* v = aView->GetFirstChild(); v; v = v->GetNextSibling()) {
     nsView* r = FindFloatingViewContaining(v, v->ConvertFromParentCoords(aPt));
     if (r)
       return r;
@@ -5598,17 +5598,17 @@ static nsView* FindViewContaining(nsView
   if (!aView->GetDimensions().Contains(aPt) ||
       aView->GetVisibility() == nsViewVisibility_kHide) {
     return nullptr;
   }
 
   nsIFrame* frame = aView->GetFrame();
   if (frame) {
     if (!frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY) ||
-        !frame->PresContext()->PresShell()->IsActive()) {
+        !frame->PresShell()->IsActive()) {
       return nullptr;
     }
   }
 
   for (nsView* v = aView->GetFirstChild(); v; v = v->GetNextSibling()) {
     nsView* r = FindViewContaining(v, v->ConvertFromParentCoords(aPt));
     if (r)
       return r;
@@ -5780,17 +5780,17 @@ PresShell::MarkFramesInListApproximately
     nsIFrame* frame = item->Frame();
     MOZ_ASSERT(frame);
 
     if (!frame->TrackingVisibility()) {
       continue;
     }
 
     // Use the presshell containing the frame.
-    auto* presShell = static_cast<PresShell*>(frame->PresContext()->PresShell());
+    auto* presShell = static_cast<PresShell*>(frame->PresShell());
     MOZ_ASSERT(!presShell->AssumeAllFramesVisible());
     if (presShell->mApproximatelyVisibleFrames.EnsureInserted(frame)) {
       // The frame was added to mApproximatelyVisibleFrames, so increment its visible count.
       frame->IncApproximateVisibleCount();
     }
 
     AddFrameToVisibleRegions(frame, presShell->mViewManager, aVisibleRegions);
   }
@@ -5914,17 +5914,17 @@ PresShell::ClearApproximatelyVisibleFram
 }
 
 void
 PresShell::MarkFramesInSubtreeApproximatelyVisible(nsIFrame* aFrame,
                                                    const nsRect& aRect,
                                                    Maybe<VisibleRegions>& aVisibleRegions,
                                                    bool aRemoveOnly /* = false */)
 {
-  MOZ_ASSERT(aFrame->PresContext()->PresShell() == this, "wrong presshell");
+  MOZ_ASSERT(aFrame->PresShell() == this, "wrong presshell");
 
   if (aFrame->TrackingVisibility() &&
       aFrame->StyleVisibility()->IsVisible() &&
       (!aRemoveOnly || aFrame->GetVisibility() == Visibility::APPROXIMATELY_VISIBLE)) {
     MOZ_ASSERT(!AssumeAllFramesVisible());
     if (mApproximatelyVisibleFrames.EnsureInserted(aFrame)) {
       // The frame was added to mApproximatelyVisibleFrames, so increment its visible count.
       aFrame->IncApproximateVisibleCount();
@@ -7261,18 +7261,17 @@ PresShell::HandleEvent(nsIFrame* aFrame,
       return NS_OK;
     }
 
     if (!frame) {
       NS_WARNING("Nothing to handle this event!");
       return NS_OK;
     }
 
-    PresShell* shell =
-        static_cast<PresShell*>(frame->PresContext()->PresShell());
+    PresShell* shell = static_cast<PresShell*>(frame->PresShell());
     switch (aEvent->mMessage) {
       case eTouchMove:
       case eTouchCancel:
       case eTouchEnd: {
         // get the correct shell to dispatch to
         WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
         for (dom::Touch* touch : touchEvent->mTouches) {
           if (!touch) {
@@ -7291,18 +7290,17 @@ PresShell::HandleEvent(nsIFrame* aFrame,
             break;
           }
 
           nsIFrame* contentFrame = content->GetPrimaryFrame();
           if (!contentFrame) {
             break;
           }
 
-          shell = static_cast<PresShell*>(
-                      contentFrame->PresContext()->PresShell());
+          shell = static_cast<PresShell*>(contentFrame->PresShell());
           if (shell) {
             break;
           }
         }
         break;
       }
     default:
       break;
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -723,16 +723,26 @@ RecomputePosition(nsIFrame* aFrame)
   // have a view somewhere in their descendants, because the corresponding view
   // needs to be repositioned properly as well.
   if (aFrame->HasView() ||
       (aFrame->GetStateBits() & NS_FRAME_HAS_CHILD_WITH_VIEW)) {
     StyleChangeReflow(aFrame, nsChangeHint_NeedReflow);
     return false;
   }
 
+  // Flexbox and Grid layout supports CSS Align and the optimizations below
+  // don't support that yet.
+  if (aFrame->HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) {
+    nsIFrame* ph = aFrame->GetPlaceholderFrame();
+    if (ph && ph->HasAnyStateBits(PLACEHOLDER_STATICPOS_NEEDS_CSSALIGN)) {
+      StyleChangeReflow(aFrame, nsChangeHint_NeedReflow);
+      return false;
+    }
+  }
+
   aFrame->SchedulePaint();
 
   // For relative positioning, we can simply update the frame rect
   if (display->IsRelativelyPositionedStyle()) {
     // Move the frame
     if (display->mPosition == NS_STYLE_POSITION_STICKY) {
       if (display->IsInnerTableStyle()) {
         // We don't currently support sticky positioning of inner table
@@ -792,17 +802,17 @@ RecomputePosition(nsIFrame* aFrame)
     return true;
   }
 
   // For the absolute positioning case, set up a fake HTML reflow state for
   // the frame, and then get the offsets and size from it. If the frame's size
   // doesn't need to change, we can simply update the frame position. Otherwise
   // we fall back to a reflow.
   RefPtr<gfxContext> rc =
-    aFrame->PresContext()->PresShell()->CreateReferenceRenderingContext();
+    aFrame->PresShell()->CreateReferenceRenderingContext();
 
   // Construct a bogus parent reflow state so that there's a usable
   // containing block reflow state.
   nsIFrame* parentFrame = aFrame->GetParent();
   WritingMode parentWM = parentFrame->GetWritingMode();
   WritingMode frameWM = aFrame->GetWritingMode();
   LogicalSize parentSize = parentFrame->GetLogicalSize();
 
@@ -1230,17 +1240,17 @@ StyleChangeReflow(nsIFrame* aFrame, nsCh
   nsIPresShell::ReflowRootHandling rootHandling;
   if (aHint & nsChangeHint_ReflowChangesSizeOrPosition) {
     rootHandling = nsIPresShell::ePositionOrSizeChange;
   } else {
     rootHandling = nsIPresShell::eNoPositionOrSizeChange;
   }
 
   do {
-    aFrame->PresContext()->PresShell()->FrameNeedsReflow(
+    aFrame->PresShell()->FrameNeedsReflow(
       aFrame, dirtyType, dirtyBits, rootHandling);
     aFrame = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(aFrame);
   } while (aFrame);
 }
 
 // Get the next sibling which might have a frame.  This only considers siblings
 // that stylo post-traversal looks at, so only elements and text.  In
 // particular, it ignores comments.
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -850,17 +850,17 @@ nsLayoutUtils::ViewIDForASR(const mozill
   return nsLayoutUtils::FindOrCreateIDFor(content);
 }
 
 nsIFrame*
 GetScrollFrameFromContent(nsIContent* aContent)
 {
   nsIFrame* frame = aContent->GetPrimaryFrame();
   if (aContent->OwnerDoc()->GetRootElement() == aContent) {
-    nsIPresShell* presShell = frame ? frame->PresContext()->PresShell() : nullptr;
+    nsIPresShell* presShell = frame ? frame->PresShell() : nullptr;
     if (!presShell) {
       presShell = aContent->OwnerDoc()->GetShell();
     }
     // We want the scroll frame, the root scroll frame differs from all
     // others in that the primary frame is not the scroll frame.
     nsIFrame* rootScrollFrame = presShell ? presShell->GetRootScrollFrame() : nullptr;
     if (rootScrollFrame) {
       frame = rootScrollFrame;
@@ -2171,27 +2171,27 @@ nsLayoutUtils::GetNearestScrollableFrame
         ScrollbarStyles ss = scrollableFrame->GetScrollbarStyles();
         if ((aFlags & SCROLLABLE_INCLUDE_HIDDEN) ||
             ss.mVertical != NS_STYLE_OVERFLOW_HIDDEN ||
             ss.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN) {
           return scrollableFrame;
         }
       }
       if (aFlags & SCROLLABLE_ALWAYS_MATCH_ROOT) {
-        nsIPresShell* ps = f->PresContext()->PresShell();
+        nsIPresShell* ps = f->PresShell();
         if (ps->GetRootScrollFrame() == f &&
             ps->GetDocument() && ps->GetDocument()->IsRootDisplayDocument()) {
           return scrollableFrame;
         }
       }
     }
     if ((aFlags & SCROLLABLE_FIXEDPOS_FINDS_ROOT) &&
         f->StyleDisplay()->mPosition == NS_STYLE_POSITION_FIXED &&
         nsLayoutUtils::IsReallyFixedPos(f)) {
-      return f->PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
+      return f->PresShell()->GetRootScrollFrameAsScrollable();
     }
   }
   return nullptr;
 }
 
 // static
 nsRect
 nsLayoutUtils::GetScrolledRect(nsIFrame* aScrolledFrame,
@@ -2371,17 +2371,17 @@ nsLayoutUtils::GetEventCoordinatesRelati
     return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
   }
 
   // Convert from root document app units to app units of the document aFrame
   // is in.
   int32_t rootAPD = rootFrame->PresContext()->AppUnitsPerDevPixel();
   int32_t localAPD = aFrame->PresContext()->AppUnitsPerDevPixel();
   widgetToView = widgetToView.ScaleToOtherAppUnits(rootAPD, localAPD);
-  nsIPresShell* shell = aFrame->PresContext()->PresShell();
+  nsIPresShell* shell = aFrame->PresShell();
 
   // XXX Bug 1224748 - Update nsLayoutUtils functions to correctly handle nsPresShell resolution
   widgetToView = widgetToView.RemoveResolution(GetCurrentAPZResolutionScale(shell));
 
   /* If we encountered a transform, we can't do simple arithmetic to figure
    * out how to convert back to aFrame's coordinates and must use the CTM.
    */
   if (transformFound || nsSVGUtils::IsInSVGTextSubtree(aFrame)) {
@@ -2772,17 +2772,17 @@ nsLayoutUtils::GetTransformToAncestorSca
 
 nsIFrame*
 nsLayoutUtils::FindNearestCommonAncestorFrame(nsIFrame* aFrame1, nsIFrame* aFrame2)
 {
   AutoTArray<nsIFrame*,100> ancestors1;
   AutoTArray<nsIFrame*,100> ancestors2;
   nsIFrame* commonAncestor = nullptr;
   if (aFrame1->PresContext() == aFrame2->PresContext()) {
-    commonAncestor = aFrame1->PresContext()->PresShell()->GetRootFrame();
+    commonAncestor = aFrame1->PresShell()->GetRootFrame();
   }
   for (nsIFrame* f = aFrame1; f != commonAncestor;
        f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
     ancestors1.AppendElement(f);
   }
   for (nsIFrame* f = aFrame2; f != commonAncestor;
        f = nsLayoutUtils::GetCrossDocParentFrame(f)) {
     ancestors2.AppendElement(f);
@@ -3273,18 +3273,17 @@ nsLayoutUtils::GetFramesForArea(nsIFrame
   builder.BeginFrame();
   nsDisplayList list(&builder);
 
   if (aFlags & IGNORE_PAINT_SUPPRESSION) {
     builder.IgnorePaintSuppression();
   }
 
   if (aFlags & IGNORE_ROOT_SCROLL_FRAME) {
-    nsIFrame* rootScrollFrame =
-      aFrame->PresContext()->PresShell()->GetRootScrollFrame();
+    nsIFrame* rootScrollFrame = aFrame->PresShell()->GetRootScrollFrame();
     if (rootScrollFrame) {
       builder.SetIgnoreScrollFrame(rootScrollFrame);
     }
   }
   if (aFlags & IGNORE_CROSS_DOC) {
     builder.SetDescendIntoSubdocuments(false);
   }
 
@@ -3455,21 +3454,21 @@ nsLayoutUtils::SetZeroMarginDisplayPortO
     }
     nsIScrollableFrame* scrollAncestor = GetAsyncScrollableAncestorFrame(frame);
     if (!scrollAncestor) {
       break;
     }
     frame = do_QueryFrame(scrollAncestor);
     MOZ_ASSERT(frame);
     MOZ_ASSERT(scrollAncestor->WantAsyncScroll() ||
-      frame->PresContext()->PresShell()->GetRootScrollFrame() == frame);
+      frame->PresShell()->GetRootScrollFrame() == frame);
     if (nsLayoutUtils::AsyncPanZoomEnabled(frame) &&
         !nsLayoutUtils::HasDisplayPort(frame->GetContent())) {
       nsLayoutUtils::SetDisplayPortMargins(
-        frame->GetContent(), frame->PresContext()->PresShell(), ScreenMargin(), 0,
+        frame->GetContent(), frame->PresShell(), ScreenMargin(), 0,
         aRepaintMode);
     }
   }
 }
 
 bool
 nsLayoutUtils::MaybeCreateDisplayPortInFirstScrollFrameEncountered(
   nsIFrame* aFrame, nsDisplayListBuilder& aBuilder)
@@ -3528,17 +3527,17 @@ nsLayoutUtils::ExpireDisplayPortOnAsyncS
       break;
     }
     frame = do_QueryFrame(scrollAncestor);
     MOZ_ASSERT(frame);
     if (!frame) {
       break;
     }
     MOZ_ASSERT(scrollAncestor->WantAsyncScroll() ||
-      frame->PresContext()->PresShell()->GetRootScrollFrame() == frame);
+      frame->PresShell()->GetRootScrollFrame() == frame);
     if (nsLayoutUtils::HasDisplayPort(frame->GetContent())) {
       scrollAncestor->TriggerDisplayPortExpiration();
       // Stop after the first trigger. If it failed, there's no point in
       // continuing because all the rest of the frames we encounter are going
       // to be ancestors of |scrollAncestor| which will keep its displayport.
       // If the trigger succeeded, we stop because when the trigger executes
       // it will call this function again to trigger the next ancestor up the
       // chain.
@@ -4278,17 +4277,17 @@ void nsLayoutUtils::RectListBuilder::Add
   RefPtr<DOMRect> rect = new DOMRect(mRectList);
 
   rect->SetLayoutRect(aRect);
   mRectList->Append(rect);
 }
 
 nsIFrame* nsLayoutUtils::GetContainingBlockForClientRect(nsIFrame* aFrame)
 {
-  return aFrame->PresContext()->PresShell()->GetRootFrame();
+  return aFrame->PresShell()->GetRootFrame();
 }
 
 nsRect
 nsLayoutUtils::GetAllInFlowRectsUnion(nsIFrame* aFrame, nsIFrame* aRelativeTo,
                                       uint32_t aFlags) {
   RectAccumulator accumulator;
   GetAllInFlowRects(aFrame, aRelativeTo, &accumulator, aFlags);
   return accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect
@@ -4758,18 +4757,17 @@ nsLayoutUtils::IsFirstContinuationOrIBSp
 }
 
 bool
 nsLayoutUtils::IsViewportScrollbarFrame(nsIFrame* aFrame)
 {
   if (!aFrame)
     return false;
 
-  nsIFrame* rootScrollFrame =
-    aFrame->PresContext()->PresShell()->GetRootScrollFrame();
+  nsIFrame* rootScrollFrame = aFrame->PresShell()->GetRootScrollFrame();
   if (!rootScrollFrame)
     return false;
 
   nsIScrollableFrame* rootScrollableFrame = do_QueryFrame(rootScrollFrame);
   NS_ASSERTION(rootScrollableFrame, "The root scorollable frame is null");
 
   if (!IsProperAncestorFrame(rootScrollFrame, aFrame))
     return false;
@@ -6484,17 +6482,17 @@ nsLayoutUtils::GetClosestLayer(nsIFrame*
   nsIFrame* layer;
   for (layer = aFrame; layer; layer = layer->GetParent()) {
     if (layer->IsAbsPosContainingBlock() ||
         (layer->GetParent() && layer->GetParent()->IsScrollFrame()))
       break;
   }
   if (layer)
     return layer;
-  return aFrame->PresContext()->PresShell()->FrameManager()->GetRootFrame();
+  return aFrame->PresShell()->FrameManager()->GetRootFrame();
 }
 
 SamplingFilter
 nsLayoutUtils::GetSamplingFilterForFrame(nsIFrame* aForFrame)
 {
   SamplingFilter defaultFilter = SamplingFilter::GOOD;
   nsStyleContext *sc;
   if (nsCSSRendering::IsCanvasFrame(aForFrame)) {
@@ -8829,23 +8827,23 @@ nsLayoutUtils::CalculateScrollableRectFo
   return contentBounds;
 }
 
 /* static */ nsRect
 nsLayoutUtils::CalculateExpandedScrollableRect(nsIFrame* aFrame)
 {
   nsRect scrollableRect =
     CalculateScrollableRectForFrame(aFrame->GetScrollTargetFrame(),
-                                    aFrame->PresContext()->PresShell()->GetRootFrame());
+                                    aFrame->PresShell()->GetRootFrame());
   nsSize compSize = CalculateCompositionSizeForFrame(aFrame);
 
-  if (aFrame == aFrame->PresContext()->PresShell()->GetRootScrollFrame()) {
+  if (aFrame == aFrame->PresShell()->GetRootScrollFrame()) {
     // the composition size for the root scroll frame does not include the
     // local resolution, so we adjust.
-    float res = aFrame->PresContext()->PresShell()->GetResolution();
+    float res = aFrame->PresShell()->GetResolution();
     compSize.width = NSToCoordRound(compSize.width / res);
     compSize.height = NSToCoordRound(compSize.height / res);
   }
 
   if (scrollableRect.width < compSize.width) {
     scrollableRect.x = std::max(0,
                                 scrollableRect.x - (compSize.width - scrollableRect.width));
     scrollableRect.width = compSize.width;
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -547,17 +547,17 @@ public:
   }
   NS_IMETHOD Run() override
   {
     if (mFrame.IsAlive()) {
       nsComboboxControlFrame* combo =
         static_cast<nsComboboxControlFrame*>(mFrame.GetFrame());
       static_cast<nsListControlFrame*>(combo->mDropdownFrame)->
         SetSuppressScrollbarUpdate(true);
-      nsCOMPtr<nsIPresShell> shell = mFrame->PresContext()->PresShell();
+      nsCOMPtr<nsIPresShell> shell = mFrame->PresShell();
       shell->FrameNeedsReflow(combo->mDropdownFrame, nsIPresShell::eResize,
                               NS_FRAME_IS_DIRTY);
       shell->FlushPendingNotifications(FlushType::Layout);
       if (mFrame.IsAlive()) {
         combo = static_cast<nsComboboxControlFrame*>(mFrame.GetFrame());
         static_cast<nsListControlFrame*>(combo->mDropdownFrame)->
           SetSuppressScrollbarUpdate(false);
         if (combo->mDelayedShowDropDown) {
@@ -1041,17 +1041,17 @@ nsComboboxControlFrame::HandleRedisplayT
   // so that any reframing that the frame constructor forces upon us is inserted
   // into the correct parent (mDisplayFrame). See bug 282607.
   NS_PRECONDITION(!mInRedisplayText, "Nested RedisplayText");
   mInRedisplayText = true;
   mRedisplayTextEvent.Forget();
 
   ActuallyDisplayText(true);
   // XXXbz This should perhaps be eResize.  Check.
-  PresContext()->PresShell()->FrameNeedsReflow(mDisplayFrame,
+  PresShell()->FrameNeedsReflow(mDisplayFrame,
                                                nsIPresShell::eStyleChange,
                                                NS_FRAME_IS_DIRTY);
 
   mInRedisplayText = false;
 }
 
 void
 nsComboboxControlFrame::ActuallyDisplayText(bool aNotify)
@@ -1359,17 +1359,17 @@ nsComboboxDisplayFrame::BuildDisplayList
 }
 
 nsIFrame*
 nsComboboxControlFrame::CreateFrameForDisplayNode()
 {
   MOZ_ASSERT(mDisplayContent);
 
   // Get PresShell
-  nsIPresShell *shell = PresContext()->PresShell();
+  nsIPresShell *shell = PresShell();
   StyleSetHandle styleSet = shell->StyleSet();
 
   // create the style contexts for the anonymous block frame and text frame
   RefPtr<nsStyleContext> styleContext;
   styleContext = styleSet->
     ResolveInheritingAnonymousBoxStyle(nsCSSAnonBoxes::mozDisplayComboboxControlFrame,
                                        mStyleContext);
 
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -1977,17 +1977,17 @@ nsListControlFrame::ScrollToIndex(int32_
 }
 
 void
 nsListControlFrame::ScrollToFrame(dom::HTMLOptionElement& aOptElement)
 {
   // otherwise we find the content's frame and scroll to it
   nsIFrame* childFrame = aOptElement.GetPrimaryFrame();
   if (childFrame) {
-    PresContext()->PresShell()->
+    PresShell()->
       ScrollFrameRectIntoView(childFrame,
                               nsRect(nsPoint(0, 0), childFrame->GetSize()),
                               nsIPresShell::ScrollAxis(), nsIPresShell::ScrollAxis(),
                               nsIPresShell::SCROLL_OVERFLOW_HIDDEN |
                               nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY);
   }
 }
 
--- a/layout/forms/nsMeterFrame.cpp
+++ b/layout/forms/nsMeterFrame.cpp
@@ -195,19 +195,18 @@ nsMeterFrame::AttributeChanged(int32_t  
   NS_ASSERTION(mBarDiv, "Meter bar div must exist!");
 
   if (aNameSpaceID == kNameSpaceID_None &&
       (aAttribute == nsGkAtoms::value ||
        aAttribute == nsGkAtoms::max   ||
        aAttribute == nsGkAtoms::min )) {
     nsIFrame* barFrame = mBarDiv->GetPrimaryFrame();
     NS_ASSERTION(barFrame, "The meter frame should have a child with a frame!");
-    PresContext()->PresShell()->FrameNeedsReflow(barFrame,
-                                                 nsIPresShell::eResize,
-                                                 NS_FRAME_IS_DIRTY);
+    PresShell()->FrameNeedsReflow(barFrame, nsIPresShell::eResize,
+                                  NS_FRAME_IS_DIRTY);
     InvalidateFrame();
   }
 
   return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute,
                                             aModType);
 }
 
 LogicalSize
--- a/layout/forms/nsProgressFrame.cpp
+++ b/layout/forms/nsProgressFrame.cpp
@@ -207,17 +207,17 @@ nsresult
 nsProgressFrame::AttributeChanged(int32_t  aNameSpaceID,
                                   nsAtom* aAttribute,
                                   int32_t  aModType)
 {
   NS_ASSERTION(mBarDiv, "Progress bar div must exist!");
 
   if (aNameSpaceID == kNameSpaceID_None &&
       (aAttribute == nsGkAtoms::value || aAttribute == nsGkAtoms::max)) {
-    auto shell = PresContext()->PresShell();
+    auto shell = PresShell();
     for (auto childFrame : PrincipalChildList()) {
       shell->FrameNeedsReflow(childFrame, nsIPresShell::eResize,
                               NS_FRAME_IS_DIRTY);
     }
     InvalidateFrame();
   }
 
   return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
--- a/layout/forms/nsRangeFrame.cpp
+++ b/layout/forms/nsRangeFrame.cpp
@@ -625,17 +625,17 @@ nsRangeFrame::UpdateForValueChange()
     // We don't know the exact dimensions or location of the thumb when native
     // theming is applied, so we just repaint the entire range.
     InvalidateFrame();
   }
 
 #ifdef ACCESSIBILITY
   nsAccessibilityService* accService = nsIPresShell::AccService();
   if (accService) {
-    accService->RangeValueChanged(PresContext()->PresShell(), mContent);
+    accService->RangeValueChanged(PresShell(), mContent);
   }
 #endif
 
   SchedulePaint();
 }
 
 void
 nsRangeFrame::DoUpdateThumbPosition(nsIFrame* aThumbFrame,
@@ -755,18 +755,18 @@ nsRangeFrame::AttributeChanged(int32_t  
         static_cast<dom::HTMLInputElement*>(GetContent())->ControlType() ==
                            NS_FORM_INPUT_RANGE;
       // If script changed the <input>'s type before setting these attributes
       // then we don't need to do anything since we are going to be reframed.
       if (typeIsRange) {
         UpdateForValueChange();
       }
     } else if (aAttribute == nsGkAtoms::orient) {
-      PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eResize,
-                                                   NS_FRAME_IS_DIRTY);
+      PresShell()->FrameNeedsReflow(this, nsIPresShell::eResize,
+                                    NS_FRAME_IS_DIRTY);
     }
   }
 
   return nsContainerFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
 }
 
 LogicalSize
 nsRangeFrame::ComputeAutoSize(gfxContext*         aRenderingContext,
--- a/layout/generic/TextOverflow.cpp
+++ b/layout/generic/TextOverflow.cpp
@@ -36,17 +36,17 @@ class LazyReferenceRenderingDrawTargetGe
 public:
   typedef mozilla::gfx::DrawTarget DrawTarget;
 
   explicit LazyReferenceRenderingDrawTargetGetterFromFrame(nsIFrame* aFrame)
     : mFrame(aFrame) {}
   virtual already_AddRefed<DrawTarget> GetRefDrawTarget() override
   {
     RefPtr<gfxContext> ctx =
-      mFrame->PresContext()->PresShell()->CreateReferenceRenderingContext();
+      mFrame->PresShell()->CreateReferenceRenderingContext();
     RefPtr<DrawTarget> dt = ctx->GetDrawTarget();
     return dt.forget();
   }
 private:
   nsIFrame* mFrame;
 };
 
 static gfxTextRun*
@@ -817,17 +817,17 @@ TextOverflow::CanHaveTextOverflow(nsIFra
 
   // Skip ComboboxControlFrame because it would clip the drop-down arrow.
   // Its anon block inherits 'text-overflow' and does what is expected.
   if (aBlockFrame->IsComboboxControlFrame()) {
     return false;
   }
 
   // Inhibit the markers if a descendant content owns the caret.
-  RefPtr<nsCaret> caret = aBlockFrame->PresContext()->PresShell()->GetCaret();
+  RefPtr<nsCaret> caret = aBlockFrame->PresShell()->GetCaret();
   if (caret && caret->IsVisible()) {
     nsCOMPtr<nsISelection> domSelection = caret->GetSelection();
     if (domSelection) {
       nsCOMPtr<nsIDOMNode> node;
       domSelection->GetFocusNode(getter_AddRefs(node));
       nsCOMPtr<nsIContent> content = do_QueryInterface(node);
       if (content && nsContentUtils::ContentIsDescendantOf(content,
                        aBlockFrame->GetContent())) {
@@ -891,17 +891,17 @@ TextOverflow::Marker::SetupString(nsIFra
     gfxTextRun* textRun = GetEllipsisTextRun(aFrame);
     if (textRun) {
       mISize = textRun->GetAdvanceWidth();
     } else {
       mISize = 0;
     }
   } else {
     RefPtr<gfxContext> rc =
-      aFrame->PresContext()->PresShell()->CreateReferenceRenderingContext();
+      aFrame->PresShell()->CreateReferenceRenderingContext();
     RefPtr<nsFontMetrics> fm =
       nsLayoutUtils::GetInflatedFontMetricsForFrame(aFrame);
     mISize = nsLayoutUtils::AppUnitWidthOfStringBidi(mStyle->mString, aFrame,
                                                      *fm, *rc);
   }
   mIntrinsicISize = mISize;
   mInitialized = true;
 }
--- a/layout/generic/ViewportFrame.cpp
+++ b/layout/generic/ViewportFrame.cpp
@@ -173,17 +173,17 @@ ViewportFrame::BuildDisplayListForTopLay
           static_cast<nsPlaceholderFrame*>(backdropPh)->GetOutOfFlowFrame();
         MOZ_ASSERT(backdropFrame);
         BuildDisplayListForTopLayerFrame(aBuilder, backdropFrame, aList);
       }
       BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
     }
   }
 
-  nsIPresShell* shell = PresContext()->PresShell();
+  nsIPresShell* shell = PresShell();
   if (nsCanvasFrame* canvasFrame = shell->GetCanvasFrame()) {
     if (Element* container = canvasFrame->GetCustomContentContainer()) {
       if (nsIFrame* frame = container->GetPrimaryFrame()) {
         BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
       }
     }
   }
 }
@@ -274,17 +274,17 @@ ViewportFrame::AdjustReflowInputAsContai
   NS_ASSERTION(GetAbsoluteContainingBlock()->GetChildList().IsEmpty() ||
                (offset.x == 0 && offset.y == 0),
                "We don't handle correct positioning of fixed frames with "
                "scrollbars in odd positions");
 
   // If a scroll position clamping scroll-port size has been set, layout
   // fixed position elements to this size instead of the computed size.
   nsRect rect(0, 0, aReflowInput->ComputedWidth(), aReflowInput->ComputedHeight());
-  nsIPresShell* ps = PresContext()->PresShell();
+  nsIPresShell* ps = PresShell();
   if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
     rect.SizeTo(ps->GetScrollPositionClampingScrollPortSize());
   }
 
   return rect;
 }
 
 void
@@ -394,30 +394,30 @@ ViewportFrame::Reflow(nsPresContext*    
   // so we don't need to change our overflow areas.
   bool overflowChanged = FinishAndStoreOverflow(&aDesiredSize);
   if (overflowChanged) {
     // We may need to alert our container to get it to pick up the
     // overflow change.
     nsSubDocumentFrame* container = static_cast<nsSubDocumentFrame*>
       (nsLayoutUtils::GetCrossDocParentFrame(this));
     if (container && !container->ShouldClipSubdocument()) {
-      container->PresContext()->PresShell()->
+      container->PresShell()->
         FrameNeedsReflow(container, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
     }
   }
 
   NS_FRAME_TRACE_REFLOW_OUT("ViewportFrame::Reflow", aStatus);
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
 }
 
 bool
 ViewportFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas)
 {
   nsIScrollableFrame* rootScrollFrame =
-    PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
+    PresShell()->GetRootScrollFrameAsScrollable();
   if (rootScrollFrame && !rootScrollFrame->IsIgnoringViewportClipping()) {
     return false;
   }
 
   return nsContainerFrame::ComputeCustomOverflow(aOverflowAreas);
 }
 
 void
--- a/layout/generic/nsAbsoluteContainingBlock.cpp
+++ b/layout/generic/nsAbsoluteContainingBlock.cpp
@@ -65,17 +65,17 @@ nsAbsoluteContainingBlock::AppendFrames(
   // Append the frames to our list of absolutely positioned frames
 #ifdef DEBUG
   nsFrame::VerifyDirtyBitSet(aFrameList);
 #endif
   mAbsoluteFrames.AppendFrames(nullptr, aFrameList);
 
   // no damage to intrinsic widths, since absolutely positioned frames can't
   // change them
-  aDelegatingFrame->PresContext()->PresShell()->
+  aDelegatingFrame->PresShell()->
     FrameNeedsReflow(aDelegatingFrame, nsIPresShell::eResize,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsAbsoluteContainingBlock::InsertFrames(nsIFrame*      aDelegatingFrame,
                                         ChildListID    aListID,
                                         nsIFrame*      aPrevFrame,
@@ -87,17 +87,17 @@ nsAbsoluteContainingBlock::InsertFrames(
 
 #ifdef DEBUG
   nsFrame::VerifyDirtyBitSet(aFrameList);
 #endif
   mAbsoluteFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);
 
   // no damage to intrinsic widths, since absolutely positioned frames can't
   // change them
-  aDelegatingFrame->PresContext()->PresShell()->
+  aDelegatingFrame->PresShell()->
     FrameNeedsReflow(aDelegatingFrame, nsIPresShell::eResize,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsAbsoluteContainingBlock::RemoveFrame(nsIFrame*       aDelegatingFrame,
                                        ChildListID     aListID,
                                        nsIFrame*       aOldFrame)
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -3039,19 +3039,18 @@ nsBlockFrame::AttributeChanged(int32_t  
             frameType == LayoutFrameType::GridContainer) {
           break;
         }
       }
       // Tell the ancestor to renumber list items within itself.
       if (ancestor) {
         // XXX Not sure if this is necessary anymore
         if (ancestor->RenumberList()) {
-          PresContext()->PresShell()->
-            FrameNeedsReflow(ancestor, nsIPresShell::eStyleChange,
-                             NS_FRAME_HAS_DIRTY_CHILDREN);
+          PresShell()->FrameNeedsReflow(ancestor, nsIPresShell::eStyleChange,
+                                        NS_FRAME_HAS_DIRTY_CHILDREN);
         }
       }
     }
   }
   return rv;
 }
 
 static inline bool
@@ -5098,26 +5097,26 @@ nsBlockFrame::SetOverflowOutOfFlows(cons
 
   if (aList.IsEmpty()) {
     if (!(GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS)) {
       return;
     }
     nsFrameList* list = RemovePropTableFrames(OverflowOutOfFlowsProperty());
     NS_ASSERTION(aPropValue == list, "prop value mismatch");
     list->Clear();
-    list->Delete(PresContext()->PresShell());
+    list->Delete(PresShell());
     RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
   }
   else if (GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) {
     NS_ASSERTION(aPropValue == GetPropTableFrames(OverflowOutOfFlowsProperty()),
                  "prop value mismatch");
     *aPropValue = aList;
   }
   else {
-    SetPropTableFrames(new (PresContext()->PresShell()) nsFrameList(aList),
+    SetPropTableFrames(new (PresShell()) nsFrameList(aList),
                        OverflowOutOfFlowsProperty());
     AddStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
   }
 }
 
 nsBulletFrame*
 nsBlockFrame::GetInsideBullet() const
 {
@@ -5165,17 +5164,17 @@ nsBlockFrame::GetPushedFloats() const
 
 nsFrameList*
 nsBlockFrame::EnsurePushedFloats()
 {
   nsFrameList *result = GetPushedFloats();
   if (result)
     return result;
 
-  result = new (PresContext()->PresShell()) nsFrameList;
+  result = new (PresShell()) nsFrameList;
   SetProperty(PushedFloatProperty(), result);
   AddStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
 
   return result;
 }
 
 nsFrameList*
 nsBlockFrame::RemovePushedFloats()
@@ -5229,17 +5228,17 @@ nsBlockFrame::AppendFrames(ChildListID  
                "unexpected block frame in SVG text");
     // Workaround for bug 1399425 in case this bit has been removed from the
     // SVGTextFrame just before the parser adds more descendant nodes.
     GetParent()->AddStateBits(NS_STATE_SVG_TEXT_CORRESPONDENCE_DIRTY);
   }
 
   AddFrames(aFrameList, lastKid);
   if (aListID != kNoReflowPrincipalList) {
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                        NS_FRAME_HAS_DIRTY_CHILDREN); // XXX sufficient?
   }
 }
 
 void
 nsBlockFrame::InsertFrames(ChildListID aListID,
                            nsIFrame* aPrevFrame,
@@ -5265,17 +5264,17 @@ nsBlockFrame::InsertFrames(ChildListID a
     printf(" after ");
     nsFrame::ListTag(stdout, aPrevFrame);
   }
   printf("\n");
 #endif
 
   AddFrames(aFrameList, aPrevFrame);
   if (aListID != kNoReflowPrincipalList) {
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                        NS_FRAME_HAS_DIRTY_CHILDREN); // XXX sufficient?
   }
 }
 
 void
 nsBlockFrame::RemoveFrame(ChildListID aListID,
                           nsIFrame* aOldFrame)
@@ -5311,17 +5310,17 @@ nsBlockFrame::RemoveFrame(ChildListID aL
     // Skip the call to |FrameNeedsReflow| below by returning now.
     DoRemoveFrame(aOldFrame, REMOVE_FIXED_CONTINUATIONS);
     return;
   }
   else {
     MOZ_CRASH("unexpected child list");
   }
 
-  PresContext()->PresShell()->
+  PresShell()->
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN); // XXX sufficient?
 }
 
 static bool
 ShouldPutNextSiblingOnNewLine(nsIFrame* aLastFrame)
 {
   LayoutFrameType type = aLastFrame->Type();
@@ -7090,17 +7089,17 @@ nsBlockFrame::SetInitialChildList(ChildL
     nsContainerFrame::SetInitialChildList(aListID, aChildList);
   }
 }
 
 void
 nsBlockFrame::CreateBulletFrameForListItem(bool aCreateBulletList,
                                            bool aListStylePositionInside)
 {
-  nsIPresShell* shell = PresContext()->PresShell();
+  nsIPresShell* shell = PresShell();
 
   CSSPseudoElementType pseudoType = aCreateBulletList ?
     CSSPseudoElementType::mozListBullet :
     CSSPseudoElementType::mozListNumber;
 
   RefPtr<nsStyleContext> kidSC = ResolveBulletStyle(pseudoType,
                                                     shell->StyleSet());
 
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -435,26 +435,26 @@ protected:
 
   NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(LineCursorProperty, nsLineBox)
   bool HasLineCursor() { return GetStateBits() & NS_BLOCK_HAS_LINE_CURSOR; }
   nsLineBox* GetLineCursor() {
     return HasLineCursor() ? GetProperty(LineCursorProperty()) : nullptr;
   }
 
   nsLineBox* NewLineBox(nsIFrame* aFrame, bool aIsBlock) {
-    return NS_NewLineBox(PresContext()->PresShell(), aFrame, aIsBlock);
+    return NS_NewLineBox(PresShell(), aFrame, aIsBlock);
   }
   nsLineBox* NewLineBox(nsLineBox* aFromLine, nsIFrame* aFrame, int32_t aCount) {
-    return NS_NewLineBox(PresContext()->PresShell(), aFromLine, aFrame, aCount);
+    return NS_NewLineBox(PresShell(), aFromLine, aFrame, aCount);
   }
   void FreeLineBox(nsLineBox* aLine) {
     if (aLine == GetLineCursor()) {
       ClearLineCursor();
     }
-    aLine->Destroy(PresContext()->PresShell());
+    aLine->Destroy(PresShell());
   }
   /**
    * Helper method for StealFrame.
    */
   void RemoveFrameFromLine(nsIFrame* aChild, nsLineList::iterator aLine,
                            nsFrameList& aFrameList, nsLineList& aLineList);
 
   void TryAllLines(nsLineList::iterator* aIterator,
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -90,18 +90,17 @@ nsContainerFrame::SetInitialChildList(Ch
       MOZ_ASSERT(aChildList.OnlyChild(), "Should have only one backdrop");
       MOZ_ASSERT(placeholder->IsPlaceholderFrame(),
                 "The frame to be stored should be a placeholder");
       MOZ_ASSERT(static_cast<nsPlaceholderFrame*>(placeholder)->
                 GetOutOfFlowFrame()->IsBackdropFrame(),
                 "The placeholder should points to a backdrop frame");
     }
 #endif
-    nsFrameList* list =
-      new (PresContext()->PresShell()) nsFrameList(aChildList);
+    nsFrameList* list = new (PresShell()) nsFrameList(aChildList);
     SetProperty(BackdropProperty(), list);
   } else {
     MOZ_ASSERT_UNREACHABLE("Unexpected child list");
   }
 }
 
 void
 nsContainerFrame::AppendFrames(ChildListID  aListID,
@@ -113,19 +112,18 @@ nsContainerFrame::AppendFrames(ChildList
   if (MOZ_UNLIKELY(aFrameList.IsEmpty())) {
     return;
   }
 
   DrainSelfOverflowList(); // ensure the last frame is in mFrames
   mFrames.AppendFrames(this, aFrameList);
 
   if (aListID != kNoReflowPrincipalList) {
-    PresContext()->PresShell()->
-      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                       NS_FRAME_HAS_DIRTY_CHILDREN);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                  NS_FRAME_HAS_DIRTY_CHILDREN);
   }
 }
 
 void
 nsContainerFrame::InsertFrames(ChildListID aListID,
                                nsIFrame* aPrevFrame,
                                nsFrameList& aFrameList)
 {
@@ -137,19 +135,18 @@ nsContainerFrame::InsertFrames(ChildList
   if (MOZ_UNLIKELY(aFrameList.IsEmpty())) {
     return;
   }
 
   DrainSelfOverflowList(); // ensure aPrevFrame is in mFrames
   mFrames.InsertFrames(this, aPrevFrame, aFrameList);
 
   if (aListID != kNoReflowPrincipalList) {
-    PresContext()->PresShell()->
-      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                       NS_FRAME_HAS_DIRTY_CHILDREN);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                  NS_FRAME_HAS_DIRTY_CHILDREN);
   }
 }
 
 void
 nsContainerFrame::RemoveFrame(ChildListID aListID,
                               nsIFrame* aOldFrame)
 {
   MOZ_ASSERT(aListID == kPrincipalList || aListID == kNoReflowPrincipalList,
@@ -157,17 +154,17 @@ nsContainerFrame::RemoveFrame(ChildListI
 
   // Loop and destroy aOldFrame and all of its continuations.
   // Request a reflow on the parent frames involved unless we were explicitly
   // told not to (kNoReflowPrincipalList).
   bool generateReflowCommand = true;
   if (kNoReflowPrincipalList == aListID) {
     generateReflowCommand = false;
   }
-  nsIPresShell* shell = PresContext()->PresShell();
+  nsIPresShell* shell = PresShell();
   nsContainerFrame* lastParent = nullptr;
   while (aOldFrame) {
     nsIFrame* oldFrameNextContinuation = aOldFrame->GetNextContinuation();
     nsContainerFrame* parent = aOldFrame->GetParent();
     // Please note that 'parent' may not actually be where 'aOldFrame' lives.
     // We really MUST use StealFrame() and nothing else here.
     // @see nsInlineFrame::StealFrame for details.
     parent->StealFrame(aOldFrame);
@@ -1252,17 +1249,17 @@ TryRemoveFrame(nsIFrame* aFrame,
                nsContainerFrame::FrameListPropertyDescriptor aProp,
                nsIFrame* aChildToRemove)
 {
   nsFrameList* list = aFrame->GetProperty(aProp);
   if (list && list->StartRemoveFrame(aChildToRemove)) {
     // aChildToRemove *may* have been removed from this list.
     if (list->IsEmpty()) {
       aFrame->RemoveProperty(aProp);
-      list->Delete(aFrame->PresContext()->PresShell());
+      list->Delete(aFrame->PresShell());
     }
     return true;
   }
   return false;
 }
 
 bool
 nsContainerFrame::MaybeStealOverflowContainerFrame(nsIFrame* aChild)
@@ -1636,27 +1633,27 @@ nsContainerFrame::DrainExcessOverflowCon
       }
       child = next;
     }
     if (toMove.IsEmpty()) {
       SetPropTableFrames(selfExcessOCFrames, ExcessOverflowContainersProperty());
     } else if (overflowContainers) {
       aMergeFunc(*overflowContainers, toMove, this);
       if (selfExcessOCFrames->IsEmpty()) {
-        selfExcessOCFrames->Delete(PresContext()->PresShell());
+        selfExcessOCFrames->Delete(PresShell());
       } else {
         SetPropTableFrames(selfExcessOCFrames, ExcessOverflowContainersProperty());
       }
     } else {
       if (selfExcessOCFrames->IsEmpty()) {
         *selfExcessOCFrames = toMove;
         overflowContainers = selfExcessOCFrames;
       } else {
         SetPropTableFrames(selfExcessOCFrames, ExcessOverflowContainersProperty());
-        auto shell = PresContext()->PresShell();
+        auto shell = PresShell();
         overflowContainers = new (shell) nsFrameList(toMove);
       }
       SetPropTableFrames(overflowContainers, OverflowContainersProperty());
     }
   }
 
   return overflowContainers;
 }
@@ -1982,19 +1979,18 @@ nsContainerFrame::AttributeChanged(int32
     return rv;
   }
   if (nsGkAtoms::start == aAttribute ||
       (nsGkAtoms::reversed == aAttribute &&
        mContent->IsHTMLElement(nsGkAtoms::ol))) {
 
     // XXX Not sure if this is necessary anymore
     if (RenumberList()) {
-      PresContext()->PresShell()->
-        FrameNeedsReflow(this, nsIPresShell::eStyleChange,
-                         NS_FRAME_HAS_DIRTY_CHILDREN);
+      PresShell()->FrameNeedsReflow(this, nsIPresShell::eStyleChange,
+                                    NS_FRAME_HAS_DIRTY_CHILDREN);
     }
   }
   return rv;
 }
 
 nsOverflowContinuationTracker::nsOverflowContinuationTracker(nsContainerFrame* aFrame,
                                                              bool              aWalkOOFFrames,
                                                              bool              aSkipOverflowContainerChildren)
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -932,12 +932,12 @@ nsContainerFrame::StealOverflowFrames()
   return list;
 }
 
 inline void
 nsContainerFrame::DestroyOverflowList()
 {
   nsFrameList* list = RemovePropTableFrames(OverflowProperty());
   MOZ_ASSERT(list && list->IsEmpty());
-  list->Delete(PresContext()->PresShell());
+  list->Delete(PresShell());
 }
 
 #endif /* nsContainerFrame_h___ */
--- a/layout/generic/nsFontInflationData.cpp
+++ b/layout/generic/nsFontInflationData.cpp
@@ -199,17 +199,17 @@ nsFontInflationData::UpdateISize(const R
   while (!nca->IsContainerForFontSizeInflation()) {
     nca = nca->GetParent()->FirstInFlow();
   }
 
   nscoord newNCAISize = ComputeDescendantISize(aReflowInput, nca);
 
   // See comment above "font.size.inflation.lineThreshold" in
   // modules/libpref/src/init/all.js .
-  nsIPresShell* presShell = bfc->PresContext()->PresShell();
+  nsIPresShell* presShell = bfc->PresShell();
   uint32_t lineThreshold = presShell->FontSizeInflationLineThreshold();
   nscoord newTextThreshold = (newNCAISize * lineThreshold) / 100;
 
   if (mTextThreshold <= mTextAmount && mTextAmount < newTextThreshold) {
     // Because we truncate our scan when we hit sufficient text, we now
     // need to rescan.
     mTextDirty = true;
   }
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -710,17 +710,17 @@ nsFrame::Init(nsIContent*       aContent
         AddStateBits(NS_FRAME_FONT_INFLATION_FLOW_ROOT);
       }
     }
     NS_ASSERTION(GetParent() ||
                  (GetStateBits() & NS_FRAME_FONT_INFLATION_CONTAINER),
                  "root frame should always be a container");
   }
 
-  if (PresContext()->PresShell()->AssumeAllFramesVisible() &&
+  if (PresShell()->AssumeAllFramesVisible() &&
       TrackingVisibility()) {
     IncApproximateVisibleCount();
   }
 
   DidSetStyleContext(nullptr);
 
   if (::IsXULBoxWrapped(this))
     ::InitBoxMetrics(this, false);
@@ -1941,17 +1941,17 @@ nsIFrame::GetVisibility() const
   return visibleCount > 0
        ? Visibility::APPROXIMATELY_VISIBLE
        : Visibility::APPROXIMATELY_NONVISIBLE;
 }
 
 void
 nsIFrame::UpdateVisibilitySynchronously()
 {
-  nsIPresShell* presShell = PresContext()->PresShell();
+  nsIPresShell* presShell = PresShell();
   if (!presShell) {
     return;
   }
 
   if (presShell->AssumeAllFramesVisible()) {
     presShell->EnsureFrameInApproximatelyVisibleList(this);
     return;
   }
@@ -2010,17 +2010,17 @@ nsIFrame::EnableVisibilityTracking()
              "Shouldn't have a VisibilityStateProperty value "
              "if NS_FRAME_VISIBILITY_IS_TRACKED is not set");
 
   // Add the state bit so we know to track visibility for this frame, and
   // initialize the frame property.
   AddStateBits(NS_FRAME_VISIBILITY_IS_TRACKED);
   SetProperty(VisibilityStateProperty(), 0);
 
-  nsIPresShell* presShell = PresContext()->PresShell();
+  nsIPresShell* presShell = PresShell();
   if (!presShell) {
     return;
   }
 
   // Schedule a visibility update. This method will virtually always be called
   // when layout has changed anyway, so it's very unlikely that any additional
   // visibility updates will be triggered by this, but this way we guarantee
   // that if this frame is currently visible we'll eventually find out.
@@ -2472,17 +2472,17 @@ DisplayDebugBorders(nsDisplayListBuilder
   // REVIEW: From nsContainerFrame::PaintChild
   if (nsFrame::GetShowFrameBorders() && !aFrame->GetRect().IsEmpty()) {
     aLists.Outlines()->AppendNewToTop(new (aBuilder)
         nsDisplayGeneric(aBuilder, aFrame, PaintDebugBorder, "DebugBorder",
                          DisplayItemType::TYPE_DEBUG_BORDER));
   }
   // Draw a border around the current event target
   if (nsFrame::GetShowEventTargetFrameBorder() &&
-      aFrame->PresContext()->PresShell()->GetDrawEventTargetFrame() == aFrame) {
+      aFrame->PresShell()->GetDrawEventTargetFrame() == aFrame) {
     aLists.Outlines()->AppendNewToTop(new (aBuilder)
         nsDisplayGeneric(aBuilder, aFrame, PaintEventTargetBorder, "EventTargetBorder",
                          DisplayItemType::TYPE_EVENT_TARGET_BORDER));
   }
 }
 #endif
 
 static bool
@@ -3364,17 +3364,17 @@ DescendIntoChild(nsDisplayListBuilder* a
     // We can stop if child's frame subtree's intersection with the
     // dirty area is empty.
     // If the child is a scrollframe that we want to ignore, then we need
     // to descend into it because its scrolled child may intersect the dirty
     // area even if the scrollframe itself doesn't.
     // There are cases where the "ignore scroll frame" on the builder is not set
     // correctly, and so we additionally want to catch cases where the child is
     // a root scrollframe and we are ignoring scrolling on the viewport.
-    nsIPresShell* shell = child->PresContext()->PresShell();
+    nsIPresShell* shell = child->PresShell();
     bool keepDescending = child == aBuilder->GetIgnoreScrollFrame() ||
       (shell->IgnoringViewportScrolling() && child == shell->GetRootScrollFrame());
     if (!keepDescending) {
       nsRect childDirty;
       if (!childDirty.IntersectRect(dirty, child->GetVisualOverflowRect()) &&
           (!child->ForceDescendIntoIfVisible())) {
         return false;
       }
@@ -3551,17 +3551,17 @@ nsIFrame::BuildDisplayListForChild(nsDis
   if (IsThemed(ourDisp) &&
       !PresContext()->GetTheme()->WidgetIsContainer(ourDisp->mAppearance))
     return;
 
   // Since we're now sure that we're adding this frame to the display list
   // (which means we're painting it, modulo occlusion), mark it as visible
   // within the displayport.
   if (aBuilder->IsPaintingToWindow() && child->TrackingVisibility()) {
-    child->PresContext()->PresShell()->EnsureFrameInApproximatelyVisibleList(child);
+    child->PresShell()->EnsureFrameInApproximatelyVisibleList(child);
     awayFromCommonPath = true;
   }
 
   child->SetBuiltDisplayList(true);
 
   // Child is composited if it's transformed, partially transparent, or has
   // SVG effects or a blend mode..
   EffectSet* effectSet = EffectSet::GetEffectSet(child);
@@ -4589,17 +4589,17 @@ NS_IMETHODIMP nsFrame::HandleRelease(nsP
       // If not, the user must have clicked in a part of the selection.
       // Place the caret before continuing!
 
       if (frameselection->MouseDownRecorded()) {
         nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, this);
         offsets = GetContentOffsetsFromPoint(pt, SKIP_HIDDEN);
         handleTableSelection = false;
       } else {
-        GetDataForTableSelection(frameselection, PresContext()->PresShell(),
+        GetDataForTableSelection(frameselection, PresShell(),
                                  aEvent->AsMouseEvent(),
                                  getter_AddRefs(parentContent),
                                  &contentOffsetForTableSel,
                                  &targetForTableSel);
       }
     }
   }
 
@@ -7919,17 +7919,17 @@ nsIFrame::GetConstFrameSelection() const
   while (frame && (frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION)) {
     nsITextControlFrame* tcf = do_QueryFrame(frame);
     if (tcf) {
       return tcf->GetOwnedFrameSelection();
     }
     frame = frame->GetParent();
   }
 
-  return PresContext()->PresShell()->ConstFrameSelection();
+  return PresShell()->ConstFrameSelection();
 }
 
 bool
 nsIFrame::IsFrameSelected() const
 {
   NS_ASSERTION(!GetContent() || GetContent()->IsSelectionDescendant(),
                "use the public IsSelected() instead");
   return nsRange::IsNodeSelected(GetContent(), 0,
--- a/layout/generic/nsFrameSelection.cpp
+++ b/layout/generic/nsFrameSelection.cpp
@@ -537,17 +537,17 @@ nsFrameSelection::ConstrainFrameAndPoint
       // fixed positioned frames.
       nsIFrame* rootFrame = mShell->FrameManager()->GetRootFrame();
       nsPoint ptInRoot = aPoint + aFrame->GetOffsetTo(rootFrame);
       nsIFrame* cursorFrame =
         nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
 
       // If the mouse cursor in on a frame which is descendant of same
       // selection root, we can expand the selection to the frame.
-      if (cursorFrame && cursorFrame->PresContext()->PresShell() == mShell)
+      if (cursorFrame && cursorFrame->PresShell() == mShell)
       {
         nsIContent* cursorContent = cursorFrame->GetContent();
         NS_ENSURE_TRUE(cursorContent, NS_ERROR_FAILURE);
         nsIContent* cursorContentRoot =
           cursorContent->GetSelectionRootContent(mShell);
         NS_ENSURE_TRUE(cursorContentRoot, NS_ERROR_UNEXPECTED);
         if (cursorContentRoot == anchorRoot)
         {
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -376,17 +376,17 @@ nsHTMLScrollFrame::TryLayout(ScrollReflo
   desiredInsideBorderSize.height = hScrollbarDesiredHeight +
     std::max(aKidMetrics->Height(), vScrollbarMinHeight);
   aState->mInsideBorderSize =
     ComputeInsideBorderSize(aState, desiredInsideBorderSize);
   nsSize scrollPortSize = nsSize(std::max(0, aState->mInsideBorderSize.width - vScrollbarDesiredWidth),
                                  std::max(0, aState->mInsideBorderSize.height - hScrollbarDesiredHeight));
 
   nsSize visualScrollPortSize = scrollPortSize;
-  nsIPresShell* presShell = PresContext()->PresShell();
+  nsIPresShell* presShell = PresShell();
   if (mHelper.mIsRoot && presShell->IsScrollPositionClampingScrollPortSizeSet()) {
     nsSize compositionSize = nsLayoutUtils::CalculateCompositionSizeForFrame(this, false);
     float resolution = presShell->GetResolution();
     compositionSize.width /= resolution;
     compositionSize.height /= resolution;
     visualScrollPortSize = nsSize(std::max(0, compositionSize.width - vScrollbarDesiredWidth),
                                   std::max(0, compositionSize.height - hScrollbarDesiredHeight));
   }
@@ -1050,17 +1050,17 @@ nsHTMLScrollFrame::Reflow(nsPresContext*
           aDesiredSize.Size(aDesiredSize.GetWritingMode()));
 
   // Restore the old scroll position, for now, even if that's not valid anymore
   // because we changed size. We'll fix it up in a post-reflow callback, because
   // our current size may only be temporary (e.g. we're compute XUL desired sizes).
   PlaceScrollArea(state, oldScrollPosition);
   if (!mHelper.mPostedReflowCallback) {
     // Make sure we'll try scrolling to restored position
-    PresContext()->PresShell()->PostReflowCallback(&mHelper);
+    PresShell()->PostReflowCallback(&mHelper);
     mHelper.mPostedReflowCallback = true;
   }
 
   bool didHaveHScrollbar = mHelper.mHasHorizontalScrollbar;
   bool didHaveVScrollbar = mHelper.mHasVerticalScrollbar;
   mHelper.mHasHorizontalScrollbar = state.mShowHScrollbar;
   mHelper.mHasVerticalScrollbar = state.mShowVScrollbar;
   nsRect newScrollAreaBounds = mHelper.mScrollPort;
@@ -1874,17 +1874,17 @@ public:
   bool SetRefreshObserver(ScrollFrameHelper *aCallee) {
     NS_ASSERTION(aCallee && !mCallee, "AsyncScroll::SetRefreshObserver - Invalid usage.");
 
     if (!RefreshDriver(aCallee)->AddRefreshObserver(this, FlushType::Style)) {
       return false;
     }
 
     mCallee = aCallee;
-    APZCCallbackHelper::SuppressDisplayport(true, mCallee->mOuter->PresContext()->PresShell());
+    APZCCallbackHelper::SuppressDisplayport(true, mCallee->mOuter->PresShell());
     return true;
   }
 
   virtual void WillRefresh(mozilla::TimeStamp aTime) override {
     // The callback may release "this".
     // We don't access members after returning, so no need for KungFuDeathGrip.
     ScrollFrameHelper::AsyncScrollCallback(mCallee, aTime);
   }
@@ -1899,17 +1899,17 @@ private:
   /*
    * The refresh driver doesn't hold a reference to its observers,
    *   so releasing this object can (and is) used to remove the observer on DTOR.
    * Currently, this object is released once the scrolling ends.
    */
   void RemoveObserver() {
     if (mCallee) {
       RefreshDriver(mCallee)->RemoveRefreshObserver(this, FlushType::Style);
-      APZCCallbackHelper::SuppressDisplayport(false, mCallee->mOuter->PresContext()->PresShell());
+      APZCCallbackHelper::SuppressDisplayport(false, mCallee->mOuter->PresShell());
     }
   }
 };
 
 /*
  * Calculate duration, possibly dynamically according to events rate and event origin.
  * (also maintain previous timestamps - which are only used here).
  */
@@ -2086,17 +2086,17 @@ ScrollFrameHelper::ScrollFrameHelper(nsC
   if (IsAlwaysActive() &&
       gfxPrefs::LayersTilesEnabled() &&
       !nsLayoutUtils::UsesAsyncScrolling(mOuter) &&
       mOuter->GetContent()) {
     // If we have tiling but no APZ, then set a 0-margin display port on
     // active scroll containers so that we paint by whole tile increments
     // when scrolling.
     nsLayoutUtils::SetDisplayPortMargins(mOuter->GetContent(),
-                                         mOuter->PresContext()->PresShell(),
+                                         mOuter->PresShell(),
                                          ScreenMargin(),
                                          0,
                                          nsLayoutUtils::RepaintMode::DoNotRepaint);
     nsLayoutUtils::SetZeroMarginDisplayPortOnAsyncScrollableAncestors(
         mOuter, nsLayoutUtils::RepaintMode::DoNotRepaint);
   }
 
 }
@@ -2447,37 +2447,37 @@ static void AdjustViews(nsIFrame* aFrame
   }
 }
 
 bool ScrollFrameHelper::IsIgnoringViewportClipping() const
 {
   if (!mIsRoot)
     return false;
   nsSubDocumentFrame* subdocFrame = static_cast<nsSubDocumentFrame*>
-    (nsLayoutUtils::GetCrossDocParentFrame(mOuter->PresContext()->PresShell()->GetRootFrame()));
+    (nsLayoutUtils::GetCrossDocParentFrame(mOuter->PresShell()->GetRootFrame()));
   return subdocFrame && !subdocFrame->ShouldClipSubdocument();
 }
 
 void ScrollFrameHelper::MarkScrollbarsDirtyForReflow() const
 {
-  nsIPresShell* presShell = mOuter->PresContext()->PresShell();
+  nsIPresShell* presShell = mOuter->PresShell();
   if (mVScrollbarBox) {
     presShell->FrameNeedsReflow(mVScrollbarBox, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
   }
   if (mHScrollbarBox) {
     presShell->FrameNeedsReflow(mHScrollbarBox, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
   }
 }
 
 bool ScrollFrameHelper::ShouldClampScrollPosition() const
 {
   if (!mIsRoot)
     return true;
   nsSubDocumentFrame* subdocFrame = static_cast<nsSubDocumentFrame*>
-    (nsLayoutUtils::GetCrossDocParentFrame(mOuter->PresContext()->PresShell()->GetRootFrame()));
+    (nsLayoutUtils::GetCrossDocParentFrame(mOuter->PresShell()->GetRootFrame()));
   return !subdocFrame || subdocFrame->ShouldClampScrollPosition();
 }
 
 bool ScrollFrameHelper::IsAlwaysActive() const
 {
   if (nsDisplayItem::ForceActiveLayers()) {
     return true;
   }
@@ -2714,17 +2714,17 @@ ClampAndAlignWithLayerPixels(const nsPoi
 /* static */ void
 ScrollFrameHelper::ScrollActivityCallback(nsITimer *aTimer, void* anInstance)
 {
   ScrollFrameHelper* self = static_cast<ScrollFrameHelper*>(anInstance);
 
   // Fire the synth mouse move.
   self->mScrollActivityTimer->Cancel();
   self->mScrollActivityTimer = nullptr;
-  self->mOuter->PresContext()->PresShell()->SynthesizeMouseMove(true);
+  self->mOuter->PresShell()->SynthesizeMouseMove(true);
 }
 
 
 void
 ScrollFrameHelper::ScheduleSyntheticMouseMove()
 {
   if (!mScrollActivityTimer) {
     mScrollActivityTimer = NS_NewTimer(
@@ -3389,17 +3389,17 @@ ScrollFrameHelper::BuildDisplayList(nsDi
     }
 
     return;
   }
 
   // Root scrollframes have FrameMetrics and clipping on their container
   // layers, so don't apply clipping again.
   mAddClipRectToLayer =
-    !(mIsRoot && mOuter->PresContext()->PresShell()->GetIsViewportOverridden());
+    !(mIsRoot && mOuter->PresShell()->GetIsViewportOverridden());
 
   // Whether we might want to build a scrollable layer for this scroll frame
   // at some point in the future. This controls whether we add the information
   // to the layer tree (a scroll info layer if necessary, and add the right
   // area to the dispatch to content layer event regions) necessary to activate
   // a scroll frame so it creates a scrollable layer.
   bool couldBuildLayer = false;
   if (aBuilder->IsPaintingToWindow()) {
@@ -3488,17 +3488,17 @@ ScrollFrameHelper::BuildDisplayList(nsDi
     nsRect clipRect = mScrollPort + aBuilder->ToReferenceFrame(mOuter);
     // Our override of GetBorderRadii ensures we never have a radius at
     // the corners where we have a scrollbar.
     nscoord radii[8];
     bool haveRadii = mOuter->GetPaddingBoxBorderRadii(radii);
     if (mIsRoot) {
       clipRect.SizeTo(nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter));
       if (mOuter->PresContext()->IsRootContentDocument()) {
-        double res = mOuter->PresContext()->PresShell()->GetResolution();
+        double res = mOuter->PresShell()->GetResolution();
         clipRect.width = NSToCoordRound(clipRect.width / res);
         clipRect.height = NSToCoordRound(clipRect.height / res);
       }
     }
 
     DisplayListClipState::AutoSaveRestore clipState(aBuilder);
     if (mClipAllDescendants) {
       clipState.ClipContentDescendants(clipRect, haveRadii ? radii : nullptr);
@@ -3591,17 +3591,17 @@ ScrollFrameHelper::BuildDisplayList(nsDi
       //
       // This is not compatible when using containes for root scrollframes.
       MOZ_ASSERT(couldBuildLayer && mScrolledFrame->GetContent() &&
         aBuilder->IsPaintingToWindow());
       if (!mWillBuildScrollableLayer) {
         // Set a displayport so next paint we don't have to force layerization
         // after the fact.
         nsLayoutUtils::SetDisplayPortMargins(mOuter->GetContent(),
-                                             mOuter->PresContext()->PresShell(),
+                                             mOuter->PresShell(),
                                              ScreenMargin(),
                                              0,
                                              nsLayoutUtils::RepaintMode::DoNotRepaint);
         // Call DecideScrollableLayer to recompute mWillBuildScrollableLayer and
         // recompute the current animated geometry root if needed.
         // It's too late to change the dirty rect so pass a copy.
         nsRect copyOfDirtyRect = dirtyRect;
         nsRect copyOfVisibleRect = visibleRect;
@@ -3773,17 +3773,17 @@ ScrollFrameHelper::DecideScrollableLayer
             *aDirtyRectHasBeenOverriden = true;
           }
         }
       }
     } else if (mIsRoot) {
       // The displayPort getter takes care of adjusting for resolution. So if
       // we have resolution but no displayPort then we need to adjust for
       // resolution here.
-      nsIPresShell* presShell = mOuter->PresContext()->PresShell();
+      nsIPresShell* presShell = mOuter->PresShell();
       *aVisibleRect = aVisibleRect->RemoveResolution(
         presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f);
       *aDirtyRect = aDirtyRect->RemoveResolution(
         presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f);
     }
   }
 
   // Since making new layers is expensive, only create a scrollable layer
@@ -3942,17 +3942,17 @@ ScrollFrameHelper::GetScrollRangeForClam
   }
   nsSize scrollPortSize = GetScrollPositionClampingScrollPortSize();
   return GetScrollRange(scrollPortSize.width, scrollPortSize.height);
 }
 
 nsSize
 ScrollFrameHelper::GetScrollPositionClampingScrollPortSize() const
 {
-  nsIPresShell* presShell = mOuter->PresContext()->PresShell();
+  nsIPresShell* presShell = mOuter->PresShell();
   if (mIsRoot && presShell->IsScrollPositionClampingScrollPortSizeSet()) {
     return presShell->GetScrollPositionClampingScrollPortSize();
   }
   return mScrollPort.Size();
 }
 
 static void
 AdjustForWholeDelta(int32_t aDelta, nscoord* aCoord)
@@ -4256,17 +4256,17 @@ GetScrollPortSizeExcludingHeadersAndFoot
 nsSize
 ScrollFrameHelper::GetPageScrollAmount() const
 {
   nsSize lineScrollAmount = GetLineScrollAmount();
   nsSize effectiveScrollPortSize;
   if (mIsRoot) {
     // Reduce effective scrollport height by the height of any fixed-pos
     // headers or footers
-    nsIFrame* root = mOuter->PresContext()->PresShell()->GetRootFrame();
+    nsIFrame* root = mOuter->PresShell()->GetRootFrame();
     effectiveScrollPortSize =
       GetScrollPortSizeExcludingHeadersAndFooters(root, mScrollPort);
   } else {
     effectiveScrollPortSize = mScrollPort.Size();
   }
   // The page increment is the size of the page, minus the smaller of
   // 10% of the size or 2 lines.
   return nsSize(
@@ -4654,17 +4654,17 @@ ScrollFrameHelper::Destroy(PostDestroyDa
 
   // Unbind the content created in CreateAnonymousContent later...
   aPostDestroyData.AddAnonymousContent(mHScrollbarContent.forget());
   aPostDestroyData.AddAnonymousContent(mVScrollbarContent.forget());
   aPostDestroyData.AddAnonymousContent(mScrollCornerContent.forget());
   aPostDestroyData.AddAnonymousContent(mResizerContent.forget());
 
   if (mPostedReflowCallback) {
-    mOuter->PresContext()->PresShell()->CancelReflowCallback(this);
+    mOuter->PresShell()->CancelReflowCallback(this);
     mPostedReflowCallback = false;
   }
 
   if (mDisplayPortExpiryTimer) {
     mDisplayPortExpiryTimer->Cancel();
     mDisplayPortExpiryTimer = nullptr;
   }
   if (mActivityExpirationState.IsTracked()) {
@@ -5321,17 +5321,17 @@ nsXULScrollFrame::XULLayout(nsBoxLayoutS
     LayoutScrollArea(resizeState, oldScrollPosition);
   }
 
   if (!mHelper.mSuppressScrollbarUpdate) {
     mHelper.LayoutScrollbars(aState, clientRect, oldScrollAreaBounds);
   }
   if (!mHelper.mPostedReflowCallback) {
     // Make sure we'll try scrolling to restored position
-    PresContext()->PresShell()->PostReflowCallback(&mHelper);
+    PresShell()->PostReflowCallback(&mHelper);
     mHelper.mPostedReflowCallback = true;
   }
   if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
     mHelper.mHadNonInitialReflow = true;
   }
 
   mHelper.UpdateSticky();
 
@@ -5526,17 +5526,17 @@ ScrollFrameHelper::ComputeCustomOverflow
   }
 
   if (needReflow) {
     // If there are scrollbars, or we're not at the beginning of the pane,
     // the scroll position may change. In this case, mark the frame as
     // needing reflow. Don't use NS_FRAME_IS_DIRTY as dirty as that means
     // we have to reflow the frame and all its descendants, and we don't
     // have to do that here. Only this frame needs to be reflowed.
-    mOuter->PresContext()->PresShell()->FrameNeedsReflow(
+    mOuter->PresShell()->FrameNeedsReflow(
       mOuter, nsIPresShell::eResize, NS_FRAME_HAS_DIRTY_CHILDREN);
     // Ensure that next time nsHTMLScrollFrame::Reflow runs, we don't skip
     // updating the scrollbars. (Because the overflow area of the scrolled
     // frame has probably just been updated, Reflow won't see it change.)
     mSkippedScrollbarLayout = true;
     return false;  // reflowing will update overflow
   }
   PostOverflowEvent();
@@ -5629,17 +5629,17 @@ AdjustOverlappingScrollbars(nsRect& aVRe
 void
 ScrollFrameHelper::LayoutScrollbars(nsBoxLayoutState& aState,
                                         const nsRect& aContentArea,
                                         const nsRect& aOldScrollArea)
 {
   NS_ASSERTION(!mSuppressScrollbarUpdate,
                "This should have been suppressed");
 
-  nsIPresShell* presShell = mOuter->PresContext()->PresShell();
+  nsIPresShell* presShell = mOuter->PresShell();
 
   bool hasResizer = HasResizer();
   bool scrollbarOnLeft = !IsScrollbarOnRight();
   bool overlayScrollBarsWithZoom =
     mIsRoot && LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) &&
     presShell->IsScrollPositionClampingScrollPortSizeSet();
 
   nsSize scrollPortClampingSize = mScrollPort.Size();
@@ -5757,49 +5757,49 @@ ScrollFrameHelper::LayoutScrollbars(nsBo
       !(mOuter->GetStateBits() & NS_FRAME_IS_DIRTY) &&
       mIsRoot) {
     mMayHaveDirtyFixedChildren = true;
   }
 
   // post reflow callback to modify scrollbar attributes
   mUpdateScrollbarAttributes = true;
   if (!mPostedReflowCallback) {
-    aState.PresContext()->PresShell()->PostReflowCallback(this);
+    aState.PresShell()->PostReflowCallback(this);
     mPostedReflowCallback = true;
   }
 }
 
 #if DEBUG
 static bool ShellIsAlive(nsWeakPtr& aWeakPtr)
 {
   nsCOMPtr<nsIPresShell> shell(do_QueryReferent(aWeakPtr));
   return !!shell;
 }
 #endif
 
 void
 ScrollFrameHelper::SetScrollbarEnabled(nsIContent* aContent, nscoord aMaxPos)
 {
   DebugOnly<nsWeakPtr> weakShell(
-    do_GetWeakReference(mOuter->PresContext()->PresShell()));
+    do_GetWeakReference(mOuter->PresShell()));
   if (aMaxPos) {
     aContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::disabled, true);
   } else {
     aContent->SetAttr(kNameSpaceID_None, nsGkAtoms::disabled,
                       NS_LITERAL_STRING("true"), true);
   }
   MOZ_ASSERT(ShellIsAlive(weakShell), "pres shell was destroyed by scrolling");
 }
 
 void
 ScrollFrameHelper::SetCoordAttribute(nsIContent* aContent, nsAtom* aAtom,
                                          nscoord aSize)
 {
   DebugOnly<nsWeakPtr> weakShell(
-    do_GetWeakReference(mOuter->PresContext()->PresShell()));
+    do_GetWeakReference(mOuter->PresShell()));
   // convert to pixels
   int32_t pixelSize = nsPresContext::AppUnitsToIntCSSPixels(aSize);
 
   // only set the attribute if it changed.
 
   nsAutoString newValue;
   newValue.AppendInt(pixelSize);
 
@@ -6088,17 +6088,17 @@ ScrollFrameHelper::SaveState() const
   }
   if (mRestorePos.y != -1 && pt == mLastPos) {
     pt = mRestorePos;
   }
   state->SetScrollState(pt);
   state->SetAllowScrollOriginDowngrade(allowScrollOriginDowngrade);
   if (mIsRoot) {
     // Only save resolution properties for root scroll frames
-    nsIPresShell* shell = mOuter->PresContext()->PresShell();
+    nsIPresShell* shell = mOuter->PresShell();
     state->SetResolution(shell->GetResolution());
     state->SetScaleToResolution(shell->ScaleToResolution());
   }
   return state;
 }
 
 void
 ScrollFrameHelper::RestoreState(nsPresState* aState)
@@ -6109,17 +6109,17 @@ ScrollFrameHelper::RestoreState(nsPresSt
   mDidHistoryRestore = true;
   mLastPos = mScrolledFrame ? GetLogicalScrollPosition() : nsPoint(0,0);
 
   // Resolution properties should only exist on root scroll frames.
   MOZ_ASSERT(mIsRoot || (!aState->GetScaleToResolution() &&
                          aState->GetResolution() == 1.0));
 
   if (mIsRoot) {
-    nsIPresShell* presShell = mOuter->PresContext()->PresShell();
+    nsIPresShell* presShell = mOuter->PresShell();
     if (aState->GetScaleToResolution()) {
       presShell->SetResolutionAndScaleTo(aState->GetResolution());
     } else {
       presShell->SetResolution(aState->GetResolution());
     }
   }
 }
 
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -6682,17 +6682,17 @@ nsGridContainerFrame::NoteNewChildren(Ch
                                       const nsFrameList& aFrameList)
 {
 #ifdef DEBUG
   ChildListIDs supportedLists =
     kAbsoluteList | kFixedList | kPrincipalList | kNoReflowPrincipalList;
   MOZ_ASSERT(supportedLists.Contains(aListID), "unexpected child list");
 #endif
 
-  nsIPresShell* shell = PresContext()->PresShell();
+  nsIPresShell* shell = PresShell();
   for (auto pif = GetPrevInFlow(); pif; pif = pif->GetPrevInFlow()) {
     if (aListID == kPrincipalList) {
       pif->AddStateBits(NS_STATE_GRID_DID_PUSH_ITEMS);
     }
     shell->FrameNeedsReflow(pif, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
   }
 }
 
@@ -6721,17 +6721,17 @@ nsGridContainerFrame::MergeSortedExcessO
   }
   MOZ_ASSERT(aList.FirstChild()->HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER),
              "this is the wrong list to put this child frame");
   MOZ_ASSERT(aList.FirstChild()->GetParent() == this);
   nsFrameList* eoc = GetPropTableFrames(ExcessOverflowContainersProperty());
   if (eoc) {
     ::MergeSortedFrameLists(*eoc, aList, GetContent());
   } else {
-    SetPropTableFrames(new (PresContext()->PresShell()) nsFrameList(aList),
+    SetPropTableFrames(new (PresShell()) nsFrameList(aList),
                        ExcessOverflowContainersProperty());
   }
 }
 
 /* static */ nsGridContainerFrame::FindItemInGridOrderResult
 nsGridContainerFrame::FindFirstItemInGridOrder(
   CSSOrderAwareFrameIterator& aIter,
   const nsTArray<GridItemInfo>& aGridItems,
@@ -6910,17 +6910,17 @@ nsGridContainerFrame::GetGridFrameWithCo
     // if any of our properties are missing, generate them
     bool reflowNeeded = (!gridFrame->HasProperty(GridColTrackInfo()) ||
                          !gridFrame->HasProperty(GridRowTrackInfo()) ||
                          !gridFrame->HasProperty(GridColumnLineInfo()) ||
                          !gridFrame->HasProperty(GridRowLineInfo()));
 
     if (reflowNeeded) {
       // Trigger a reflow that generates additional grid property data.
-      nsIPresShell* shell = gridFrame->PresContext()->PresShell();
+      nsIPresShell* shell = gridFrame->PresShell();
       gridFrame->AddStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES);
       shell->FrameNeedsReflow(gridFrame,
                               nsIPresShell::eResize,
                               NS_FRAME_IS_DIRTY);
       shell->FlushPendingNotifications(FlushType::Layout);
 
       // Since the reflow may have side effects, get the grid frame again.
       gridFrame = GetGridContainerFrame(aFrame);
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -636,16 +636,20 @@ public:
   {
     mozilla::PodZero(&mOverflow);
   }
 
   nsPresContext* PresContext() const {
     return StyleContext()->PresContext();
   }
 
+  nsIPresShell* PresShell() const {
+    return PresContext()->PresShell();
+  }
+
   /**
    * Called to initialize the frame. This is called immediately after creating
    * the frame.
    *
    * If the frame is a continuing frame, then aPrevInFlow indicates the previous
    * frame (the frame that was split).
    *
    * Each subclass that need a view should override this method and call
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -183,26 +183,26 @@ nsImageFrame::DisconnectMap()
     return;
   }
 
   mImageMap->Destroy();
   mImageMap = nullptr;
 
 #ifdef ACCESSIBILITY
   if (nsAccessibilityService* accService = GetAccService()) {
-    accService->RecreateAccessible(PresContext()->PresShell(), mContent);
+    accService->RecreateAccessible(PresShell(), mContent);
   }
 #endif
 }
 
 void
 nsImageFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
 {
   if (mReflowCallbackPosted) {
-    PresContext()->PresShell()->CancelReflowCallback(this);
+    PresShell()->CancelReflowCallback(this);
     mReflowCallbackPosted = false;
   }
 
   // Tell our image map, if there is one, to clean up
   // This causes the nsImageMap to unregister itself as
   // a DOM listener.
   DisconnectMap();
 
@@ -1067,17 +1067,17 @@ nsImageFrame::Reflow(nsPresContext*     
   } else {
     // We've just reflowed and we should have an accurate size, so we're ready
     // to request a decode.
     MaybeDecodeForPredictedSize();
   }
   FinishAndStoreOverflow(&aMetrics, aReflowInput.mStyleDisplay);
 
   if ((GetStateBits() & NS_FRAME_FIRST_REFLOW) && !mReflowCallbackPosted) {
-    nsIPresShell* shell = PresContext()->PresShell();
+    nsIPresShell* shell = PresShell();
     mReflowCallbackPosted = true;
     shell->PostReflowCallback(this);
   }
 
   NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
                   ("exit nsImageFrame::Reflow: size=%d,%d",
                   aMetrics.Width(), aMetrics.Height()));
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aMetrics);
@@ -2119,17 +2119,17 @@ nsImageFrame::GetCursor(const nsPoint& a
     nsCOMPtr<nsIContent> area = map->GetArea(p.x, p.y);
     if (area) {
       // Use the cursor from the style of the *area* element.
       // XXX Using the image as the parent style context isn't
       // technically correct, but it's probably the right thing to do
       // here, since it means that areas on which the cursor isn't
       // specified will inherit the style from the image.
       RefPtr<nsStyleContext> areaStyle =
-        PresContext()->PresShell()->StyleSet()->
+        PresShell()->StyleSet()->
           ResolveStyleFor(area->AsElement(), StyleContext(),
                           LazyComputeBehavior::Allow);
       FillCursorInformationFromStyle(areaStyle->StyleUserInterface(),
                                      aCursor);
       if (NS_STYLE_CURSOR_AUTO == aCursor.mCursor) {
         aCursor.mCursor = NS_STYLE_CURSOR_DEFAULT;
       }
       return NS_OK;
@@ -2145,19 +2145,18 @@ nsImageFrame::AttributeChanged(int32_t a
 {
   nsresult rv = nsAtomicContainerFrame::AttributeChanged(aNameSpaceID,
                                                          aAttribute, aModType);
   if (NS_FAILED(rv)) {
     return rv;
   }
   if (nsGkAtoms::alt == aAttribute)
   {
-    PresContext()->PresShell()->FrameNeedsReflow(this,
-                                                 nsIPresShell::eStyleChange,
-                                                 NS_FRAME_IS_DIRTY);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eStyleChange,
+                                  NS_FRAME_IS_DIRTY);
   }
 
   return NS_OK;
 }
 
 void
 nsImageFrame::OnVisibilityChange(Visibility aNewVisibility,
                                  const Maybe<OnNonvisible>& aNonvisibleAction)
--- a/layout/generic/nsPluginFrame.cpp
+++ b/layout/generic/nsPluginFrame.cpp
@@ -190,17 +190,17 @@ nsPluginFrame::Init(nsIContent*       aC
   nsFrame::Init(aContent, aParent, aPrevInFlow);
   CreateView();
 }
 
 void
 nsPluginFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
 {
   if (mReflowCallbackPosted) {
-    PresContext()->PresShell()->CancelReflowCallback(this);
+    PresShell()->CancelReflowCallback(this);
   }
 
   // Ensure our DidComposite observer is gone.
   mDidCompositeObserver = nullptr;
 
   // Tell content owner of the instance to disconnect its frame.
   nsCOMPtr<nsIObjectLoadingContent> objContent(do_QueryInterface(mContent));
   NS_ASSERTION(objContent, "Why not an object loading content?");
@@ -354,17 +354,17 @@ nsPluginFrame::PrepForDrawing(nsIWidget 
 
   if (!IsHidden()) {
     viewMan->SetViewVisibility(view, nsViewVisibility_kShow);
   }
 
 #ifdef ACCESSIBILITY
   nsAccessibilityService* accService = nsIPresShell::AccService();
   if (accService) {
-    accService->RecreateAccessible(PresContext()->PresShell(), mContent);
+    accService->RecreateAccessible(PresShell(), mContent);
   }
 #endif
 
   return NS_OK;
 }
 
 #define EMBED_DEF_WIDTH 240
 #define EMBED_DEF_HEIGHT 200
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -216,33 +216,33 @@ nsSubDocumentFrame::GetSubdocumentPresSh
   nsView* subdocView = mInnerView->GetFirstChild();
   if (!subdocView)
     return nullptr;
 
   nsIPresShell* presShell = nullptr;
 
   nsIFrame* subdocRootFrame = subdocView->GetFrame();
   if (subdocRootFrame) {
-    presShell = subdocRootFrame->PresContext()->PresShell();
+    presShell = subdocRootFrame->PresShell();
   }
 
   // If painting is suppressed in the presshell, we try to look for a better
   // presshell to use.
   if (!presShell || (presShell->IsPaintingSuppressed() &&
                      !(aFlags & IGNORE_PAINT_SUPPRESSION))) {
     // During page transition mInnerView will sometimes have two children, the
     // first being the new page that may not have any frame, and the second
     // being the old page that will probably have a frame.
     nsView* nextView = subdocView->GetNextSibling();
     nsIFrame* frame = nullptr;
     if (nextView) {
       frame = nextView->GetFrame();
     }
     if (frame) {
-      nsIPresShell* ps = frame->PresContext()->PresShell();
+      nsIPresShell* ps = frame->PresShell();
       if (!presShell || (ps && !ps->IsPaintingSuppressed() && sShowPreviousPage)) {
         subdocView = nextView;
         subdocRootFrame = frame;
         presShell = ps;
       }
     }
     if (!presShell) {
       // If we don't have a frame we use this roundabout way to get the pres shell.
@@ -842,17 +842,17 @@ nsSubDocumentFrame::Reflow(nsPresContext
     if (subdocRootFrame) {
       aDesiredSize.mOverflowAreas.UnionWith(subdocRootFrame->GetOverflowAreas() + offset);
     }
   }
 
   FinishAndStoreOverflow(&aDesiredSize);
 
   if (!aPresContext->IsPaginated() && !mPostedReflowCallback) {
-    PresContext()->PresShell()->PostReflowCallback(this);
+    PresShell()->PostReflowCallback(this);
     mPostedReflowCallback = true;
   }
 
   NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS,
      ("exit nsSubDocumentFrame::Reflow: size=%d,%d status=%s",
       aDesiredSize.Width(), aDesiredSize.Height(), ToString(aStatus).c_str()));
 
   NS_FRAME_SET_TRUNCATION(aStatus, aReflowInput, aDesiredSize);
@@ -906,17 +906,17 @@ nsSubDocumentFrame::AttributeChanged(int
           framesetFrame->RecalculateBorderResize();
         }
       }
     }
   }
   else if (aAttribute == nsGkAtoms::showresizer) {
     nsIFrame* rootFrame = GetSubdocumentRootFrame();
     if (rootFrame) {
-      rootFrame->PresContext()->PresShell()->
+      rootFrame->PresShell()->
         FrameNeedsReflow(rootFrame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
     }
   }
   else if (aAttribute == nsGkAtoms::marginwidth ||
            aAttribute == nsGkAtoms::marginheight) {
 
     // Retrieve the attributes
     CSSIntSize margins = GetMarginAttributes();
@@ -995,17 +995,17 @@ private:
 
 static nsView*
 BeginSwapDocShellsForViews(nsView* aSibling);
 
 void
 nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
 {
   if (mPostedReflowCallback) {
-    PresContext()->PresShell()->CancelReflowCallback(this);
+    PresShell()->CancelReflowCallback(this);
     mPostedReflowCallback = false;
   }
 
   // Detach the subdocument's views and stash them in the frame loader.
   // We can then reattach them if we're being reframed (for example if
   // the frame has been made position:fixed).
   RefPtr<nsFrameLoader> frameloader = FrameLoader();
   if (frameloader) {
@@ -1016,17 +1016,17 @@ nsSubDocumentFrame::DestroyFrom(nsIFrame
       frameloader->SetDetachedSubdocFrame(
         detachedViews->GetFrame(), mContent->OwnerDoc());
 
       // We call nsFrameLoader::HideViewer() in a script runner so that we can
       // safely determine whether the frame is being reframed or destroyed.
       nsContentUtils::AddScriptRunner(
         new nsHideViewer(mContent,
                          frameloader,
-                         PresContext()->PresShell(),
+                         PresShell(),
                          (mDidCreateDoc || mCallingShow)));
     } else {
       frameloader->SetDetachedSubdocFrame(nullptr, nullptr);
       if (mDidCreateDoc || mCallingShow) {
         frameloader->Hide();
       }
     }
   }
@@ -1249,22 +1249,22 @@ nsSubDocumentFrame::EndSwapDocShells(nsI
     ::EndSwapDocShellsForViews(other->mInnerView->GetFirstChild());
   }
 
   // Now make sure we reflow both frames, in case their contents
   // determine their size.
   // And repaint them, for good measure, in case there's nothing
   // interesting that happens during reflow.
   if (weakThis.IsAlive()) {
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
     InvalidateFrameSubtree();
   }
   if (weakOther.IsAlive()) {
-    other->PresContext()->PresShell()->
+    other->PresShell()->
       FrameNeedsReflow(other, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
     other->InvalidateFrameSubtree();
   }
 }
 
 nsView*
 nsSubDocumentFrame::EnsureInnerView()
 {
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -676,17 +676,17 @@ UnhookTextRunFromFrames(gfxTextRun* aTex
   }
 }
 
 static void
 InvalidateFrameDueToGlyphsChanged(nsIFrame* aFrame)
 {
   MOZ_ASSERT(aFrame);
 
-  nsIPresShell* shell = aFrame->PresContext()->PresShell();
+  nsIPresShell* shell = aFrame->PresShell();
   for (nsIFrame* f = aFrame; f;
        f = nsLayoutUtils::GetNextContinuationOrIBSplitSibling(f)) {
     f->InvalidateFrame();
 
     // If this is a non-display text frame within SVG <text>, we need
     // to reflow the SVGTextFrame. (This is similar to reflowing the
     // SVGTextFrame in response to style changes, in
     // SVGTextFrame::DidSetStyleContext.)
@@ -2031,17 +2031,17 @@ GetFontGroupForFrame(const nsIFrame* aFr
 #if defined(_MSC_VER) && defined(_M_IX86)
 #pragma optimize("", on)
 #endif
 
 static already_AddRefed<DrawTarget>
 CreateReferenceDrawTarget(const nsTextFrame* aTextFrame)
 {
   RefPtr<gfxContext> ctx =
-    aTextFrame->PresContext()->PresShell()->CreateReferenceRenderingContext();
+    aTextFrame->PresShell()->CreateReferenceRenderingContext();
   RefPtr<DrawTarget> dt = ctx->GetDrawTarget();
   return dt.forget();
 }
 
 static already_AddRefed<gfxTextRun>
 GetHyphenTextRun(const gfxTextRun* aTextRun, DrawTarget* aDrawTarget,
                  nsTextFrame* aTextFrame)
 {
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -357,17 +357,17 @@ nsDisplayRemote::nsDisplayRemote(nsDispl
 {
   if (aBuilder->IsBuildingLayerEventRegions()) {
     bool frameIsPointerEventsNone =
       aFrame->StyleUserInterface()->GetEffectivePointerEvents(aFrame) ==
         NS_STYLE_POINTER_EVENTS_NONE;
     if (aBuilder->IsInsidePointerEventsNoneDoc() || frameIsPointerEventsNone) {
       mEventRegionsOverride |= EventRegionsOverride::ForceEmptyHitRegion;
     }
-    if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(aFrame->PresContext()->PresShell())) {
+    if (nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(aFrame->PresShell())) {
       mEventRegionsOverride |= EventRegionsOverride::ForceDispatchToContent;
     }
   }
 }
 
 already_AddRefed<Layer>
 nsDisplayRemote::BuildLayer(nsDisplayListBuilder* aBuilder,
                             LayerManager* aManager,
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -700,17 +700,17 @@ nsMathMLContainerFrame::ReLayoutChildren
   RebuildAutomaticDataForChildren(frame);
 
   // Ask our parent frame to reflow us
   nsIFrame* parent = frame->GetParent();
   NS_ASSERTION(parent, "No parent to pass the reflow request up to");
   if (!parent)
     return NS_OK;
 
-  frame->PresContext()->PresShell()->
+  frame->PresShell()->
     FrameNeedsReflow(frame, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
 
   return NS_OK;
 }
 
 // There are precise rules governing children of a MathML frame,
 // and properties such as the scriptlevel depends on those rules.
 // Hence for things to work, callers must use Append/Insert/etc wisely.
@@ -765,17 +765,17 @@ nsMathMLContainerFrame::RemoveFrame(Chil
 nsresult
 nsMathMLContainerFrame::AttributeChanged(int32_t         aNameSpaceID,
                                          nsAtom*        aAttribute,
                                          int32_t         aModType)
 {
   // XXX Since they are numerous MathML attributes that affect layout, and
   // we can't check all of them here, play safe by requesting a reflow.
   // XXXldb This should only do work for attributes that cause changes!
-  PresContext()->PresShell()->
+  PresShell()->
     FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
 
   return NS_OK;
 }
 
 void
 nsMathMLContainerFrame::GatherAndStoreOverflow(ReflowOutput* aMetrics)
 {
--- a/layout/mathml/nsMathMLmactionFrame.cpp
+++ b/layout/mathml/nsMathMLmactionFrame.cpp
@@ -221,17 +221,17 @@ nsMathMLmactionFrame::AttributeChanged(i
   } else {
     // let the base class handle other attribute changes
     return
       nsMathMLContainerFrame::AttributeChanged(aNameSpaceID,
                                                aAttribute, aModType);
   }
 
   if (needsReflow) {
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
   }
 
   return NS_OK;
 }
 
 // ################################################################
 // Event handlers
@@ -328,14 +328,14 @@ nsMathMLmactionFrame::MouseClick()
     if (mChildCount > 1) {
       int32_t selection = (mSelection == mChildCount)? 1 : mSelection + 1;
       nsAutoString value;
       value.AppendInt(selection);
       bool notify = false; // don't yet notify the document
       mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::selection_, value, notify);
 
       // Now trigger a content-changed reflow...
-      PresContext()->PresShell()->
+      PresShell()->
         FrameNeedsReflow(mSelectedFrame, nsIPresShell::eTreeChange,
                          NS_FRAME_IS_DIRTY);
     }
   }
 }
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -738,29 +738,29 @@ nsMathMLmtableWrapperFrame::AttributeCha
   NS_ASSERTION(tableFrame && tableFrame->IsTableFrame(),
                "should always have an inner table frame");
   nsIFrame* rgFrame = tableFrame->PrincipalChildList().FirstChild();
   if (!rgFrame || !rgFrame->IsTableRowGroupFrame())
     return NS_OK;
 
   // align - just need to issue a dirty (resize) reflow command
   if (aAttribute == nsGkAtoms::align) {
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
     return NS_OK;
   }
 
   // displaystyle - may seem innocuous, but it is actually very harsh --
   // like changing an unit. Blow away and recompute all our automatic
   // presentational data, and issue a style-changed reflow request
   if (aAttribute == nsGkAtoms::displaystyle_) {
     nsMathMLContainerFrame::RebuildAutomaticDataForChildren(GetParent());
     // Need to reflow the parent, not us, because this can actually
     // affect siblings.
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(GetParent(), nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
     return NS_OK;
   }
 
   // ...and the other attributes affect rows or columns in one way or another
 
   nsPresContext* presContext = tableFrame->PresContext();
   if (aAttribute == nsGkAtoms::rowspacing_ ||
--- a/layout/mathml/nsMathMLmunderoverFrame.cpp
+++ b/layout/mathml/nsMathMLmunderoverFrame.cpp
@@ -72,17 +72,17 @@ nsMathMLmunderoverFrame::InheritAutomati
 
   return NS_OK;
 }
 
 void
 nsMathMLmunderoverFrame::DestroyFrom(nsIFrame* aDestroyRoot, PostDestroyData& aPostDestroyData)
 {
   if (!mPostReflowIncrementScriptLevelCommands.IsEmpty()) {
-    PresContext()->PresShell()->CancelReflowCallback(this);
+    PresShell()->CancelReflowCallback(this);
   }
   nsMathMLContainerFrame::DestroyFrom(aDestroyRoot, aPostDestroyData);
 }
 
 uint8_t
 nsMathMLmunderoverFrame::ScriptIncrement(nsIFrame* aFrame)
 {
   nsIFrame* child = mFrames.FirstChild();
@@ -114,17 +114,17 @@ nsMathMLmunderoverFrame::SetIncrementScr
   }
 
   auto element = static_cast<nsMathMLElement*>(child->GetContent());
   if (element->GetIncrementScriptLevel() == aIncrement) {
     return;
   }
 
   if (mPostReflowIncrementScriptLevelCommands.IsEmpty()) {
-    PresContext()->PresShell()->PostReflowCallback(this);
+    PresShell()->PostReflowCallback(this);
   }
 
   mPostReflowIncrementScriptLevelCommands.AppendElement(
       SetIncrementScriptLevelCommand { aChildIndex, aIncrement });
 }
 
 bool
 nsMathMLmunderoverFrame::ReflowFinished()
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -1455,17 +1455,17 @@ FindElementBackground(nsIFrame* aForFram
   return !htmlBG->IsTransparent(aRootElementFrame);
 }
 
 bool
 nsCSSRendering::FindBackgroundFrame(nsIFrame* aForFrame,
                                     nsIFrame** aBackgroundFrame)
 {
   nsIFrame* rootElementFrame =
-    aForFrame->PresContext()->PresShell()->FrameConstructor()->GetRootElementStyleFrame();
+    aForFrame->PresShell()->FrameConstructor()->GetRootElementStyleFrame();
   if (IsCanvasFrame(aForFrame)) {
     *aBackgroundFrame = FindCanvasBackgroundFrame(aForFrame, rootElementFrame);
     return true;
   } else {
     *aBackgroundFrame = aForFrame;
     return FindElementBackground(aForFrame, rootElementFrame);
   }
 }
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -1120,17 +1120,17 @@ void nsDisplayListBuilder::MarkOutOfFlow
   nsRect visible = GetVisibleRect();
   nsRect dirtyRectRelativeToDirtyFrame = GetDirtyRect();
   if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(aFrame) &&
       IsPaintingToWindow()) {
     NS_ASSERTION(aDirtyFrame == aFrame->GetParent(), "Dirty frame should be viewport frame");
     // position: fixed items are reflowed into and only drawn inside the
     // viewport, or the scroll position clamping scrollport size, if one is
     // set.
-    nsIPresShell* ps = aFrame->PresContext()->PresShell();
+    nsIPresShell* ps = aFrame->PresShell();
     if (ps->IsScrollPositionClampingScrollPortSizeSet()) {
       dirtyRectRelativeToDirtyFrame =
         nsRect(nsPoint(0, 0), ps->GetScrollPositionClampingScrollPortSize());
       visible = dirtyRectRelativeToDirtyFrame;
 #ifdef MOZ_WIDGET_ANDROID
     } else {
       dirtyRectRelativeToDirtyFrame =
         nsRect(nsPoint(0, 0), aDirtyFrame->GetSize());
@@ -1261,17 +1261,17 @@ nsDisplayListBuilder::IncrementPresShell
   }
 }
 
 void
 nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
                                      bool aPointerEventsNoneDoc)
 {
   PresShellState* state = mPresShellStates.AppendElement();
-  state->mPresShell = aReferenceFrame->PresContext()->PresShell();
+  state->mPresShell = aReferenceFrame->PresShell();
   state->mCaretFrame = nullptr;
   state->mFirstFrameMarkedForDisplay = mFramesMarkedForDisplay.Length();
 
   nsIScrollableFrame* sf = state->mPresShell->GetRootScrollFrameAsScrollable();
   if (sf) {
     // We are forcing a rebuild of nsDisplayCanvasBackgroundColor to make sure
     // that the canvas background color will be set correctly, and that only one
     // unscrollable item will be created.
@@ -1344,17 +1344,17 @@ DisplayListIsNonBlank(nsDisplayList* aLi
   }
   return false;
 }
 
 void
 nsDisplayListBuilder::LeavePresShell(nsIFrame* aReferenceFrame, nsDisplayList* aPaintedContents)
 {
   NS_ASSERTION(CurrentPresShellState()->mPresShell ==
-      aReferenceFrame->PresContext()->PresShell(),
+      aReferenceFrame->PresShell(),
       "Presshell mismatch");
 
   if (mIsPaintingToWindow) {
     nsPresContext* pc = aReferenceFrame->PresContext();
     if (!pc->HadNonBlankPaint()) {
       if (!CurrentPresShellState()->mIsBackgroundOnly &&
           DisplayListIsNonBlank(aPaintedContents)) {
         pc->NotifyNonBlankPaint();
@@ -1439,17 +1439,17 @@ nsDisplayListBuilder::MarkFramesForDispl
     MarkOutOfFlowFrameForDisplay(aDirtyFrame, e);
   }
 
   if (!aDirtyFrame->GetParent()) {
     // This is the viewport frame of aDirtyFrame's presshell.
     // Store the current display data so that it can be used for fixed
     // background images.
     NS_ASSERTION(CurrentPresShellState()->mPresShell ==
-        aDirtyFrame->PresContext()->PresShell(),
+        aDirtyFrame->PresShell(),
         "Presshell mismatch");
     MOZ_ASSERT(!CurrentPresShellState()->mFixedBackgroundDisplayData,
                "already traversed this presshell's root frame?");
 
     const DisplayItemClipChain* clipChain =
       CopyWholeChain(mClipState.GetClipChainForContainingBlockDescendants());
     const DisplayItemClipChain* combinedClipChain = mClipState.GetCurrentCombinedClipChain(this);
     const ActiveScrolledRoot* asr = mCurrentActiveScrolledRoot;
@@ -3269,17 +3269,17 @@ RegisterThemeGeometry(nsDisplayListBuild
 }
 
 // Return the bounds of the viewport relative to |aFrame|'s reference frame.
 // Returns Nothing() if transforming into |aFrame|'s coordinate space fails.
 static Maybe<nsRect>
 GetViewportRectRelativeToReferenceFrame(nsDisplayListBuilder* aBuilder,
                                         nsIFrame* aFrame)
 {
-  nsIFrame* rootFrame = aFrame->PresContext()->PresShell()->GetRootFrame();
+  nsIFrame* rootFrame = aFrame->PresShell()->GetRootFrame();
   nsRect rootRect = rootFrame->GetRectRelativeToSelf();
   if (nsLayoutUtils::TransformRect(rootFrame, aFrame, rootRect) == nsLayoutUtils::TRANSFORM_SUCCEEDED) {
     return Some(rootRect + aBuilder->ToReferenceFrame(aFrame));
   }
   return Nothing();
 }
 
 /* static */ nsDisplayBackgroundImage::InitData
@@ -6858,17 +6858,17 @@ nsDisplaySubDocument::nsDisplaySubDocume
     : nsDisplayOwnLayer(aBuilder, aFrame, aList, aBuilder->CurrentActiveScrolledRoot(), aFlags)
     , mScrollParentId(aBuilder->GetCurrentScrollParentId())
     , mShouldFlatten(false)
     , mSubDocFrame(aSubDocFrame)
 {
   MOZ_COUNT_CTOR(nsDisplaySubDocument);
   mForceDispatchToContentRegion =
     aBuilder->IsBuildingLayerEventRegions() &&
-    nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(aFrame->PresContext()->PresShell());
+    nsLayoutUtils::HasDocumentLevelListenersForApzAwareEvents(aFrame->PresShell());
 
   // The SubDocument display item is conceptually outside the viewport frame,
   // so in cases where the viewport frame is an AGR, the SubDocument's AGR
   // should be not the viewport frame itself, but its parent AGR.
   if (*mAnimatedGeometryRoot == mFrame && mAnimatedGeometryRoot->mParentAGR) {
     mAnimatedGeometryRoot = mAnimatedGeometryRoot->mParentAGR;
   }
 }
@@ -6945,17 +6945,17 @@ nsDisplaySubDocument::ComputeVisibility(
 {
   bool usingDisplayPort = UseDisplayPortForViewport(aBuilder, mFrame);
 
   if (!(mFlags & GENERATE_SCROLLABLE_LAYER) || !usingDisplayPort) {
     return nsDisplayWrapList::ComputeVisibility(aBuilder, aVisibleRegion);
   }
 
   nsRect displayport;
-  nsIFrame* rootScrollFrame = mFrame->PresContext()->PresShell()->GetRootScrollFrame();
+  nsIFrame* rootScrollFrame = mFrame->PresShell()->GetRootScrollFrame();
   MOZ_ASSERT(rootScrollFrame);
   Unused << nsLayoutUtils::GetDisplayPort(rootScrollFrame->GetContent(), &displayport,
     RelativeTo::ScrollFrame);
 
   nsRegion childVisibleRegion;
   // The visible region for the children may be much bigger than the hole we
   // are viewing the children from, so that the compositor process has enough
   // content to asynchronously pan while content is being refreshed.
@@ -7022,26 +7022,26 @@ nsDisplayResolution::~nsDisplayResolutio
 #endif
 
 void
 nsDisplayResolution::HitTest(nsDisplayListBuilder* aBuilder,
                              const nsRect& aRect,
                              HitTestState* aState,
                              nsTArray<nsIFrame*> *aOutFrames)
 {
-  nsIPresShell* presShell = mFrame->PresContext()->PresShell();
+  nsIPresShell* presShell = mFrame->PresShell();
   nsRect rect = aRect.RemoveResolution(presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f);
   mList.HitTest(aBuilder, rect, aState, aOutFrames);
 }
 
 already_AddRefed<Layer>
 nsDisplayResolution::BuildLayer(nsDisplayListBuilder* aBuilder,
                                 LayerManager* aManager,
                                 const ContainerLayerParameters& aContainerParameters) {
-  nsIPresShell* presShell = mFrame->PresContext()->PresShell();
+  nsIPresShell* presShell = mFrame->PresShell();
   ContainerLayerParameters containerParameters(
     presShell->GetResolution(), presShell->GetResolution(), nsIntPoint(),
     aContainerParameters);
 
   RefPtr<Layer> layer = nsDisplaySubDocument::BuildLayer(
     aBuilder, aManager, containerParameters);
   layer->SetPostScale(1.0f / presShell->GetResolution(),
                       1.0f / presShell->GetResolution());
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3305,40 +3305,40 @@ public:
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayReflowCount() {
     MOZ_COUNT_DTOR(nsDisplayReflowCount);
   }
 #endif
 
   virtual void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override {
-    mFrame->PresContext()->PresShell()->PaintCount(mFrameName, aCtx,
-                                                   mFrame->PresContext(),
-                                                   mFrame, ToReferenceFrame(),
-                                                   mColor);
+    mFrame->PresShell()->PaintCount(mFrameName, aCtx,
+                                    mFrame->PresContext(),
+                                    mFrame, ToReferenceFrame(),
+                                    mColor);
   }
   NS_DISPLAY_DECL_NAME("nsDisplayReflowCount", TYPE_REFLOW_COUNT)
 protected:
   const char* mFrameName;
   nscolor mColor;
 };
 
 #define DO_GLOBAL_REFLOW_COUNT_DSP(_name)                                     \
   PR_BEGIN_MACRO                                                              \
     if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
-        PresContext()->PresShell()->IsPaintingFrameCounts()) {                \
+        PresShell()->IsPaintingFrameCounts()) {                               \
         aLists.Outlines()->AppendNewToTop(                                    \
             new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name));      \
     }                                                                         \
   PR_END_MACRO
 
 #define DO_GLOBAL_REFLOW_COUNT_DSP_COLOR(_name, _color)                       \
   PR_BEGIN_MACRO                                                              \
     if (!aBuilder->IsBackgroundOnly() && !aBuilder->IsForEventDelivery() &&   \
-        PresContext()->PresShell()->IsPaintingFrameCounts()) {                \
+        PresShell()->IsPaintingFrameCounts()) {                               \
         aLists.Outlines()->AppendNewToTop(                                    \
              new (aBuilder) nsDisplayReflowCount(aBuilder, this, _name, _color)); \
     }                                                                         \
   PR_END_MACRO
 
 /*
   Macro to be used for classes that don't actually implement BuildDisplayList
  */
--- a/layout/reftests/async-scrolling/reftest.list
+++ b/layout/reftests/async-scrolling/reftest.list
@@ -1,16 +1,16 @@
 skip-if(!asyncPan) == bg-fixed-1.html bg-fixed-1-ref.html
 skip-if(!asyncPan) == bg-fixed-cover-1.html bg-fixed-cover-1-ref.html
 skip-if(!asyncPan) == bg-fixed-cover-2.html bg-fixed-cover-2-ref.html
 skip-if(!asyncPan) == bg-fixed-cover-3.html bg-fixed-cover-3-ref.html
 skip-if(!asyncPan) == bg-fixed-child.html bg-fixed-child-ref.html
 skip-if(!asyncPan) == bg-fixed-child-clip-1.html bg-fixed-child-clip-ref.html
 skip-if(!asyncPan) == bg-fixed-child-clip-2.html bg-fixed-child-clip-ref.html
-fuzzy(1,246) fuzzy-if(skiaContent,2,170) fuzzy-if(browserIsRemote&&d2d,53,185) skip-if(!asyncPan) == bg-fixed-child-mask.html bg-fixed-child-mask-ref.html
+fuzzy(1,246) fuzzy-if(skiaContent,2,170) fuzzy-if(browserIsRemote&&d2d,53,187) skip-if(!asyncPan) == bg-fixed-child-mask.html bg-fixed-child-mask-ref.html
 skip-if(!asyncPan) == bg-fixed-in-opacity.html bg-fixed-in-opacity-ref.html
 skip-if(!asyncPan) == bg-fixed-child-no-culling-1.html bg-fixed-child-no-culling-1-ref.html
 skip-if(!asyncPan) == bg-fixed-child-no-culling-2.html bg-fixed-child-no-culling-2-ref.html
 skip-if(!asyncPan) == bg-fixed-child-no-culling-3.html bg-fixed-child-no-culling-3-ref.html
 fuzzy-if(Android,2,4000) fuzzy-if(browserIsRemote&&cocoaWidget,2,179524) fuzzy-if(browserIsRemote&&winWidget,1,74590) fuzzy-if(gtkWidget&&layersGPUAccelerated,1,3528) skip-if(!asyncPan) == bg-fixed-transformed-image.html bg-fixed-transformed-image-ref.html
 skip-if(!asyncPan) == element-1.html element-1-ref.html
 pref(layers.force-active,true) skip-if(!asyncPan) == iframe-1.html iframe-1-ref.html
 skip-if(!asyncPan) == nested-1.html nested-1-ref.html
--- a/layout/reftests/border-radius/reftest.list
+++ b/layout/reftests/border-radius/reftest.list
@@ -38,32 +38,32 @@ fuzzy-if(skiaContent,12,83) fuzzy-if(web
 # Tests for border clipping
 fails == clipping-1.html clipping-1-ref.html # background color should completely fill box; bug 466572
 != clipping-2.html about:blank # background color clipped to inner/outer border, can't get
 # great tests for this due to antialiasing problems described in bug 466572
 fuzzy-if(skiaContent,17,62) fuzzy-if(webrender,41-41,66-66) == clipping-3.html clipping-3-ref.xhtml # edge of border-radius clips an underlying object's background
 
 # Tests for clipping the contents of replaced elements and overflow!=visible
 != clipping-4-ref.html clipping-4-notref.html
-fuzzy-if(true,1,20) fuzzy-if(d2d,64,196) fuzzy-if(cocoaWidget,1,180) fuzzy-if(Android,140,237) == clipping-4-canvas.html clipping-4-ref.html # bug 732535
+fuzzy-if(true,1,20) fuzzy-if(d2d,72,196) fuzzy-if(cocoaWidget,1,180) fuzzy-if(Android,140,237) == clipping-4-canvas.html clipping-4-ref.html # bug 732535
 fuzzy-if(Android,5,54) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,10) fuzzy-if(skiaContent,1,172) == clipping-4-image.html clipping-4-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,10) fuzzy-if(skiaContent,1,77) == clipping-4-overflow-hidden.html clipping-4-ref.html
 == clipping-5-canvas.html clipping-5-refc.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) == clipping-5-image.html clipping-5-refi.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(skiaContent,1,77) == clipping-5-overflow-hidden.html clipping-5-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,5,21) fuzzy-if(skiaContent,1,97) == clipping-5-refi.html clipping-5-ref.html
-fuzzy-if(true,1,7) fuzzy-if(d2d,48,94) fuzzy-if(cocoaWidget,1,99) fuzzy-if(Android,99,115) fuzzy-if(skiaContent,1,77) == clipping-5-refc.html clipping-5-ref.html # bug 732535
+fuzzy-if(true,1,7) fuzzy-if(d2d,55,94) fuzzy-if(cocoaWidget,1,99) fuzzy-if(Android,99,115) fuzzy-if(skiaContent,1,77) == clipping-5-refc.html clipping-5-ref.html # bug 732535
 fuzzy-if(winWidget,105,71) fuzzy-if(Android,8,469) fuzzy-if(skiaContent,7,58) fuzzy-if(d3d11&&advancedLayers,120,319) fuzzy-if(winWidget&&stylo,137,319) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical
 fuzzy-if(true,2,29) fuzzy-if(d2d,46,71) fuzzy-if(Android,255,586) fuzzy-if(skiaContent,28,96) == clipping-7.html clipping-7-ref.html # ColorLayer and MaskLayer with transforms that aren't identical. Reference image rendered without using layers (which causes fuzzy failures).
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) == clipping-and-zindex-1.html clipping-and-zindex-1-ref.html
-fuzzy-if(cocoaWidget,1,4) fuzzy-if(d3d11&&advancedLayers,30,3) == intersecting-clipping-1-canvas.html intersecting-clipping-1-refc.html
+fuzzy-if(cocoaWidget,1,4) fuzzy-if(d2d,59,342) fuzzy-if(d3d11&&advancedLayers&&!d2d,30,3) == intersecting-clipping-1-canvas.html intersecting-clipping-1-refc.html
 == intersecting-clipping-1-image.html intersecting-clipping-1-refi.html
 == intersecting-clipping-1-overflow-hidden.html intersecting-clipping-1-ref.html
 fuzzy-if(Android,5,105) fuzzy-if(d2d,1,20) fuzzy-if(skiaContent,1,300) == intersecting-clipping-1-refi.html intersecting-clipping-1-ref.html
-fuzzy-if(true,1,33) fuzzy-if(d2d,48,350) fuzzy-if(cocoaWidget,1,332) fuzzy-if(Android,124,440) fuzzy-if(skiaContent,1,135) fuzzy-if(d3d11&&advancedLayers,48,353) == intersecting-clipping-1-refc.html intersecting-clipping-1-ref.html # bug 732535
+fuzzy-if(true,1,33) fuzzy-if(d2d,59,350) fuzzy-if(cocoaWidget,1,332) fuzzy-if(Android,124,440) fuzzy-if(skiaContent,1,135) fuzzy-if(d3d11&&advancedLayers,59,353) == intersecting-clipping-1-refc.html intersecting-clipping-1-ref.html # bug 732535
 
 # Inheritance
 == inherit-1.html inherit-1-ref.html # border-radius shouldn't inherit
 
 # Table elements
 == table-collapse-1.html table-collapse-1-ref.html # border-radius is ignored on internal table elements
 # when border-collapse: collapse
 
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1709,17 +1709,17 @@ needs-focus != 703186-1.html 703186-2.ht
 == 711359-1.html 711359-1-ref.html
 == 712849-1.html 712849-1-ref.html
 == 713856-static.html  713856-ref.html
 == 713856-dynamic.html 713856-ref.html
 == 714519-1-as.html 714519-1-ref.html
 == 714519-1-q.html 714519-1-ref.html
 == 714519-2-as.html 714519-2-ref.html
 == 714519-2-q.html 714519-2-ref.html
-fuzzy-if(true,1,21) fuzzy-if(d2d,69,173) fuzzy-if(cocoaWidget,1,170) == 718521.html 718521-ref.html # bug 773482
+fuzzy-if(true,1,21) fuzzy-if(d2d,71,173) fuzzy-if(cocoaWidget,1,170) == 718521.html 718521-ref.html # bug 773482
 == 720987.html 720987-ref.html
 == 722888-1.html 722888-1-ref.html
 fuzzy(2,40000) == 722923-1.html 722923-1-ref.html
 == 723484-1.html 723484-1-ref.html
 random-if(Android) == 728983-1.html 728983-1-ref.html
 == 729143-1.html 729143-1-ref.html
 == 731521-1.html 731521-1-ref.html
 needs-focus == 731726-1.html 731726-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-align-dynamic-pos-001-ref.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>Reference: dynamic change .left on abs.pos. item w. align-self:center</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.grid {
+  display: inline-grid;
+  position: relative;
+  background: lightgrey;
+  grid: 50px 50px / 50px 50px;
+}
+
+#item {
+  background: grey;
+  position: absolute;
+  align-self: center;
+  left: 20px;
+}
+
+  </style>
+</head>
+<body>
+
+<div class="grid">
+  <div id="item">X</div>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-align-dynamic-pos-001.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>CSS Grid Test: dynamic change .left on abs.pos. item w. align-self:center</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-self">
+  <link rel="match" href="grid-item-align-dynamic-pos-001-ref.html">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.grid {
+  display: inline-grid;
+  position: relative;
+  background: lightgrey;
+  grid: 50px 50px / 50px 50px;
+}
+
+#item {
+  background: grey;
+  position: absolute;
+  align-self: center;
+  left: 10px;
+}
+
+  </style>
+</head>
+<body>
+
+<div class="grid">
+  <div id="item">X</div>
+</div>
+
+<script>
+  document.body.offsetLeft;
+  var items = Array.prototype.slice.call(document.querySelectorAll('#item'));
+  items.map(item =>  item.style.left = "20px");
+  document.body.offsetLeft;
+</script>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-align-dynamic-pos-002-ref.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>Reference: dynamic change .left on abs.pos. item w. align-self:end</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.grid {
+  display: inline-grid;
+  position: relative;
+  background: lightgrey;
+  grid: 50px 50px / 50px 50px;
+}
+
+#item {
+  background: grey;
+  position: absolute;
+  align-self: end;
+  left: 20px;
+}
+
+  </style>
+</head>
+<body>
+
+<div class="grid">
+  <div id="item">X</div>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-align-dynamic-pos-002.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>CSS Grid Test: dynamic change .left on abs.pos. item w. align-self:end</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-self">
+  <link rel="match" href="grid-item-align-dynamic-pos-002-ref.html">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.grid {
+  display: inline-grid;
+  background: lightgrey;
+  grid: 50px 50px / 50px 50px;
+}
+
+#item {
+  background: grey;
+  position: absolute;
+  align-self: end;
+  left: 10px;
+}
+
+  </style>
+</head>
+<body>
+
+<div class="grid">
+  <div id="item">X</div>
+</div>
+
+<script>
+  document.body.offsetLeft;
+  var items = Array.prototype.slice.call(document.querySelectorAll('#item'));
+  items.map(item =>  item.style.left = "20px");
+  document.body.offsetLeft;
+</script>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-align-dynamic-pos-003-ref.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>Reference: dynamic change .left on abs.pos. item w. align-self:start</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.grid {
+  display: inline-grid;
+  position: relative;
+  background: lightgrey;
+  grid: 50px 50px / 50px 50px;
+}
+
+#item {
+  background: grey;
+  position: absolute;
+  align-self: start;
+  left: 20px;
+}
+
+  </style>
+</head>
+<body>
+
+<div class="grid">
+  <div style="align-self: start; font-size:32pt">X</div>
+  <div id="item" style="grid-area:2/2">X</div>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-grid/grid-item-align-dynamic-pos-003.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>CSS Grid Test: dynamic change .left on abs.pos. item w. align-self:start</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-self">
+  <link rel="match" href="grid-item-align-dynamic-pos-003-ref.html">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.grid {
+  display: inline-grid;
+  position: relative;
+  background: lightgrey;
+  grid: 50px 50px / 50px 50px;
+}
+
+#item {
+  background: grey;
+  position: absolute;
+  align-self: start;
+  left: 10px;
+}
+
+  </style>
+</head>
+<body>
+
+<div class="grid">
+  <div style="align-self: start; font-size:32pt">X</div>
+  <div id="item" style="grid-area:2/2">X</div>
+</div>
+
+<script>
+  document.body.offsetLeft;
+  var items = Array.prototype.slice.call(document.querySelectorAll('#item'));
+  items.map(item =>  item.style.left = "20px");
+  document.body.offsetLeft;
+</script>
+
+</body>
+</html>
--- a/layout/reftests/css-grid/reftest.list
+++ b/layout/reftests/css-grid/reftest.list
@@ -273,10 +273,14 @@ asserts(0-10) == grid-fragmentation-015.
 == grid-fragmentation-dyn2-028.html grid-fragmentation-028-ref.html
 == grid-fragmentation-dyn3-028.html grid-fragmentation-028-ref.html
 == grid-fragmentation-dyn4-028.html grid-fragmentation-028-ref.html
 == grid-fragmentation-dyn5-028.html grid-fragmentation-028-ref.html
 == grid-fragmentation-dyn1-029.html grid-fragmentation-029-ref.html
 == grid-fragmentation-dyn2-029.html grid-fragmentation-029-ref.html
 == grid-fragmentation-dyn2-030.html grid-fragmentation-030-ref.html
 == grid-fragmentation-dyn2-031.html grid-fragmentation-031-ref.html
+
 == bug1306106.html bug1306106-ref.html
 == grid-percent-intrinsic-sizing-001.html grid-percent-intrinsic-sizing-001-ref.html
+== grid-item-align-dynamic-pos-001.html grid-item-align-dynamic-pos-001-ref.html
+== grid-item-align-dynamic-pos-002.html grid-item-align-dynamic-pos-002-ref.html
+== grid-item-align-dynamic-pos-003.html grid-item-align-dynamic-pos-003-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-item-align-self-dynamic-pos-001-ref.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>Reference: dynamic change .left on abs.pos. item w. align-self:center</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.flexbox {
+  display: flex;
+  position: relative;
+  height: 100px;
+}
+
+#item {
+  background: grey;
+  position: relative;
+  align-self: center;
+  left: 20px;
+}
+
+</style>
+</head>
+<body>
+
+<div class="flexbox">
+  <div id="item">X</div>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-item-align-self-dynamic-pos-001.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>CSS Flexbox Test: dynamic change .left on abs.pos. item w. align-self:center</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-self">
+  <link rel="match" href="flexbox-item-align-self-dynamic-pos-001-ref.html">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.flexbox {
+  display: flex;
+  position: relative;
+  height: 100px;
+}
+
+#item {
+  background: grey;
+  position: absolute;
+  align-self: center;
+  left: 10px;
+}
+
+</style>
+</head>
+<body>
+
+<div class="flexbox">
+  <div id="item">X</div>
+</div>
+
+<script>
+  document.body.offsetLeft;
+  var items = Array.prototype.slice.call(document.querySelectorAll('#item'));
+  items.map(item =>  item.style.left = "20px");
+  document.body.offsetLeft;
+</script>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-item-align-self-dynamic-pos-002-ref.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>Reference: dynamic change .left on abs.pos. item w. align-self:end</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.flexbox {
+  display: flex;
+  position: relative;
+  height: 100px;
+}
+
+#item {
+  background: grey;
+  position: relative;
+  align-self: end;
+  left: 20px;
+}
+
+</style>
+</head>
+<body>
+
+<div class="flexbox">
+  <div id="item">X</div>
+</div>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/flexbox/flexbox-item-align-self-dynamic-pos-002.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+  <title>CSS Flexbox Test: dynamic change .left on abs.pos. item w. align-self:end</title>
+  <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1405319">
+  <link rel="help" href="https://drafts.csswg.org/css-align-3/#propdef-align-self">
+  <link rel="match" href="flexbox-item-align-self-dynamic-pos-002-ref.html">
+  <style type="text/css">
+html,body {
+  color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+.flexbox {
+  display: flex;
+  height: 100px;
+}
+
+#item {
+  background: grey;
+  position: absolute;
+  align-self: end;
+  left: 10px;
+}
+
+</style>
+</head>
+<body>
+
+<div class="flexbox">
+  <div id="item">X</div>
+</div>
+
+<script>
+  document.body.offsetLeft;
+  var items = Array.prototype.slice.call(document.querySelectorAll('#item'));
+  items.map(item =>  item.style.left = "20px");
+  document.body.offsetLeft;
+</script>
+
+</body>
+</html>
--- a/layout/reftests/flexbox/reftest.list
+++ b/layout/reftests/flexbox/reftest.list
@@ -14,16 +14,18 @@ include pagination/reftest.list
 
 # Tests for cross-axis alignment (align-self / align-items properties)
 fails == flexbox-align-self-baseline-horiz-2.xhtml  flexbox-align-self-baseline-horiz-2-ref.xhtml # bug 793456, and possibly others
 # This one fails on windows R (but not Ru, strangely) and GTK.
 # On Windows R and GTK, the single-line <label> flex item has a different
 # background size in test vs. ref
 fuzzy-if(cocoaWidget,1,2) random-if(winWidget||gtkWidget) skip-if(Android) == flexbox-align-self-baseline-horiz-3.xhtml  flexbox-align-self-baseline-horiz-3-ref.xhtml # XXXdholbert investigate the random-if. The skip-if(Android) is because checkbox/radio appearance:none doesn't work as expected.
 == flexbox-align-self-baseline-horiz-4.xhtml flexbox-align-self-baseline-horiz-4-ref.xhtml
+== flexbox-item-align-self-dynamic-pos-001.html flexbox-item-align-self-dynamic-pos-001-ref.html
+== flexbox-item-align-self-dynamic-pos-002.html flexbox-item-align-self-dynamic-pos-002-ref.html
 
 # Tests for box-sizing on flex containers and flex items.
 == flexbox-box-sizing-on-container-horiz-1.html flexbox-box-sizing-on-container-horiz-1-ref.html
 == flexbox-box-sizing-on-container-vert-1.html flexbox-box-sizing-on-container-vert-1-ref.html
 == flexbox-box-sizing-on-items-horiz-1a.html flexbox-box-sizing-on-items-horiz-1-ref.html
 == flexbox-box-sizing-on-items-horiz-1b.html flexbox-box-sizing-on-items-horiz-1-ref.html
 == flexbox-box-sizing-on-items-vert-1a.html flexbox-box-sizing-on-items-vert-1-ref.html
 == flexbox-box-sizing-on-items-vert-1b.html flexbox-box-sizing-on-items-vert-1-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/style/crashtests/1415663.html
@@ -0,0 +1,13 @@
+<html>
+  <head>
+    <script>
+      function boom() {
+        document.getElementById('x').createShadowRoot()
+      }
+    </script>
+  </head>
+  <body onload=boom()>
+    <marquee id='x'>
+      <table id='x'>
+  </body>
+</html>
\ No newline at end of file
--- a/layout/style/crashtests/crashtests.list
+++ b/layout/style/crashtests/crashtests.list
@@ -255,9 +255,10 @@ load 1404057.html
 load 1409502.html
 load 1409931.html
 load 1410226-1.html
 load 1410226-2.html
 load 1411143.html
 load 1411478.html
 load 1413288.html
 load 1413361.html
+load 1415663.html
 pref(dom.webcomponents.enabled,true) load 1415353.html
--- a/layout/style/nsFontFaceUtils.cpp
+++ b/layout/style/nsFontFaceUtils.cpp
@@ -105,17 +105,17 @@ ScheduleReflow(nsIPresShell* aShell, nsI
 
 /* static */ void
 nsFontFaceUtils::MarkDirtyForFontChange(nsIFrame* aSubtreeRoot,
                                         const gfxUserFontEntry* aFont)
 {
   AutoTArray<nsIFrame*, 4> subtrees;
   subtrees.AppendElement(aSubtreeRoot);
 
-  nsIPresShell* ps = aSubtreeRoot->PresContext()->PresShell();
+  nsIPresShell* ps = aSubtreeRoot->PresShell();
 
   // check descendants, iterating over subtrees that may include
   // additional subtrees associated with placeholders
   do {
     nsIFrame* subtreeRoot = subtrees.ElementAt(subtrees.Length() - 1);
     subtrees.RemoveElementAt(subtrees.Length() - 1);
 
     // Check all descendants to see if they use the font
--- a/layout/svg/SVGObserverUtils.h
+++ b/layout/svg/SVGObserverUtils.h
@@ -172,17 +172,17 @@ protected:
 
   ElementTracker mObservedElementTracker;
 };
 
 struct nsSVGFrameReferenceFromProperty
 {
   explicit nsSVGFrameReferenceFromProperty(nsIFrame* aFrame)
     : mFrame(aFrame)
-    , mFramePresShell(aFrame->PresContext()->PresShell())
+    , mFramePresShell(aFrame->PresShell())
   {}
 
   // Clear our reference to the frame.
   void Detach();
 
   // null if the frame has become invalid
   nsIFrame* Get();
 
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -3326,17 +3326,17 @@ SVGTextFrame::ScheduleReflowSVGNonDispla
       }
       f->AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
     }
     f = f->GetParent();
   }
 
   MOZ_ASSERT(f, "should have found an ancestor frame to reflow");
 
-  PresContext()->PresShell()->FrameNeedsReflow(f, aReason, NS_FRAME_IS_DIRTY);
+  PresShell()->FrameNeedsReflow(f, aReason, NS_FRAME_IS_DIRTY);
 }
 
 NS_IMPL_ISUPPORTS(SVGTextFrame::MutationObserver, nsIMutationObserver)
 
 void
 SVGTextFrame::MutationObserver::ContentAppended(nsIDocument* aDocument,
                                                 nsIContent* aContainer,
                                                 nsIContent* aFirstNewContent)
@@ -4208,17 +4208,17 @@ SVGTextFrame::GetSubStringLengthSlowFall
                                              float* aResult)
 {
   // We need to make sure that we've been reflowed before updating the glyph
   // positioning.
   // XXX perf: It may be possible to limit reflow to just calling ReflowSVG,
   // but we would still need to resort to full reflow for percentage
   // positioning attributes.  For now we just do a full reflow regardless since
   // the cases that would cause us to be called are relatively uncommon.
-  PresContext()->PresShell()->FlushPendingNotifications(FlushType::Layout);
+  PresShell()->FlushPendingNotifications(FlushType::Layout);
 
   UpdateGlyphPositioning();
 
   // Convert charnum/nchars from addressable characters relative to
   // aContent to global character indices.
   CharIterator chit(this, CharIterator::eAddressable, aContent);
   if (!chit.AdvanceToSubtree() ||
       !chit.Next(charnum) ||
--- a/layout/svg/nsSVGForeignObjectFrame.cpp
+++ b/layout/svg/nsSVGForeignObjectFrame.cpp
@@ -435,17 +435,17 @@ nsSVGForeignObjectFrame::NotifySVGChange
 
   // If we're called while the PresShell is handling reflow events then we
   // must have been called as a result of the NotifyViewportChange() call in
   // our nsSVGOuterSVGFrame's Reflow() method. We must not call RequestReflow
   // at this point (i.e. during reflow) because it could confuse the
   // PresShell and prevent it from reflowing us properly in future. Besides
   // that, nsSVGOuterSVGFrame::DidReflow will take care of reflowing us
   // synchronously, so there's no need.
-  if (needReflow && !PresContext()->PresShell()->IsReflowLocked()) {
+  if (needReflow && !PresShell()->IsReflowLocked()) {
     RequestReflow(nsIPresShell::eResize);
   }
 
   if (needNewCanvasTM) {
     // Do this after calling InvalidateAndScheduleBoundsUpdate in case we
     // change the code and it needs to use it.
     mCanvasTM = nullptr;
   }
@@ -498,17 +498,17 @@ void nsSVGForeignObjectFrame::RequestRef
   if (GetStateBits() & NS_FRAME_FIRST_REFLOW)
     // If we haven't had a ReflowSVG() yet, nothing to do.
     return;
 
   nsIFrame* kid = PrincipalChildList().FirstChild();
   if (!kid)
     return;
 
-  PresContext()->PresShell()->FrameNeedsReflow(kid, aType, NS_FRAME_IS_DIRTY);
+  PresShell()->FrameNeedsReflow(kid, aType, NS_FRAME_IS_DIRTY);
 }
 
 void
 nsSVGForeignObjectFrame::DoReflow()
 {
   MarkInReflow();
   // Skip reflow if we're zero-sized, unless this is our first reflow.
   if (IsDisabled() &&
--- a/layout/svg/nsSVGImageFrame.cpp
+++ b/layout/svg/nsSVGImageFrame.cpp
@@ -96,17 +96,17 @@ nsSVGImageFrame::Init(nsIContent*       
 /* virtual */ void
 nsSVGImageFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
 {
   if (GetStateBits() & NS_FRAME_IS_NONDISPLAY) {
     DecApproximateVisibleCount();
   }
 
   if (mReflowCallbackPosted) {
-    PresContext()->PresShell()->CancelReflowCallback(this);
+    PresShell()->CancelReflowCallback(this);
     mReflowCallbackPosted = false;
   }
 
   nsCOMPtr<nsIImageLoadingContent> imageLoader =
     do_QueryInterface(nsFrame::mContent);
 
   if (imageLoader) {
     imageLoader->FrameDestroyed(this);
@@ -446,17 +446,17 @@ nsSVGImageFrame::ReflowSVG()
 
   if (mState & NS_FRAME_FIRST_REFLOW) {
     // Make sure we have our filter property (if any) before calling
     // FinishAndStoreOverflow (subsequent filter changes are handled off
     // nsChangeHint_UpdateEffects):
     SVGObserverUtils::UpdateEffects(this);
 
     if (!mReflowCallbackPosted) {
-      nsIPresShell* shell = PresContext()->PresShell();
+      nsIPresShell* shell = PresShell();
       mReflowCallbackPosted = true;
       shell->PostReflowCallback(this);
     }
   }
 
   nsRect overflow = nsRect(nsPoint(0,0), mRect.Size());
   nsOverflowAreas overflowAreas(overflow, overflow);
   FinishAndStoreOverflow(overflowAreas, mRect.Size());
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -126,17 +126,17 @@ nsSVGOuterSVGFrame::Init(nsIContent*    
       nsIFrame* embeddingFrame;
       if (IsRootOfReplacedElementSubDoc(&embeddingFrame) && embeddingFrame) {
         if (MOZ_UNLIKELY(!embeddingFrame->HasAllStateBits(NS_FRAME_IS_DIRTY)) &&
             DependsOnIntrinsicSize(embeddingFrame)) {
           // Looks like this document is loading after the embedding element
           // has had its first reflow, and that its size depends on our
           // intrinsic size.  We need it to resize itself to use our (now
           // available) intrinsic size:
-          embeddingFrame->PresContext()->PresShell()->
+          embeddingFrame->PresShell()->
             FrameNeedsReflow(embeddingFrame, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
         }
       }
     }
   }
 }
 
 //----------------------------------------------------------------------
@@ -509,17 +509,17 @@ void
 nsSVGOuterSVGFrame::DidReflow(nsPresContext*   aPresContext,
                               const ReflowInput*  aReflowInput,
                               nsDidReflowStatus aStatus)
 {
   nsSVGDisplayContainerFrame::DidReflow(aPresContext,aReflowInput,aStatus);
 
   // Make sure elements styled by :hover get updated if script/animation moves
   // them under or out from under the pointer:
-  PresContext()->PresShell()->SynthesizeMouseMove(false);
+  PresShell()->SynthesizeMouseMove(false);
 }
 
 /* virtual */ void
 nsSVGOuterSVGFrame::UnionChildOverflow(nsOverflowAreas& aOverflowAreas)
 {
   // See the comments in Reflow above.
 
   // WARNING!! Keep this in sync with Reflow above!
@@ -711,24 +711,24 @@ nsSVGOuterSVGFrame::AttributeChanged(int
       // Don't call ChildrenOnlyTransformChanged() here, since we call it
       // under Reflow if the width/height actually changed.
 
       nsIFrame* embeddingFrame;
       if (IsRootOfReplacedElementSubDoc(&embeddingFrame) && embeddingFrame) {
         if (DependsOnIntrinsicSize(embeddingFrame)) {
           // Tell embeddingFrame's presShell it needs to be reflowed (which takes
           // care of reflowing us too).
-          embeddingFrame->PresContext()->PresShell()->
+          embeddingFrame->PresShell()->
             FrameNeedsReflow(embeddingFrame, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
         }
         // else our width and height is overridden - don't reflow anything
       } else {
         // We are not embedded by reference, so our 'width' and 'height'
         // attributes are not overridden - we need to reflow.
-        PresContext()->PresShell()->
+        PresShell()->
           FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
       }
     }
   }
 
   return NS_OK;
 }
 
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -243,17 +243,17 @@ nsSVGUtils::ScheduleReflowSVG(nsIFrame *
     // need to call PresShell::FrameNeedsReflow, since we have an
     // nsSVGOuterSVGFrame::DidReflow call pending.
     return;
   }
 
   nsFrameState dirtyBit =
     (outerSVGFrame == aFrame ? NS_FRAME_IS_DIRTY : NS_FRAME_HAS_DIRTY_CHILDREN);
 
-  aFrame->PresContext()->PresShell()->FrameNeedsReflow(
+  aFrame->PresShell()->FrameNeedsReflow(
     outerSVGFrame, nsIPresShell::eResize, dirtyBit);
 }
 
 bool
 nsSVGUtils::NeedsReflowSVG(nsIFrame *aFrame)
 {
   MOZ_ASSERT(aFrame->IsFrameOfType(nsIFrame::eSVG),
              "SVG uses bits differently!");
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -61,17 +61,17 @@ public:
   NS_DISPLAY_DECL_NAME("TableCellSelection", TYPE_TABLE_CELL_SELECTION)
 
   bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                mozilla::wr::IpcResourceUpdateQueue& aResources,
                                const StackingContextHelper& aSc,
                                mozilla::layers::WebRenderLayerManager* aManager,
                                nsDisplayListBuilder* aDisplayListBuilder) override
   {
-    RefPtr<nsFrameSelection> frameSelection = mFrame->PresContext()->PresShell()->FrameSelection();
+    RefPtr<nsFrameSelection> frameSelection = mFrame->PresShell()->FrameSelection();
     if (frameSelection->GetTableCellSelection()) {
       return false;
     }
 
     return true;
   }
 };
 
@@ -213,17 +213,17 @@ nsresult
 nsTableCellFrame::AttributeChanged(int32_t         aNameSpaceID,
                                    nsAtom*        aAttribute,
                                    int32_t         aModType)
 {
   // We need to recalculate in this case because of the nowrap quirk in
   // BasicTableLayoutStrategy
   if (aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::nowrap &&
       PresContext()->CompatibilityMode() == eCompatibility_NavQuirks) {
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
   }
 
   if (aAttribute == nsGkAtoms::rowspan || aAttribute == nsGkAtoms::colspan) {
     nsLayoutUtils::PostRestyleEvent(mContent->AsElement(),
                                     nsRestyleHint(0),
                                     nsChangeHint_UpdateTableCellSpans);
   }
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -237,17 +237,17 @@ nsTableColGroupFrame::InsertFrames(Child
 }
 
 void
 nsTableColGroupFrame::InsertColsReflow(int32_t                   aColIndex,
                                        const nsFrameList::Slice& aCols)
 {
   AddColsToTable(aColIndex, true, aCols);
 
-  PresContext()->PresShell()->FrameNeedsReflow(this,
+  PresShell()->FrameNeedsReflow(this,
                                                nsIPresShell::eTreeChange,
                                                NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsTableColGroupFrame::RemoveChild(nsTableColFrame& aChild,
                                   bool             aResetSubsequentColIndices)
 {
@@ -265,19 +265,18 @@ nsTableColGroupFrame::RemoveChild(nsTabl
     }
     else {
       nsIFrame* nextGroup = GetNextSibling();
       if (nextGroup) // reset next and all following colgroups
         ResetColIndices(nextGroup, colIndex);
     }
   }
 
-  PresContext()->PresShell()->FrameNeedsReflow(this,
-                                               nsIPresShell::eTreeChange,
-                                               NS_FRAME_HAS_DIRTY_CHILDREN);
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsTableColGroupFrame::RemoveFrame(ChildListID     aListID,
                                   nsIFrame*       aOldFrame)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
 
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -368,17 +368,17 @@ nsTableFrame::RowOrColSpanChanged(nsTabl
       uint32_t colIndex = aCellFrame->ColIndex();
       RemoveCell(aCellFrame, rowIndex);
       AutoTArray<nsTableCellFrame*, 1> cells;
       cells.AppendElement(aCellFrame);
       InsertCells(cells, rowIndex, colIndex - 1);
 
       // XXX Should this use eStyleChange?  It currently doesn't need
       // to, but it might given more optimization.
-      PresContext()->PresShell()->
+      PresShell()->
         FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
     }
   }
 }
 
 
 /* ****** CellMap methods ******* */
 
@@ -721,17 +721,17 @@ nsTableFrame::AppendAnonymousColFrames(n
                                        int32_t               aNumColsToAdd,
                                        nsTableColType        aColType,
                                        bool                  aAddToTable)
 {
   NS_PRECONDITION(aColGroupFrame, "null frame");
   NS_PRECONDITION(aColType != eColAnonymousCol, "Shouldn't happen");
   MOZ_ASSERT(aNumColsToAdd > 0, "We should be adding _something_.");
 
-  nsIPresShell *shell = PresContext()->PresShell();
+  nsIPresShell *shell = PresShell();
 
   // Get the last col frame
   nsFrameList newColFrames;
 
   int32_t startIndex = mColFrames.Length();
   int32_t lastIndex  = startIndex + aNumColsToAdd - 1;
 
   for (int32_t childX = startIndex; childX <= lastIndex; childX++) {
@@ -1214,31 +1214,31 @@ nsDisplayTableItem::UpdateForFrameBackgr
 
   mPartHasFixedBackground = true;
 }
 
 nsDisplayItemGeometry*
 nsDisplayTableItem::AllocateGeometry(nsDisplayListBuilder* aBuilder)
 {
   return new nsDisplayTableItemGeometry(this, aBuilder,
-      mFrame->GetOffsetTo(mFrame->PresContext()->PresShell()->GetRootFrame()));
+      mFrame->GetOffsetTo(mFrame->PresShell()->GetRootFrame()));
 }
 
 void
 nsDisplayTableItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                               const nsDisplayItemGeometry* aGeometry,
                                               nsRegion *aInvalidRegion) const
 {
   auto geometry =
     static_cast<const nsDisplayTableItemGeometry*>(aGeometry);
 
   bool invalidateForAttachmentFixed = false;
   if (mDrawsBackground && mPartHasFixedBackground) {
     nsPoint frameOffsetToViewport = mFrame->GetOffsetTo(
-        mFrame->PresContext()->PresShell()->GetRootFrame());
+        mFrame->PresShell()->GetRootFrame());
     invalidateForAttachmentFixed =
         frameOffsetToViewport != geometry->mFrameOffsetToViewport;
   }
 
   if (invalidateForAttachmentFixed ||
       (aBuilder->ShouldSyncDecodeImages() &&
        geometry->ShouldInvalidateToSyncDecodeImages())) {
     bool snap;
@@ -2572,18 +2572,18 @@ nsTableFrame::AppendFrames(ChildListID  
       mFrames.AppendFrame(nullptr, f);
     }
   }
 
 #ifdef DEBUG_TABLE_CELLMAP
   printf("=== TableFrame::AppendFrames\n");
   Dump(true, true, true);
 #endif
-  PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                                               NS_FRAME_HAS_DIRTY_CHILDREN);
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
   SetGeometryDirty();
 }
 
 // Needs to be at file scope or ArrayLength fails to compile.
 struct ChildListInsertions {
   nsIFrame::ChildListID mID;
   nsFrameList mList;
 };
@@ -2744,18 +2744,18 @@ nsTableFrame::HomogenousInsertFrames(Chi
   } else {
     NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
     NS_NOTREACHED("How did we even get here?");
     // Just insert the frame and don't worry about reflowing it
     mFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);
     return;
   }
 
-  PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                                               NS_FRAME_HAS_DIRTY_CHILDREN);
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
   SetGeometryDirty();
 #ifdef DEBUG_TABLE_CELLMAP
   printf("=== TableFrame::InsertFrames\n");
   Dump(true, true, true);
 #endif
 }
 
 void
@@ -2833,17 +2833,17 @@ nsTableFrame::DoRemoveFrame(ChildListID 
 void
 nsTableFrame::RemoveFrame(ChildListID     aListID,
                           nsIFrame*       aOldFrame)
 {
   NS_ASSERTION(aListID == kColGroupList ||
                mozilla::StyleDisplay::TableColumnGroup !=
                  aOldFrame->StyleDisplay()->mDisplay,
                "Wrong list name; use kColGroupList iff colgroup");
-  nsIPresShell* shell = PresContext()->PresShell();
+  nsIPresShell* shell = PresShell();
   nsTableFrame* lastParent = nullptr;
   while (aOldFrame) {
     nsIFrame* oldFrameNextContinuation = aOldFrame->GetNextContinuation();
     nsTableFrame* parent = static_cast<nsTableFrame*>(aOldFrame->GetParent());
     if (parent != lastParent) {
       parent->DrainSelfOverflowList();
     }
     parent->DoRemoveFrame(aListID, aOldFrame);
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -213,18 +213,18 @@ nsTableRowFrame::AppendFrames(ChildListI
   nsTableFrame* tableFrame = GetTableFrame();
   for (nsFrameList::Enumerator e(newCells) ; !e.AtEnd(); e.Next()) {
     nsIFrame *childFrame = e.get();
     NS_ASSERTION(IS_TABLE_CELL(childFrame->Type()),
                  "Not a table cell frame/pseudo frame construction failure");
     tableFrame->AppendCell(static_cast<nsTableCellFrame&>(*childFrame), GetRowIndex());
   }
 
-  PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                                               NS_FRAME_HAS_DIRTY_CHILDREN);
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
   tableFrame->SetGeometryDirty();
 }
 
 
 void
 nsTableRowFrame::InsertFrames(ChildListID  aListID,
                               nsIFrame*    aPrevFrame,
                               nsFrameList& aFrameList)
@@ -259,18 +259,18 @@ nsTableRowFrame::InsertFrames(ChildListI
   }
   // insert the cells into the cell map
   int32_t colIndex = -1;
   if (prevCellFrame) {
     colIndex = prevCellFrame->ColIndex();
   }
   tableFrame->InsertCells(cellChildren, GetRowIndex(), colIndex);
 
-  PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                                               NS_FRAME_HAS_DIRTY_CHILDREN);
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
   tableFrame->SetGeometryDirty();
 }
 
 void
 nsTableRowFrame::RemoveFrame(ChildListID aListID,
                              nsIFrame*   aOldFrame)
 {
   NS_ASSERTION(aListID == kPrincipalList, "unexpected child list");
@@ -279,19 +279,18 @@ nsTableRowFrame::RemoveFrame(ChildListID
   nsTableCellFrame* cellFrame = static_cast<nsTableCellFrame*>(aOldFrame);
   // remove the cell from the cell map
   nsTableFrame* tableFrame = GetTableFrame();
   tableFrame->RemoveCell(cellFrame, GetRowIndex());
 
   // Remove the frame and destroy it
   mFrames.DestroyFrame(aOldFrame);
 
-  PresContext()->PresShell()->
-    FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                     NS_FRAME_HAS_DIRTY_CHILDREN);
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
 
   tableFrame->SetGeometryDirty();
 }
 
 /* virtual */ nsMargin
 nsTableRowFrame::GetUsedMargin() const
 {
   return nsMargin(0,0,0,0);
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -1484,19 +1484,18 @@ nsTableRowGroupFrame::AppendFrames(Child
 
   int32_t rowIndex = GetRowCount();
   // Append the frames to the sibling chain
   mFrames.AppendFrames(nullptr, aFrameList);
 
   if (rows.Length() > 0) {
     nsTableFrame* tableFrame = GetTableFrame();
     tableFrame->AppendRows(this, rowIndex, rows);
-    PresContext()->PresShell()->
-      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                       NS_FRAME_HAS_DIRTY_CHILDREN);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                  NS_FRAME_HAS_DIRTY_CHILDREN);
     tableFrame->SetGeometryDirty();
   }
 }
 
 void
 nsTableRowGroupFrame::InsertFrames(ChildListID     aListID,
                                    nsIFrame*       aPrevFrame,
                                    nsFrameList&    aFrameList)
@@ -1534,19 +1533,18 @@ nsTableRowGroupFrame::InsertFrames(Child
   mFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);
 
   int32_t numRows = rows.Length();
   if (numRows > 0) {
     nsTableRowFrame* prevRow = (nsTableRowFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, LayoutFrameType::TableRow);
     int32_t rowIndex = (prevRow) ? prevRow->GetRowIndex() + 1 : startRowIndex;
     tableFrame->InsertRows(this, rows, rowIndex, true);
 
-    PresContext()->PresShell()->
-      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                       NS_FRAME_HAS_DIRTY_CHILDREN);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                  NS_FRAME_HAS_DIRTY_CHILDREN);
     tableFrame->SetGeometryDirty();
   }
 }
 
 void
 nsTableRowGroupFrame::RemoveFrame(ChildListID     aListID,
                                   nsIFrame*       aOldFrame)
 {
@@ -1556,19 +1554,18 @@ nsTableRowGroupFrame::RemoveFrame(ChildL
 
   // XXX why are we doing the QI stuff?  There shouldn't be any non-rows here.
   nsTableRowFrame* rowFrame = do_QueryFrame(aOldFrame);
   if (rowFrame) {
     nsTableFrame* tableFrame = GetTableFrame();
     // remove the rows from the table (and flag a rebalance)
     tableFrame->RemoveRows(*rowFrame, 1, true);
 
-    PresContext()->PresShell()->
-      FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                       NS_FRAME_HAS_DIRTY_CHILDREN);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                  NS_FRAME_HAS_DIRTY_CHILDREN);
     tableFrame->SetGeometryDirty();
   }
   mFrames.DestroyFrame(aOldFrame);
 }
 
 /* virtual */ nsMargin
 nsTableRowGroupFrame::GetUsedMargin() const
 {
--- a/layout/tables/nsTableWrapperFrame.cpp
+++ b/layout/tables/nsTableWrapperFrame.cpp
@@ -116,18 +116,18 @@ nsTableWrapperFrame::AppendFrames(ChildL
   MOZ_ASSERT(kCaptionList == aListID, "unexpected child list");
   MOZ_ASSERT(aFrameList.IsEmpty() ||
              aFrameList.FirstChild()->IsTableCaption(),
              "appending non-caption frame to captionList");
   mCaptionFrames.AppendFrames(this, aFrameList);
 
   // Reflow the new caption frame. It's already marked dirty, so
   // just tell the pres shell.
-  PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                                               NS_FRAME_HAS_DIRTY_CHILDREN);
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsTableWrapperFrame::InsertFrames(ChildListID     aListID,
                                   nsIFrame*       aPrevFrame,
                                   nsFrameList&    aFrameList)
 {
   MOZ_ASSERT(kCaptionList == aListID, "unexpected child list");
@@ -135,18 +135,18 @@ nsTableWrapperFrame::InsertFrames(ChildL
              aFrameList.FirstChild()->IsTableCaption(),
              "inserting non-caption frame into captionList");
   MOZ_ASSERT(!aPrevFrame || aPrevFrame->GetParent() == this,
              "inserting after sibling frame with different parent");
   mCaptionFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);
 
   // Reflow the new caption frame. It's already marked dirty, so
   // just tell the pres shell.
-  PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                                               NS_FRAME_HAS_DIRTY_CHILDREN);
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsTableWrapperFrame::RemoveFrame(ChildListID  aListID,
                                  nsIFrame*    aOldFrame)
 {
   // We only have two child frames: the inner table and one caption frame.
   // The inner frame can't be removed so this should be the caption
@@ -156,19 +156,18 @@ nsTableWrapperFrame::RemoveFrame(ChildLi
     // The old caption isize had an effect on the inner table isize, so
     // we're going to need to reflow it. Mark it dirty
     InnerTableFrame()->AddStateBits(NS_FRAME_IS_DIRTY);
   }
 
   // Remove the frame and destroy it
   mCaptionFrames.DestroyFrame(aOldFrame);
 
-  PresContext()->PresShell()->
-    FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                     NS_FRAME_HAS_DIRTY_CHILDREN); // also means child removed
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsTableWrapperFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                       const nsDisplayListSet& aLists)
 {
   // No border, background or outline are painted because they all belong
   // to the inner table.
--- a/layout/xul/nsBoxFrame.cpp
+++ b/layout/xul/nsBoxFrame.cpp
@@ -1025,19 +1025,18 @@ nsBoxFrame::RemoveFrame(ChildListID     
   // notify the layout manager
   if (mLayoutManager)
     mLayoutManager->ChildrenRemoved(this, state, aOldFrame);
 
   // destroy the child frame
   aOldFrame->Destroy();
 
   // mark us dirty and generate a reflow command
-  PresContext()->PresShell()->
-    FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                     NS_FRAME_HAS_DIRTY_CHILDREN);
+  PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsBoxFrame::InsertFrames(ChildListID     aListID,
                          nsIFrame*       aPrevFrame,
                          nsFrameList&    aFrameList)
 {
    NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this,
@@ -1062,19 +1061,18 @@ nsBoxFrame::InsertFrames(ChildListID    
    CheckBoxOrder();
 
 #ifdef DEBUG_LAYOUT
    // if we are in debug make sure our children are in debug as well.
    if (mState & NS_STATE_CURRENTLY_IN_DEBUG)
        SetDebugOnChildList(state, mFrames.FirstChild(), true);
 #endif
 
-   PresContext()->PresShell()->
-     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                      NS_FRAME_HAS_DIRTY_CHILDREN);
+   PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                 NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 
 void
 nsBoxFrame::AppendFrames(ChildListID     aListID,
                          nsFrameList&    aFrameList)
 {
    NS_PRECONDITION(aListID == kPrincipalList, "We don't support out-of-flow kids");
@@ -1096,19 +1094,18 @@ nsBoxFrame::AppendFrames(ChildListID    
 #ifdef DEBUG_LAYOUT
    // if we are in debug make sure our children are in debug as well.
    if (mState & NS_STATE_CURRENTLY_IN_DEBUG)
        SetDebugOnChildList(state, mFrames.FirstChild(), true);
 #endif
 
    // XXXbz why is this NS_FRAME_FIRST_REFLOW check here?
    if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
-     PresContext()->PresShell()->
-       FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                        NS_FRAME_HAS_DIRTY_CHILDREN);
+     PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                   NS_FRAME_HAS_DIRTY_CHILDREN);
    }
 }
 
 /* virtual */ nsContainerFrame*
 nsBoxFrame::GetContentInsertionFrame()
 {
   if (GetStateBits() & NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK)
     return PrincipalChildList().FirstChild()->GetContentInsertionFrame();
@@ -1223,46 +1220,45 @@ nsBoxFrame::AttributeChanged(int32_t aNa
              aAttribute == nsGkAtoms::start ||
              aAttribute == nsGkAtoms::end) {
       RemoveStateBits(NS_STATE_STACK_NOT_POSITIONED);
     }
     else if (aAttribute == nsGkAtoms::mousethrough) {
       UpdateMouseThrough();
     }
 
-    PresContext()->PresShell()->
-      FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eStyleChange,
+                                  NS_FRAME_IS_DIRTY);
   }
   else if (aAttribute == nsGkAtoms::ordinal) {
     nsIFrame* parent = GetParentXULBox(this);
     // If our parent is not a box, there's not much we can do... but in that
     // case our ordinal doesn't matter anyway, so that's ok.
     // Also don't bother with popup frames since they are kept on the
     // kPopupList and XULRelayoutChildAtOrdinal() only handles
     // principal children.
     if (parent && !(GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
         StyleDisplay()->mDisplay != mozilla::StyleDisplay::MozPopup) {
       parent->XULRelayoutChildAtOrdinal(this);
       // XXXldb Should this instead be a tree change on the child or parent?
-      PresContext()->PresShell()->
-        FrameNeedsReflow(parent, nsIPresShell::eStyleChange,
-                         NS_FRAME_IS_DIRTY);
+      PresShell()->FrameNeedsReflow(parent, nsIPresShell::eStyleChange,
+                                    NS_FRAME_IS_DIRTY);
     }
   }
   // If the accesskey changed, register for the new value
   // The old value has been unregistered in nsXULElement::SetAttr
   else if (aAttribute == nsGkAtoms::accesskey) {
     RegUnregAccessKey(true);
   }
   else if (aAttribute == nsGkAtoms::rows &&
            mContent->IsXULElement(nsGkAtoms::tree)) {
     // Reflow ourselves and all our children if "rows" changes, since
     // nsTreeBodyFrame's layout reads this from its parent (this frame).
-    PresContext()->PresShell()->
-      FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eStyleChange,
+                                  NS_FRAME_IS_DIRTY);
   }
 
   return rv;
 }
 
 #ifdef DEBUG_LAYOUT
 void
 nsBoxFrame::GetDebugPref()
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -144,17 +144,17 @@ nsImageBoxFrame::AttributeChanged(int32_
                                   nsAtom* aAttribute,
                                   int32_t aModType)
 {
   nsresult rv = nsLeafBoxFrame::AttributeChanged(aNameSpaceID, aAttribute,
                                                  aModType);
 
   if (aAttribute == nsGkAtoms::src) {
     UpdateImage();
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
   }
   else if (aAttribute == nsGkAtoms::validate)
     UpdateLoadFlags();
 
   return rv;
 }
 
@@ -856,17 +856,17 @@ nsImageBoxFrame::OnSizeAvailable(imgIReq
   nscoord w, h;
   aImage->GetWidth(&w);
   aImage->GetHeight(&h);
 
   mIntrinsicSize.SizeTo(nsPresContext::CSSPixelsToAppUnits(w),
                         nsPresContext::CSSPixelsToAppUnits(h));
 
   if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
   }
 
   return NS_OK;
 }
 
 nsresult
 nsImageBoxFrame::OnDecodeComplete(imgIRequest* aRequest)
@@ -880,17 +880,17 @@ nsresult
 nsImageBoxFrame::OnLoadComplete(imgIRequest* aRequest, nsresult aStatus)
 {
   if (NS_SUCCEEDED(aStatus)) {
     // Fire an onload DOM event.
     FireImageDOMEvent(mContent, eLoad);
   } else {
     // Fire an onerror DOM event.
     mIntrinsicSize.SizeTo(0, 0);
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
     FireImageDOMEvent(mContent, eLoadError);
   }
 
   return NS_OK;
 }
 
 nsresult
--- a/layout/xul/nsListBoxBodyFrame.cpp
+++ b/layout/xul/nsListBoxBodyFrame.cpp
@@ -211,17 +211,17 @@ nsListBoxBodyFrame::Init(nsIContent*    
   mRowHeight = fm->MaxHeight();
 }
 
 void
 nsListBoxBodyFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
 {
   // make sure we cancel any posted callbacks.
   if (mReflowCallbackPosted)
-     PresContext()->PresShell()->CancelReflowCallback(this);
+     PresShell()->CancelReflowCallback(this);
 
   // Revoke any pending position changed events
   for (uint32_t i = 0; i < mPendingPositionChangeEvents.Length(); ++i) {
     mPendingPositionChangeEvents[i]->Revoke();
   }
 
   // Make sure we tell our listbox's box object we're being destroyed.
   if (mBoxObject) {
@@ -234,17 +234,17 @@ nsListBoxBodyFrame::DestroyFrom(nsIFrame
 nsresult
 nsListBoxBodyFrame::AttributeChanged(int32_t aNameSpaceID,
                                      nsAtom* aAttribute,
                                      int32_t aModType)
 {
   nsresult rv = NS_OK;
 
   if (aAttribute == nsGkAtoms::rows) {
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
   }
   else
     rv = nsBoxFrame::AttributeChanged(aNameSpaceID, aAttribute, aModType);
 
   return rv;
 
 }
@@ -487,17 +487,17 @@ nsListBoxBodyFrame::ReflowFinished()
   if (mAdjustScroll) {
      VerticalScroll(mYPosition);
      mAdjustScroll = false;
   }
 
   // if the row height changed then mark everything as a style change.
   // That will dirty the entire listbox
   if (mRowHeightWasSet) {
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
      int32_t pos = mCurrentIndex * mRowHeight;
      if (mYPosition != pos)
        mAdjustScroll = true;
     mRowHeightWasSet = false;
   }
 
   mReflowCallbackPosted = false;
@@ -775,17 +775,17 @@ nsListBoxBodyFrame::ComputeTotalRowCount
   }
 }
 
 void
 nsListBoxBodyFrame::PostReflowCallback()
 {
   if (!mReflowCallbackPosted) {
     mReflowCallbackPosted = true;
-    PresContext()->PresShell()->PostReflowCallback(this);
+    PresShell()->PostReflowCallback(this);
   }
 }
 
 ////////// scrolling
 
 nsresult
 nsListBoxBodyFrame::ScrollToIndex(int32_t aRowIndex)
 {
@@ -1069,55 +1069,55 @@ nsListBoxBodyFrame::CreateRows()
 void
 nsListBoxBodyFrame::DestroyRows(int32_t& aRowsToLose)
 {
   // We need to destroy frames until our row count has been properly
   // reduced.  A reflow will then pick up and create the new frames.
   nsIFrame* childFrame = GetFirstFrame();
   nsBoxLayoutState state(PresContext());
 
-  nsCSSFrameConstructor* fc = PresContext()->PresShell()->FrameConstructor();
+  nsCSSFrameConstructor* fc = PresShell()->FrameConstructor();
   fc->BeginUpdate();
   while (childFrame && aRowsToLose > 0) {
     --aRowsToLose;
 
     nsIFrame* nextFrame = childFrame->GetNextSibling();
     RemoveChildFrame(state, childFrame);
 
     mTopFrame = childFrame = nextFrame;
   }
   fc->EndUpdate();
 
-  PresContext()->PresShell()->
+  PresShell()->
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsListBoxBodyFrame::ReverseDestroyRows(int32_t& aRowsToLose)
 {
   // We need to destroy frames until our row count has been properly
   // reduced.  A reflow will then pick up and create the new frames.
   nsIFrame* childFrame = GetLastFrame();
   nsBoxLayoutState state(PresContext());
 
-  nsCSSFrameConstructor* fc = PresContext()->PresShell()->FrameConstructor();
+  nsCSSFrameConstructor* fc = PresShell()->FrameConstructor();
   fc->BeginUpdate();
   while (childFrame && aRowsToLose > 0) {
     --aRowsToLose;
 
     nsIFrame* prevFrame;
     prevFrame = childFrame->GetPrevSibling();
     RemoveChildFrame(state, childFrame);
 
     mBottomFrame = childFrame = prevFrame;
   }
   fc->EndUpdate();
 
-  PresContext()->PresShell()->
+  PresShell()->
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 static bool
 IsListItemChild(nsListBoxBodyFrame* aParent, nsIContent* aChild,
                 nsIFrame** aChildFrame)
 {
@@ -1296,26 +1296,26 @@ nsListBoxBodyFrame::ContinueReflow(nscoo
 
     if (lastChild != startingPoint) {
       // We have some hangers on (probably caused by shrinking the size of the window).
       // Nuke them.
       nsIFrame* currFrame = startingPoint->GetNextSibling();
       nsBoxLayoutState state(PresContext());
 
       nsCSSFrameConstructor* fc =
-        PresContext()->PresShell()->FrameConstructor();
+        PresShell()->FrameConstructor();
       fc->BeginUpdate();
       while (currFrame) {
         nsIFrame* nextFrame = currFrame->GetNextSibling();
         RemoveChildFrame(state, currFrame);
         currFrame = nextFrame;
       }
       fc->EndUpdate();
 
-      PresContext()->PresShell()->
+      PresShell()->
         FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                          NS_FRAME_HAS_DIRTY_CHILDREN);
     }
     return false;
   }
   else
     return true;
 }
@@ -1323,34 +1323,34 @@ nsListBoxBodyFrame::ContinueReflow(nscoo
 NS_IMETHODIMP
 nsListBoxBodyFrame::ListBoxAppendFrames(nsFrameList& aFrameList)
 {
   // append them after
   nsBoxLayoutState state(PresContext());
   const nsFrameList::Slice& newFrames = mFrames.AppendFrames(nullptr, aFrameList);
   if (mLayoutManager)
     mLayoutManager->ChildrenAppended(this, state, newFrames);
-  PresContext()->PresShell()->
+  PresShell()->
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsListBoxBodyFrame::ListBoxInsertFrames(nsIFrame* aPrevFrame,
                                         nsFrameList& aFrameList)
 {
   // insert the frames to our info list
   nsBoxLayoutState state(PresContext());
   const nsFrameList::Slice& newFrames =
     mFrames.InsertFrames(nullptr, aPrevFrame, aFrameList);
   if (mLayoutManager)
     mLayoutManager->ChildrenInserted(this, state, aPrevFrame, newFrames);
-  PresContext()->PresShell()->
+  PresShell()->
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 
   return NS_OK;
 }
 
 //
 // Called by nsCSSFrameConstructor when a new listitem content is inserted.
@@ -1381,17 +1381,17 @@ nsListBoxBodyFrame::OnContentInserted(ns
     mRowsToPrepend = 1;
   } else if (nextSiblingContent) {
     // we may be inserting before a frame that is on screen
     nsIFrame* nextSiblingFrame = nextSiblingContent->GetPrimaryFrame();
     mLinkupFrame = nextSiblingFrame;
   }
 
   CreateRows();
-  PresContext()->PresShell()->
+  PresShell()->
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 //
 // Called by nsCSSFrameConstructor when listitem content is removed.
 //
 void
@@ -1467,17 +1467,17 @@ nsListBoxBodyFrame::OnContentRemoved(nsP
     mTopFrame = mTopFrame->GetNextSibling();
 
   // Go ahead and delete the frame.
   nsBoxLayoutState state(aPresContext);
   if (aChildFrame) {
     RemoveChildFrame(state, aChildFrame);
   }
 
-  PresContext()->PresShell()->
+  PresShell()->
     FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                      NS_FRAME_HAS_DIRTY_CHILDREN);
 }
 
 void
 nsListBoxBodyFrame::GetListItemContentAt(int32_t aIndex, nsIContent** aContent)
 {
   *aContent = nullptr;
@@ -1524,17 +1524,17 @@ nsListBoxBodyFrame::RemoveChildFrame(nsB
 {
   MOZ_ASSERT(mFrames.ContainsFrame(aFrame));
   MOZ_ASSERT(aFrame != GetContentInsertionFrame());
 
 #ifdef ACCESSIBILITY
   nsAccessibilityService* accService = nsIPresShell::AccService();
   if (accService) {
     nsIContent* content = aFrame->GetContent();
-    accService->ContentRemoved(PresContext()->PresShell(), content);
+    accService->ContentRemoved(PresShell(), content);
   }
 #endif
 
   mFrames.RemoveFrame(aFrame);
   if (mLayoutManager)
     mLayoutManager->ChildrenRemoved(this, aState, aFrame);
   aFrame->Destroy();
 }
--- a/layout/xul/nsMenuBarFrame.cpp
+++ b/layout/xul/nsMenuBarFrame.cpp
@@ -157,17 +157,17 @@ nsMenuBarFrame::FindMenuWithShortcut(nsI
   }
   if (accessKeys.IsEmpty() && charCode)
     accessKeys.AppendElement(charCode);
 
   if (accessKeys.IsEmpty())
     return nullptr; // no character was pressed so just return
 
   // Enumerate over our list of frames.
-  auto insertion = PresContext()->PresShell()->FrameConstructor()->
+  auto insertion = PresShell()->FrameConstructor()->
     GetInsertionPoint(GetContent(), nullptr);
   nsContainerFrame* immediateParent = insertion.mParentFrame;
   if (!immediateParent)
     immediateParent = this;
 
   // Find a most preferred accesskey which should be returned.
   nsIFrame* foundMenu = nullptr;
   size_t foundIndex = accessKeys.NoIndex;
--- a/layout/xul/nsMenuFrame.cpp
+++ b/layout/xul/nsMenuFrame.cpp
@@ -226,17 +226,17 @@ nsMenuFrame::Init(nsIContent*       aCon
   nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
 
   // Set up a mediator which can be used for callbacks on this frame.
   mTimerMediator = new nsMenuTimerMediator(this);
 
   BuildAcceleratorText(false);
   if (!mReflowCallbackPosted) {
     mReflowCallbackPosted = true;
-    PresContext()->PresShell()->PostReflowCallback(this);
+    PresShell()->PostReflowCallback(this);
   }
 }
 
 const nsFrameList&
 nsMenuFrame::GetChildList(ChildListID aListID) const
 {
   if (kPopupList == aListID) {
     nsFrameList* list = GetPopupList();
@@ -279,28 +279,28 @@ nsMenuFrame::GetPopupList() const
 void
 nsMenuFrame::DestroyPopupList()
 {
   NS_ASSERTION(HasPopup(), "huh?");
   nsFrameList* prop = RemoveProperty(PopupListProperty());
   NS_ASSERTION(prop && prop->IsEmpty(),
                "popup list must exist and be empty when destroying");
   RemoveStateBits(NS_STATE_MENU_HAS_POPUP_LIST);
-  prop->Delete(PresContext()->PresShell());
+  prop->Delete(PresShell());
 }
 
 void
 nsMenuFrame::SetPopupFrame(nsFrameList& aFrameList)
 {
   for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) {
     nsMenuPopupFrame* popupFrame = do_QueryFrame(e.get());
     if (popupFrame) {
       // Remove the frame from the list and store it in a nsFrameList* property.
       aFrameList.RemoveFrame(popupFrame);
-      nsFrameList* popupList = new (PresContext()->PresShell()) nsFrameList(popupFrame, popupFrame);
+      nsFrameList* popupList = new (PresShell()) nsFrameList(popupFrame, popupFrame);
       SetProperty(PopupListProperty(), popupList);
       AddStateBits(NS_STATE_MENU_HAS_POPUP_LIST);
       break;
     }
   }
 }
 
 void
@@ -313,17 +313,17 @@ nsMenuFrame::SetInitialChildList(ChildLi
   }
   nsBoxFrame::SetInitialChildList(aListID, aChildList);
 }
 
 void
 nsMenuFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
 {
   if (mReflowCallbackPosted) {
-    PresContext()->PresShell()->CancelReflowCallback(this);
+    PresShell()->CancelReflowCallback(this);
     mReflowCallbackPosted = false;
   }
 
   // Kill our timer if one is active. This is not strictly necessary as
   // the pointer to this frame will be cleared from the mediator, but
   // this is done for added safety.
   if (mOpenTimer) {
     mOpenTimer->Cancel();
@@ -1302,17 +1302,17 @@ void
 nsMenuFrame::RemoveFrame(ChildListID     aListID,
                          nsIFrame*       aOldFrame)
 {
   nsFrameList* popupList = GetPopupList();
   if (popupList && popupList->FirstChild() == aOldFrame) {
     popupList->RemoveFirstChild();
     aOldFrame->Destroy();
     DestroyPopupList();
-    PresContext()->PresShell()->
+    PresShell()->
       FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                        NS_FRAME_HAS_DIRTY_CHILDREN);
     return;
   }
   nsBoxFrame::RemoveFrame(aListID, aOldFrame);
 }
 
 void
@@ -1323,17 +1323,17 @@ nsMenuFrame::InsertFrames(ChildListID   
   if (!HasPopup() && (aListID == kPrincipalList || aListID == kPopupList)) {
     SetPopupFrame(aFrameList);
     if (HasPopup()) {
 #ifdef DEBUG_LAYOUT
       nsBoxLayoutState state(PresContext());
       SetXULDebug(state, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
 #endif
 
-      PresContext()->PresShell()->
+      PresShell()->
         FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                          NS_FRAME_HAS_DIRTY_CHILDREN);
     }
   }
 
   if (aFrameList.IsEmpty())
     return;
 
@@ -1351,17 +1351,17 @@ nsMenuFrame::AppendFrames(ChildListID   
   if (!HasPopup() && (aListID == kPrincipalList || aListID == kPopupList)) {
     SetPopupFrame(aFrameList);
     if (HasPopup()) {
 
 #ifdef DEBUG_LAYOUT
       nsBoxLayoutState state(PresContext());
       SetXULDebug(state, aFrameList, mState & NS_STATE_CURRENTLY_IN_DEBUG);
 #endif
-      PresContext()->PresShell()->
+      PresShell()->
         FrameNeedsReflow(this, nsIPresShell::eTreeChange,
                          NS_FRAME_HAS_DIRTY_CHILDREN);
     }
   }
 
   if (aFrameList.IsEmpty())
     return;
 
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -939,18 +939,18 @@ nsMenuPopupFrame::ShowPopup(bool aIsCont
       AutoWeakFrame weakFrame(this);
       menuFrame->PopupOpened();
       if (!weakFrame.IsAlive())
         return;
     }
 
     // do we need an actual reflow here?
     // is SetPopupPosition all that is needed?
-    PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
-                                                 NS_FRAME_HAS_DIRTY_CHILDREN);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                  NS_FRAME_HAS_DIRTY_CHILDREN);
 
     if (mPopupType == ePopupTypeMenu) {
       nsCOMPtr<nsISound> sound(do_CreateInstance("@mozilla.org/sound;1"));
       if (sound)
         sound->PlayEventSound(nsISound::EVENT_MENU_POPUP);
     }
   }
 
@@ -1873,17 +1873,17 @@ nsIScrollableFrame* nsMenuPopupFrame::Ge
   } while (currFrame);
 
   return nullptr;
 }
 
 void nsMenuPopupFrame::EnsureMenuItemIsVisible(nsMenuFrame* aMenuItem)
 {
   if (aMenuItem) {
-    aMenuItem->PresContext()->PresShell()->ScrollFrameRectIntoView(
+    aMenuItem->PresShell()->ScrollFrameRectIntoView(
       aMenuItem,
       nsRect(nsPoint(0,0), aMenuItem->GetRect().Size()),
       nsIPresShell::ScrollAxis(),
       nsIPresShell::ScrollAxis(),
       nsIPresShell::SCROLL_OVERFLOW_HIDDEN |
       nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY);
   }
 }
@@ -2024,17 +2024,17 @@ nsMenuPopupFrame::ChangeMenuItem(nsMenuF
     // On Windows, a menulist should update its value whenever navigation was
     // done by the keyboard.
 #ifdef XP_WIN
     if (aFromKey && IsOpen() && IsMenuList()) {
       // Fire a command event as the new item, but we don't want to close
       // the menu, blink it, or update any other state of the menuitem. The
       // command event will cause the item to be selected.
       nsContentUtils::DispatchXULCommand(aMenuItem->GetContent(), /* aTrusted = */ true,
-                                         nullptr, PresContext()->PresShell(),
+                                         nullptr, PresShell(),
                                          false, false, false, false);
     }
 #endif
   }
 
   mCurrentMenu = aMenuItem;
 
   return NS_OK;
@@ -2057,17 +2057,17 @@ nsMenuPopupFrame::FindMenuWithShortcut(n
 {
   uint32_t charCode, keyCode;
   aKeyEvent->GetCharCode(&charCode);
   aKeyEvent->GetKeyCode(&keyCode);
 
   doAction = false;
 
   // Enumerate over our list of frames.
-  auto insertion = PresContext()->PresShell()->
+  auto insertion = PresShell()->
     FrameConstructor()->GetInsertionPoint(GetContent(), nullptr);
   nsContainerFrame* immediateParent = insertion.mParentFrame;
   if (!immediateParent)
     immediateParent = this;
 
   uint32_t matchCount = 0, matchShortcutCount = 0;
   bool foundActive = false;
   bool isShortcut;
@@ -2334,17 +2334,17 @@ nsMenuPopupFrame::MoveToAttributePositio
   if (NS_SUCCEEDED(err1) && NS_SUCCEEDED(err2))
     MoveTo(pos, false);
 }
 
 void
 nsMenuPopupFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
 {
   if (mReflowCallbackData.mPosted) {
-    PresContext()->PresShell()->CancelReflowCallback(this);
+    PresShell()->CancelReflowCallback(this);
     mReflowCallbackData.Clear();
   }
 
   nsMenuFrame* menu = do_QueryFrame(GetParent());
   if (menu) {
     // clear the open attribute on the parent menu
     nsContentUtils::AddScriptRunner(
       new nsUnsetAttrRunnable(menu->GetContent(), nsGkAtoms::open));
--- a/layout/xul/nsProgressMeterFrame.cpp
+++ b/layout/xul/nsProgressMeterFrame.cpp
@@ -47,17 +47,17 @@ nsReflowFrameRunnable::nsReflowFrameRunn
   , mBitToAdd(aBitToAdd)
 {
 }
 
 NS_IMETHODIMP
 nsReflowFrameRunnable::Run()
 {
   if (mWeakFrame.IsAlive()) {
-    mWeakFrame->PresContext()->PresShell()->
+    mWeakFrame->PresShell()->
       FrameNeedsReflow(mWeakFrame, mIntrinsicDirty, mBitToAdd);
   }
   return NS_OK;
 }
 
 //
 // NS_NewToolbarFrame
 //
@@ -107,17 +107,17 @@ public:
 };
 
 NS_IMETHODIMP
 nsProgressMeterFrame::DoXULLayout(nsBoxLayoutState& aState)
 {
   if (mNeedsReflowCallback) {
     nsIReflowCallback* cb = new nsAsyncProgressMeterInit(this);
     if (cb) {
-      PresContext()->PresShell()->PostReflowCallback(cb);
+      PresShell()->PostReflowCallback(cb);
     }
     mNeedsReflowCallback = false;
   }
   return nsBoxFrame::DoXULLayout(aState);
 }
 
 nsresult
 nsProgressMeterFrame::AttributeChanged(int32_t aNameSpaceID,
--- a/layout/xul/nsScrollbarFrame.cpp
+++ b/layout/xul/nsScrollbarFrame.cpp
@@ -150,17 +150,17 @@ nsScrollbarFrame::GetScrollbarMediator()
     nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame();
     sbm = do_QueryFrame(scrolledFrame);
     if (sbm) {
       return sbm;
     }
   }
   sbm = do_QueryFrame(f);
   if (f && !sbm) {
-    f = f->PresContext()->PresShell()->GetRootScrollFrame();
+    f = f->PresShell()->GetRootScrollFrame();
     if (f && f->GetContent() == mScrollbarMediator) {
       return do_QueryFrame(f);
     }
   }
   return sbm;
 }
 
 nsresult
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -98,17 +98,17 @@ nsSliderFrame::nsSliderFrame(nsStyleCont
 {
 }
 
 // stop timer
 nsSliderFrame::~nsSliderFrame()
 {
   if (mSuppressionActive) {
     APZCCallbackHelper::SuppressDisplayport(false, PresContext() ?
-                                                   PresContext()->PresShell() :
+                                                   PresShell() :
                                                    nullptr);
   }
 }
 
 void
 nsSliderFrame::Init(nsIContent*       aContent,
                     nsContainerFrame* aParent,
                     nsIFrame*         aPrevInFlow)
@@ -308,17 +308,17 @@ nsSliderFrame::AttributeChanged(int32_t 
       }
   }
 
   if (aAttribute == nsGkAtoms::minpos ||
       aAttribute == nsGkAtoms::maxpos ||
       aAttribute == nsGkAtoms::pageincrement ||
       aAttribute == nsGkAtoms::increment) {
 
-      PresContext()->PresShell()->
+      PresShell()->
         FrameNeedsReflow(this, nsIPresShell::eStyleChange, NS_FRAME_IS_DIRTY);
   }
 
   return rv;
 }
 
 void
 nsSliderFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
@@ -1128,17 +1128,17 @@ nsSliderFrame::StartAPZDrag(WidgetGUIEve
   bool hasAPZView = hasID && (scrollTargetId != layers::FrameMetrics::NULL_SCROLL_ID);
 
   if (!hasAPZView) {
     return;
   }
 
   nsCOMPtr<nsIContent> scrollbar = GetContentOfBox(scrollbarBox);
 
-  nsIPresShell* shell = PresContext()->PresShell();
+  nsIPresShell* shell = PresShell();
   uint64_t inputblockId = InputAPZContext::GetInputBlockId();
   uint32_t presShellId = shell->GetPresShellId();
   AsyncDragMetrics dragMetrics(scrollTargetId, presShellId, inputblockId,
                                NSAppUnitsToFloatPixels(mDragStart,
                                  float(AppUnitsPerCSSPixel())),
                                isHorizontal ? ScrollDirection::HORIZONTAL :
                                               ScrollDirection::VERTICAL);
 
@@ -1636,28 +1636,28 @@ nsSliderFrame::AsyncScrollbarDragRejecte
     SuppressDisplayport();
   }
 }
 
 void
 nsSliderFrame::SuppressDisplayport()
 {
   if (!mSuppressionActive) {
-    MOZ_ASSERT(PresContext()->PresShell());
-    APZCCallbackHelper::SuppressDisplayport(true, PresContext()->PresShell());
+    MOZ_ASSERT(PresShell());
+    APZCCallbackHelper::SuppressDisplayport(true, PresShell());
     mSuppressionActive = true;
   }
 }
 
 void
 nsSliderFrame::UnsuppressDisplayport()
 {
   if (mSuppressionActive) {
-    MOZ_ASSERT(PresContext()->PresShell());
-    APZCCallbackHelper::SuppressDisplayport(false, PresContext()->PresShell());
+    MOZ_ASSERT(PresShell());
+    APZCCallbackHelper::SuppressDisplayport(false, PresShell());
     mSuppressionActive = false;
   }
 }
 
 bool
 nsSliderFrame::OnlySystemGroupDispatch(EventMessage aMessage) const
 {
   // If we are in a native anonymous subtree, do not dispatch mouse-move events
--- a/layout/xul/nsTextBoxFrame.cpp
+++ b/layout/xul/nsTextBoxFrame.cpp
@@ -78,17 +78,17 @@ nsTextBoxFrame::AttributeChanged(int32_t
                                  int32_t         aModType)
 {
     bool aResize;
     bool aRedraw;
 
     UpdateAttributes(aAttribute, aResize, aRedraw);
 
     if (aResize) {
-        PresContext()->PresShell()->
+        PresShell()->
             FrameNeedsReflow(this, nsIPresShell::eStyleChange,
                              NS_FRAME_IS_DIRTY);
     } else if (aRedraw) {
         nsBoxLayoutState state(PresContext());
         XULRedraw(state);
     }
 
     // If the accesskey changed, register for the new value
@@ -210,17 +210,17 @@ nsTextBoxFrame::UpdateAccesskey(WeakFram
         mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, accesskey);
     }
 
     if (!accesskey.Equals(mAccessKey)) {
         // Need to get clean mTitle.
         RecomputeTitle();
         mAccessKey = accesskey;
         UpdateAccessTitle();
-        PresContext()->PresShell()->
+        PresShell()->
             FrameNeedsReflow(this, nsIPresShell::eStyleChange,
                              NS_FRAME_IS_DIRTY);
         return true;
     }
     return false;
 }
 
 void
@@ -513,17 +513,17 @@ nsTextBoxFrame::DrawText(gfxContext&    
         params.offset = params.ascent;
         params.decoration = NS_STYLE_TEXT_DECORATION_LINE_OVERLINE;
         params.style = overStyle;
         nsCSSRendering::PaintDecorationLine(this, *drawTarget, params);
       }
     }
 
     RefPtr<gfxContext> refContext =
-        PresContext()->PresShell()->CreateReferenceRenderingContext();
+        PresShell()->CreateReferenceRenderingContext();
     DrawTarget* refDrawTarget = refContext->GetDrawTarget();
 
     CalculateUnderline(refDrawTarget, *fontMet);
 
     nscolor c = aOverrideColor ? *aOverrideColor : StyleColor()->mColor;
     ColorPattern color(ToDeviceColor(c));
     aRenderingContext.SetColor(Color::FromABGR(c));
 
@@ -973,17 +973,17 @@ nsTextBoxFrame::DidSetStyleContext(nsSty
 }
 
 NS_IMETHODIMP
 nsTextBoxFrame::DoXULLayout(nsBoxLayoutState& aBoxLayoutState)
 {
     if (mNeedsReflowCallback) {
         nsIReflowCallback* cb = new nsAsyncAccesskeyUpdate(this);
         if (cb) {
-            PresContext()->PresShell()->PostReflowCallback(cb);
+            PresShell()->PostReflowCallback(cb);
         }
         mNeedsReflowCallback = false;
     }
 
     nsresult rv = nsLeafBoxFrame::DoXULLayout(aBoxLayoutState);
 
     CalcDrawRect(*aBoxLayoutState.GetRenderingContext());
 
@@ -1096,17 +1096,17 @@ nsTextBoxFrame::CalcDrawRect(gfxContext 
     nscoord titleWidth =
         CalculateTitleForWidth(aRenderingContext, textRect.ISize(wm));
 
 #ifdef ACCESSIBILITY
     // Make sure to update the accessible tree in case when cropped title is
     // changed.
     nsAccessibilityService* accService = GetAccService();
     if (accService) {
-        accService->UpdateLabelValue(PresContext()->PresShell(), mContent,
+        accService->UpdateLabelValue(PresShell(), mContent,
                                      mCroppedTitle);
     }
 #endif
 
     // determine if and at which position to put the underline
     UpdateAccessIndex();
 
     // make the rect as small as our (cropped) text.
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -243,17 +243,17 @@ nsTreeBodyFrame::CalcMaxRowWidth()
   nsStyleContext* rowContext = GetPseudoStyleContext(nsCSSAnonBoxes::mozTreeRow);
   nsMargin rowMargin(0,0,0,0);
   GetBorderPadding(rowContext, rowMargin);
 
   nscoord rowWidth;
   nsTreeColumn* col;
 
   RefPtr<gfxContext> rc =
-    PresContext()->PresShell()->CreateReferenceRenderingContext();
+    PresShell()->CreateReferenceRenderingContext();
 
   for (int32_t row = 0; row < mRowCount; ++row) {
     rowWidth = 0;
 
     for (col = mColumns->GetFirstColumn(); col; col = col->GetNext()) {
       nscoord desiredWidth, currentWidth;
       nsresult rv = GetCellWidth(row, col, rc, desiredWidth, currentWidth);
       if (NS_FAILED(rv)) {
@@ -277,17 +277,17 @@ nsTreeBodyFrame::DestroyFrom(nsIFrame* a
   if (mScrollbarActivity) {
     mScrollbarActivity->Destroy();
     mScrollbarActivity = nullptr;
   }
 
   mScrollEvent.Revoke();
   // Make sure we cancel any posted callbacks.
   if (mReflowCallbackPosted) {
-    PresContext()->PresShell()->CancelReflowCallback(this);
+    PresShell()->CancelReflowCallback(this);
     mReflowCallbackPosted = false;
   }
 
   if (mColumns)
     mColumns->SetTree(nullptr);
 
   // Save off our info into the box object.
   nsCOMPtr<nsPIBoxObject> box(do_QueryInterface(mTreeBoxObject));
@@ -344,20 +344,20 @@ nsTreeBodyFrame::EnsureBoxObject()
     }
   }
 }
 
 void
 nsTreeBodyFrame::EnsureView()
 {
   if (!mView) {
-    if (PresContext()->PresShell()->IsReflowLocked()) {
+    if (PresShell()->IsReflowLocked()) {
       if (!mReflowCallbackPosted) {
         mReflowCallbackPosted = true;
-        PresContext()->PresShell()->PostReflowCallback(this);
+        PresShell()->PostReflowCallback(this);
       }
       return;
     }
     nsCOMPtr<nsIBoxObject> box = do_QueryInterface(mTreeBoxObject);
     if (box) {
       AutoWeakFrame weakFrame(this);
       nsCOMPtr<nsITreeView> treeView;
       mTreeBoxObject->GetView(getter_AddRefs(treeView));
@@ -384,23 +384,23 @@ nsTreeBodyFrame::EnsureView()
   }
 }
 
 void
 nsTreeBodyFrame::ManageReflowCallback(const nsRect& aRect, nscoord aHorzWidth)
 {
   if (!mReflowCallbackPosted &&
       (!aRect.IsEqualEdges(mRect) || mHorzWidth != aHorzWidth)) {
-    PresContext()->PresShell()->PostReflowCallback(this);
+    PresShell()->PostReflowCallback(this);
     mReflowCallbackPosted = true;
     mOriginalHorzWidth = mHorzWidth;
   }
   else if (mReflowCallbackPosted &&
            mHorzWidth != aHorzWidth && mOriginalHorzWidth == aHorzWidth) {
-    PresContext()->PresShell()->CancelReflowCallback(this);
+    PresShell()->CancelReflowCallback(this);
     mReflowCallbackPosted = false;
     mOriginalHorzWidth = -1;
   }
 }
 
 void
 nsTreeBodyFrame::SetXULBounds(nsBoxLayoutState& aBoxLayoutState, const nsRect& aRect,
                               bool aRemoveOverflowArea)
@@ -522,22 +522,22 @@ nsTreeBodyFrame::SetView(nsITreeView * a
     }
 
     // View, meet the tree.
     AutoWeakFrame weakFrame(this);
     mView->SetTree(mTreeBoxObject);
     NS_ENSURE_STATE(weakFrame.IsAlive());
     mView->GetRowCount(&mRowCount);
 
-    if (!PresContext()->PresShell()->IsReflowLocked()) {
+    if (!PresShell()->IsReflowLocked()) {
       // The scrollbar will need to be updated.
       FullScrollbarsUpdate(false);
     } else if (!mReflowCallbackPosted) {
       mReflowCallbackPosted = true;
-      PresContext()->PresShell()->PostReflowCallback(this);
+      PresShell()->PostReflowCallback(this);
     }
   }
 
   return NS_OK;
 }
 
 nsresult
 nsTreeBodyFrame::SetFocused(bool aFocused)
@@ -1766,17 +1766,17 @@ nsTreeBodyFrame::IsCellCropped(int32_t a
   nscoord currentSize, desiredSize;
   nsresult rv;
 
   RefPtr<nsTreeColumn> col = GetColumnImpl(aCol);
   if (!col)
     return NS_ERROR_INVALID_ARG;
 
   RefPtr<gfxContext> rc =
-    PresContext()->PresShell()->CreateReferenceRenderingContext();
+    PresShell()->CreateReferenceRenderingContext();
 
   rv = GetCellWidth(aRow, col, rc, desiredSize, currentSize);
   NS_ENSURE_SUCCESS(rv, rv);
 
   *_retval = desiredSize > currentSize;
 
   return NS_OK;
 }
@@ -1787,19 +1787,18 @@ nsTreeBodyFrame::MarkDirtyIfSelect()
   nsIContent* baseElement = GetBaseElement();
 
   if (baseElement && baseElement->IsHTMLElement(nsGkAtoms::select)) {
     // If we are an intrinsically sized select widget, we may need to
     // resize, if the widest item was removed or a new item was added.
     // XXX optimize this more
 
     mStringWidth = -1;
-    PresContext()->PresShell()->FrameNeedsReflow(this,
-                                                 nsIPresShell::eTreeChange,
-                                                 NS_FRAME_IS_DIRTY);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
+                                  NS_FRAME_IS_DIRTY);
   }
 }
 
 nsresult
 nsTreeBodyFrame::CreateTimer(const LookAndFeel::IntID aID,
                              nsTimerCallbackFunc aFunc, int32_t aType,
                              nsITimer** aTimer, const char* aName)
 {
@@ -2915,18 +2914,18 @@ nsTreeBodyFrame::PaintTreeBody(gfxContex
     NSRectToSnappedRect(mInnerBox + aPt, PresContext()->AppUnitsPerDevPixel(),
                         *drawTarget));
   int32_t oldPageCount = mPageLength;
   if (!mHasFixedRowCount)
     mPageLength = mInnerBox.height/mRowHeight;
 
   if (oldPageCount != mPageLength || mHorzWidth != CalcHorzWidth(GetScrollParts())) {
     // Schedule a ResizeReflow that will update our info properly.
-    PresContext()->PresShell()->
-      FrameNeedsReflow(this, nsIPresShell::eResize, NS_FRAME_IS_DIRTY);
+    PresShell()->FrameNeedsReflow(this, nsIPresShell::eResize,
+                                  NS_FRAME_IS_DIRTY);
   }
 #ifdef DEBUG
   int32_t rowCount = mRowCount;
   mView->GetRowCount(&rowCount);
   NS_WARNING_ASSERTION(mRowCount == rowCount, "row count changed unexpectedly");
 #endif
 
   DrawResult result = DrawResult::SUCCESS;
--- a/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp
+++ b/media/webrtc/signaling/src/media-conduit/WebrtcGmpVideoCodec.cpp
@@ -314,23 +314,22 @@ int32_t
 WebrtcGmpVideoEncoder::Encode(const webrtc::VideoFrame& aInputImage,
                               const webrtc::CodecSpecificInfo* aCodecSpecificInfo,
                               const std::vector<webrtc::FrameType>* aFrameTypes)
 {
   MOZ_ASSERT(aInputImage.width() >= 0 && aInputImage.height() >= 0);
   // Would be really nice to avoid this sync dispatch, but it would require a
   // copy of the frame, since it doesn't appear to actually have a refcount.
   // Passing 'this' is safe since this is synchronous.
-  mGMPThread->Dispatch(
+  mozilla::SyncRunnable::DispatchToThread(mGMPThread,
       WrapRunnable(this,
                    &WebrtcGmpVideoEncoder::Encode_g,
                    &aInputImage,
                    aCodecSpecificInfo,
-                   aFrameTypes),
-      NS_DISPATCH_SYNC);
+                   aFrameTypes));
 
   return WEBRTC_VIDEO_CODEC_OK;
 }
 
 void
 WebrtcGmpVideoEncoder::RegetEncoderForResolutionChange(
     uint32_t aWidth,
     uint32_t aHeight,
--- a/modules/libpref/Preferences.h
+++ b/modules/libpref/Preferences.h
@@ -100,101 +100,122 @@ public:
 
   // Returns shared default pref branch instance. NOTE: not addreffed.
   static nsIPrefBranch* GetDefaultRootBranch()
   {
     NS_ENSURE_TRUE(InitStaticMembers(), nullptr);
     return sPreferences->mDefaultRootBranch;
   }
 
-  // Gets int or bool type pref value with default value if failed to get the
-  // pref.
+  // Gets the type of the pref.
+  static int32_t GetDefaultType(const char* aPref);
+
+  // Fallible getters of default values.
+  static nsresult GetDefaultBool(const char* aPref, bool* aResult);
+  static nsresult GetDefaultInt(const char* aPref, int32_t* aResult);
+  static nsresult GetDefaultUint(const char* aPref, uint32_t* aResult)
+  {
+    return GetDefaultInt(aPref, reinterpret_cast<int32_t*>(aResult));
+  }
+  static nsresult GetDefaultCString(const char* aPref, nsACString& aResult);
+  static nsresult GetDefaultString(const char* aPref, nsAString& aResult);
+  static nsresult GetDefaultLocalizedCString(const char* aPref,
+                                             nsACString& aResult);
+  static nsresult GetDefaultLocalizedString(const char* aPref,
+                                            nsAString& aResult);
+  static nsresult GetDefaultComplex(const char* aPref,
+                                    const nsIID& aType,
+                                    void** aResult);
+
+  // Infallible getters of default values, with fallback results on failure.
+  static bool GetDefaultBool(const char* aPref, bool aFailedResult)
+  {
+    bool result;
+    return NS_SUCCEEDED(GetDefaultBool(aPref, &result)) ? result
+                                                        : aFailedResult;
+  }
+  static int32_t GetDefaultInt(const char* aPref, int32_t aFailedResult)
+  {
+    int32_t result;
+    return NS_SUCCEEDED(GetDefaultInt(aPref, &result)) ? result : aFailedResult;
+  }
+  static uint32_t GetDefaultUint(const char* aPref, uint32_t aFailedResult)
+  {
+    return static_cast<uint32_t>(
+      GetDefaultInt(aPref, static_cast<int32_t>(aFailedResult)));
+  }
+
+  // Gets the type of the pref.
+  static int32_t GetType(const char* aPref);
+
+  // Fallible getters of user or default values.
+  static nsresult GetBool(const char* aPref, bool* aResult);
+  static nsresult GetInt(const char* aPref, int32_t* aResult);
+  static nsresult GetUint(const char* aPref, uint32_t* aResult)
+  {
+    return GetInt(aPref, reinterpret_cast<int32_t*>(aResult));
+  }
+  static nsresult GetFloat(const char* aPref, float* aResult);
+  static nsresult GetCString(const char* aPref, nsACString& aResult);
+  static nsresult GetString(const char* aPref, nsAString& aResult);
+  static nsresult GetLocalizedCString(const char* aPref, nsACString& aResult);
+  static nsresult GetLocalizedString(const char* aPref, nsAString& aResult);
+  static nsresult GetComplex(const char* aPref,
+                             const nsIID& aType,
+                             void** aResult);
+
+  // Infallible getters of user or default values, with fallback results on
+  // failure.
   static bool GetBool(const char* aPref, bool aDefault = false)
   {
     bool result = aDefault;
     GetBool(aPref, &result);
     return result;
   }
-
   static int32_t GetInt(const char* aPref, int32_t aDefault = 0)
   {
     int32_t result = aDefault;
     GetInt(aPref, &result);
     return result;
   }
-
   static uint32_t GetUint(const char* aPref, uint32_t aDefault = 0)
   {
     uint32_t result = aDefault;
     GetUint(aPref, &result);
     return result;
   }
-
   static float GetFloat(const char* aPref, float aDefault = 0)
   {
     float result = aDefault;
     GetFloat(aPref, &result);
     return result;
   }
 
-  // Gets int, float, or bool type pref value with raw return value of
-  // nsIPrefBranch.
-  //
-  // |aResult| must not be nullptr; its contents are never modified when these
-  // methods fail.
-  static nsresult GetBool(const char* aPref, bool* aResult);
-  static nsresult GetInt(const char* aPref, int32_t* aResult);
-  static nsresult GetFloat(const char* aPref, float* aResult);
-  static nsresult GetUint(const char* aPref, uint32_t* aResult)
-  {
-    int32_t result;
-    nsresult rv = GetInt(aPref, &result);
-    if (NS_SUCCEEDED(rv)) {
-      *aResult = static_cast<uint32_t>(result);
-    }
-    return rv;
-  }
-
-  // Gets string type pref value with raw return value of nsIPrefBranch.
-  // |aResult| is never modified when these methods fail.
-  static nsresult GetCString(const char* aPref, nsACString& aResult);
-  static nsresult GetString(const char* aPref, nsAString& aResult);
-  static nsresult GetLocalizedCString(const char* aPref, nsACString& aResult);
-  static nsresult GetLocalizedString(const char* aPref, nsAString& aResult);
-
-  static nsresult GetComplex(const char* aPref,
-                             const nsIID& aType,
-                             void** aResult);
-
-  // Sets various type pref values.
+  // Setters of user values.
   static nsresult SetBool(const char* aPref, bool aValue);
   static nsresult SetInt(const char* aPref, int32_t aValue);
   static nsresult SetUint(const char* aPref, uint32_t aValue)
   {
     return SetInt(aPref, static_cast<int32_t>(aValue));
   }
   static nsresult SetFloat(const char* aPref, float aValue);
   static nsresult SetCString(const char* aPref, const char* aValue);
   static nsresult SetCString(const char* aPref, const nsACString& aValue);
   static nsresult SetString(const char* aPref, const char16ptr_t aValue);
   static nsresult SetString(const char* aPref, const nsAString& aValue);
-
   static nsresult SetComplex(const char* aPref,
                              const nsIID& aType,
                              nsISupports* aValue);
 
   // Clears user set pref.
   static nsresult ClearUser(const char* aPref);
 
   // Whether the pref has a user value or not.
   static bool HasUserValue(const char* aPref);
 
-  // Gets the type of the pref.
-  static int32_t GetType(const char* aPref);
-
   // Adds/Removes the observer for the root pref branch. See nsIPrefBranch.idl
   // for details.
   static nsresult AddStrongObserver(nsIObserver* aObserver, const char* aPref);
   static nsresult AddWeakObserver(nsIObserver* aObserver, const char* aPref);
   static nsresult RemoveObserver(nsIObserver* aObserver, const char* aPref);
 
   // Adds/Removes two or more observers for the root pref branch. Pass to
   // aPrefs an array of const char* whose last item is nullptr.
@@ -270,61 +291,16 @@ public:
   template<MemoryOrdering Order>
   static nsresult AddAtomicUintVarCache(Atomic<uint32_t, Order>* aVariable,
                                         const char* aPref,
                                         uint32_t aDefault = 0);
   static nsresult AddFloatVarCache(float* aVariable,
                                    const char* aPref,
                                    float aDefault = 0.0f);
 
-  // Gets the default bool, int or uint value of the pref. The result is raw
-  // result of nsIPrefBranch::Get*Pref(). If the pref could have any value, you
-  // need to use these methods. If not so, you could use the methods below.
-  static nsresult GetDefaultBool(const char* aPref, bool* aResult);
-  static nsresult GetDefaultInt(const char* aPref, int32_t* aResult);
-  static nsresult GetDefaultUint(const char* aPref, uint32_t* aResult)
-  {
-    return GetDefaultInt(aPref, reinterpret_cast<int32_t*>(aResult));
-  }
-
-  // Gets the default bool, int or uint value of the pref directly. You can set
-  // an invalid value of the pref to |aFailedResult|. If these methods fail to
-  // get the default value, they return |aFailedResult|.
-  static bool GetDefaultBool(const char* aPref, bool aFailedResult)
-  {
-    bool result;
-    return NS_SUCCEEDED(GetDefaultBool(aPref, &result)) ? result
-                                                        : aFailedResult;
-  }
-  static int32_t GetDefaultInt(const char* aPref, int32_t aFailedResult)
-  {
-    int32_t result;
-    return NS_SUCCEEDED(GetDefaultInt(aPref, &result)) ? result : aFailedResult;
-  }
-  static uint32_t GetDefaultUint(const char* aPref, uint32_t aFailedResult)
-  {
-    return static_cast<uint32_t>(
-      GetDefaultInt(aPref, static_cast<int32_t>(aFailedResult)));
-  }
-
-  // Gets the default value of the char type pref.
-  static nsresult GetDefaultCString(const char* aPref, nsACString& aResult);
-  static nsresult GetDefaultString(const char* aPref, nsAString& aResult);
-  static nsresult GetDefaultLocalizedCString(const char* aPref,
-                                             nsACString& aResult);
-  static nsresult GetDefaultLocalizedString(const char* aPref,
-                                            nsAString& aResult);
-
-  static nsresult GetDefaultComplex(const char* aPref,
-                                    const nsIID& aType,
-                                    void** aResult);
-
-  // Gets the type of the pref.
-  static int32_t GetDefaultType(const char* aPref);
-
   // Used to synchronise preferences between chrome and content processes.
   static void GetPreferences(InfallibleTArray<PrefSetting>* aPrefs);
   static void GetPreference(PrefSetting* aPref);
   static void SetPreference(const PrefSetting& aPref);
 
   static void SetInitPreferences(nsTArray<PrefSetting>* aPrefs);
 
 #ifdef DEBUG
--- a/netwerk/base/LoadInfo.cpp
+++ b/netwerk/base/LoadInfo.cpp
@@ -53,16 +53,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
   , mLoadingContext(do_GetWeakReference(aLoadingContext))
   , mContextForTopLevelLoad(nullptr)
   , mSecurityFlags(aSecurityFlags)
   , mInternalContentPolicyType(aContentPolicyType)
   , mTainting(LoadTainting::Basic)
   , mUpgradeInsecureRequests(false)
   , mVerifySignedContent(false)
   , mEnforceSRI(false)
+  , mForceAllowDataURI(false)
   , mForceInheritPrincipalDropped(false)
   , mInnerWindowID(0)
   , mOuterWindowID(0)
   , mParentOuterWindowID(0)
   , mTopOuterWindowID(0)
   , mFrameOuterWindowID(0)
   , mEnforceSecurity(false)
   , mInitialSecurityCheckDone(false)
@@ -236,16 +237,17 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* a
   , mPrincipalToInherit(nullptr)
   , mContextForTopLevelLoad(do_GetWeakReference(aContextForTopLevelLoad))
   , mSecurityFlags(aSecurityFlags)
   , mInternalContentPolicyType(nsIContentPolicy::TYPE_DOCUMENT)
   , mTainting(LoadTainting::Basic)
   , mUpgradeInsecureRequests(false)
   , mVerifySignedContent(false)
   , mEnforceSRI(false)
+  , mForceAllowDataURI(false)
   , mForceInheritPrincipalDropped(false)
   , mInnerWindowID(0)
   , mOuterWindowID(0)
   , mParentOuterWindowID(0)
   , mTopOuterWindowID(0)
   , mFrameOuterWindowID(0)
   , mEnforceSecurity(false)
   , mInitialSecurityCheckDone(false)
@@ -304,16 +306,17 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
   , mLoadingContext(rhs.mLoadingContext)
   , mContextForTopLevelLoad(rhs.mContextForTopLevelLoad)
   , mSecurityFlags(rhs.mSecurityFlags)
   , mInternalContentPolicyType(rhs.mInternalContentPolicyType)
   , mTainting(rhs.mTainting)
   , mUpgradeInsecureRequests(rhs.mUpgradeInsecureRequests)
   , mVerifySignedContent(rhs.mVerifySignedContent)
   , mEnforceSRI(rhs.mEnforceSRI)
+  , mForceAllowDataURI(rhs.mForceAllowDataURI)
   , mForceInheritPrincipalDropped(rhs.mForceInheritPrincipalDropped)
   , mInnerWindowID(rhs.mInnerWindowID)
   , mOuterWindowID(rhs.mOuterWindowID)
   , mParentOuterWindowID(rhs.mParentOuterWindowID)
   , mTopOuterWindowID(rhs.mTopOuterWindowID)
   , mFrameOuterWindowID(rhs.mFrameOuterWindowID)
   , mEnforceSecurity(rhs.mEnforceSecurity)
   , mInitialSecurityCheckDone(rhs.mInitialSecurityCheckDone)
@@ -341,16 +344,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
                    nsIPrincipal* aSandboxedLoadingPrincipal,
                    nsIURI* aResultPrincipalURI,
                    nsSecurityFlags aSecurityFlags,
                    nsContentPolicyType aContentPolicyType,
                    LoadTainting aTainting,
                    bool aUpgradeInsecureRequests,
                    bool aVerifySignedContent,
                    bool aEnforceSRI,
+                   bool aForceAllowDataURI,
                    bool aForceInheritPrincipalDropped,
                    uint64_t aInnerWindowID,
                    uint64_t aOuterWindowID,
                    uint64_t aParentOuterWindowID,
                    uint64_t aTopOuterWindowID,
                    uint64_t aFrameOuterWindowID,
                    bool aEnforceSecurity,
                    bool aInitialSecurityCheckDone,
@@ -373,16 +377,17 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadin
   , mPrincipalToInherit(aPrincipalToInherit)
   , mResultPrincipalURI(aResultPrincipalURI)
   , mSecurityFlags(aSecurityFlags)
   , mInternalContentPolicyType(aContentPolicyType)
   , mTainting(aTainting)
   , mUpgradeInsecureRequests(aUpgradeInsecureRequests)
   , mVerifySignedContent(aVerifySignedContent)
   , mEnforceSRI(aEnforceSRI)
+  , mForceAllowDataURI(aForceAllowDataURI)
   , mForceInheritPrincipalDropped(aForceInheritPrincipalDropped)
   , mInnerWindowID(aInnerWindowID)
   , mOuterWindowID(aOuterWindowID)
   , mParentOuterWindowID(aParentOuterWindowID)
   , mTopOuterWindowID(aTopOuterWindowID)
   , mFrameOuterWindowID(aFrameOuterWindowID)
   , mEnforceSecurity(aEnforceSecurity)
   , mInitialSecurityCheckDone(aInitialSecurityCheckDone)
@@ -747,16 +752,33 @@ LoadInfo::SetEnforceSRI(bool aEnforceSRI
 NS_IMETHODIMP
 LoadInfo::GetEnforceSRI(bool* aResult)
 {
   *aResult = mEnforceSRI;
   return NS_OK;
 }
 
 NS_IMETHODIMP
+LoadInfo::SetForceAllowDataURI(bool aForceAllowDataURI)
+{
+  MOZ_ASSERT(!mForceAllowDataURI ||
+             mInternalContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT,
+             "can only allow data URI navigation for TYPE_DOCUMENT");
+  mForceAllowDataURI = aForceAllowDataURI;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+LoadInfo::GetForceAllowDataURI(bool* aForceAllowDataURI)
+{
+  *aForceAllowDataURI = mForceAllowDataURI;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 LoadInfo::GetForceInheritPrincipalDropped(bool* aResult)
 {
   *aResult = mForceInheritPrincipalDropped;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 LoadInfo::GetInnerWindowID(uint64_t* aResult)
--- a/netwerk/base/LoadInfo.h
+++ b/netwerk/base/LoadInfo.h
@@ -98,16 +98,17 @@ private:
            nsIPrincipal* aSandboxedLoadingPrincipal,
            nsIURI* aResultPrincipalURI,
            nsSecurityFlags aSecurityFlags,
            nsContentPolicyType aContentPolicyType,
            LoadTainting aTainting,
            bool aUpgradeInsecureRequests,
            bool aVerifySignedContent,
            bool aEnforceSRI,
+           bool aForceAllowDataURI,
            bool aForceInheritPrincipalDropped,
            uint64_t aInnerWindowID,
            uint64_t aOuterWindowID,
            uint64_t aParentOuterWindowID,
            uint64_t aTopOuterWindowID,
            uint64_t aFrameOuterWindowID,
            bool aEnforceSecurity,
            bool aInitialSecurityCheckDone,
@@ -154,16 +155,17 @@ private:
   nsWeakPtr                        mLoadingContext;
   nsWeakPtr                        mContextForTopLevelLoad;
   nsSecurityFlags                  mSecurityFlags;
   nsContentPolicyType              mInternalContentPolicyType;
   LoadTainting                     mTainting;
   bool                             mUpgradeInsecureRequests;
   bool                             mVerifySignedContent;
   bool                             mEnforceSRI;
+  bool                             mForceAllowDataURI;
   bool                             mForceInheritPrincipalDropped;
   uint64_t                         mInnerWindowID;
   uint64_t                         mOuterWindowID;
   uint64_t                         mParentOuterWindowID;
   uint64_t                         mTopOuterWindowID;
   uint64_t                         mFrameOuterWindowID;
   bool                             mEnforceSecurity;
   bool                             mInitialSecurityCheckDone;
--- a/netwerk/base/nsILoadInfo.idl
+++ b/netwerk/base/nsILoadInfo.idl
@@ -502,16 +502,21 @@ interface nsILoadInfo : nsISupports
   [infallible] attribute boolean verifySignedContent;
 
   /**
    * If true, this load will fail if it has no SRI integrity
    */
   [infallible] attribute boolean enforceSRI;
 
   /**
+   * If true, toplevel data: URI navigation is allowed
+   */
+  [infallible] attribute boolean forceAllowDataURI;
+
+  /**
    * The SEC_FORCE_INHERIT_PRINCIPAL flag may be dropped when a load info
    * object is created.  Specifically, it will be dropped if the SEC_SANDBOXED
    * flag is also present.  This flag is set if SEC_FORCE_INHERIT_PRINCIPAL was
    * dropped.
    */
   [infallible] readonly attribute boolean forceInheritPrincipalDropped;
 
   /**
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -42,16 +42,17 @@ struct LoadInfoArgs
   OptionalPrincipalInfo       sandboxedLoadingPrincipalInfo;
   OptionalURIParams           resultPrincipalURI;
   uint32_t                    securityFlags;
   uint32_t                    contentPolicyType;
   uint32_t                    tainting;
   bool                        upgradeInsecureRequests;
   bool                        verifySignedContent;
   bool                        enforceSRI;
+  bool                        forceAllowDataURI;
   bool                        forceInheritPrincipalDropped;
   uint64_t                    innerWindowID;
   uint64_t                    outerWindowID;
   uint64_t                    parentOuterWindowID;
   uint64_t                    topOuterWindowID;
   uint64_t                    frameOuterWindowID;
   bool                        enforceSecurity;
   bool                        initialSecurityCheckDone;
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -114,18 +114,16 @@ Http2Session::Http2Session(nsISocketTran
   , mPingSentEpoch(0)
   , mPreviousUsed(false)
   , mWaitingForSettingsAck(false)
   , mGoAwayOnPush(false)
   , mUseH2Deps(false)
   , mAttemptingEarlyData(attemptingEarlyData)
   , mOriginFrameActivated(false)
   , mTlsHandshakeFinished(false)
-  , mFlushOKAddStream(false)
-  , mFlushOKReadSegments(false)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
   static uint64_t sSerial;
   mSerial = ++sSerial;
 
   LOG3(("Http2Session::Http2Session %p serial=0x%" PRIX64 "\n", this, mSerial));
 
@@ -381,23 +379,16 @@ Http2Session::RegisterStreamID(Http2Stre
 bool
 Http2Session::AddStream(nsAHttpTransaction *aHttpTransaction,
                         int32_t aPriority,
                         bool aUseTunnel,
                         nsIInterfaceRequestor *aCallbacks)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
-  MOZ_DIAGNOSTIC_ASSERT(!mFlushOKAddStream);
-  mFlushOKAddStream = true;
-  auto cleanup = MakeScopeExit([&] () {
-    MOZ_DIAGNOSTIC_ASSERT(mFlushOKAddStream);
-    mFlushOKAddStream = false;
-  });
-
   // integrity check
   if (mStreamTransactionHash.Get(aHttpTransaction)) {
     LOG3(("   New transaction already present\n"));
     MOZ_ASSERT(false, "AddStream duplicate transaction pointer");
     return false;
   }
 
   if (!mConnection) {
@@ -547,34 +538,16 @@ Http2Session::RealignOutputQueue()
   mOutputQueueUsed -= mOutputQueueSent;
   memmove(mOutputQueueBuffer.get(),
           mOutputQueueBuffer.get() + mOutputQueueSent,
           mOutputQueueUsed);
   mOutputQueueSent = 0;
 }
 
 void
-Http2Session::MaybeFlushOutputQueue()
-{
-  // Only try to flush the output queue if we know any mSegmentReader that's set
-  // is properly set through the right channels. Otherwise, just set our write
-  // callbacks so the connection can call in with a proper segment reader that
-  // we'll be sure we can write to.
-  // See bug 1402014 comment 6
-  MOZ_ASSERT(OnSocketThread(), "not on socket thread");
-  LOG3(("Http2Session::MaybeFlushOutputQueue mFlushOKAddStream=%d, "
-        "mFlushOKReadSegments=%d", mFlushOKAddStream, mFlushOKReadSegments));
-  if (mFlushOKAddStream || mFlushOKReadSegments) {
-    FlushOutputQueue();
-  } else {
-    SetWriteCallbacks();
-  }
-}
-
-void
 Http2Session::FlushOutputQueue()
 {
   if (!mSegmentReader || !mOutputQueueUsed)
     return;
 
   nsresult rv;
   uint32_t countRead;
   uint32_t avail = mOutputQueueUsed - mOutputQueueSent;
@@ -816,44 +789,44 @@ Http2Session::GeneratePing(bool isAck)
     memcpy(packet + kFrameHeaderBytes,
            mInputFrameBuffer.get() + kFrameHeaderBytes, 8);
   } else {
     CreateFrameHeader(packet, 8, FRAME_TYPE_PING, 0, 0);
     memset(packet + kFrameHeaderBytes, 0, 8);
   }
 
   LogIO(this, nullptr, "Generate Ping", packet, kFrameHeaderBytes + 8);
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 }
 
 void
 Http2Session::GenerateSettingsAck()
 {
   // need to generate ack of this settings frame
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
   LOG3(("Http2Session::GenerateSettingsAck %p\n", this));
 
   char *packet = EnsureOutputBuffer(kFrameHeaderBytes);
   mOutputQueueUsed += kFrameHeaderBytes;
   CreateFrameHeader(packet, 0, FRAME_TYPE_SETTINGS, kFlag_ACK, 0);
   LogIO(this, nullptr, "Generate Settings ACK", packet, kFrameHeaderBytes);
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 }
 
 void
 Http2Session::GeneratePriority(uint32_t aID, uint8_t aPriorityWeight)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
   LOG3(("Http2Session::GeneratePriority %p %X %X\n",
         this, aID, aPriorityWeight));
 
   char *packet = CreatePriorityFrame(aID, 0, aPriorityWeight);
 
   LogIO(this, nullptr, "Generate Priority", packet, kFrameHeaderBytes + 5);
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 }
 
 void
 Http2Session::GenerateRstStream(uint32_t aStatusCode, uint32_t aID)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
   // make sure we don't do this twice for the same stream (at least if we
@@ -870,17 +843,17 @@ Http2Session::GenerateRstStream(uint32_t
   uint32_t frameSize = kFrameHeaderBytes + 4;
   char *packet = EnsureOutputBuffer(frameSize);
   mOutputQueueUsed += frameSize;
   CreateFrameHeader(packet, 4, FRAME_TYPE_RST_STREAM, 0, aID);
 
   NetworkEndian::writeUint32(packet + kFrameHeaderBytes, aStatusCode);
 
   LogIO(this, nullptr, "Generate Reset", packet, frameSize);
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 }
 
 void
 Http2Session::GenerateGoAway(uint32_t aStatusCode)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
   LOG3(("Http2Session::GenerateGoAway %p code=%X\n", this, aStatusCode));
 
@@ -893,17 +866,17 @@ Http2Session::GenerateGoAway(uint32_t aS
 
   // last-good-stream-id are bytes 9-12 reflecting pushes
   NetworkEndian::writeUint32(packet + kFrameHeaderBytes, mOutgoingGoAwayID);
 
   // bytes 13-16 are the status code.
   NetworkEndian::writeUint32(packet + frameSize - 4, aStatusCode);
 
   LogIO(this, nullptr, "Generate GoAway", packet, frameSize);
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 }
 
 // The Hello is comprised of
 // 1] 24 octets of magic, which are designed to
 // flush out silent but broken intermediaries
 // 2] a settings frame which sets a small flow control window for pushes
 // 3] a window update frame which creates a large session flow control window
 // 4] 6 priority frames for streams which will never be opened with headers
@@ -1015,32 +988,32 @@ Http2Session::SendHello()
     MOZ_ASSERT(mNextStreamID == kUrgentStartGroupID);
     CreatePriorityNode(kUrgentStartGroupID, 0, 240, "urgentStart");
     mNextStreamID += 2;
     // Hey, you! YES YOU! If you add/remove any groups here, you almost
     // certainly need to change the lookup of the stream/ID hash in
     // Http2Session::OnTransportStatus. Yeah, that's right. YOU!
   }
 
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 }
 
 void
 Http2Session::SendPriorityFrame(uint32_t streamID,
                                 uint32_t dependsOn,
                                 uint8_t weight)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
   LOG3(("Http2Session::SendPriorityFrame %p Frame 0x%X depends on 0x%X "
         "weight %d\n", this, streamID, dependsOn, weight));
 
   char *packet = CreatePriorityFrame(streamID, dependsOn, weight);
 
   LogIO(this, nullptr, "SendPriorityFrame", packet, kFrameHeaderBytes + 5);
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 }
 
 char *
 Http2Session::CreatePriorityFrame(uint32_t streamID,
                                   uint32_t dependsOn,
                                   uint8_t weight)
 {
   char *packet = EnsureOutputBuffer(kFrameHeaderBytes + 5);
@@ -2767,47 +2740,39 @@ nsresult
 Http2Session::ReadSegmentsAgain(nsAHttpSegmentReader *reader,
                                 uint32_t count, uint32_t *countRead, bool *again)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
   MOZ_ASSERT(!mSegmentReader || !reader || (mSegmentReader == reader),
              "Inconsistent Write Function Callback");
 
-  MOZ_DIAGNOSTIC_ASSERT(!mFlushOKReadSegments);
-  mFlushOKReadSegments = true;
-  auto cleanup = MakeScopeExit([&] () {
-    MOZ_DIAGNOSTIC_ASSERT(mFlushOKReadSegments);
-    mFlushOKReadSegments = false;
-  });
-
   nsresult rv = ConfirmTLSProfile();
   if (NS_FAILED(rv)) {
     if (mGoAwayReason == INADEQUATE_SECURITY) {
       LOG3(("Http2Session::ReadSegments %p returning INADEQUATE_SECURITY %" PRIx32,
             this, static_cast<uint32_t>(NS_ERROR_NET_INADEQUATE_SECURITY)));
       rv = NS_ERROR_NET_INADEQUATE_SECURITY;
     }
     return rv;
   }
 
-  if (reader) {
-    SetSegmentReader(reader);
-  }
+  if (reader)
+    mSegmentReader = reader;
 
   *countRead = 0;
 
   LOG3(("Http2Session::ReadSegments %p", this));
 
   Http2Stream *stream = static_cast<Http2Stream *>(mReadyForWrite.PopFront());
   if (!stream) {
     LOG3(("Http2Session %p could not identify a stream to write; suspending.",
           this));
     uint32_t availBeforeFlush = mOutputQueueUsed - mOutputQueueSent;
-    MaybeFlushOutputQueue();
+    FlushOutputQueue();
     uint32_t availAfterFlush = mOutputQueueUsed - mOutputQueueSent;
     if (availBeforeFlush != availAfterFlush) {
       LOG3(("Http2Session %p ResumeRecv After early flush in ReadSegments", this));
       Unused << ResumeRecv();
     }
     SetWriteCallbacks();
     if (mAttemptingEarlyData) {
       // We can still try to send our preamble as early-data
@@ -2816,17 +2781,17 @@ Http2Session::ReadSegmentsAgain(nsAHttpS
     return *countRead ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
   }
 
   uint32_t earlyDataUsed = 0;
   if (mAttemptingEarlyData) {
     if (!stream->Do0RTT()) {
       LOG3(("Http2Session %p will not get early data from Http2Stream %p 0x%X",
             this, stream, stream->StreamID()));
-      MaybeFlushOutputQueue();
+      FlushOutputQueue();
       SetWriteCallbacks();
       if (!mCannotDo0RTTStreams.Contains(stream)) {
         mCannotDo0RTTStreams.AppendElement(stream);
       }
       // We can still send our preamble
       *countRead = mOutputQueueUsed - mOutputQueueSent;
       return *countRead ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
     }
@@ -2858,17 +2823,17 @@ Http2Session::ReadSegmentsAgain(nsAHttpS
           stream->StreamID()));
     m0RTTStreams.AppendElement(stream);
   }
 
   // Not every permutation of stream->ReadSegents produces data (and therefore
   // tries to flush the output queue) - SENDING_FIN_STREAM can be an example
   // of that. But we might still have old data buffered that would be good
   // to flush.
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 
   // Allow new server reads - that might be data or control information
   // (e.g. window updates or http replies) that are responses to these writes
   Unused << ResumeRecv();
 
   if (stream->RequestBlockedOnRead()) {
 
     // We are blocked waiting for input - either more http headers or
@@ -3669,17 +3634,17 @@ void
 Http2Session::UpdateLocalRwin(Http2Stream *stream, uint32_t bytes)
 {
   // make sure there is room for 2 window updates even though
   // we may not generate any.
   EnsureOutputBuffer(2 * (kFrameHeaderBytes + 4));
 
   UpdateLocalStreamWindow(stream, bytes);
   UpdateLocalSessionWindow(bytes);
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 }
 
 void
 Http2Session::Close(nsresult aReason)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
 
   if (mClosed)
@@ -3758,17 +3723,17 @@ Http2Session::OnReadSegment(const char *
                             uint32_t count, uint32_t *countRead)
 {
   MOZ_ASSERT(OnSocketThread(), "not on socket thread");
   nsresult rv;
 
   // If we can release old queued data then we can try and write the new
   // data directly to the network without using the output queue at all
   if (mOutputQueueUsed)
-    MaybeFlushOutputQueue();
+    FlushOutputQueue();
 
   if (!mOutputQueueUsed && mSegmentReader) {
     // try and write directly without output queue
     rv = mSegmentReader->OnReadSegment(buf, count, countRead);
 
     if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
       *countRead = 0;
     } else if (NS_FAILED(rv)) {
@@ -3800,26 +3765,26 @@ Http2Session::OnReadSegment(const char *
 
   if ((mOutputQueueUsed + count) > (mOutputQueueSize - kQueueReserved))
     return NS_BASE_STREAM_WOULD_BLOCK;
 
   memcpy(mOutputQueueBuffer.get() + mOutputQueueUsed, buf, count);
   mOutputQueueUsed += count;
   *countRead = count;
 
-  MaybeFlushOutputQueue();
+  FlushOutputQueue();
 
   return NS_OK;
 }
 
 nsresult
 Http2Session::CommitToSegmentSize(uint32_t count, bool forceCommitment)
 {
   if (mOutputQueueUsed && !mAttemptingEarlyData)
-    MaybeFlushOutputQueue();
+    FlushOutputQueue();
 
   // would there be enough room to buffer this if needed?
   if ((mOutputQueueUsed + count) <= (mOutputQueueSize - kQueueReserved))
     return NS_OK;
 
   // if we are using part of our buffers already, try again later unless
   // forceCommitment is set.
   if (mOutputQueueUsed && !forceCommitment)
@@ -4586,23 +4551,10 @@ Http2Session::TopLevelOuterContentWindow
 
   mCurrentForegroundTabOuterContentWindowId = windowId;
 
   for (auto iter = mStreamTransactionHash.Iter(); !iter.Done(); iter.Next()) {
     iter.Data()->TopLevelOuterContentWindowIdChanged(windowId);
   }
 }
 
-void
-Http2Session::SetSegmentReader(nsAHttpSegmentReader *reader)
-{
-  LOG3(("Http2Session::SetSegmentReader this=%p mClosed=%d mSegmentReader=%p reader=%p",
-        this, mClosed, mSegmentReader, reader));
-  MOZ_DIAGNOSTIC_ASSERT(!mSegmentReader || reader == mSegmentReader);
-  if (mClosed) {
-    mSegmentReader = nullptr;
-  } else {
-    mSegmentReader = reader;
-  }
-}
-
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/Http2Session.h
+++ b/netwerk/protocol/http/Http2Session.h
@@ -215,17 +215,17 @@ public:
 
   // a similar version for Http2Stream
   void TransactionHasDataToWrite(Http2Stream *);
 
   // an overload of nsAHttpSegementReader
   virtual MOZ_MUST_USE nsresult CommitToSegmentSize(uint32_t size,
                                                     bool forceCommitment) override;
   MOZ_MUST_USE nsresult BufferOutput(const char *, uint32_t, uint32_t *);
-  void     MaybeFlushOutputQueue();
+  void     FlushOutputQueue();
   uint32_t AmountOfOutputBuffered() { return mOutputQueueUsed - mOutputQueueSent; }
 
   uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
 
   MOZ_MUST_USE bool TryToActivate(Http2Stream *stream);
   void ConnectPushedStream(Http2Stream *stream);
   void ConnectSlowConsumer(Http2Stream *stream);
 
@@ -558,22 +558,16 @@ private:
     nsHttpRequestHead mRequestHead;
   };
 
   // A h2 session will be created before all socket events are trigered,
   // e.g. NS_NET_STATUS_TLS_HANDSHAKE_ENDED and for TFO many others.
   // We should propagate this events to the first nsHttpTransaction.
   RefPtr<nsHttpTransaction> mFirstHttpTransaction;
   bool mTlsHandshakeFinished;
-
-  void SetSegmentReader(nsAHttpSegmentReader *);
-  void FlushOutputQueue();
-  bool mFlushOKAddStream;
-  bool mFlushOKReadSegments;
-
 private:
 /// connect tunnels
   void DispatchOnTunnel(nsAHttpTransaction *, nsIInterfaceRequestor *);
   void CreateTunnel(nsHttpTransaction *, nsHttpConnectionInfo *, nsIInterfaceRequestor *);
   void RegisterTunnel(Http2Stream *);
   void UnRegisterTunnel(Http2Stream *);
   uint32_t FindTunnelCount(nsHttpConnectionInfo *);
   nsDataHashtable<nsCStringHashKey, uint32_t> mTunnelHash;
--- a/netwerk/protocol/http/Http2Stream.cpp
+++ b/netwerk/protocol/http/Http2Stream.cpp
@@ -953,17 +953,17 @@ Http2Stream::TransmitFrame(const char *b
 
     Http2Session::LogIO(mSession, this, "Writing from Transaction Buffer",
                          buf, transmittedCount);
 
     *countUsed += mTxStreamFrameSize;
   }
 
   if (!mAttempting0RTT) {
-    mSession->MaybeFlushOutputQueue();
+    mSession->FlushOutputQueue();
   }
 
   // calling this will trigger waiting_for if mRequestBodyLenRemaining is 0
   UpdateTransportSendEvents(mTxInlineFrameUsed + mTxStreamFrameSize);
 
   mTxInlineFrameUsed = 0;
   mTxStreamFrameSize = 0;
 
--- a/taskcluster/scripts/misc/build-clang-windows-helper32.sh
+++ b/taskcluster/scripts/misc/build-clang-windows-helper32.sh
@@ -42,16 +42,18 @@ MOZCONFIG="$(pwd)/mozconfig"
 cat > ${MOZCONFIG} <<EOF
 mk_add_options MOZ_OBJDIR=$(pwd)/objdir
 EOF
 
 # gets a bit too verbose here
 set +x
 
 BUILD_CLANG_DIR=build/src/build/build-clang
-MOZCONFIG=${MOZCONFIG} build/src/mach python ${BUILD_CLANG_DIR}/build-clang.py -c ${BUILD_CLANG_DIR}/${1}
+cd ${BUILD_CLANG_DIR}
+MOZCONFIG=${MOZCONFIG} ../../mach python ./build-clang.py -c ./${1}
+cd -
 
 set -x
 
 # Put a tarball in the artifacts dir
 UPLOAD_PATH=public/build
 mkdir -p ${UPLOAD_PATH}
-cp clang*.tar.* ${UPLOAD_PATH}
+cp ${BUILD_CLANG_DIR}/clang*.tar.* ${UPLOAD_PATH}
--- a/taskcluster/scripts/misc/build-clang-windows-helper64.sh
+++ b/taskcluster/scripts/misc/build-clang-windows-helper64.sh
@@ -41,16 +41,19 @@ MOZCONFIG="$(pwd)/mozconfig"
 cat > ${MOZCONFIG} <<EOF
 mk_add_options MOZ_OBJDIR=$(pwd)/objdir
 EOF
 
 # gets a bit too verbose here
 set +x
 
 BUILD_CLANG_DIR=build/src/build/build-clang
-MOZCONFIG=${MOZCONFIG} build/src/mach python ${BUILD_CLANG_DIR}/build-clang.py -c ${BUILD_CLANG_DIR}/${1}
+cd ${BUILD_CLANG_DIR}
+MOZCONFIG=${MOZCONFIG} ../../mach python ./build-clang.py -c ./${1}
+cd -
+
 
 set -x
 
 # Put a tarball in the artifacts dir
 UPLOAD_PATH=public/build
 mkdir -p ${UPLOAD_PATH}
-cp clang*.tar.* ${UPLOAD_PATH}
+cp ${BUILD_CLANG_DIR}/clang*.tar.* ${UPLOAD_PATH}
--- a/testing/mozbase/mozfile/mozfile/mozfile.py
+++ b/testing/mozbase/mozfile/mozfile/mozfile.py
@@ -56,27 +56,18 @@ def extract_zip(src, dest):
             bundle = zipfile.ZipFile(src)
         except Exception:
             print("src: %s" % src)
             raise
 
     namelist = bundle.namelist()
 
     for name in namelist:
+        bundle.extract(name, dest)
         filename = os.path.realpath(os.path.join(dest, name))
-        if name.endswith('/'):
-            if not os.path.isdir(filename):
-                os.makedirs(filename)
-        else:
-            path = os.path.dirname(filename)
-            if not os.path.isdir(path):
-                os.makedirs(path)
-            _dest = open(filename, 'wb')
-            _dest.write(bundle.read(name))
-            _dest.close()
         mode = bundle.getinfo(name).external_attr >> 16 & 0x1FF
         # Only update permissions if attributes are set. Otherwise fallback to the defaults.
         if mode:
             os.chmod(filename, mode)
     bundle.close()
     return namelist
 
 
--- a/toolkit/components/extensions/webrequest/StreamFilterParent.cpp
+++ b/toolkit/components/extensions/webrequest/StreamFilterParent.cpp
@@ -413,18 +413,21 @@ StreamFilterParent::OnStartRequest(nsIRe
     });
   }
 
   nsresult rv = mOrigListener->OnStartRequest(aRequest, aContext);
 
   // Important: Do this only *after* running the next listener in the chain, so
   // that we get the final delivery target after any retargeting that it may do.
   if (nsCOMPtr<nsIThreadRetargetableRequest> req = do_QueryInterface(aRequest)) {
-    Unused << req->GetDeliveryTarget(getter_AddRefs(mIOThread));
-    MOZ_ASSERT(mIOThread);
+    nsCOMPtr<nsIEventTarget> thread;
+    Unused << req->GetDeliveryTarget(getter_AddRefs(thread));
+    if (thread) {
+      mIOThread = Move(thread);
+    }
   }
 
   return rv;
 }
 
 NS_IMETHODIMP
 StreamFilterParent::OnStopRequest(nsIRequest* aRequest,
                                   nsISupports* aContext,
--- a/view/nsView.cpp
+++ b/view/nsView.cpp
@@ -1141,10 +1141,10 @@ nsView::HandleEvent(WidgetGUIEvent* aEve
   }
 
   return result;
 }
 
 bool
 nsView::IsPrimaryFramePaintSuppressed()
 {
-  return sShowPreviousPage && mFrame && mFrame->PresContext()->PresShell()->IsPaintingSuppressed();
+  return sShowPreviousPage && mFrame && mFrame->PresShell()->IsPaintingSuppressed();
 }
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -7446,17 +7446,17 @@ nsWindow::GetAccessible()
   // In case of popup window return a popup accessible.
   nsView* view = nsView::GetViewFor(this);
   if (view) {
     nsIFrame* frame = view->GetFrame();
     if (frame && nsLayoutUtils::IsPopup(frame)) {
       nsAccessibilityService* accService = GetOrCreateAccService();
       if (accService) {
         a11y::DocAccessible* docAcc =
-          GetAccService()->GetDocAccessible(frame->PresContext()->PresShell());
+          GetAccService()->GetDocAccessible(frame->PresShell());
         if (docAcc) {
           NS_LOG_WMGETOBJECT(this, mWnd,
                              docAcc->GetAccessibleOrDescendant(frame->GetContent()));
           return docAcc->GetAccessibleOrDescendant(frame->GetContent());
         }
       }
     }
   }
--- a/xpcom/threads/AbstractThread.cpp
+++ b/xpcom/threads/AbstractThread.cpp
@@ -41,30 +41,30 @@ public:
     // more complicated than it already is.
     //
     // If you need to use tail dispatch on other XPCOM threads, you'll need to
     // implement an nsIThreadObserver to fire the tail dispatcher at the
     // appropriate times. You will also need to modify this assertion.
     MOZ_ASSERT_IF(aRequireTailDispatch, NS_IsMainThread() && aTarget->IsOnCurrentThread());
   }
 
-  virtual void Dispatch(already_AddRefed<nsIRunnable> aRunnable,
-                        DispatchFailureHandling aFailureHandling = AssertDispatchSuccess,
-                        DispatchReason aReason = NormalDispatch) override
+  virtual nsresult Dispatch(already_AddRefed<nsIRunnable> aRunnable,
+                            DispatchFailureHandling aFailureHandling = AssertDispatchSuccess,
+                            DispatchReason aReason = NormalDispatch) override
   {
     AbstractThread* currentThread;
     if (aReason != TailDispatch && (currentThread = GetCurrent()) && RequiresTailDispatch(currentThread)) {
       currentThread->TailDispatcher().AddTask(this, Move(aRunnable), aFailureHandling);
-      return;
+      return NS_OK;
     }
 
     RefPtr<nsIRunnable> runner(new Runner(this, Move(aRunnable), false /* already drained by TaskGroupRunnable  */));
     nsresult rv = mTarget->Dispatch(runner.forget(), NS_DISPATCH_NORMAL);
     MOZ_DIAGNOSTIC_ASSERT(aFailureHandling == DontAssertDispatchSuccess || NS_SUCCEEDED(rv));
-    Unused << rv;
+    return rv;
   }
 
   // Prevent a GCC warning about the other overload of Dispatch being hidden.
   using AbstractThread::Dispatch;
 
   virtual bool IsCurrentThreadIn() override
   {
     return mTarget->IsOnCurrentThread();
--- a/xpcom/threads/AbstractThread.h
+++ b/xpcom/threads/AbstractThread.h
@@ -64,19 +64,19 @@ public:
   NS_IMETHOD_(bool) IsOnCurrentThreadInfallible(void) override;
   NS_IMETHOD IsOnCurrentThread(bool *_retval) override;
   NS_IMETHOD Dispatch(already_AddRefed<nsIRunnable> event, uint32_t flags) override;
   NS_IMETHOD DispatchFromScript(nsIRunnable *event, uint32_t flags) override;
   NS_IMETHOD DelayedDispatch(already_AddRefed<nsIRunnable> event, uint32_t delay) override;
 
   enum DispatchFailureHandling { AssertDispatchSuccess, DontAssertDispatchSuccess };
   enum DispatchReason { NormalDispatch, TailDispatch };
-  virtual void Dispatch(already_AddRefed<nsIRunnable> aRunnable,
-                        DispatchFailureHandling aHandling = AssertDispatchSuccess,
-                        DispatchReason aReason = NormalDispatch) = 0;
+  virtual nsresult Dispatch(already_AddRefed<nsIRunnable> aRunnable,
+                            DispatchFailureHandling aHandling = AssertDispatchSuccess,
+                            DispatchReason aReason = NormalDispatch) = 0;
 
   virtual bool IsCurrentThreadIn() = 0;
 
   // Returns a TaskDispatcher that will dispatch its tasks when the currently-
   // running tasks pops off the stack.
   //
   // May only be called when running within the it is invoked up, and only on
   // threads which support it.
--- a/xpcom/threads/TaskQueue.h
+++ b/xpcom/threads/TaskQueue.h
@@ -56,30 +56,30 @@ public:
   TaskQueue(already_AddRefed<nsIEventTarget> aTarget,
             const char* aName,
             bool aSupportsTailDispatch = false);
 
   TaskDispatcher& TailDispatcher() override;
 
   TaskQueue* AsTaskQueue() override { return this; }
 
-  void Dispatch(already_AddRefed<nsIRunnable> aRunnable,
-                DispatchFailureHandling aFailureHandling = AssertDispatchSuccess,
-                DispatchReason aReason = NormalDispatch) override
+  nsresult Dispatch(already_AddRefed<nsIRunnable> aRunnable,
+                    DispatchFailureHandling aFailureHandling = AssertDispatchSuccess,
+                    DispatchReason aReason = NormalDispatch) override
   {
     nsCOMPtr<nsIRunnable> r = aRunnable;
     {
       MonitorAutoLock mon(mQueueMonitor);
       nsresult rv = DispatchLocked(/* passed by ref */r, aFailureHandling, aReason);
 #if defined(DEBUG) || !defined(RELEASE_OR_BETA) || defined(EARLY_BETA_OR_EARLIER)
       if (NS_FAILED(rv) && aFailureHandling == AssertDispatchSuccess) {
         MOZ_CRASH_UNSAFE_PRINTF("%s: Dispatch failed. rv=%x", mName, uint32_t(rv));
       }
 #endif
-      Unused << rv;
+      return rv;
     }
     // If the ownership of |r| is not transferred in DispatchLocked() due to
     // dispatch failure, it will be deleted here outside the lock. We do so
     // since the destructor of the runnable might access TaskQueue and result
     // in deadlocks.
   }
 
   // Prevent a GCC warning about the other overload of Dispatch being hidden.