Merge mozilla-central to mozilla-inbound
authorDorel Luca <dluca@mozilla.com>
Tue, 03 Apr 2018 07:24:53 +0300
changeset 776579 ac667545d8aaa2174674d683ebb494444f5b9821
parent 776491 9111840008a1707bfabc031a66612436d71135b0 (current diff)
parent 776477 d75d996016dcf325c2db2ed8a47af512d07ffacd (diff)
child 776580 42eb374b79abf455e54fde651d1449c132846809
push id104907
push userbmo:ato@sny.no
push dateTue, 03 Apr 2018 10:28:20 +0000
milestone61.0a1
Merge mozilla-central to mozilla-inbound
testing/web-platform/meta/css/css-flexbox/auto-margins-001.html.ini
xpcom/typelib/xpt/xpt_struct.cpp
xpcom/typelib/xpt/xpt_xdr.cpp
xpcom/typelib/xpt/xpt_xdr.h
--- a/browser/components/enterprisepolicies/Policies.jsm
+++ b/browser/components/enterprisepolicies/Policies.jsm
@@ -56,16 +56,30 @@ var EXPORTED_SYMBOLS = ["Policies"];
  *   It will be different for each policy. It could be a boolean,
  *   a string, an array or a complex object. All parameters have
  *   been validated according to the schema, and no unknown
  *   properties will be present on them.
  *
  * The callbacks will be bound to their parent policy object.
  */
 var Policies = {
+  "Authentication": {
+    onBeforeAddons(manager, param) {
+      if ("SPNEGO" in param) {
+        setAndLockPref("network.negotiate-auth.trusted-uris", param.SPNEGO.join(", "));
+      }
+      if ("Delegated" in param) {
+        setAndLockPref("network.negotiate-auth.delegation-uris", param.Delegated.join(", "));
+      }
+      if ("NTLM" in param) {
+        setAndLockPref("network.automatic-ntlm-auth.trusted-uris", param.NTLM.join(", "));
+      }
+    }
+  },
+
   "BlockAboutAddons": {
     onBeforeUIStartup(manager, param) {
       if (param) {
         manager.disallowFeature("about:addons", true);
       }
     }
   },
 
@@ -103,16 +117,24 @@ var Policies = {
   },
 
   "Bookmarks": {
     onAllWindowsRestored(manager, param) {
       BookmarksPolicies.processBookmarks(param);
     }
   },
 
+  "Certificates": {
+    onBeforeAddons(manager, param) {
+      if ("ImportEnterpriseRoots" in param) {
+        setAndLockPref("security.enterprise_roots.enabled", true);
+      }
+    }
+  },
+
   "Cookies": {
     onBeforeUIStartup(manager, param) {
       addAllowDenyPermissions("cookie", param.Allow, param.Block);
 
       if (param.Block) {
         const hosts = param.Block.map(uri => uri.host).sort().join("\n");
         runOncePerModification("clearCookiesForBlockedHosts", hosts, () => {
           for (let blocked of param.Block) {
--- a/browser/components/enterprisepolicies/schemas/policies-schema.json
+++ b/browser/components/enterprisepolicies/schemas/policies-schema.json
@@ -1,12 +1,40 @@
 {
   "$schema": "http://json-schema.org/draft-04/schema#",
   "type": "object",
   "properties": {
+    "Authentication": {
+      "description": "Sites that support integrated authentication. See https://developer.mozilla.org/en-US/docs/Mozilla/Integrated_authentication",
+      "first_available": "60.0",
+      "enterprise_only": true,
+
+      "type": "object",
+      "properties": {
+        "SPNEGO" : {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        },
+        "Delegated" : {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        },
+        "NTLM" : {
+          "type": "array",
+          "items": {
+            "type": "string"
+          }
+        }
+      }
+    },
+
     "BlockAboutAddons": {
       "description": "Block access to the Add-ons Mananger (about:addons).",
       "first_available": "60.0",
 
       "type": "boolean"
     },
 
     "BlockAboutConfig": {
@@ -65,16 +93,28 @@
           "Folder": {
             "type": "string"
           }
         },
         "required": ["Title", "URL"]
       }
     },
 
+    "Certificates": {
+      "description": "Whether or not to use built in certs.",
+      "first_available": "60.0",
+
+      "type": "object",
+      "properties": {
+        "ImportEnterpriseRoots": {
+          "type": "boolean"
+        }
+      }
+    },
+
     "Cookies": {
       "description": "Allow or deny websites to set cookies.",
       "first_available": "60.0",
 
       "type": "object",
       "properties": {
         "Allow": {
           "type": "array",
--- a/browser/components/enterprisepolicies/tests/browser/browser_policies_simple_pref_policies.js
+++ b/browser/components/enterprisepolicies/tests/browser/browser_policies_simple_pref_policies.js
@@ -70,16 +70,42 @@ const POLICIES_TESTS = [
     }
   },
 
   // POLICY: OverrideFirstRunPage
   {
     policies: { "OverrideFirstRunPage": "https://www.example.com/" },
     lockedPrefs: { "startup.homepage_welcome_url": "https://www.example.com/" },
   },
+
+  // POLICY: Authentication
+  {
+    policies: {
+      "Authentication": {
+        "SPNEGO": ["a.com", "b.com"],
+        "Delegated": ["a.com", "b.com"],
+        "NTLM": ["a.com", "b.com"],
+      }
+    },
+    lockedPrefs: {
+      "network.negotiate-auth.trusted-uris": "a.com, b.com",
+      "network.negotiate-auth.delegation-uris": "a.com, b.com",
+      "network.automatic-ntlm-auth.trusted-uris": "a.com, b.com",
+    }
+  },
+  {
+    policies: {
+      "Certificates": {
+        "ImportEnterpriseRoots": true,
+      }
+    },
+    lockedPrefs: {
+      "security.enterprise_roots.enabled": true,
+    }
+  },
 ];
 
 add_task(async function test_policy_remember_passwords() {
   for (let test of POLICIES_TESTS) {
     await setupPolicyEngineWithJson({
       "policies": test.policies
     });
 
--- a/devtools/client/inspector/boxmodel/test/browser_boxmodel_pseudo-element.js
+++ b/devtools/client/inspector/boxmodel/test/browser_boxmodel_pseudo-element.js
@@ -48,25 +48,25 @@ const res1 = [
     value: "32"
   },
   {
     selector: ".boxmodel-margin.boxmodel-top > span",
     value: 0
   },
   {
     selector: ".boxmodel-margin.boxmodel-left > span",
-    value: 0
+    value: 4 // (100 - (10 * 2) - (20 * 2) - 32) / 2
   },
   {
     selector: ".boxmodel-margin.boxmodel-bottom > span",
     value: 6
   },
   {
     selector: ".boxmodel-margin.boxmodel-right > span",
-    value: 0
+    value: 4 // (100 - (10 * 2) - (20 * 2) - 32) / 2
   },
   {
     selector: ".boxmodel-padding.boxmodel-top > span",
     value: 0
   },
   {
     selector: ".boxmodel-padding.boxmodel-left > span",
     value: 0
--- a/layout/base/GeometryUtils.cpp
+++ b/layout/base/GeometryUtils.cpp
@@ -147,21 +147,17 @@ GetBoxRectForFrame(nsIFrame** aFrame, CS
     return r;
   }
 
   f = *aFrame;
   switch (aType) {
   case CSSBoxType::Content: r = f->GetContentRectRelativeToSelf(); break;
   case CSSBoxType::Padding: r = f->GetPaddingRectRelativeToSelf(); break;
   case CSSBoxType::Border: r = nsRect(nsPoint(0, 0), f->GetSize()); break;
-  case CSSBoxType::Margin: {
-    r = nsRect(nsPoint(0, 0), f->GetSize());
-    r.Inflate(f->GetUsedMargin());
-    break;
-  }
+  case CSSBoxType::Margin: r = f->GetMarginRectRelativeToSelf(); break;
   default: MOZ_ASSERT(false, "unknown box type"); return r;
   }
 
   return r;
 }
 
 class AccumulateQuadCallback : public nsLayoutUtils::BoxCallback {
 public:
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -2526,17 +2526,17 @@ ReflowInput::InitConstraints(nsPresConte
   // Save our containing block dimensions
   mContainingBlockSize = aContainingBlockSize;
 }
 
 static void
 UpdateProp(nsIFrame* aFrame,
            const FramePropertyDescriptor<nsMargin>* aProperty,
            bool aNeeded,
-           nsMargin& aNewValue)
+           const nsMargin& aNewValue)
 {
   if (aNeeded) {
     nsMargin* propValue = aFrame->GetProperty(aProperty);
     if (propValue) {
       *propValue = aNewValue;
     } else {
       aFrame->AddProperty(aProperty, new nsMargin(aNewValue));
     }
@@ -2561,20 +2561,20 @@ SizeComputationInput::InitOffsets(Writin
   nsPresContext *presContext = mFrame->PresContext();
   mFrame->DeleteProperty(nsIFrame::UsedBorderProperty());
 
   // Compute margins from the specified margin style information. These
   // become the default computed values, and may be adjusted below
   // XXX fix to provide 0,0 for the top&bottom margins for
   // inline-non-replaced elements
   bool needMarginProp = ComputeMargin(aWM, aPercentBasis);
-  // XXX We need to include 'auto' horizontal margins in this too!
-  // ... but if we did that, we'd need to fix nsFrame::GetUsedMargin
-  // to use it even when the margins are all zero (since sometimes
-  // they get treated as auto)
+  // Note that ComputeMargin() simplistically resolves 'auto' margins to 0.
+  // In formatting contexts where this isn't correct, some later code will
+  // need to update the UsedMargin() property with the actual resolved value.
+  // One example of this is ::CalculateBlockSideMargins().
   ::UpdateProp(mFrame, nsIFrame::UsedMarginProperty(), needMarginProp,
                ComputedPhysicalMargin());
 
 
   const nsStyleDisplay* disp = mFrame->StyleDisplayWithOptionalParam(aDisplay);
   bool isThemed = mFrame->IsThemed(disp);
   bool needPaddingProp;
   nsIntMargin widget;
@@ -2795,17 +2795,26 @@ ReflowInput::CalculateBlockSideMargins(L
       margin.IStart(cbWM) += forStart;
       margin.IEnd(cbWM) += availMarginSpace - forStart;
     } else {
       margin.IStart(cbWM) += availMarginSpace;
     }
   } else if (isAutoEndMargin) {
     margin.IEnd(cbWM) += availMarginSpace;
   }
-  SetComputedLogicalMargin(margin.ConvertTo(mWritingMode, cbWM));
+  LogicalMargin marginInOurWM = margin.ConvertTo(mWritingMode, cbWM);
+  SetComputedLogicalMargin(marginInOurWM);
+
+  if (isAutoStartMargin || isAutoEndMargin) {
+    // Update the UsedMargin property if we were tracking it already.
+    nsMargin* propValue = mFrame->GetProperty(nsIFrame::UsedMarginProperty());
+    if (propValue) {
+      *propValue = marginInOurWM.GetPhysicalMargin(mWritingMode);
+    }
+  }
 }
 
 #define NORMAL_LINE_HEIGHT_FACTOR 1.2f    // in term of emHeight
 // For "normal" we use the font's normal line height (em height + leading).
 // If both internal leading and  external leading specified by font itself
 // are zeros, we should compensate this by creating extra (external) leading
 // in eCompensateLeading mode. This is necessary because without this
 // compensation, normal line height might looks too tight.
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -548,16 +548,19 @@ public:
   // cross axis).
   bool IsStretched() const         { return mIsStretched; }
 
   // Indicates whether we need to resolve an 'auto' value for the main-axis
   // min-[width|height] property.
   bool NeedsMinSizeAutoResolution() const
     { return mNeedsMinSizeAutoResolution; }
 
+  bool HasAnyAutoMargin() const
+    { return mHasAnyAutoMargin; }
+
   // Indicates whether this item is a "strut" left behind by an element with
   // visibility:collapse.
   bool IsStrut() const             { return mIsStrut; }
 
   // IsInlineAxisMainAxis() returns true if this item's inline axis is parallel
   // (or antiparallel) to the container's main axis. Otherwise (i.e. if this
   // item's inline axis is orthogonal to the container's main axis), this
   // function returns false. The next 3 methods are all other ways of asking
@@ -853,16 +856,19 @@ protected:
   bool mIsStretched; // See IsStretched() documentation
   bool mIsStrut;     // Is this item a "strut" left behind by an element
                      // with visibility:collapse?
   const bool mIsInlineAxisMainAxis; // See IsInlineAxisMainAxis() documentation
 
   // Does this item need to resolve a min-[width|height]:auto (in main-axis).
   bool mNeedsMinSizeAutoResolution;
 
+  // Does this item have an auto margin in either main or cross axis?
+  bool mHasAnyAutoMargin;
+
   uint8_t mAlignSelf; // My "align-self" computed value (with "auto"
                       // swapped out for parent"s "align-items" value,
                       // in our constructor).
 };
 
 /**
  * Represents a single flex line in a flex container.
  * Manages a linked list of the FlexItems that are in the line.
@@ -1811,17 +1817,17 @@ FlexItem::FlexItem(ReflowInput& aFlexIte
     mHadMinViolation(false),
     mHadMaxViolation(false),
     mHadMeasuringReflow(false),
     mIsStretched(false),
     mIsStrut(false),
     mIsInlineAxisMainAxis(aAxisTracker.IsRowOriented() !=
                           aAxisTracker.GetWritingMode().IsOrthogonalTo(mWM))
     // mNeedsMinSizeAutoResolution is initialized in CheckForMinSizeAuto()
-    // mAlignSelf, see below
+    // mAlignSelf, mHasAnyAutoMargin see below
 {
   MOZ_ASSERT(mFrame, "expecting a non-null child frame");
   MOZ_ASSERT(!mFrame->IsPlaceholderFrame(),
              "placeholder frames should not be treated as flex items");
   MOZ_ASSERT(!(mFrame->GetStateBits() & NS_FRAME_OUT_OF_FLOW),
              "out-of-flow frames should not be treated as flex items");
   MOZ_ASSERT(mIsInlineAxisMainAxis ==
              nsFlexContainerFrame::IsItemInlineAxisMainAxis(mFrame),
@@ -1848,22 +1854,26 @@ FlexItem::FlexItem(ReflowInput& aFlexIte
 
     // XXX strip off the <overflow-position> bit until we implement that
     mAlignSelf &= ~NS_STYLE_ALIGN_FLAG_BITS;
   }
 
   SetFlexBaseSizeAndMainSize(aFlexBaseSize);
   CheckForMinSizeAuto(aFlexItemReflowInput, aAxisTracker);
 
+
+  const nsStyleSides& styleMargin =
+    aFlexItemReflowInput.mStyleMargin->mMargin;
+  mHasAnyAutoMargin = styleMargin.HasInlineAxisAuto(mWM) ||
+                      styleMargin.HasBlockAxisAuto(mWM);
+
   // Assert that any "auto" margin components are set to 0.
   // (We'll resolve them later; until then, we want to treat them as 0-sized.)
 #ifdef DEBUG
   {
-    const nsStyleSides& styleMargin =
-      aFlexItemReflowInput.mStyleMargin->mMargin;
     NS_FOR_CSS_SIDES(side) {
       if (styleMargin.GetUnit(side) == eStyleUnit_Auto) {
         MOZ_ASSERT(GetMarginComponentForSide(side) == 0,
                    "Someone else tried to resolve our auto margin");
       }
     }
   }
 #endif // DEBUG
@@ -1912,16 +1922,17 @@ FlexItem::FlexItem(nsIFrame* aChildFrame
     mIsFrozen(true),
     mHadMinViolation(false),
     mHadMaxViolation(false),
     mHadMeasuringReflow(false),
     mIsStretched(false),
     mIsStrut(true), // (this is the constructor for making struts, after all)
     mIsInlineAxisMainAxis(true), // (doesn't matter b/c we're not doing layout)
     mNeedsMinSizeAutoResolution(false),
+    mHasAnyAutoMargin(false),
     mAlignSelf(NS_STYLE_ALIGN_FLEX_START)
 {
   MOZ_ASSERT(mFrame, "expecting a non-null child frame");
   MOZ_ASSERT(NS_STYLE_VISIBILITY_COLLAPSE ==
              mFrame->StyleVisibility()->mVisible,
              "Should only make struts for children with 'visibility:collapse'");
   MOZ_ASSERT(!mFrame->IsPlaceholderFrame(),
              "placeholder frames should not be treated as flex items");
@@ -4748,16 +4759,26 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
           }
         }
       }
       if (itemNeedsReflow) {
         ReflowFlexItem(aPresContext, aAxisTracker, aReflowInput,
                        *item, framePos, containerSize);
       }
 
+      // If the item has auto margins, and we were tracking the UsedMargin
+      // property, set the property to the computed margin values.
+      if (item->HasAnyAutoMargin()) {
+        nsMargin* propValue =
+          item->Frame()->GetProperty(nsIFrame::UsedMarginProperty());
+        if (propValue) {
+          *propValue = item->GetMargin();
+        }
+      }
+
       // If this is our first item and we haven't established a baseline for
       // the container yet (i.e. if we don't have 'align-self: baseline' on any
       // children), then use this child's first baseline as the container's
       // baseline.
       if (item == firstItem &&
           flexContainerAscent == nscoord_MIN) {
         flexContainerAscent = itemNormalBPos + item->ResolvedAscent(true);
       }
@@ -4948,20 +4969,16 @@ nsFlexContainerFrame::ReflowFlexItem(nsP
     // the changes in bug 851607. So this has no effect right now, but it might
     // make a difference if we optimize to use dirty bits in the
     // future. (Reftests flexbox-resizeviewport-1.xhtml and -2.xhtml are
     // intended to catch any regressions here, if we end up relying on this bit
     // & neglecting to set it.)
     aItem.Frame()->AddStateBits(NS_FRAME_CONTAINS_RELATIVE_BSIZE);
   }
 
-  // XXXdholbert Might need to actually set the correct margins in the
-  // reflow state at some point, so that they can be saved on the frame for
-  // UsedMarginProperty().  Maybe doesn't matter though...?
-
   // If we're overriding the computed width or height, *and* we had an
   // earlier "measuring" reflow, then this upcoming reflow needs to be
   // treated as a resize.
   if (aItem.HadMeasuringReflow()) {
     if (didOverrideComputedISize) {
       // (This is somewhat redundant, since ReflowInput::InitResizeFlags()
       // already calls SetIResize() whenever our computed ISize has changed
       // since the previous reflow. Still, it's nice for symmetry, and it might
--- a/mozglue/linker/ElfLoader.cpp
+++ b/mozglue/linker/ElfLoader.cpp
@@ -80,17 +80,21 @@ void *
   if (!handle) {
     ElfLoader::Singleton.lastError = "dlsym(NULL, sym) unsupported";
     return nullptr;
   }
   if (handle != RTLD_DEFAULT && handle != RTLD_NEXT) {
     LibHandle *h = reinterpret_cast<LibHandle *>(handle);
     return h->GetSymbolPtr(symbol);
   }
-  return dlsym(handle, symbol);
+
+  void* sym = dlsym(handle, symbol);
+  ElfLoader::Singleton.lastError = dlerror();
+
+  return sym;
 }
 
 int
 __wrap_dlclose(void *handle)
 {
   if (!handle) {
     ElfLoader::Singleton.lastError = "No handle given to dlclose()";
     return -1;
@@ -351,16 +355,17 @@ LibHandle::MappableMUnmap(void *addr, si
  */
 already_AddRefed<LibHandle>
 SystemElf::Load(const char *path, int flags)
 {
   /* The Android linker returns a handle when the file name matches an
    * already loaded library, even when the full path doesn't exist */
   if (path && path[0] == '/' && (access(path, F_OK) == -1)){
     DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, (void *)nullptr);
+    ElfLoader::Singleton.lastError = "Specified file does not exist";
     return nullptr;
   }
 
   void *handle = dlopen(path, flags);
   DEBUG_LOG("dlopen(\"%s\", 0x%x) = %p", path, flags, handle);
   ElfLoader::Singleton.lastError = dlerror();
   if (handle) {
     SystemElf *elf = new SystemElf(path, handle);
--- a/mozglue/linker/ElfLoader.h
+++ b/mozglue/linker/ElfLoader.h
@@ -449,17 +449,17 @@ protected:
   /* Last error. Used for dlerror() */
   friend class SystemElf;
   friend const char *__wrap_dlerror(void);
   friend void *__wrap_dlsym(void *handle, const char *symbol);
   friend int __wrap_dlclose(void *handle);
   const char *lastError;
 
 private:
-  ElfLoader() : expect_shutdown(true)
+  ElfLoader() : expect_shutdown(true), lastError(nullptr)
   {
     pthread_mutex_init(&handlesMutex, nullptr);
   }
 
   ~ElfLoader();
 
   /* Initialization code that can't run during static initialization. */
   void Init();
--- a/servo/components/style/properties/longhand/svg.mako.rs
+++ b/servo/components/style/properties/longhand/svg.mako.rs
@@ -134,18 +134,20 @@
     pub use ::properties::longhands::background_size::single_value as single_value;
     pub use ::properties::longhands::background_size::computed_value as computed_value;
 
     #[inline]
     pub fn get_initial_value() -> computed_value::T {
         background_size::get_initial_value()
     }
 
-    pub fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                         -> Result<SpecifiedValue,ParseError<'i>> {
+    pub fn parse<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<SpecifiedValue, ParseError<'i>> {
         background_size::parse(context, input)
     }
 </%helpers:longhand>
 
 ${helpers.single_keyword("mask-composite",
                          "add subtract intersect exclude",
                          vector=True,
                          products="gecko",
--- a/servo/components/style/properties/shorthand/background.mako.rs
+++ b/servo/components/style/properties/shorthand/background.mako.rs
@@ -28,18 +28,20 @@
                 background_origin::single_value::SpecifiedValue::PaddingBox =>
                     background_clip::single_value::SpecifiedValue::PaddingBox,
                 background_origin::single_value::SpecifiedValue::BorderBox =>
                     background_clip::single_value::SpecifiedValue::BorderBox,
             }
         }
     }
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let mut background_color = None;
 
         % for name in "image position_x position_y repeat size attachment origin clip".split():
             // Vec grows from 0 to 4 by default on first push().  So allocate
             // with capacity 1, so in the common case of only one item we don't
             // way overallocate.  Note that we always push at least one item if
             // parsing succeeds.
             let mut background_${name} = background_${name}::SpecifiedValue(Vec::with_capacity(1));
@@ -195,18 +197,20 @@
 
 <%helpers:shorthand name="background-position"
                     sub_properties="background-position-x background-position-y"
                     spec="https://drafts.csswg.org/css-backgrounds-4/#the-background-position">
     use properties::longhands::{background_position_x, background_position_y};
     use values::specified::AllowQuirks;
     use values::specified::position::Position;
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         // Vec grows from 0 to 4 by default on first push().  So allocate with
         // capacity 1, so in the common case of only one item we don't way
         // overallocate.  Note that we always push at least one item if parsing
         // succeeds.
         let mut position_x = background_position_x::SpecifiedValue(Vec::with_capacity(1));
         let mut position_y = background_position_y::SpecifiedValue(Vec::with_capacity(1));
         let mut any = false;
 
--- a/servo/components/style/properties/shorthand/border.mako.rs
+++ b/servo/components/style/properties/shorthand/border.mako.rs
@@ -19,18 +19,20 @@
 
 <%helpers:shorthand name="border-width" sub_properties="${
         ' '.join('border-%s-width' % side
                  for side in PHYSICAL_SIDES)}"
     spec="https://drafts.csswg.org/css-backgrounds/#border-width">
     use values::generics::rect::Rect;
     use values::specified::{AllowQuirks, BorderSideWidth};
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let rect = Rect::parse_with(context, input, |_, i| {
             BorderSideWidth::parse_quirky(context, i, AllowQuirks::Yes)
         })?;
         Ok(expanded! {
             border_top_width: rect.0,
             border_right_width: rect.1,
             border_bottom_width: rect.2,
             border_left_width: rect.3,
@@ -43,20 +45,20 @@
             let ${side} = &self.border_${side}_width;
             % endfor
             Rect::new(top, right, bottom, left).to_css(dest)
         }
     }
 </%helpers:shorthand>
 
 
-pub fn parse_border<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                            -> Result<(specified::Color,
-                                       specified::BorderStyle,
-                                       specified::BorderSideWidth), ParseError<'i>> {
+pub fn parse_border<'i, 't>(
+    context: &ParserContext,
+    input: &mut Parser<'i, 't>,
+) -> Result<(specified::Color, specified::BorderStyle, specified::BorderSideWidth), ParseError<'i>> {
     use values::specified::{Color, BorderStyle, BorderSideWidth};
     let _unused = context;
     let mut color = None;
     let mut style = None;
     let mut width = None;
     let mut any = false;
     loop {
         if color.is_none() {
@@ -101,18 +103,20 @@ pub fn parse_border<'i, 't>(context: &Pa
         name="border-${side}"
         sub_properties="${' '.join(
             'border-%s-%s' % (side, prop)
             for prop in ['color', 'style', 'width']
         )}"
         alias="${maybe_moz_logical_alias(product, (side, logical), '-moz-border-%s')}"
         spec="${spec}">
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let (color, style, width) = super::parse_border(context, input)?;
         Ok(expanded! {
             border_${to_rust_ident(side)}_color: color,
             border_${to_rust_ident(side)}_style: style,
             border_${to_rust_ident(side)}_width: width
         })
     }
 
@@ -133,18 +137,20 @@ pub fn parse_border<'i, 't>(context: &Pa
 <%helpers:shorthand name="border"
     sub_properties="${' '.join('border-%s-%s' % (side, prop)
         for side in PHYSICAL_SIDES
         for prop in ['color', 'style', 'width'])}
         ${' '.join('border-image-%s' % name
         for name in ['outset', 'repeat', 'slice', 'source', 'width'])}"
     spec="https://drafts.csswg.org/css-backgrounds/#border">
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         use properties::longhands::{border_image_outset, border_image_repeat, border_image_slice};
         use properties::longhands::{border_image_source, border_image_width};
 
         let (color, style, width) = super::parse_border(context, input)?;
         Ok(expanded! {
             % for side in PHYSICAL_SIDES:
                 border_${side}_color: color.clone(),
                 border_${side}_style: style,
@@ -202,18 +208,20 @@ pub fn parse_border<'i, 't>(context: &Pa
     'border-%s-radius' % (corner)
      for corner in ['top-left', 'top-right', 'bottom-right', 'bottom-left']
 )}" extra_prefixes="webkit" spec="https://drafts.csswg.org/css-backgrounds/#border-radius">
     use values::generics::rect::Rect;
     use values::generics::border::BorderCornerRadius;
     use values::specified::border::BorderRadius;
     use parser::Parse;
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let radii = BorderRadius::parse(context, input)?;
         Ok(expanded! {
             border_top_left_radius: radii.top_left,
             border_top_right_radius: radii.top_right,
             border_bottom_right_radius: radii.bottom_right,
             border_bottom_left_radius: radii.bottom_left,
         })
     }
@@ -237,18 +245,20 @@ pub fn parse_border<'i, 't>(context: &Pa
 </%helpers:shorthand>
 
 <%helpers:shorthand name="border-image" sub_properties="border-image-outset
     border-image-repeat border-image-slice border-image-source border-image-width"
     extra_prefixes="moz webkit" spec="https://drafts.csswg.org/css-backgrounds-3/#border-image">
     use properties::longhands::{border_image_outset, border_image_repeat, border_image_slice};
     use properties::longhands::{border_image_source, border_image_width};
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         % for name in "outset repeat slice source width".split():
             let mut border_image_${name} = border_image_${name}::get_initial_specified_value();
         % endfor
 
         let result: Result<_, ParseError> = input.try(|input| {
             % for name in "outset repeat slice source width".split():
                 let mut ${name} = None;
             % endfor
--- a/servo/components/style/properties/shorthand/box.mako.rs
+++ b/servo/components/style/properties/shorthand/box.mako.rs
@@ -6,18 +6,20 @@
 
 <%helpers:shorthand name="overflow" sub_properties="overflow-x overflow-y"
                     spec="https://drafts.csswg.org/css-overflow/#propdef-overflow">
     use properties::longhands::overflow_x::parse as parse_overflow;
     % if product == "gecko":
         use properties::longhands::overflow_x::SpecifiedValue;
     % endif
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         % if product == "gecko":
             let moz_kw_found = input.try(|input| {
                 try_match_ident_ignore_ascii_case! { input,
                     "-moz-scrollbars-horizontal" => {
                         Ok(expanded! {
                             overflow_x: SpecifiedValue::Scroll,
                             overflow_y: SpecifiedValue::Hidden,
                         })
@@ -113,29 +115,33 @@ macro_rules! try_parse_one {
                     sub_properties="transition-property transition-duration
                                     transition-timing-function
                                     transition-delay"
                     spec="https://drafts.csswg.org/css-transitions/#propdef-transition">
     % for prop in "delay duration property timing_function".split():
     use properties::longhands::transition_${prop};
     % endfor
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         struct SingleTransition {
             % for prop in "duration timing_function delay".split():
             transition_${prop}: transition_${prop}::SingleSpecifiedValue,
             % endfor
             // Unlike other properties, transition-property uses an Option<> to
             // represent 'none' as `None`.
             transition_property: Option<transition_property::SingleSpecifiedValue>,
         }
 
-        fn parse_one_transition<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                                        -> Result<SingleTransition,ParseError<'i>> {
+        fn parse_one_transition<'i, 't>(
+            context: &ParserContext,
+            input: &mut Parser<'i, 't>,
+        ) -> Result<SingleTransition,ParseError<'i>> {
             % for prop in "property duration timing_function delay".split():
             let mut ${prop} = None;
             % endfor
 
             let mut parsed = 0;
             loop {
                 parsed += 1;
 
@@ -255,26 +261,30 @@ macro_rules! try_parse_one {
     <%
         props = "name duration timing_function delay iteration_count \
                  direction fill_mode play_state".split()
     %>
     % for prop in props:
     use properties::longhands::animation_${prop};
     % endfor
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         struct SingleAnimation {
             % for prop in props:
             animation_${prop}: animation_${prop}::SingleSpecifiedValue,
             % endfor
         }
 
-        fn parse_one_animation<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                                       -> Result<SingleAnimation,ParseError<'i>> {
+        fn parse_one_animation<'i, 't>(
+            context: &ParserContext,
+            input: &mut Parser<'i, 't>,
+        ) -> Result<SingleAnimation, ParseError<'i>> {
             % for prop in props:
             let mut ${prop} = None;
             % endfor
 
             let mut parsed = 0;
             // NB: Name must be the last one here so that keywords valid for other
             // longhands are not interpreted as names.
             //
@@ -359,18 +369,20 @@ macro_rules! try_parse_one {
 </%helpers:shorthand>
 
 <%helpers:shorthand name="scroll-snap-type" products="gecko"
                     gecko_pref="layout.css.scroll-snap.enabled"
                     sub_properties="scroll-snap-type-x scroll-snap-type-y"
                     spec="https://drafts.csswg.org/css-scroll-snap/#propdef-scroll-snap-type">
     use properties::longhands::scroll_snap_type_x;
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let result = scroll_snap_type_x::parse(context, input)?;
         Ok(expanded! {
             scroll_snap_type_x: result,
             scroll_snap_type_y: result,
         })
     }
 
     impl<'a> ToCss for LonghandsToSerialize<'a>  {
--- a/servo/components/style/properties/shorthand/column.mako.rs
+++ b/servo/components/style/properties/shorthand/column.mako.rs
@@ -6,19 +6,20 @@
 
 <%helpers:shorthand name="columns"
                     sub_properties="column-width column-count"
                     servo_pref="layout.columns.enabled",
                     derive_serialize="True"
                     extra_prefixes="moz" spec="https://drafts.csswg.org/css-multicol/#propdef-columns">
     use properties::longhands::{column_count, column_width};
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
-
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let mut column_count = None;
         let mut column_width = None;
         let mut autos = 0;
 
         loop {
             if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
                 // Leave the options to None, 'auto' is the initial value.
                 autos += 1;
@@ -56,18 +57,20 @@
 
 <%helpers:shorthand name="column-rule" products="gecko" extra_prefixes="moz"
     sub_properties="column-rule-width column-rule-style column-rule-color"
     derive_serialize="True"
     spec="https://drafts.csswg.org/css-multicol/#propdef-column-rule">
     use properties::longhands::{column_rule_width, column_rule_style};
     use properties::longhands::column_rule_color;
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         % for name in "width style color".split():
         let mut column_rule_${name} = None;
         % endfor
         let mut any = false;
 
         loop {
             % for name in "width style color".split():
             if column_rule_${name}.is_none() {
--- a/servo/components/style/properties/shorthand/font.mako.rs
+++ b/servo/components/style/properties/shorthand/font.mako.rs
@@ -37,18 +37,20 @@
     %>
     % if product == "gecko":
         % for prop in gecko_sub_properties:
             use properties::longhands::font_${prop};
         % endfor
     % endif
     use self::font_family::SpecifiedValue as FontFamily;
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let mut nb_normals = 0;
         let mut style = None;
         let mut variant_caps = None;
         let mut weight = None;
         let mut stretch = None;
         let size;
         % if product == "gecko":
             if let Ok(sys) = input.try(SystemFont::parse) {
@@ -257,18 +259,20 @@
     %>
 
 % for prop in sub_properties:
     use properties::longhands::font_variant_${prop};
 % endfor
     #[allow(unused_imports)]
     use values::specified::FontVariantLigatures;
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
     % for prop in sub_properties:
         let mut ${prop} = None;
     % endfor
 
         if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
             // Leave the values to None, 'normal' is the initial value for all the sub properties.
         } else if input.try(|input| input.expect_ident_matching("none")).is_ok() {
             // The 'none' value sets 'font-variant-ligatures' to 'none' and resets all other sub properties
--- a/servo/components/style/properties/shorthand/inherited_svg.mako.rs
+++ b/servo/components/style/properties/shorthand/inherited_svg.mako.rs
@@ -4,18 +4,20 @@
 
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
 <%helpers:shorthand name="marker" products="gecko"
     sub_properties="marker-start marker-end marker-mid"
     spec="https://www.w3.org/TR/SVG2/painting.html#MarkerShorthand">
     use values::specified::UrlOrNone;
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         use parser::Parse;
         let url = UrlOrNone::parse(context, input)?;
 
         Ok(expanded! {
             marker_start: url.clone(),
             marker_mid: url.clone(),
             marker_end: url,
         })
--- a/servo/components/style/properties/shorthand/inherited_text.mako.rs
+++ b/servo/components/style/properties/shorthand/inherited_text.mako.rs
@@ -5,18 +5,20 @@
 <%namespace name="helpers" file="/helpers.mako.rs" />
 
 <%helpers:shorthand name="text-emphasis" products="gecko"
     sub_properties="text-emphasis-style text-emphasis-color"
     derive_serialize="True"
     spec="https://drafts.csswg.org/css-text-decor-3/#text-emphasis-property">
     use properties::longhands::{text_emphasis_color, text_emphasis_style};
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let mut color = None;
         let mut style = None;
 
         loop {
             if color.is_none() {
                 if let Ok(value) = input.try(|input| text_emphasis_color::parse(context, input)) {
                     color = Some(value);
                     continue
@@ -47,18 +49,20 @@
                     sub_properties="-webkit-text-stroke-width
                                     -webkit-text-stroke-color"
                     gecko_pref="layout.css.prefixes.webkit"
                     products="gecko"
                     derive_serialize="True"
                     spec="https://compat.spec.whatwg.org/#the-webkit-text-stroke">
     use properties::longhands::{_webkit_text_stroke_color, _webkit_text_stroke_width};
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let mut color = None;
         let mut width = None;
         loop {
             if color.is_none() {
                 if let Ok(value) = input.try(|input| _webkit_text_stroke_color::parse(context, input)) {
                     color = Some(value);
                     continue
                 }
--- a/servo/components/style/properties/shorthand/list.mako.rs
+++ b/servo/components/style/properties/shorthand/list.mako.rs
@@ -6,18 +6,20 @@
 
 <%helpers:shorthand name="list-style"
                     sub_properties="list-style-position list-style-image list-style-type"
                     derive_serialize="True"
                     spec="https://drafts.csswg.org/css-lists/#propdef-list-style">
     use properties::longhands::{list_style_image, list_style_position, list_style_type};
     use values::{Either, None_};
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         // `none` is ambiguous until we've finished parsing the shorthands, so we count the number
         // of times we see it.
         let mut nones = 0u8;
         let (mut image, mut position, mut list_style_type, mut any) = (None, None, None, false);
         loop {
             if input.try(|input| input.expect_ident_matching("none")).is_ok() {
                 nones = nones + 1;
                 if nones > 2 {
--- a/servo/components/style/properties/shorthand/mask.mako.rs
+++ b/servo/components/style/properties/shorthand/mask.mako.rs
@@ -31,18 +31,20 @@
                     mask_clip::single_value::SpecifiedValue::StrokeBox,
                 mask_origin::single_value::SpecifiedValue::ViewBox=>
                     mask_clip::single_value::SpecifiedValue::ViewBox,
                 % endif
             }
         }
     }
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         % for name in "image mode position_x position_y size repeat origin clip composite".split():
             // Vec grows from 0 to 4 by default on first push().  So allocate
             // with capacity 1, so in the common case of only one item we don't
             // way overallocate.  Note that we always push at least one item if
             // parsing succeeds.
             let mut mask_${name} = mask_${name}::SpecifiedValue(Vec::with_capacity(1));
         % endfor
 
--- a/servo/components/style/properties/shorthand/outline.mako.rs
+++ b/servo/components/style/properties/shorthand/outline.mako.rs
@@ -7,18 +7,20 @@
 <%helpers:shorthand name="outline"
                     sub_properties="outline-width outline-style outline-color"
                     derive_serialize="True"
                     spec="https://drafts.csswg.org/css-ui/#propdef-outline">
     use properties::longhands::{outline_color, outline_width, outline_style};
     use values::specified;
     use parser::Parse;
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let _unused = context;
         let mut color = None;
         let mut style = None;
         let mut width = None;
         let mut any = false;
         loop {
             if color.is_none() {
                 if let Ok(value) = input.try(|i| specified::Color::parse(context, i)) {
@@ -59,18 +61,20 @@
 <%helpers:shorthand name="-moz-outline-radius" sub_properties="${' '.join(
     '-moz-outline-radius-%s' % corner
     for corner in ['topleft', 'topright', 'bottomright', 'bottomleft']
 )}" products="gecko" spec="Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-outline-radius)">
     use values::generics::rect::Rect;
     use values::specified::border::BorderRadius;
     use parser::Parse;
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let radii = BorderRadius::parse(context, input)?;
         Ok(expanded! {
             _moz_outline_radius_topleft: radii.top_left,
             _moz_outline_radius_topright: radii.top_right,
             _moz_outline_radius_bottomright: radii.bottom_right,
             _moz_outline_radius_bottomleft: radii.bottom_left,
         })
     }
--- a/servo/components/style/properties/shorthand/position.mako.rs
+++ b/servo/components/style/properties/shorthand/position.mako.rs
@@ -6,18 +6,20 @@
 
 <%helpers:shorthand name="flex-flow"
                     sub_properties="flex-direction flex-wrap"
                     extra_prefixes="webkit"
                     derive_serialize="True"
                     spec="https://drafts.csswg.org/css-flexbox/#flex-flow-property">
     use properties::longhands::{flex_direction, flex_wrap};
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         let mut direction = None;
         let mut wrap = None;
         loop {
             if direction.is_none() {
                 if let Ok(value) = input.try(|input| flex_direction::parse(context, input)) {
                     direction = Some(value);
                     continue
                 }
--- a/servo/components/style/properties/shorthand/text.mako.rs
+++ b/servo/components/style/properties/shorthand/text.mako.rs
@@ -11,18 +11,20 @@
 
     % if product == "gecko":
         use values::specified;
         use properties::longhands::{text_decoration_line, text_decoration_style, text_decoration_color};
     % else:
         use properties::longhands::text_decoration_line;
     % endif
 
-    pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                               -> Result<Longhands, ParseError<'i>> {
+    pub fn parse_value<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Longhands, ParseError<'i>> {
         % if product == "gecko":
             let (mut line, mut style, mut color, mut any) = (None, None, None, false);
         % else:
             let (mut line, mut any) = (None, false);
         % endif
 
         loop {
             macro_rules! parse_component {
--- a/servo/components/style/values/specified/length.rs
+++ b/servo/components/style/values/specified/length.rs
@@ -596,27 +596,30 @@ impl Length {
         }
         input.parse_nested_block(|input| {
             CalcNode::parse_length(context, input, num_context).map(|calc| Length::Calc(Box::new(calc)))
         })
     }
 
     /// Parse a non-negative length
     #[inline]
-    pub fn parse_non_negative<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
-                                      -> Result<Length, ParseError<'i>> {
+    pub fn parse_non_negative<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+    ) -> Result<Self, ParseError<'i>> {
         Self::parse_non_negative_quirky(context, input, AllowQuirks::No)
     }
 
     /// Parse a non-negative length, allowing quirks.
     #[inline]
-    pub fn parse_non_negative_quirky<'i, 't>(context: &ParserContext,
-                                             input: &mut Parser<'i, 't>,
-                                             allow_quirks: AllowQuirks)
-                                             -> Result<Length, ParseError<'i>> {
+    pub fn parse_non_negative_quirky<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+        allow_quirks: AllowQuirks,
+    ) -> Result<Self, ParseError<'i>> {
         Self::parse_internal(context, input, AllowedNumericType::NonNegative, allow_quirks)
     }
 
     /// Get an absolute length from a px value.
     #[inline]
     pub fn from_px(px_value: CSSFloat) -> Length {
         Length::NoCalc(NoCalcLength::from_px(px_value))
     }
@@ -625,20 +628,21 @@ impl Length {
 impl Parse for Length {
     fn parse<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
         Self::parse_quirky(context, input, AllowQuirks::No)
     }
 }
 
 impl Length {
     /// Parses a length, with quirks.
-    pub fn parse_quirky<'i, 't>(context: &ParserContext,
-                                input: &mut Parser<'i, 't>,
-                                allow_quirks: AllowQuirks)
-                                -> Result<Self, ParseError<'i>> {
+    pub fn parse_quirky<'i, 't>(
+        context: &ParserContext,
+        input: &mut Parser<'i, 't>,
+        allow_quirks: AllowQuirks,
+    ) -> Result<Self, ParseError<'i>> {
         Self::parse_internal(context, input, AllowedNumericType::All, allow_quirks)
     }
 }
 
 /// A wrapper of Length, whose value must be >= 0.
 pub type NonNegativeLength = NonNegative<Length>;
 
 impl Parse for NonNegativeLength {
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -317670,16 +317670,22 @@
     ]
    ],
    "css/cssom-view/cssom-getBoundingClientRect-002.html": [
     [
      "/css/cssom-view/cssom-getBoundingClientRect-002.html",
      {}
     ]
    ],
+   "css/cssom-view/cssom-getBoxQuads-001.html": [
+    [
+     "/css/cssom-view/cssom-getBoxQuads-001.html",
+     {}
+    ]
+   ],
    "css/cssom-view/cssom-getClientRects-002.html": [
     [
      "/css/cssom-view/cssom-getClientRects-002.html",
      {}
     ]
    ],
    "css/cssom-view/cssom-getClientRects.html": [
     [
@@ -531061,16 +531067,20 @@
   "css/cssom-view/cssom-getBoundingClientRect-001.html": [
    "7118495560adadebcca98e6add47a74669f87788",
    "testharness"
   ],
   "css/cssom-view/cssom-getBoundingClientRect-002.html": [
    "8dfaa313b4abad30281d07ce22ac06a61754cc06",
    "testharness"
   ],
+  "css/cssom-view/cssom-getBoxQuads-001.html": [
+   "6236946f2eb29b2fdb3e7b3c1152ef275d921759",
+   "testharness"
+  ],
   "css/cssom-view/cssom-getClientRects-002.html": [
    "da348da01e09474f652ff1dfb6869665740668d5",
    "testharness"
   ],
   "css/cssom-view/cssom-getClientRects.html": [
    "f4e750bc1267f5c519a513ef1f25bf3660365788",
    "testharness"
   ],
deleted file mode 100644
--- a/testing/web-platform/meta/css/css-flexbox/auto-margins-001.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[auto-margins-001.html]
-  expected: FAIL
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/cssom-view/cssom-getBoxQuads-001.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+ <head>
+  <title>CSSOM View - getBoxQuads() returns proper border and margin boxes for block and flex</title>
+  <link rel="help" href="https://drafts.csswg.org/cssom-view/#the-geometryutils-interface">
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+
+  <style>
+    .container {
+      width: 100px;
+      height: 50px;
+      background-color: gray;
+    }
+    span {
+      display: block;
+      background: gold;
+      height: 4px;
+      width: 14px;
+      margin: auto;
+      padding: 0px;
+      border: 3px solid blue;
+    }
+  </style>
+ </head>
+ <body>
+  <div class="container">
+  <span id="block-block"></span>
+  </div>
+
+  <div class="container" style="display:flex">
+  <span id="flex-block"></span>
+  </div>
+
+  <script>
+    test(function() {
+      let bb = document.getElementById("block-block");
+      assert_equals(bb.getBoxQuads({box: "border"})[0].bounds.width,  20, "Block layout border box is expected width.");
+      assert_equals(bb.getBoxQuads({box: "margin"})[0].bounds.width, 100, "Block layout margin box is expected width.");
+
+      // For containers that expand items to fill block-axis space, measure the box heights also.
+      let fb = document.getElementById("flex-block");
+      assert_equals(fb.getBoxQuads({box: "border"})[0].bounds.width,  20, "Flex layout border box is expected width.");
+      assert_equals(fb.getBoxQuads({box: "margin"})[0].bounds.width, 100, "Flex layout margin box is expected width.");
+
+      assert_equals(fb.getBoxQuads({box: "border"})[0].bounds.height, 10, "Flex layout border box is expected height.");
+      assert_equals(fb.getBoxQuads({box: "margin"})[0].bounds.height, 50, "Flex layout margin box is expected height.");
+    });
+  </script>
+ </body>
+</html>
--- a/toolkit/components/places/SyncedBookmarksMirror.jsm
+++ b/toolkit/components/places/SyncedBookmarksMirror.jsm
@@ -3402,20 +3402,20 @@ class BookmarkMerger {
     this.remoteTree = remoteTree;
     this.newRemoteContents = newRemoteContents;
     this.matchingDupesByLocalParentNode = new Map();
     this.mergedGuids = new Set();
     this.deleteLocally = new Set();
     this.deleteRemotely = new Set();
     this.structureCounts = {
       new: 0,
-      remoteItemDel: 0,
-      localFolderDel: 0,
-      localItemDel: 0,
-      remoteFolderDel: 0,
+      remoteRevives: 0, // Remote non-folder change wins over local deletion.
+      localDeletes: 0, // Local folder deletion wins over remote change.
+      localRevives: 0, // Local non-folder change wins over remote deletion.
+      remoteDeletes: 0, // Remote folder deletion wins over local change.
     };
     this.dupeCount = 0;
     this.extraTelemetryEvents = [];
   }
 
   summarizeTelemetryEvents() {
     let events = [...this.extraTelemetryEvents];
     if (this.dupeCount > 0) {
@@ -4103,27 +4103,27 @@ class BookmarkMerger {
 
     if (remoteNode.needsMerge) {
       if (!remoteNode.isFolder()) {
         // If a non-folder child is deleted locally and changed remotely, we
         // ignore the local deletion and take the remote child.
         MirrorLog.trace("Remote non-folder ${remoteNode} deleted locally " +
                         "and changed remotely; taking remote change",
                         { remoteNode });
-        this.structureCounts.remoteItemDel++;
+        this.structureCounts.remoteRevives++;
         return BookmarkMerger.STRUCTURE.UNCHANGED;
       }
       // For folders, we always take the local deletion and relocate remotely
       // changed grandchildren to the merged node. We could use the mirror to
       // revive the child folder, but it's easier to relocate orphaned
       // grandchildren than to partially revive the child folder.
       MirrorLog.trace("Remote folder ${remoteNode} deleted locally " +
                       "and changed remotely; taking local deletion",
                       { remoteNode });
-      this.structureCounts.localFolderDel++;
+      this.structureCounts.localDeletes++;
     } else {
       MirrorLog.trace("Remote node ${remoteNode} deleted locally and not " +
                        "changed remotely; taking local deletion",
                        { remoteNode });
     }
 
     this.deleteRemotely.add(remoteNode.guid);
 
@@ -4172,22 +4172,22 @@ class BookmarkMerger {
       }
       return BookmarkMerger.STRUCTURE.UNCHANGED;
     }
 
     if (localNode.needsMerge) {
       if (!localNode.isFolder()) {
         MirrorLog.trace("Local non-folder ${localNode} deleted remotely and " +
                         "changed locally; taking local change", { localNode });
-        this.structureCounts.localItemDel++;
+        this.structureCounts.localRevives++;
         return BookmarkMerger.STRUCTURE.UNCHANGED;
       }
       MirrorLog.trace("Local folder ${localNode} deleted remotely and " +
                       "changed locally; taking remote deletion", { localNode });
-      this.structureCounts.remoteFolderDel++;
+      this.structureCounts.remoteDeletes++;
     } else {
       MirrorLog.trace("Local node ${localNode} deleted remotely and not " +
                       "changed locally; taking remote deletion", { localNode });
     }
 
     MirrorLog.trace("Local node ${localNode} deleted remotely; taking remote " +
                     "deletion", { localNode });
 
--- a/toolkit/components/places/tests/sync/test_bookmark_deletion.js
+++ b/toolkit/components/places/tests/sync/test_bookmark_deletion.js
@@ -109,17 +109,17 @@ add_task(async function test_complex_orp
     bmkUri: "http://example.com/f",
   }]));
 
   info("Apply remote");
   let changesToUpload = await buf.apply();
   deepEqual(await buf.fetchUnmergedGuids(), [], "Should merge all items");
   deepEqual(mergeTelemetryEvents, [{
     value: "structure",
-    extra: { new: "2", localFolderDel: "1", remoteFolderDel: "1" },
+    extra: { new: "2", localDeletes: "1", remoteDeletes: "1" },
   }], "Should record telemetry with structure change counts");
 
   let idsToUpload = inspectChangeRecords(changesToUpload);
   deepEqual(idsToUpload, {
     updated: ["bookmarkEEEE", "bookmarkFFFF", "folderAAAAAA", "folderCCCCCC"],
     deleted: ["folderDDDDDD"],
   }, "Should upload new records for (A > E), (C > F); tombstone for D");
 
@@ -301,17 +301,17 @@ add_task(async function test_locally_mod
     deleted: true,
   }]);
 
   info("Apply remote");
   let changesToUpload = await buf.apply();
   deepEqual(await buf.fetchUnmergedGuids(), [], "Should merge all items");
   deepEqual(mergeTelemetryEvents, [{
     value: "structure",
-    extra: { new: "1", localItemDel: "1", remoteFolderDel: "2" },
+    extra: { new: "1", localRevives: "1", remoteDeletes: "2" },
   }], "Should record telemetry for local item and remote folder deletions");
 
   let idsToUpload = inspectChangeRecords(changesToUpload);
   deepEqual(idsToUpload, {
     updated: ["bookmarkAAAA", "bookmarkFFFF", "bookmarkGGGG", "menu"],
     deleted: [],
   }, "Should upload A, relocated local orphans, and menu");
 
@@ -448,17 +448,17 @@ add_task(async function test_locally_del
     bmkUri: "http://example.com/g-remote",
   }]);
 
   info("Apply remote");
   let changesToUpload = await buf.apply();
   deepEqual(await buf.fetchUnmergedGuids(), [], "Should merge all items");
   deepEqual(mergeTelemetryEvents, [{
     value: "structure",
-    extra: { new: "1", remoteItemDel: "1", localFolderDel: "2" },
+    extra: { new: "1", remoteRevives: "1", localDeletes: "2" },
   }], "Should record telemetry for remote item and local folder deletions");
 
   let idsToUpload = inspectChangeRecords(changesToUpload);
   deepEqual(idsToUpload, {
     updated: ["bookmarkFFFF", "bookmarkGGGG", "menu"],
     deleted: ["bookmarkCCCC", "bookmarkEEEE", "folderBBBBBB", "folderDDDDDD"],
   }, "Should upload relocated remote orphans and menu");
 
--- a/toolkit/modules/InlineSpellCheckerContent.jsm
+++ b/toolkit/modules/InlineSpellCheckerContent.jsm
@@ -44,16 +44,22 @@ var InlineSpellCheckerContent = {
     }
 
     if (!spellChecker.mInlineSpellChecker.enableRealTimeSpell) {
       return { canSpellCheck: true,
                initialSpellCheckPending: spellChecker.initialSpellCheckPending,
                enableRealTimeSpell: false };
     }
 
+    if (spellChecker.initialSpellCheckPending) {
+      return { canSpellCheck: true,
+               initialSpellCheckPending: true,
+               enableRealTimeSpell: true };
+    }
+
     let dictionaryList = {};
     let realSpellChecker = spellChecker.mInlineSpellChecker.spellChecker;
     realSpellChecker.GetDictionaryList(dictionaryList, {});
 
     // The original list we get is in random order. We need our list to be
     // sorted by display names.
     dictionaryList = spellChecker.sortDictionaryList(dictionaryList.value).map((obj) => {
       return obj.id;