Merge autoland to mozilla central. a=merge
authorCristian Tuns <ctuns@mozilla.com>
Mon, 18 Apr 2022 05:14:42 -0400
changeset 684946 0d591d3bc99786bdb3cb057203a3831110d00800
parent 684945 53dbcc3cbe3c88fa9de5cedc9fc382eda6e33c82 (current diff)
parent 684944 70a7d85084d6422e1aa12b63dc6b5f3d79b5d266 (diff)
child 684947 06fc2f19869a00910a219c864b935a1026360626
child 684963 ee3e0c0d04480e9546ff082948b7289fbc948cf4
push id16598
push userffxbld-merge
push dateMon, 02 May 2022 14:23:32 +0000
treeherdermozilla-beta@de86a81c7a63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone101.0a1
first release with
nightly linux32
0d591d3bc997 / 101.0a1 / 20220418091627 / files
nightly linux64
0d591d3bc997 / 101.0a1 / 20220418091627 / files
nightly mac
0d591d3bc997 / 101.0a1 / 20220418091627 / files
nightly win32
0d591d3bc997 / 101.0a1 / 20220418091627 / files
nightly win64
0d591d3bc997 / 101.0a1 / 20220418091627 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge autoland to mozilla central. a=merge
--- a/docs/contributing/stack_quickref.rst
+++ b/docs/contributing/stack_quickref.rst
@@ -47,16 +47,27 @@ created on Phabricator. For this, merge 
 
     # Git
     # Replace "pick" by "squash" or "fixup"
     $ git rebase -i
 
 Then, push to Phabricator and abandon the old change.
 
 
+Submitting the first patch on the stack
+---------------------------------------
+
+There are times when you are working on multiple patches and
+just want to submit the first one. For this, you can use:
+
+.. code-block:: shell
+
+    $ moz-phab submit .
+
+
 Reorder the stack
 -----------------
 
 Sometimes, we want to change the order the patches in the stack.
 Fortunately, VCS support this easily.
 
 .. code-block:: shell
 
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -200,16 +200,17 @@
 #include "mozilla/dom/Performance.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/PostMessageEvent.h"
 #include "mozilla/dom/ProcessingInstruction.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
 #include "mozilla/dom/ResizeObserverController.h"
 #include "mozilla/dom/SVGElement.h"
+#include "mozilla/dom/SVGDocument.h"
 #include "mozilla/dom/SVGSVGElement.h"
 #include "mozilla/dom/SVGUseElement.h"
 #include "mozilla/dom/ScriptLoader.h"
 #include "mozilla/dom/ScriptSettings.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/dom/ServiceWorkerContainer.h"
 #include "mozilla/dom/ServiceWorkerDescriptor.h"
 #include "mozilla/dom/ServiceWorkerManager.h"
--- a/dom/ipc/BrowserParent.cpp
+++ b/dom/ipc/BrowserParent.cpp
@@ -3057,18 +3057,17 @@ mozilla::ipc::IPCResult BrowserParent::R
   return IPC_OK();
 }
 
 bool BrowserParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent) {
   nsCOMPtr<nsIWidget> textInputHandlingWidget = GetTextInputHandlingWidget();
   if (!textInputHandlingWidget) {
     return true;
   }
-  if (NS_WARN_IF(!mContentCache.HandleQueryContentEvent(
-          aEvent, textInputHandlingWidget)) ||
+  if (!mContentCache.HandleQueryContentEvent(aEvent, textInputHandlingWidget) ||
       NS_WARN_IF(aEvent.Failed())) {
     return true;
   }
   switch (aEvent.mMessage) {
     case eQueryTextRect:
     case eQueryCaretRect:
     case eQueryEditorRect: {
       nsCOMPtr<nsIWidget> browserWidget = GetWidget();
--- a/image/AutoRestoreSVGState.h
+++ b/image/AutoRestoreSVGState.h
@@ -5,45 +5,58 @@
 
 #ifndef mozilla_image_AutoRestoreSVGState_h
 #define mozilla_image_AutoRestoreSVGState_h
 
 #include "mozilla/Attributes.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/SVGContextPaint.h"
 #include "mozilla/dom/SVGSVGElement.h"
+#include "nsPresContext.h"
 #include "SVGDrawingParameters.h"
 #include "SVGDocumentWrapper.h"
+#include "mozilla/dom/DocumentInlines.h"
+#include "mozilla/dom/SVGDocument.h"
+#include "mozilla/dom/BrowsingContextBinding.h"
 
-namespace mozilla {
-namespace image {
+namespace mozilla::image {
 
 class MOZ_STACK_CLASS AutoRestoreSVGState final {
  public:
   AutoRestoreSVGState(const SVGDrawingParameters& aParams,
                       SVGDocumentWrapper* aSVGDocumentWrapper,
                       bool aContextPaint)
       : AutoRestoreSVGState(aParams.svgContext, aParams.animationTime,
                             aSVGDocumentWrapper, aContextPaint) {}
 
   AutoRestoreSVGState(const Maybe<SVGImageContext>& aSVGContext,
                       float aAnimationTime,
                       SVGDocumentWrapper* aSVGDocumentWrapper,
                       bool aContextPaint)
-      : mIsDrawing(aSVGDocumentWrapper->mIsDrawing)
+      : mIsDrawing(aSVGDocumentWrapper->mIsDrawing),
         // Apply any 'preserveAspectRatio' override (if specified) to the root
         // element:
-        ,
-        mPAR(aSVGContext, aSVGDocumentWrapper->GetRootSVGElem())
+        mPAR(aSVGContext, aSVGDocumentWrapper->GetRootSVGElem()),
         // Set the animation time:
-        ,
         mTime(aSVGDocumentWrapper->GetRootSVGElem(), aAnimationTime) {
     MOZ_ASSERT(!mIsDrawing.SavedValue());
     MOZ_ASSERT(aSVGDocumentWrapper->GetDocument());
 
+    if (auto* pc = aSVGDocumentWrapper->GetDocument()->GetPresContext()) {
+      pc->SetColorSchemeOverride([&] {
+        if (aSVGContext && aSVGContext->GetColorScheme()) {
+          auto scheme = *aSVGContext->GetColorScheme();
+          return scheme == ColorScheme::Light
+                     ? dom::PrefersColorSchemeOverride::Light
+                     : dom::PrefersColorSchemeOverride::Dark;
+        }
+        return dom::PrefersColorSchemeOverride::None;
+      }());
+    }
+
     aSVGDocumentWrapper->mIsDrawing = true;
 
     // Set context paint (if specified) on the document:
     if (aContextPaint) {
       MOZ_ASSERT(aSVGContext->GetContextPaint());
       mContextPaint.emplace(*aSVGContext->GetContextPaint(),
                             *aSVGDocumentWrapper->GetDocument());
     }
@@ -51,12 +64,11 @@ class MOZ_STACK_CLASS AutoRestoreSVGStat
 
  private:
   AutoRestore<bool> mIsDrawing;
   AutoPreserveAspectRatioOverride mPAR;
   AutoSVGTimeSetRestore mTime;
   Maybe<AutoSetRestoreSVGContextPaint> mContextPaint;
 };
 
-}  // namespace image
-}  // namespace mozilla
+}  // namespace mozilla::image
 
 #endif  // mozilla_image_AutoRestoreSVGState_h
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -445,16 +445,21 @@ class imgMemoryReporter final : public n
         }
         if (context.GetPreserveAspectRatio()) {
           nsAutoString aspect;
           context.GetPreserveAspectRatio()->ToString(aspect);
           surfacePathPrefix.AppendLiteral("preserveAspectRatio=(");
           LossyAppendUTF16toASCII(aspect, surfacePathPrefix);
           surfacePathPrefix.AppendLiteral(") ");
         }
+        if (auto scheme = context.GetColorScheme()) {
+          surfacePathPrefix.AppendLiteral("colorScheme=");
+          surfacePathPrefix.AppendInt(int32_t(*scheme));
+          surfacePathPrefix.AppendLiteral(" ");
+        }
         if (context.GetContextPaint()) {
           const SVGEmbeddingContextPaint* paint = context.GetContextPaint();
           surfacePathPrefix.AppendLiteral("contextPaint=(");
           if (paint->GetFill()) {
             surfacePathPrefix.AppendLiteral(" fill=");
             surfacePathPrefix.AppendInt(paint->GetFill()->ToABGR(), 16);
           }
           if (paint->GetFillOpacity() != 1.0) {
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -6701,17 +6701,18 @@ ImgDrawResult nsLayoutUtils::DrawBackgro
 /* static */
 ImgDrawResult nsLayoutUtils::DrawImage(
     gfxContext& aContext, ComputedStyle* aComputedStyle,
     nsPresContext* aPresContext, imgIContainer* aImage,
     const SamplingFilter aSamplingFilter, const nsRect& aDest,
     const nsRect& aFill, const nsPoint& aAnchor, const nsRect& aDirty,
     uint32_t aImageFlags, float aOpacity) {
   Maybe<SVGImageContext> svgContext;
-  SVGImageContext::MaybeStoreContextPaint(svgContext, aComputedStyle, aImage);
+  SVGImageContext::MaybeStoreContextPaint(svgContext, *aPresContext,
+                                          *aComputedStyle, aImage);
 
   return DrawImageInternal(aContext, aPresContext, aImage, aSamplingFilter,
                            aDest, aFill, aAnchor, aDirty, svgContext,
                            aImageFlags, ExtendMode::CLAMP, aOpacity);
 }
 
 /* static */
 nsRect nsLayoutUtils::GetWholeImageDestination(const nsSize& aWholeImageSize,
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -882,16 +882,32 @@ Maybe<ColorScheme> nsPresContext::GetOve
     case dom::PrefersColorSchemeOverride::None:
     case dom::PrefersColorSchemeOverride::EndGuard_:
       break;
   }
 
   return Nothing();
 }
 
+void nsPresContext::SetColorSchemeOverride(
+    PrefersColorSchemeOverride aOverride) {
+  auto oldScheme = mDocument->PreferredColorScheme();
+
+  mOverriddenOrEmbedderColorScheme = aOverride;
+
+  if (mDocument->PreferredColorScheme() != oldScheme) {
+    // We need to restyle because not only media queries have changed, system
+    // colors may as well via the prefers-color-scheme meta tag / effective
+    // color-scheme property value.
+    MediaFeatureValuesChanged({RestyleHint::RecascadeSubtree(), nsChangeHint(0),
+                               MediaFeatureChangeReason::SystemMetricsChange},
+                              MediaFeatureChangePropagation::JustThisDocument);
+  }
+}
+
 void nsPresContext::RecomputeBrowsingContextDependentData() {
   MOZ_ASSERT(mDocument);
   dom::Document* doc = mDocument;
   // Resource documents inherit all this state from their display document.
   while (dom::Document* outer = doc->GetDisplayDocument()) {
     doc = outer;
   }
   auto* browsingContext = doc->GetBrowsingContext();
@@ -900,40 +916,30 @@ void nsPresContext::RecomputeBrowsingCon
     // as a result of the zoom on the embedder document so it doesn't really
     // matter... Medium also doesn't affect those.
     return;
   }
   SetFullZoom(browsingContext->FullZoom());
   SetTextZoom(browsingContext->TextZoom());
   SetOverrideDPPX(browsingContext->OverrideDPPX());
 
-  auto oldScheme = mDocument->PreferredColorScheme();
   auto* top = browsingContext->Top();
-  mOverriddenOrEmbedderColorScheme = [&] {
+  SetColorSchemeOverride([&] {
     auto overriden = top->PrefersColorSchemeOverride();
     if (overriden != PrefersColorSchemeOverride::None) {
       return overriden;
     }
     for (auto* cur = browsingContext; cur; cur = cur->GetParent()) {
       auto embedder = cur->GetEmbedderColorScheme();
       if (embedder != PrefersColorSchemeOverride::None) {
         return embedder;
       }
     }
     return PrefersColorSchemeOverride::None;
-  }();
-
-  if (mDocument->PreferredColorScheme() != oldScheme) {
-    // We need to restyle because not only media queries have changed, system
-    // colors may as well via the prefers-color-scheme meta tag / effective
-    // color-scheme property value.
-    MediaFeatureValuesChanged({RestyleHint::RecascadeSubtree(), nsChangeHint(0),
-                               MediaFeatureChangeReason::SystemMetricsChange},
-                              MediaFeatureChangePropagation::JustThisDocument);
-  }
+  }());
 
   if (doc == mDocument) {
     // Medium doesn't apply to resource documents, etc.
     RefPtr<nsAtom> mediumToEmulate;
     if (MOZ_UNLIKELY(!top->GetMediumOverride().IsEmpty())) {
       nsAutoString lower;
       nsContentUtils::ASCIIToLower(top->GetMediumOverride(), lower);
       mediumToEmulate = NS_Atomize(lower);
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -587,16 +587,21 @@ class nsPresContext : public nsISupports
   Maybe<mozilla::ColorScheme> GetOverriddenOrEmbedderColorScheme() const;
 
   /**
    * Recomputes the data dependent on the browsing context, like zoom and text
    * zoom.
    */
   void RecomputeBrowsingContextDependentData();
 
+  /**
+   * Sets the effective color scheme override, and invalidate stuff as needed.
+   */
+  void SetColorSchemeOverride(mozilla::dom::PrefersColorSchemeOverride);
+
   mozilla::CSSCoord GetAutoQualityMinFontSize() const {
     return DevPixelsToFloatCSSPixels(mAutoQualityMinFontSizePixelsPref);
   }
 
   /**
    * Return the device's screen size in inches, for font size
    * inflation.
    *
new file mode 100644
--- /dev/null
+++ b/layout/reftests/color-scheme/prefers-color-scheme-dark.svg
@@ -0,0 +1,6 @@
+<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    :root { color: purple }
+  </style>
+  <rect fill="currentColor" width="32" height="32"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/color-scheme/prefers-color-scheme-light.svg
@@ -0,0 +1,6 @@
+<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    :root { color: blue }
+  </style>
+  <rect fill="currentColor" width="32" height="32"/>
+</svg>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/color-scheme/prefers-color-scheme-svg-image-ref.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<div style="color-scheme: light">
+  <img src="prefers-color-scheme-light.svg">
+</div>
+<div style="color-scheme: dark">
+  <img src="prefers-color-scheme-dark.svg">
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/color-scheme/prefers-color-scheme-svg-image.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<div style="color-scheme: light">
+  <img src="prefers-color-scheme.svg">
+</div>
+<div style="color-scheme: dark">
+  <img src="prefers-color-scheme.svg">
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/color-scheme/prefers-color-scheme.svg
@@ -0,0 +1,9 @@
+<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
+  <style>
+    :root { color: blue }
+    @media (prefers-color-scheme: dark) {
+      :root { color: purple }
+    }
+  </style>
+  <rect fill="currentColor" width="32" height="32"/>
+</svg>
--- a/layout/reftests/color-scheme/reftest.list
+++ b/layout/reftests/color-scheme/reftest.list
@@ -1,4 +1,6 @@
 defaults pref(layout.css.color-scheme.enabled,true)
 
 != color-scheme-basic.html color-scheme-basic-notref.html
 != color-scheme-themed-button.html color-scheme-themed-button-notref.html
+
+== chrome://reftest/content/color-scheme/prefers-color-scheme-svg-image.html chrome://reftest/content/color-scheme/prefers-color-scheme-svg-image-ref.html
--- a/layout/svg/SVGImageContext.cpp
+++ b/layout/svg/SVGImageContext.cpp
@@ -5,61 +5,71 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Main header first:
 #include "SVGImageContext.h"
 
 // Keep others in (case-insensitive) order:
 #include "gfxUtils.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/LookAndFeel.h"
+#include "mozilla/dom/Document.h"
 #include "nsIFrame.h"
 #include "nsPresContext.h"
 #include "nsStyleStruct.h"
 
 namespace mozilla {
 
 /* static */
 void SVGImageContext::MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
                                              nsIFrame* aFromFrame,
                                              imgIContainer* aImgContainer) {
-  return MaybeStoreContextPaint(aContext, aFromFrame->Style(), aImgContainer);
+  return MaybeStoreContextPaint(aContext, *aFromFrame->PresContext(),
+                                *aFromFrame->Style(), aImgContainer);
 }
 
 /* static */
-void SVGImageContext::MaybeStoreContextPaint(
-    Maybe<SVGImageContext>& aContext, const ComputedStyle* aFromComputedStyle,
-    imgIContainer* aImgContainer) {
-  const nsStyleSVG* style = aFromComputedStyle->StyleSVG();
+void SVGImageContext::MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
+                                             const nsPresContext& aPresContext,
+                                             const ComputedStyle& aStyle,
+                                             imgIContainer* aImgContainer) {
+  if (aImgContainer->GetType() != imgIContainer::TYPE_VECTOR) {
+    // Avoid this overhead for raster images.
+    return;
+  }
 
+  if (aPresContext.Document()->IsDocumentURISchemeChrome()) {
+    if (!aContext) {
+      aContext.emplace();
+    }
+    auto scheme = LookAndFeel::ColorSchemeForStyle(
+        *aPresContext.Document(), aStyle.StyleUI()->mColorScheme.bits);
+    aContext->SetColorScheme(Some(scheme));
+  }
+
+  const nsStyleSVG* style = aStyle.StyleSVG();
   if (!style->ExposesContextProperties()) {
     // Content must have '-moz-context-properties' set to the names of the
     // properties it wants to expose to images it links to.
     return;
   }
 
-  if (aImgContainer->GetType() != imgIContainer::TYPE_VECTOR) {
-    // Avoid this overhead for raster images.
-    return;
-  }
-
   bool haveContextPaint = false;
 
   auto contextPaint = MakeRefPtr<SVGEmbeddingContextPaint>();
 
   if ((style->mMozContextProperties.bits & StyleContextPropertyBits::FILL) &&
       style->mFill.kind.IsColor()) {
     haveContextPaint = true;
-    contextPaint->SetFill(
-        style->mFill.kind.AsColor().CalcColor(*aFromComputedStyle));
+    contextPaint->SetFill(style->mFill.kind.AsColor().CalcColor(aStyle));
   }
   if ((style->mMozContextProperties.bits & StyleContextPropertyBits::STROKE) &&
       style->mStroke.kind.IsColor()) {
     haveContextPaint = true;
-    contextPaint->SetStroke(
-        style->mStroke.kind.AsColor().CalcColor(*aFromComputedStyle));
+    contextPaint->SetStroke(style->mStroke.kind.AsColor().CalcColor(aStyle));
   }
   if (style->mMozContextProperties.bits &
       StyleContextPropertyBits::FILL_OPACITY) {
     haveContextPaint = true;
     contextPaint->SetFillOpacity(style->mFillOpacity.IsOpacity()
                                      ? style->mFillOpacity.AsOpacity()
                                      : 1.0f);
   }
--- a/layout/svg/SVGImageContext.h
+++ b/layout/svg/SVGImageContext.h
@@ -11,21 +11,22 @@
 #include "mozilla/SVGContextPaint.h"
 #include "mozilla/SVGPreserveAspectRatio.h"
 #include "Units.h"
 
 class nsIFrame;
 
 namespace mozilla {
 
+enum class ColorScheme : uint8_t;
 class ComputedStyle;
 
 // SVG image-specific rendering context. For imgIContainer::Draw.
 // Used to pass information such as
-//  - viewport information from CSS, and
+//  - viewport and color-scheme information from CSS, and
 //  - overridden attributes from an SVG <image> element
 // to the image's internal SVG document when it's drawn.
 class SVGImageContext {
  public:
   SVGImageContext() = default;
 
   /**
    * Currently it seems that the aViewportSize parameter ends up being used
@@ -40,34 +41,42 @@ class SVGImageContext {
    * nsLayoutUtils::Draw*Image() methods on the way to DrawImageInternal
    * creating |fallbackContext|).  Using Maybe<T> allows code to pass Nothing()
    * in order to get the size that's created for |fallbackContext|.  At some
    * point we need to clean this code up, make our abstractions clear, create
    * that utility and stop using Maybe for this parameter.
    */
   explicit SVGImageContext(
       const Maybe<CSSIntSize>& aViewportSize,
-      const Maybe<SVGPreserveAspectRatio>& aPreserveAspectRatio = Nothing())
+      const Maybe<SVGPreserveAspectRatio>& aPreserveAspectRatio = Nothing(),
+      const Maybe<ColorScheme>& aColorScheme = Nothing())
       : mViewportSize(aViewportSize),
-        mPreserveAspectRatio(aPreserveAspectRatio) {}
+        mPreserveAspectRatio(aPreserveAspectRatio),
+        mColorScheme(aColorScheme) {}
 
   static void MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
                                      nsIFrame* aFromFrame,
                                      imgIContainer* aImgContainer);
 
   static void MaybeStoreContextPaint(Maybe<SVGImageContext>& aContext,
-                                     const ComputedStyle* aFromComputedStyle,
-                                     imgIContainer* aImgContainer);
+                                     const nsPresContext&, const ComputedStyle&,
+                                     imgIContainer*);
 
   const Maybe<CSSIntSize>& GetViewportSize() const { return mViewportSize; }
 
   void SetViewportSize(const Maybe<CSSIntSize>& aSize) {
     mViewportSize = aSize;
   }
 
+  const Maybe<ColorScheme>& GetColorScheme() const { return mColorScheme; }
+
+  void SetColorScheme(const Maybe<ColorScheme>& aScheme) {
+    mColorScheme = aScheme;
+  }
+
   const Maybe<SVGPreserveAspectRatio>& GetPreserveAspectRatio() const {
     return mPreserveAspectRatio;
   }
 
   void SetPreserveAspectRatio(const Maybe<SVGPreserveAspectRatio>& aPAR) {
     mPreserveAspectRatio = aPAR;
   }
 
@@ -81,41 +90,47 @@ class SVGImageContext {
     bool contextPaintIsEqual =
         // neither have context paint, or they have the same object:
         (mContextPaint == aOther.mContextPaint) ||
         // or both have context paint that are different but equivalent objects:
         (mContextPaint && aOther.mContextPaint &&
          *mContextPaint == *aOther.mContextPaint);
 
     return contextPaintIsEqual && mViewportSize == aOther.mViewportSize &&
-           mPreserveAspectRatio == aOther.mPreserveAspectRatio;
+           mPreserveAspectRatio == aOther.mPreserveAspectRatio &&
+           mColorScheme == aOther.mColorScheme;
   }
 
   bool operator!=(const SVGImageContext& aOther) const {
     return !(*this == aOther);
   }
 
   PLDHashNumber Hash() const {
     PLDHashNumber hash = 0;
     if (mContextPaint) {
       hash = HashGeneric(hash, mContextPaint->Hash());
     }
     return HashGeneric(hash, mViewportSize.map(HashSize).valueOr(0),
-                       mPreserveAspectRatio.map(HashPAR).valueOr(0));
+                       mPreserveAspectRatio.map(HashPAR).valueOr(0),
+                       mColorScheme.map(HashColorScheme).valueOr(0));
   }
 
  private:
   static PLDHashNumber HashSize(const CSSIntSize& aSize) {
     return HashGeneric(aSize.width, aSize.height);
   }
   static PLDHashNumber HashPAR(const SVGPreserveAspectRatio& aPAR) {
     return aPAR.Hash();
   }
+  static PLDHashNumber HashColorScheme(ColorScheme aScheme) {
+    return HashGeneric(uint8_t(aScheme));
+  }
 
   // NOTE: When adding new member-vars, remember to update Hash() & operator==.
   RefPtr<SVGEmbeddingContextPaint> mContextPaint;
   Maybe<CSSIntSize> mViewportSize;
   Maybe<SVGPreserveAspectRatio> mPreserveAspectRatio;
+  Maybe<ColorScheme> mColorScheme;
 };
 
 }  // namespace mozilla
 
 #endif  // LAYOUT_SVG_SVGIMAGECONTEXT_H_
--- a/layout/tools/reftest/jar.mn
+++ b/layout/tools/reftest/jar.mn
@@ -7,16 +7,17 @@ reftest.jar:
   content/box-shadow (../../reftests/box-shadow/*)
   content/bugs (../../reftests/bugs/*)
   content/css-display (../../reftests/css-display/*)
   content/forms/input/file (../../reftests/forms/input/file/*)
   content/forms/input/text (../../reftests/forms/input/text/*)
   content/forms/placeholder (../../reftests/forms/placeholder/*)
   content/forms/textbox (../../reftests/forms/textbox/*)
   content/image-region (../../reftests/image-region/*)
+  content/color-scheme (../../reftests/color-scheme/*)
   content/invalidation (../../reftests/invalidation/*)
   content/native-theme (../../reftests/native-theme/*)
   content/reftest-sanity (../../reftests/reftest-sanity/*)
   content/text-shadow (../../reftests/text-shadow/*)
   content/writing-mode (../../reftests/writing-mode/*)
   content/xul-document-load (../../reftests/xul-document-load/*)
   content/xul (../../reftests/xul/*)
   content/xul/reftest (../../xul/reftest/*)
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -3214,18 +3214,18 @@ ImgDrawResult nsTreeBodyFrame::PaintTwis
 
         // Center the image. XXX Obey vertical-align style prop?
         if (imageSize.height < twistyRect.height) {
           anchorPoint.y += (twistyRect.height - imageSize.height) / 2;
         }
 
         // Apply context paint if applicable
         Maybe<SVGImageContext> svgContext;
-        SVGImageContext::MaybeStoreContextPaint(svgContext, twistyContext,
-                                                image);
+        SVGImageContext::MaybeStoreContextPaint(svgContext, *aPresContext,
+                                                *twistyContext, image);
 
         // Paint the image.
         result &= nsLayoutUtils::DrawSingleUnscaledImage(
             aRenderingContext, aPresContext, image, SamplingFilter::POINT,
             anchorPoint, &aDirtyRect, svgContext, imgIContainer::FLAG_NONE,
             &imageSize);
       }
     }
@@ -3588,17 +3588,18 @@ ImgDrawResult nsTreeBodyFrame::PaintChec
     }
 
     if (imageSize.width < checkboxRect.width) {
       pt.x += (checkboxRect.width - imageSize.width) / 2;
     }
 
     // Apply context paint if applicable
     Maybe<SVGImageContext> svgContext;
-    SVGImageContext::MaybeStoreContextPaint(svgContext, checkboxContext, image);
+    SVGImageContext::MaybeStoreContextPaint(svgContext, *aPresContext,
+                                            *checkboxContext, image);
     // Paint the image.
     result &= nsLayoutUtils::DrawSingleUnscaledImage(
         aRenderingContext, aPresContext, image, SamplingFilter::POINT, pt,
         &aDirtyRect, svgContext, imgIContainer::FLAG_NONE, &imageSize);
   }
 
   return result;
 }
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -9830,16 +9830,25 @@
 # If line-height is lower than this value (in device pixels), 1 line scroll
 # scrolls this height.
 - name: mousewheel.min_line_scroll_amount
   type: int32_t
   value: 5
   mirror: always
 
 #---------------------------------------------------------------------------
+# Prefs starting with "mozilla."
+#---------------------------------------------------------------------------
+
+- name: mozilla.widget.raise-on-setfocus
+  type: bool
+  value: true
+  mirror: once
+
+#---------------------------------------------------------------------------
 # Prefs starting with "network."
 #---------------------------------------------------------------------------
 
 # Force less-secure NTLMv1 when needed (NTLMv2 is the default).
 - name: network.auth.force-generic-ntlm-v1
   type: RelaxedAtomicBool
   value: false
   mirror: always
@@ -13117,16 +13126,21 @@
   mirror: once
 
 # Use opaque region for MozContainer wl_surface
 - name: widget.wayland.opaque-region.enabled
   type: bool
   value: true
   mirror: once
 
+- name: widget.wayland.use-move-to-rect
+  type: bool
+  value: true
+  mirror: once
+
 # Use frame callback based vsync
 - name: widget.wayland.vsync.enabled
   type: bool
   value: true
   mirror: once
 #endif
 
 #ifdef MOZ_WIDGET_GTK
@@ -13258,16 +13272,21 @@
   type: float
 #if defined(XP_WIN)
   value: 1100.0f
 #else
   value: 550.0f
 #endif
   mirror: always
 
+- name: widget.transparent-windows
+  type: bool
+  value: true
+  mirror: once
+
 #---------------------------------------------------------------------------
 # Prefs starting with "xul."
 #---------------------------------------------------------------------------
 
 # Pref to control whether arrow-panel animations are enabled or not.
 # Transitions are currently disabled on Linux due to rendering issues on
 # certain configurations.
 - name: xul.panel-animations.enabled
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -3688,19 +3688,16 @@ pref("network.tcp.keepalive.idle_time", 
 // inconsistent state. See bug 1582647 comment 30
 pref("network.psl.onUpdate_notify", false);
 
 #ifdef MOZ_WIDGET_GTK
   pref("widget.content.gtk-theme-override", "");
   pref("widget.disable-workspace-management", false);
   pref("widget.titlebar-x11-use-shape-mask", false);
 #endif
-#ifdef MOZ_WAYLAND
-  pref("widget.wayland.use-move-to-rect", true);
-#endif
 
 // All the Geolocation preferences are here.
 //
 #ifndef EARLY_BETA_OR_EARLIER
   pref("geo.provider.network.url", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_LOCATION_SERVICE_API_KEY%");
 #else
   // Use MLS on Nightly and early Beta.
   pref("geo.provider.network.url", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
--- a/modules/libpref/moz.build
+++ b/modules/libpref/moz.build
@@ -56,16 +56,17 @@ pref_groups = [
     "intl",
     "javascript",
     "layers",
     "layout",
     "mathml",
     "media",
     "midi",
     "mousewheel",
+    "mozilla",
     "network",
     "nglayout",
     "page_load",
     "pdfjs",
     "permissions",
     "plain_text",
     "plugin",
     "plugins",
--- a/servo/components/style/values/specified/length.rs
+++ b/servo/components/style/values/specified/length.rs
@@ -309,16 +309,17 @@ pub enum ViewportVariant {
     Small,
     /// https://drafts.csswg.org/css-values/#large-viewport-percentage-units
     Large,
     /// https://drafts.csswg.org/css-values/#dynamic-viewport-percentage-units
     Dynamic,
 }
 
 /// https://drafts.csswg.org/css-values/#viewport-relative-units
+#[derive(PartialEq)]
 enum ViewportUnit {
     /// *vw units.
     Vw,
     /// *vh units.
     Vh,
     /// *vmin units.
     Vmin,
     /// *vmax units.
@@ -589,53 +590,31 @@ impl ViewportPercentageLength {
                 debug_unreachable!("Forgot to handle unit in try_sum()")
             },
         })
     }
 
     /// Computes the given viewport-relative length for the given viewport size.
     pub fn to_computed_value(&self, context: &Context) -> CSSPixelLength {
         let (variant, unit, factor) = self.unpack();
+        let size = context.viewport_size_for_viewport_unit_resolution(variant);
         let length = match unit {
-            ViewportUnit::Vw => context.viewport_size_for_viewport_unit_resolution(variant).width,
-            ViewportUnit::Vh => context.viewport_size_for_viewport_unit_resolution(variant).height,
-            ViewportUnit::Vmin => {
-                let base_size =
-                    context.viewport_size_for_viewport_unit_resolution(variant);
-                cmp::min(base_size.width, base_size.height)
-            },
-            ViewportUnit::Vmax => {
-                let base_size =
-                    context.viewport_size_for_viewport_unit_resolution(variant);
-                cmp::max(base_size.width, base_size.height)
-            },
-            ViewportUnit::Vb => {
-                let base_size =
-                    context.viewport_size_for_viewport_unit_resolution(variant);
+            ViewportUnit::Vw => size.width,
+            ViewportUnit::Vh => size.height,
+            ViewportUnit::Vmin => cmp::min(size.width, size.height),
+            ViewportUnit::Vmax => cmp::max(size.width, size.height),
+            ViewportUnit::Vi | ViewportUnit::Vb => {
                 context
                     .rule_cache_conditions
                     .borrow_mut()
                     .set_writing_mode_dependency(context.builder.writing_mode);
-                if context.style().writing_mode.is_vertical() {
-                    base_size.width
+                if (unit == ViewportUnit::Vb) == context.style().writing_mode.is_vertical() {
+                    size.width
                 } else {
-                    base_size.height
-                }
-            },
-            ViewportUnit::Vi => {
-                let base_size =
-                    context.viewport_size_for_viewport_unit_resolution(variant);
-                context
-                    .rule_cache_conditions
-                    .borrow_mut()
-                    .set_writing_mode_dependency(context.builder.writing_mode);
-                if context.style().writing_mode.is_vertical() {
-                    base_size.height
-                } else {
-                    base_size.width
+                    size.height
                 }
             },
         };
 
         // FIXME: Bug 1396535, we need to fix the extremely small viewport length for transform.
         // See bug 989802. We truncate so that adding multiple viewport units
         // that add up to 100 does not overflow due to rounding differences
         let trunc_scaled = ((length.0 as f64) * factor as f64 / 100.).trunc();
--- a/widget/cocoa/MOZIconHelper.h
+++ b/widget/cocoa/MOZIconHelper.h
@@ -6,28 +6,30 @@
 #ifndef MOZIconHelper_h
 #define MOZIconHelper_h
 
 #import <Cocoa/Cocoa.h>
 
 #include "nsRect.h"
 
 class imgIContainer;
+class nsPresContext;
 
 namespace mozilla {
 class ComputedStyle;
 }
 
 @interface MOZIconHelper : NSObject
 
 // Returns an autoreleased empty NSImage.
 + (NSImage*)placeholderIconWithSize:(NSSize)aSize;
 
 // Returns an autoreleased NSImage.
 + (NSImage*)iconImageFromImageContainer:(imgIContainer*)aImage
                                withSize:(NSSize)aSize
+                            presContext:(const nsPresContext*)aPresContext
                           computedStyle:(const mozilla::ComputedStyle*)aComputedStyle
                                 subrect:(const nsIntRect&)aSubRect
                             scaleFactor:(CGFloat)aScaleFactor;
 
 @end
 
 #endif  // MOZIconHelper_h
--- a/widget/cocoa/MOZIconHelper.mm
+++ b/widget/cocoa/MOZIconHelper.mm
@@ -17,29 +17,31 @@
 // Returns an autoreleased empty NSImage.
 + (NSImage*)placeholderIconWithSize:(NSSize)aSize {
   return [[[NSImage alloc] initWithSize:aSize] autorelease];
 }
 
 // Returns an autoreleased NSImage.
 + (NSImage*)iconImageFromImageContainer:(imgIContainer*)aImage
                                withSize:(NSSize)aSize
+                            presContext:(const nsPresContext*)aPresContext
                           computedStyle:(const mozilla::ComputedStyle*)aComputedStyle
                                 subrect:(const nsIntRect&)aSubRect
                             scaleFactor:(CGFloat)aScaleFactor {
   bool isEntirelyBlack = false;
   NSImage* retainedImage = nil;
   nsresult rv;
   if (aScaleFactor != 0.0f) {
     rv = nsCocoaUtils::CreateNSImageFromImageContainer(aImage, imgIContainer::FRAME_CURRENT,
-                                                       aComputedStyle, &retainedImage, aScaleFactor,
-                                                       &isEntirelyBlack);
+                                                       aPresContext, aComputedStyle, &retainedImage,
+                                                       aScaleFactor, &isEntirelyBlack);
   } else {
     rv = nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
-        aImage, imgIContainer::FRAME_CURRENT, aComputedStyle, &retainedImage, &isEntirelyBlack);
+        aImage, imgIContainer::FRAME_CURRENT, aPresContext, aComputedStyle, &retainedImage,
+        &isEntirelyBlack);
   }
 
   NSImage* image = [retainedImage autorelease];
 
   if (NS_FAILED(rv) || !image) {
     return nil;
   }
 
--- a/widget/cocoa/OSXNotificationCenter.mm
+++ b/widget/cocoa/OSXNotificationCenter.mm
@@ -504,19 +504,19 @@ OSXNotificationCenter::OnImageReady(nsIS
   }
 
   OSXNotificationInfo* osxni = static_cast<OSXNotificationInfo*>(aUserData);
   if (!osxni->mPendingNotification) {
     return NS_ERROR_FAILURE;
   }
 
   NSImage* cocoaImage = nil;
-  // TODO: Pass ComputedStyle here to support context paint properties
+  // TODO: Pass pres context / ComputedStyle here to support context paint properties
   nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(image, imgIContainer::FRAME_FIRST,
-                                                                  nullptr, &cocoaImage);
+                                                                  nullptr, nullptr, &cocoaImage);
   (osxni->mPendingNotification).contentImage = cocoaImage;
   [cocoaImage release];
   ShowPendingNotification(osxni);
 
   return NS_OK;
 
   NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
 }
--- a/widget/cocoa/nsCocoaUtils.h
+++ b/widget/cocoa/nsCocoaUtils.h
@@ -261,16 +261,17 @@ class nsCocoaUtils {
       @param aResult the resulting NSImage
       @param scaleFactor the desired scale factor of the NSImage (2 for a retina display)
       @param aIsEntirelyBlack an outparam that, if non-null, will be set to a
                               bool that indicates whether the RGB values on all
                               pixels are zero
       @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
    */
   static nsresult CreateNSImageFromImageContainer(imgIContainer* aImage, uint32_t aWhichFrame,
+                                                  const nsPresContext* aPresContext,
                                                   const mozilla::ComputedStyle* aComputedStyle,
                                                   NSImage** aResult, CGFloat scaleFactor,
                                                   bool* aIsEntirelyBlack = nullptr);
 
   /** Creates a Cocoa <code>NSImage</code> from a frame of an <code>imgIContainer</code>.
       The new <code>NSImage</code> will have both a regular and HiDPI representation.
       The caller owns the <code>NSImage</code>.
       @param aImage the image to extract a frame from
@@ -279,18 +280,19 @@ class nsCocoaUtils {
                             context paint properties, can be null
       @param aResult the resulting NSImage
       @param aIsEntirelyBlack an outparam that, if non-null, will be set to a
                               bool that indicates whether the RGB values on all
                               pixels are zero
       @return NS_OK if the conversion worked, NS_ERROR_FAILURE otherwise
    */
   static nsresult CreateDualRepresentationNSImageFromImageContainer(
-      imgIContainer* aImage, uint32_t aWhichFrame, const mozilla::ComputedStyle* aComputedStyle,
-      NSImage** aResult, bool* aIsEntirelyBlack = nullptr);
+      imgIContainer* aImage, uint32_t aWhichFrame, const nsPresContext* aPresContext,
+      const mozilla::ComputedStyle* aComputedStyle, NSImage** aResult,
+      bool* aIsEntirelyBlack = nullptr);
 
   /**
    * Returns nsAString for aSrc.
    */
   static void GetStringForNSString(const NSString* aSrc, nsAString& aDist);
 
   /**
    * Makes NSString instance for aString.
--- a/widget/cocoa/nsCocoaUtils.mm
+++ b/widget/cocoa/nsCocoaUtils.mm
@@ -39,28 +39,25 @@
 #include "mozilla/SVGImageContext.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/gfx/2D.h"
 
 using namespace mozilla;
 using namespace mozilla::widget;
 
 using mozilla::dom::Promise;
-using mozilla::gfx::BackendType;
 using mozilla::gfx::DataSourceSurface;
 using mozilla::gfx::DrawTarget;
-using mozilla::gfx::Factory;
 using mozilla::gfx::SamplingFilter;
 using mozilla::gfx::IntPoint;
 using mozilla::gfx::IntRect;
 using mozilla::gfx::IntSize;
 using mozilla::gfx::SurfaceFormat;
 using mozilla::gfx::SourceSurface;
 using mozilla::image::ImageRegion;
-using std::ceil;
 
 LazyLogModule gCocoaUtilsLog("nsCocoaUtils");
 #undef LOG
 #define LOG(...) MOZ_LOG(gCocoaUtilsLog, LogLevel::Debug, (__VA_ARGS__))
 
 /*
  * For each audio and video capture request, we hold an owning reference
  * to a promise to be resolved when the request's async callback is invoked.
@@ -384,16 +381,17 @@ nsresult nsCocoaUtils::CreateNSImageFrom
   [*aResult addRepresentation:offscreenRep];
   [offscreenRep release];
   return NS_OK;
 
   NS_OBJC_END_TRY_BLOCK_RETURN(NS_ERROR_FAILURE);
 }
 
 nsresult nsCocoaUtils::CreateNSImageFromImageContainer(imgIContainer* aImage, uint32_t aWhichFrame,
+                                                       const nsPresContext* aPresContext,
                                                        const ComputedStyle* aComputedStyle,
                                                        NSImage** aResult, CGFloat scaleFactor,
                                                        bool* aIsEntirelyBlack) {
   RefPtr<SourceSurface> surface;
   int32_t width = 0, height = 0;
   aImage->GetWidth(&width);
   aImage->GetHeight(&height);
 
@@ -407,18 +405,18 @@ nsresult nsCocoaUtils::CreateNSImageFrom
       NS_ERROR("Failed to create valid DrawTarget");
       return NS_ERROR_FAILURE;
     }
 
     RefPtr<gfxContext> context = gfxContext::CreateOrNull(drawTarget);
     MOZ_ASSERT(context);
 
     Maybe<SVGImageContext> svgContext;
-    if (aComputedStyle) {
-      SVGImageContext::MaybeStoreContextPaint(svgContext, aComputedStyle, aImage);
+    if (aPresContext && aComputedStyle) {
+      SVGImageContext::MaybeStoreContextPaint(svgContext, *aPresContext, *aComputedStyle, aImage);
     }
     mozilla::image::ImgDrawResult res =
         aImage->Draw(context, scaledSize, ImageRegion::Create(scaledSize), aWhichFrame,
                      SamplingFilter::POINT, svgContext, imgIContainer::FLAG_SYNC_DECODE, 1.0);
 
     if (res != mozilla::image::ImgDrawResult::SUCCESS) {
       return NS_ERROR_FAILURE;
     }
@@ -446,39 +444,39 @@ nsresult nsCocoaUtils::CreateNSImageFrom
   // Ensure the image will be rendered the correct size on a retina display
   NSSize size = NSMakeSize(width, height);
   [*aResult setSize:size];
   [[[*aResult representations] objectAtIndex:0] setSize:size];
   return NS_OK;
 }
 
 nsresult nsCocoaUtils::CreateDualRepresentationNSImageFromImageContainer(
-    imgIContainer* aImage, uint32_t aWhichFrame, const ComputedStyle* aComputedStyle,
-    NSImage** aResult, bool* aIsEntirelyBlack) {
+    imgIContainer* aImage, uint32_t aWhichFrame, const nsPresContext* aPresContext,
+    const ComputedStyle* aComputedStyle, NSImage** aResult, bool* aIsEntirelyBlack) {
   int32_t width = 0, height = 0;
   aImage->GetWidth(&width);
   aImage->GetHeight(&height);
   NSSize size = NSMakeSize(width, height);
   *aResult = [[NSImage alloc] init];
   [*aResult setSize:size];
 
   NSImage* newRepresentation = nil;
-  nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(
-      aImage, aWhichFrame, aComputedStyle, &newRepresentation, 1.0f, aIsEntirelyBlack);
+  nsresult rv = CreateNSImageFromImageContainer(aImage, aWhichFrame, aPresContext, aComputedStyle,
+                                                &newRepresentation, 1.0f, aIsEntirelyBlack);
   if (NS_FAILED(rv) || !newRepresentation) {
     return NS_ERROR_FAILURE;
   }
 
   [[[newRepresentation representations] objectAtIndex:0] setSize:size];
   [*aResult addRepresentation:[[newRepresentation representations] objectAtIndex:0]];
   [newRepresentation release];
   newRepresentation = nil;
 
-  rv = nsCocoaUtils::CreateNSImageFromImageContainer(aImage, aWhichFrame, aComputedStyle,
-                                                     &newRepresentation, 2.0f, aIsEntirelyBlack);
+  rv = CreateNSImageFromImageContainer(aImage, aWhichFrame, aPresContext, aComputedStyle,
+                                       &newRepresentation, 2.0f, aIsEntirelyBlack);
   if (NS_FAILED(rv) || !newRepresentation) {
     return NS_ERROR_FAILURE;
   }
 
   [[[newRepresentation representations] objectAtIndex:0] setSize:size];
   [*aResult addRepresentation:[[newRepresentation representations] objectAtIndex:0]];
   [newRepresentation release];
   return NS_OK;
--- a/widget/cocoa/nsCursorManager.mm
+++ b/widget/cocoa/nsCursorManager.mm
@@ -257,17 +257,17 @@ static constexpr nsCursor kCustomCursor 
   nsIntSize size = nsIWidget::CustomCursorSize(aCursor);
   // prevent DoS attacks
   if (size.width > 128 || size.height > 128) {
     return NS_ERROR_FAILURE;
   }
 
   NSImage* cursorImage;
   nsresult rv = nsCocoaUtils::CreateNSImageFromImageContainer(
-      aCursor.mContainer, imgIContainer::FRAME_FIRST, nullptr, &cursorImage, scaleFactor);
+      aCursor.mContainer, imgIContainer::FRAME_FIRST, nullptr, nullptr, &cursorImage, scaleFactor);
   if (NS_FAILED(rv) || !cursorImage) {
     return NS_ERROR_FAILURE;
   }
 
   {
     NSSize cocoaSize = NSMakeSize(size.width, size.height);
     [cursorImage setSize:cocoaSize];
     [[[cursorImage representations] objectAtIndex:0] setSize:cocoaSize];
--- a/widget/cocoa/nsMenuItemIconX.h
+++ b/widget/cocoa/nsMenuItemIconX.h
@@ -15,16 +15,17 @@
 #include "mozilla/widget/IconLoader.h"
 
 class nsIconLoaderService;
 class nsIURI;
 class nsIContent;
 class nsIPrincipal;
 class imgRequestProxy;
 class nsMenuParentX;
+class nsPresContext;
 
 namespace mozilla {
 class ComputedStyle;
 }
 
 class nsMenuItemIconX final : public mozilla::widget::IconLoader::Listener {
  public:
   class Listener {
@@ -53,17 +54,17 @@ class nsMenuItemIconX final : public moz
 
  protected:
   // Returns whether there should be an icon.
   bool StartIconLoad(nsIContent* aContent);
 
   // GetIconURI returns null if the item should not have any icon.
   already_AddRefed<nsIURI> GetIconURI(nsIContent* aContent);
 
-  nsCOMPtr<nsIContent> mContent;  // always non-null
   Listener* mListener;            // [weak]
   nsIntRect mImageRegionRect;
   RefPtr<mozilla::ComputedStyle> mComputedStyle;
+  RefPtr<nsPresContext> mPresContext;
   NSImage* mIconImage = nil;  // [strong]
   RefPtr<mozilla::widget::IconLoader> mIconLoader;
 };
 
 #endif  // nsMenuItemIconX_h_
--- a/widget/cocoa/nsMenuItemIconX.mm
+++ b/widget/cocoa/nsMenuItemIconX.mm
@@ -18,16 +18,17 @@
 #if __GLIBCXX__ <= 20070719
 #  ifndef __EXCEPTIONS
 #    define __EXCEPTIONS
 #  endif
 #endif
 
 #include "MOZIconHelper.h"
 #include "mozilla/dom/Document.h"
+#include "mozilla/dom/DocumentInlines.h"
 #include "nsCocoaUtils.h"
 #include "nsComputedDOMStyle.h"
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsIContentPolicy.h"
 #include "nsMenuItemX.h"
 #include "nsMenuItemIconX.h"
@@ -145,16 +146,17 @@ already_AddRefed<nsIURI> nsMenuItemIconX
   // 'auto' is represented by a [0, 0, 0, 0] rect. Only set mImageRegionRect
   // if we have some other value.
   if (r.IsEmpty()) {
     mImageRegionRect.SetEmpty();
   } else {
     mImageRegionRect = r.ToNearestPixels(mozilla::AppUnitsPerCSSPixel());
   }
   mComputedStyle = std::move(sc);
+  mPresContext = document->GetPresContext();
 
   return iconURI.forget();
 }
 
 //
 // mozilla::widget::IconLoader::Listener
 //
 
@@ -163,20 +165,22 @@ nsresult nsMenuItemIconX::OnComplete(img
 
   if (mIconImage) {
     [mIconImage release];
     mIconImage = nil;
   }
 
   mIconImage = [[MOZIconHelper iconImageFromImageContainer:aImage
                                                   withSize:NSMakeSize(kIconSize, kIconSize)
+                                               presContext:mPresContext
                                              computedStyle:mComputedStyle
                                                    subrect:mImageRegionRect
                                                scaleFactor:0.0f] retain];
   mComputedStyle = nullptr;
+  mPresContext = nullptr;
 
   if (mListener) {
     mListener->IconUpdated();
   }
 
   mIconLoader->Destroy();
 
   return NS_OK;
--- a/widget/cocoa/nsTouchBarInputIcon.mm
+++ b/widget/cocoa/nsTouchBarInputIcon.mm
@@ -114,16 +114,17 @@ void nsTouchBarInputIcon::ReleaseJSObjec
 
 nsresult nsTouchBarInputIcon::OnComplete(imgIContainer* aImage) {
   NS_OBJC_BEGIN_TRY_BLOCK_RETURN
 
   // We ask only for the HiDPI images since all Touch Bars are Retina
   // displays and we have no need for icons @1x.
   NSImage* image = [MOZIconHelper iconImageFromImageContainer:aImage
                                                      withSize:NSMakeSize(kIconHeight, kIconHeight)
+                                                  presContext:nullptr
                                                 computedStyle:nullptr
                                                       subrect:mImageRegionRect
                                                   scaleFactor:kHiDPIScalingFactor];
   [mButton setImage:image];
   [mShareScrubber setButtonImage:image];
   [mPopoverItem setCollapsedRepresentationImage:image];
 
   mIconLoader->Destroy();
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -47,16 +47,17 @@
 #include "mozilla/MiscEvents.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/NativeKeyBindingsType.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/PresShell.h"
 #include "mozilla/ProfilerLabels.h"
 #include "mozilla/ScopeExit.h"
 #include "mozilla/StaticPrefs_apz.h"
+#include "mozilla/StaticPrefs_mozilla.h"
 #include "mozilla/StaticPrefs_ui.h"
 #include "mozilla/StaticPrefs_widget.h"
 #include "mozilla/TextEventDispatcher.h"
 #include "mozilla/TextEvents.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/UniquePtrExtensions.h"
 #include "mozilla/WidgetUtils.h"
 #include "mozilla/WritingModes.h"
@@ -313,19 +314,16 @@ class CurrentX11TimeGetter {
 };
 
 }  // namespace mozilla
 
 // The window from which the focus manager asks us to dispatch key events.
 static nsWindow* gFocusWindow = nullptr;
 static bool gBlockActivateEvent = false;
 static bool gGlobalsInitialized = false;
-static bool gRaiseWindows = true;
-static bool gTransparentWindows = true;
-static bool gUseMoveToRect = true;
 static bool gUseAspectRatio = true;
 static uint32_t gLastTouchID = 0;
 
 #define NS_WINDOW_TITLE_MAX_LENGTH 4095
 #define kWindowPositionSlop 20
 
 // cursor cache
 static GdkCursor* gCursorCache[eCursorCount];
@@ -1759,17 +1757,17 @@ void nsWindow::UpdateWaylandPopupHierarc
   mWaylandToplevel->WaylandPopupHierarchyValidateByLayout(
       &layoutPopupWidgetChain);
 
   changedPopup->WaylandPopupHierarchyCalculatePositions();
 
   nsWindow* popup = changedPopup;
   while (popup) {
     const bool useMoveToRect = [&] {
-      if (!gUseMoveToRect) {
+      if (!StaticPrefs::widget_wayland_use_move_to_rect_AtStartup()) {
         return false;  // Not available.
       }
       if (!popup->mPopupMatchesLayout) {
         // We can use move_to_rect only when popups in popup hierarchy matches
         // layout hierarchy as move_to_rect request that parent/child
         // popups are adjacent.
         return false;
       }
@@ -2859,17 +2857,18 @@ void nsWindow::SetFocus(Raise aRaise, mo
   GtkWidget* toplevelWidget = gtk_widget_get_toplevel(GTK_WIDGET(mContainer));
 
   LOG("  gFocusWindow [%p]\n", gFocusWindow);
   LOG("  mContainer [%p]\n", GTK_WIDGET(mContainer));
   LOG("  Toplevel widget [%p]\n", toplevelWidget);
 
   // Make sure that our owning widget has focus.  If it doesn't try to
   // grab it.  Note that we don't set our focus flag in this case.
-  if (gRaiseWindows && aRaise == Raise::Yes && toplevelWidget &&
+  if (StaticPrefs::mozilla_widget_raise_on_setfocus_AtStartup() &&
+      aRaise == Raise::Yes && toplevelWidget &&
       !gtk_widget_has_focus(toplevelWidget)) {
     if (gtk_widget_get_visible(mShell)) {
       gdk_window_show_unraised(gtk_widget_get_window(mShell));
       // Unset the urgency hint if possible.
       SetUrgencyHint(mShell, false);
     }
   }
 
@@ -2880,17 +2879,18 @@ void nsWindow::SetFocus(Raise aRaise, mo
   }
 
   if (aRaise == Raise::Yes) {
     // means request toplevel activation.
 
     // This is asynchronous.
     // If and when the window manager accepts the request, then the focus
     // widget will get a focus-in-event signal.
-    if (gRaiseWindows && toplevelWindow->mIsShown && toplevelWindow->mShell &&
+    if (StaticPrefs::mozilla_widget_raise_on_setfocus_AtStartup() &&
+        toplevelWindow->mIsShown && toplevelWindow->mShell &&
         !gtk_window_is_active(GTK_WINDOW(toplevelWindow->mShell))) {
       uint32_t timestamp = GDK_CURRENT_TIME;
 
       nsGTKToolkit* GTKToolkit = nsGTKToolkit::GetToolkit();
       if (GTKToolkit) {
         timestamp = GTKToolkit->GetFocusTimestamp();
         GTKToolkit->SetFocusTimestamp(0);
       }
@@ -5657,23 +5657,25 @@ nsresult nsWindow::Create(nsIWidget* aPa
    */
   GtkStyleContext* style = gtk_widget_get_style_context(mShell);
   mDrawToContainer = GdkIsWaylandDisplay() ||
                      (mGtkWindowDecoration == GTK_DECORATION_CLIENT) ||
                      gtk_style_context_has_class(style, "csd");
   eventWidget = mDrawToContainer ? container : mShell;
 
   // Prevent GtkWindow from painting a background to avoid flickering.
-  gtk_widget_set_app_paintable(eventWidget, gTransparentWindows);
+  gtk_widget_set_app_paintable(
+      eventWidget, StaticPrefs::widget_transparent_windows_AtStartup());
 
   gtk_widget_add_events(eventWidget, kEvents);
 
   if (mDrawToContainer) {
     gtk_widget_add_events(mShell, GDK_PROPERTY_CHANGE_MASK);
-    gtk_widget_set_app_paintable(mShell, gTransparentWindows);
+    gtk_widget_set_app_paintable(
+        mShell, StaticPrefs::widget_transparent_windows_AtStartup());
   }
   if (mTransparencyBitmapForTitlebar) {
     moz_container_force_default_visual(mContainer);
   }
 
   // If we draw to mContainer window then configure it now because
   // gtk_container_add() realizes the child widget.
   gtk_widget_set_has_window(container, mDrawToContainer);
@@ -8094,23 +8096,16 @@ static void drag_data_received_event_cb(
   RefPtr<nsWindow> window = get_window_for_gtk_widget(aWidget);
   if (!window) return;
 
   window->OnDragDataReceivedEvent(aWidget, aDragContext, aX, aY, aSelectionData,
                                   aInfo, aTime, aData);
 }
 
 static nsresult initialize_prefs(void) {
-  gRaiseWindows =
-      Preferences::GetBool("mozilla.widget.raise-on-setfocus", true);
-  gTransparentWindows =
-      Preferences::GetBool("widget.transparent-windows", true);
-  gUseMoveToRect =
-      Preferences::GetBool("widget.wayland.use-move-to-rect", true);
-
   if (Preferences::HasUserValue("widget.use-aspect-ratio")) {
     gUseAspectRatio = Preferences::GetBool("widget.use-aspect-ratio", true);
   } else {
     static const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP");
     gUseAspectRatio =
         currentDesktop ? (strstr(currentDesktop, "GNOME") != nullptr) : false;
   }