Merge autoland to mozilla-central. a=merge
authorNarcis Beleuzu <nbeleuzu@mozilla.com>
Sat, 31 Mar 2018 01:18:06 +0300
changeset 410827 8059b8b2abe9aee49ae69c804b8d9fef6ae42df5
parent 410815 f4fcdaef616807d1e31a849db0c60a3a4bdc8778 (current diff)
parent 410826 09d4e91d46e75f5afd44b0f55a764c54fbcb9717 (diff)
child 410828 a8a0db59e9fecc60b4b5731e621cd63d8327b6a0
child 410840 1282febe554e2dbf191c9832a9d46bead116cdce
child 410872 5a73741b38e736bb7d46c3e2d66c680ec2a6a61b
push id33741
push usernbeleuzu@mozilla.com
push dateFri, 30 Mar 2018 22:18:29 +0000
treeherdermozilla-central@8059b8b2abe9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone61.0a1
first release with
nightly linux32
8059b8b2abe9 / 61.0a1 / 20180331045244 / files
nightly linux64
8059b8b2abe9 / 61.0a1 / 20180331045244 / files
nightly mac
8059b8b2abe9 / 61.0a1 / 20180331045244 / files
nightly win32
8059b8b2abe9 / 61.0a1 / 20180331045244 / files
nightly win64
8059b8b2abe9 / 61.0a1 / 20180331045244 / 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
testing/web-platform/tests/css/cssom-view/cssom-getBoxQuads-001.html
--- a/browser/components/distribution.js
+++ b/browser/components/distribution.js
@@ -367,17 +367,21 @@ DistributionCustomizer.prototype = {
         if (usedPreferences.indexOf(key) > -1) {
           continue;
         }
         try {
           let value = this._ini.getString("Preferences", key);
           if (value) {
             value = value.replace(/%LOCALE%/g, this._locale);
             value = value.replace(/%LANGUAGE%/g, this._language);
-            defaults.set(key, parseValue(value));
+            if (key == "general.useragent.locale") {
+              defaults.set("intl.locale.requested", parseValue(value));
+            } else {
+              defaults.set(key, parseValue(value));
+            }
           }
         } catch (e) { /* ignore bad prefs and move on */ }
       }
     }
 
     let localizedStr = Cc["@mozilla.org/pref-localizedstring;1"].
       createInstance(Ci.nsIPrefLocalizedString);
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -3589,17 +3589,17 @@ nsDOMWindowUtils::GetIsHandlingUserInput
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetMillisSinceLastUserInput(double* aMillisSinceLastUserInput)
 {
   TimeStamp lastInput = EventStateManager::LatestUserInputStart();
   if (lastInput.IsNull()) {
-    *aMillisSinceLastUserInput = 0;
+    *aMillisSinceLastUserInput = -1.0f;
     return NS_OK;
   }
 
   *aMillisSinceLastUserInput = (TimeStamp::Now() - lastInput).ToMilliseconds();
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -1644,17 +1644,18 @@ interface nsIDOMWindowUtils : nsISupport
   /**
    * Returns true if a user input is being handled.
    *
    * This calls EventStateManager::IsHandlingUserInput().
    */
   readonly attribute boolean isHandlingUserInput;
 
   /**
-   * Returns milliseconds elapsed since last user input was started
+   * Returns milliseconds elapsed since last user input was started.
+   * Returns -1 if there wasn't any previous user input.
    *
    * This relies on EventStateManager::LatestUserInputStart()
    */
   readonly attribute double millisSinceLastUserInput;
 
   /**
    * After calling the method, the window for which this DOMWindowUtils
    * was created can be closed using scripts.
--- a/layout/base/GeometryUtils.cpp
+++ b/layout/base/GeometryUtils.cpp
@@ -147,17 +147,21 @@ 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 = f->GetMarginRectRelativeToSelf(); break;
+  case CSSBoxType::Margin: {
+    r = nsRect(nsPoint(0, 0), f->GetSize());
+    r.Inflate(f->GetUsedMargin());
+    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,
-           const nsMargin& aNewValue)
+           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);
-  // 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().
+  // 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)
   ::UpdateProp(mFrame, nsIFrame::UsedMarginProperty(), needMarginProp,
                ComputedPhysicalMargin());
 
 
   const nsStyleDisplay* disp = mFrame->StyleDisplayWithOptionalParam(aDisplay);
   bool isThemed = mFrame->IsThemed(disp);
   bool needPaddingProp;
   nsIntMargin widget;
@@ -2795,26 +2795,17 @@ ReflowInput::CalculateBlockSideMargins(L
       margin.IStart(cbWM) += forStart;
       margin.IEnd(cbWM) += availMarginSpace - forStart;
     } else {
       margin.IStart(cbWM) += availMarginSpace;
     }
   } else if (isAutoEndMargin) {
     margin.IEnd(cbWM) += availMarginSpace;
   }
-  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);
-    }
-  }
+  SetComputedLogicalMargin(margin.ConvertTo(mWritingMode, cbWM));
 }
 
 #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,19 +548,16 @@ 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
@@ -856,19 +853,16 @@ 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.
@@ -1817,17 +1811,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, mHasAnyAutoMargin see below
+    // mAlignSelf, 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),
@@ -1854,26 +1848,22 @@ 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
@@ -1924,17 +1914,16 @@ 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");
@@ -4761,26 +4750,16 @@ 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);
       }
@@ -4971,16 +4950,20 @@ 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/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -401,16 +401,18 @@ public class BrowserApp extends GeckoApp
 
     private ExtensionPermissionsHelper mExtensionPermissionsHelper;
 
     // The tab to be selected on editing mode exit.
     private Integer mTargetTabForEditingMode;
 
     private final TabEditingState mLastTabEditingState = new TabEditingState();
 
+    private boolean mSuppressNextKeyUp;
+
     // The animator used to toggle HomePager visibility has a race where if the HomePager is shown
     // (starting the animation), the HomePager is hidden, and the HomePager animation completes,
     // both the web content and the HomePager will be hidden. This flag is used to prevent the
     // race by determining if the web content should be hidden at the animation's end.
     private boolean mHideWebContentOnAnimationEnd;
 
     private final DynamicToolbar mDynamicToolbar = new DynamicToolbar();
 
@@ -575,16 +577,20 @@ public class BrowserApp extends GeckoApp
     public boolean onKey(View v, int keyCode, KeyEvent event) {
         if (AndroidGamepadManager.handleKeyEvent(event)) {
             return true;
         }
 
         // Global onKey handler. This is called if the focused UI doesn't
         // handle the key event, and before Gecko swallows the events.
         if (event.getAction() != KeyEvent.ACTION_DOWN) {
+            if (mSuppressNextKeyUp && event.getAction() == KeyEvent.ACTION_UP) {
+                mSuppressNextKeyUp = false;
+                return true;
+            }
             return false;
         }
 
         if ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) {
             switch (keyCode) {
                 case KeyEvent.KEYCODE_BUTTON_Y:
                     // Toggle/focus the address bar on gamepad-y button.
                     if (mBrowserChrome.getVisibility() == View.VISIBLE) {
@@ -1386,18 +1392,23 @@ public class BrowserApp extends GeckoApp
             @Override
             public void onActivate() {
                 enterEditingMode();
             }
         });
 
         mBrowserToolbar.setOnCommitListener(new BrowserToolbar.OnCommitListener() {
             @Override
-            public void onCommit() {
-                commitEditingMode();
+            public void onCommitByKey() {
+                if (commitEditingMode()) {
+                    // We're committing in response to a key-down event. Since we'll be hiding the
+                    // ToolbarEditLayout, the corresponding key-up event will end up being sent to
+                    // Gecko which we don't want, as this messes up tracking of the last user input.
+                    mSuppressNextKeyUp = true;
+                }
             }
         });
 
         mBrowserToolbar.setOnDismissListener(new BrowserToolbar.OnDismissListener() {
             @Override
             public void onDismiss() {
                 mBrowserToolbar.cancelEdit();
             }
@@ -2676,19 +2687,22 @@ public class BrowserApp extends GeckoApp
         mBrowserToolbar.startEditing(url, animator);
 
         showHomePagerWithAnimator(panelId, null, animator);
 
         animator.start();
         Telemetry.startUISession(TelemetryContract.Session.AWESOMESCREEN);
     }
 
-    private void commitEditingMode() {
+    /**
+     * @return True if editing mode was successfully committed.
+     */
+    private boolean commitEditingMode() {
         if (!mBrowserToolbar.isEditing()) {
-            return;
+            return false;
         }
 
         Telemetry.stopUISession(TelemetryContract.Session.AWESOMESCREEN,
                                 TelemetryContract.Reason.COMMIT);
 
         final String url = mBrowserToolbar.commitEdit();
 
         // HACK: We don't know the url that will be loaded when hideHomePager is initially called
@@ -2700,16 +2714,18 @@ public class BrowserApp extends GeckoApp
         //
         // Here we call hideHomePager for the second time with the URL to be loaded so that
         // hideHomePager is called with the correct state for the upcoming page load.
         //
         // Expected to be fixed by bug 915825.
         hideHomePager(url);
         loadUrlOrKeywordSearch(url);
         clearSelectedTabApplicationId();
+
+        return true;
     }
 
     private void clearSelectedTabApplicationId() {
         final Tab selected = Tabs.getInstance().getSelectedTab();
         if (selected != null) {
             selected.setApplicationId(null);
         }
     }
--- a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java
@@ -58,19 +58,16 @@ public final class IntentHelper implemen
         "Intent:OpenForResult",
         "Intent:OpenNoHandler",
     };
 
     // via http://developer.android.com/distribute/tools/promote/linking.html
     private static final String MARKET_INTENT_URI_PACKAGE_PREFIX = "market://details?id=";
     private static final String EXTRA_BROWSER_FALLBACK_URL = "browser_fallback_url";
 
-    /** A partial URI to an error page - the encoded error URI should be appended before loading. */
-    private static final String UNKNOWN_PROTOCOL_URI_PREFIX = "about:neterror?e=unknownProtocolFound&u=";
-
     private static IntentHelper instance;
 
     private IntentHelper() {
         EventDispatcher.getInstance().registerGeckoThreadListener(this, GECKO_EVENTS);
         EventDispatcher.getInstance().registerUiThreadListener(this, UI_EVENTS);
     }
 
     public static IntentHelper init() {
@@ -500,37 +497,28 @@ public final class IntentHelper implemen
      *                 the uri to load if Java does not load a page
      */
     private void openNoHandler(final GeckoBundle msg, final EventCallback callback) {
         final String uri = msg.getString("uri");
         final GeckoBundle errorResponse = new GeckoBundle();
 
         if (TextUtils.isEmpty(uri)) {
             Log.w(LOGTAG, "Received empty URL - loading about:neterror");
-            errorResponse.putString("uri", getUnknownProtocolErrorPageUri(""));
             errorResponse.putBoolean("isFallback", false);
             callback.sendError(errorResponse);
             return;
         }
 
         final Intent intent;
         try {
             // TODO (bug 1173626): This will not handle android-app uris on non 5.1 devices.
             intent = Intent.parseUri(uri, 0);
         } catch (final URISyntaxException e) {
-            String errorUri;
-            try {
-                errorUri = getUnknownProtocolErrorPageUri(URLEncoder.encode(uri, "UTF-8"));
-            } catch (final UnsupportedEncodingException encodingE) {
-                errorUri = getUnknownProtocolErrorPageUri("");
-            }
-
             // Don't log the exception to prevent leaking URIs.
             Log.w(LOGTAG, "Unable to parse Intent URI - loading about:neterror");
-            errorResponse.putString("uri", errorUri);
             errorResponse.putBoolean("isFallback", false);
             callback.sendError(errorResponse);
             return;
         }
 
         // For this flow, we follow Chrome's lead:
         //   https://developer.chrome.com/multidevice/android/intents
         final String fallbackUrl = intent.getStringExtra(EXTRA_BROWSER_FALLBACK_URL);
@@ -570,17 +558,16 @@ public final class IntentHelper implemen
             // many websites have catered to this behavior. For example, the site might set a timeout and load a play
             // store url for their app if the intent link fails to load, i.e. the app is not installed.
             // These work-arounds would often end with our users seeing about:neterror instead of the intended experience.
             // While I feel showing about:neterror is a better solution for users (when not hacked around),
             // we should match the status quo for the good of our users.
             //
             // Don't log the URI to prevent leaking it.
             Log.w(LOGTAG, "Unable to open URI, maybe showing neterror");
-            errorResponse.putString("uri", getUnknownProtocolErrorPageUri(intent.getData().toString()));
             errorResponse.putBoolean("isFallback", false);
             callback.sendError(errorResponse);
         }
     }
 
     private static boolean isFallbackUrlValid(@Nullable final String fallbackUrl) {
         if (fallbackUrl == null) {
             return false;
@@ -596,26 +583,16 @@ public final class IntentHelper implemen
             }
         } catch (final URISyntaxException e) {
             // Do not include Exception to avoid leaking uris.
             Log.w(LOGTAG, "URISyntaxException parsing fallback URI");
         }
         return false;
     }
 
-    /**
-     * Returns an about:neterror uri with the unknownProtocolFound text as a parameter.
-     * @param encodedUri The encoded uri. While the page does not open correctly without specifying
-     *                   a uri parameter, it happily accepts the empty String so this argument may
-     *                   be the empty String.
-     */
-    private String getUnknownProtocolErrorPageUri(final String encodedUri) {
-        return UNKNOWN_PROTOCOL_URI_PREFIX + encodedUri;
-    }
-
     private static class ResultHandler implements ActivityResultHandler {
         private final EventCallback callback;
 
         public ResultHandler(final EventCallback callback) {
             this.callback = callback;
         }
 
         @Override
--- a/mobile/android/base/java/org/mozilla/gecko/Tab.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tab.java
@@ -698,16 +698,21 @@ public class Tab {
                 if (!TextUtils.equals(oldURL, getURL()))
                     return;
 
                 ThumbnailHelper.getInstance().getAndProcessThumbnailFor(tab);
             }
         }, 500);
     }
 
+    void handleLoadError() {
+        setState(STATE_ERROR);
+        setLoadProgress(LOAD_PROGRESS_LOADED);
+    }
+
     void handleContentLoaded() {
         setLoadProgressIfLoading(LOAD_PROGRESS_LOADED);
     }
 
     protected void saveThumbnailToDB(final BrowserDB db) {
         final BitmapDrawable thumbnail = mThumbnail;
         if (thumbnail == null) {
             return;
--- a/mobile/android/base/java/org/mozilla/gecko/Tabs.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tabs.java
@@ -632,22 +632,27 @@ public class Tabs implements BundleEvent
             } else if ((state & GeckoAppShell.WPL_STATE_STOP) != 0) {
                 Log.i(LOGTAG, "zerdatime " + SystemClock.elapsedRealtime() +
                       " - page load stop");
                 tab.handleDocumentStop(message.getBoolean("success"));
                 notifyListeners(tab, Tabs.TabEvents.STOP);
             }
 
         } else if ("Content:LoadError".equals(event)) {
-            tab.handleContentLoaded();
+            tab.handleLoadError();
             notifyListeners(tab, Tabs.TabEvents.LOAD_ERROR);
 
         } else if ("Content:DOMContentLoaded".equals(event)) {
-            tab.handleContentLoaded();
-            notifyListeners(tab, TabEvents.LOADED);
+            if (TextUtils.isEmpty(message.getString("errorType"))) {
+                tab.handleContentLoaded();
+                notifyListeners(tab, TabEvents.LOADED);
+            } else {
+                tab.handleLoadError();
+                notifyListeners(tab, TabEvents.LOAD_ERROR);
+            }
 
         } else if ("Content:PageShow".equals(event)) {
             tab.setLoadedFromCache(message.getBoolean("fromCache"));
             tab.updateUserRequested(message.getString("userRequested"));
             notifyListeners(tab, TabEvents.PAGE_SHOW);
 
         } else if ("Content:DOMTitleChanged".equals(event)) {
             tab.updateTitle(message.getString("title"));
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/BrowserToolbar.java
@@ -89,17 +89,17 @@ public abstract class BrowserToolbar ext
     private static final int LIGHTWEIGHT_THEME_INVERT_ALPHA_END = 179;
     public static final int LIGHTWEIGHT_THEME_INVERT_ALPHA_TABLET = 51;
 
     public interface OnActivateListener {
         public void onActivate();
     }
 
     public interface OnCommitListener {
-        public void onCommit();
+        public void onCommitByKey();
     }
 
     public interface OnDismissListener {
         public void onDismiss();
     }
 
     public interface OnFilterListener {
         public void onFilter(String searchText, AutocompleteHandler handler);
--- a/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java
+++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/ToolbarEditText.java
@@ -592,17 +592,17 @@ public class ToolbarEditText extends Cus
             }
 
             if (keyCode == KeyEvent.KEYCODE_ENTER) {
                 // If the edit text has a composition string, don't submit the text yet.
                 // ENTER is needed to commit the composition string.
                 final Editable content = getText();
                 if (!hasCompositionString(content)) {
                     if (mCommitListener != null) {
-                        mCommitListener.onCommit();
+                        mCommitListener.onCommitByKey();
                     }
 
                     return true;
                 }
             }
 
             if (keyCode == KeyEvent.KEYCODE_BACK) {
                 // Drop the virtual keyboard.
@@ -618,17 +618,17 @@ public class ToolbarEditText extends Cus
         @Override
         public boolean onKey(View v, int keyCode, KeyEvent event) {
             if (keyCode == KeyEvent.KEYCODE_ENTER || GamepadUtils.isActionKey(event)) {
                 if (event.getAction() != KeyEvent.ACTION_DOWN) {
                     return true;
                 }
 
                 if (mCommitListener != null) {
-                    mCommitListener.onCommit();
+                    mCommitListener.onCommitByKey();
                 }
 
                 return true;
             }
 
             if (GamepadUtils.isBackKey(event)) {
                 if (mDismissListener != null) {
                     mDismissListener.onDismiss();
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -4565,17 +4565,18 @@ Tab.prototype = {
     }
 
     // Update the page actions URI for helper apps.
     if (BrowserApp.selectedTab == this) {
       ExternalApps.updatePageActionUri(fixedURI);
     }
 
     if ((!aRequest || Components.isSuccessCode(aRequest.status)) &&
-        !fixedURI.displaySpec.startsWith("about:neterror") && !this.isSearch) {
+        !(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_ERROR_PAGE) &&
+        !this.isSearch) {
       // If this won't end up in an error page and the user isn't searching,
       // don't retain the typed entry.
       this.userRequested = "";
     }
 
     let message = {
       type: "Content:LocationChange",
       tabID: this.id,
--- a/mobile/android/components/ContentDispatchChooser.js
+++ b/mobile/android/components/ContentDispatchChooser.js
@@ -80,18 +80,18 @@ ContentDispatchChooser.prototype =
           return;
         }
 
         // We couldn't open this. If this was from a click, it's likely that we just
         // want this to fail silently. If the user entered this on the address bar, though,
         // we want to show the neterror page.
         let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
         let millis = dwu.millisSinceLastUserInput;
-        if (millis > 0 && millis >= 1000) {
-          window.location.href = data.uri;
+        if (millis < 0 || millis >= 1000) {
+          window.document.docShell.displayLoadError(Cr.NS_ERROR_UNKNOWN_PROTOCOL, aURI, null);
         } else {
           this._closeBlankWindow(window);
         }
       });
     }
   },
 };
 
--- a/mobile/android/components/geckoview/GeckoViewStartup.js
+++ b/mobile/android/components/geckoview/GeckoViewStartup.js
@@ -32,32 +32,34 @@ GeckoViewStartup.prototype = {
     let protocolHandler = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
     protocolHandler.setSubstitution("android", Services.io.newURI(url));
   },
 
   /* ----------  nsIObserver  ---------- */
   observe: function(aSubject, aTopic, aData) {
     switch (aTopic) {
       case "app-startup": {
-        this.setResourceSubstitutions();
-
         // Parent and content process.
         Services.obs.addObserver(this, "chrome-document-global-created");
         Services.obs.addObserver(this, "content-document-global-created");
 
         GeckoViewUtils.addLazyGetter(this, "GeckoViewPermission", {
           service: "@mozilla.org/content-permission/prompt;1",
           observers: [
             "getUserMedia:ask-device-permission",
             "getUserMedia:request",
             "PeerConnection:request",
           ],
         });
 
-        if (Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT) {
+        if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT) {
+          // Parent process only.
+          this.setResourceSubstitutions();
+
+        } else {
           // Content process only.
           GeckoViewUtils.addLazyGetter(this, "GeckoViewPrompt", {
             service: "@mozilla.org/prompter;1",
           });
         }
         break;
       }
 
--- a/python/mozboot/mozboot/archlinux.py
+++ b/python/mozboot/mozboot/archlinux.py
@@ -15,20 +15,17 @@ from mozboot.linux_common import StyloIn
 
 
 class ArchlinuxBootstrapper(StyloInstall, BaseBootstrapper):
     '''Archlinux experimental bootstrapper.'''
 
     SYSTEM_PACKAGES = [
         'autoconf2.13',
         'base-devel',
-        'ccache',
-        'mercurial',
         'nodejs',
-        'npm',
         'python2',
         'python2-setuptools',
         'unzip',
         'zip',
     ]
 
     BROWSER_PACKAGES = [
         'alsa-lib',
@@ -52,17 +49,16 @@ class ArchlinuxBootstrapper(StyloInstall
         'gst-plugins-base-libs',
         'imake',
         'inetutils',
         'libpulse',
         'xorg-server-xvfb',
         'yasm',
         'gst-libav',
         'gst-plugins-good',
-        'networkmanager',
     ]
 
     BROWSER_AUR_PACKAGES = [
         'https://aur.archlinux.org/cgit/aur.git/snapshot/uuid.tar.gz',
     ]
 
     MOBILE_ANDROID_COMMON_PACKAGES = [
         # It would be nice to handle alternative JDKs.  See
--- a/python/mozboot/mozboot/centosfedora.py
+++ b/python/mozboot/mozboot/centosfedora.py
@@ -17,17 +17,16 @@ class CentOSFedoraBootstrapper(StyloInst
         self.distro = distro
         self.version = version
         self.dist_id = dist_id
 
         self.group_packages = []
 
         self.packages = [
             'autoconf213',
-            'mercurial',
             'nodejs',
             'npm',
             'which',
         ]
 
         self.browser_group_packages = [
             'GNOME Software Development',
         ]
--- a/python/mozboot/mozboot/debian.py
+++ b/python/mozboot/mozboot/debian.py
@@ -29,17 +29,16 @@ Choice:
 
 
 class DebianBootstrapper(StyloInstall, BaseBootstrapper):
     # These are common packages for all Debian-derived distros (such as
     # Ubuntu).
     COMMON_PACKAGES = [
         'autoconf2.13',
         'build-essential',
-        'ccache',
         'nodejs',
         'python-dev',
         'python-pip',
         'python-setuptools',
         'unzip',
         'uuid',
         'zip',
     ]
--- a/python/mozboot/mozboot/freebsd.py
+++ b/python/mozboot/mozboot/freebsd.py
@@ -13,17 +13,16 @@ class FreeBSDBootstrapper(BaseBootstrapp
         BaseBootstrapper.__init__(self, **kwargs)
         self.version = int(version.split('.')[0])
         self.flavor = flavor.lower()
 
         self.packages = [
             'autoconf213',
             'gmake',
             'gtar',
-            'mercurial',
             'npm',
             'pkgconf',
             'py%s%s-sqlite3' % sys.version_info[0:2],
             'rust',
             'watchman',
             'zip',
         ]
 
--- a/python/mozboot/mozboot/gentoo.py
+++ b/python/mozboot/mozboot/gentoo.py
@@ -11,18 +11,17 @@ from mozboot.linux_common import StyloIn
 class GentooBootstrapper(StyloInstall, BaseBootstrapper):
     def __init__(self, version, dist_id, **kwargs):
         BaseBootstrapper.__init__(self, **kwargs)
 
         self.version = version
         self.dist_id = dist_id
 
     def install_system_packages(self):
-        self.run_as_root(['emerge', '--noreplace', '--quiet', 'dev-vcs/git',
-                          'mercurial', 'nodejs'])
+        self.run_as_root(['emerge', '--noreplace', '--quiet', 'nodejs'])
 
     def install_browser_packages(self):
         self.ensure_browser_packages()
 
     def install_browser_artifact_mode_packages(self):
         self.ensure_browser_packages(artifact_mode=True)
 
     def install_mobile_android_packages(self):
--- a/python/mozboot/mozboot/openbsd.py
+++ b/python/mozboot/mozboot/openbsd.py
@@ -7,17 +7,16 @@ from __future__ import absolute_import
 from mozboot.base import BaseBootstrapper
 
 
 class OpenBSDBootstrapper(BaseBootstrapper):
     def __init__(self, version, **kwargs):
         BaseBootstrapper.__init__(self, **kwargs)
 
         self.packages = [
-            'mercurial',
             'autoconf-2.13',
             'gmake',
             'gtar',
             'node',
             'rust',
             'wget',
             'unzip',
             'zip',
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -314070,22 +314070,16 @@
     ]
    ],
    "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": [
     [
@@ -525377,20 +525371,16 @@
   "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"
   ],
@@ -537798,17 +537788,17 @@
    "2275720296bd3ea4ef012ed5ef3ea63a4c5f953d",
    "testharness"
   ],
   "custom-elements/Document-createElementNS.html": [
    "799f59e3bf8ab0830e44faa3ffef6d3303da42eb",
    "testharness"
   ],
   "custom-elements/HTMLElement-constructor.html": [
-   "4dc04a8b026538bddee52586f2df50206abc9334",
+   "64522527ef425b90c704b20b000c8feef0d1ca25",
    "testharness"
   ],
   "custom-elements/OWNERS": [
    "9f6553b67cad3b479d3beb678653db4e712ed227",
    "support"
   ],
   "custom-elements/adopted-callback.html": [
    "3eaf4dbfe67edd892c9a950c20a87c9b9ed565fa",
@@ -537842,17 +537832,17 @@
    "ad030517981b11892126023bc758b7fe323a3d14",
    "testharness"
   ],
   "custom-elements/historical.html": [
    "991ebcff1d8b59a7a4d959f3061a17e0e8a83704",
    "testharness"
   ],
   "custom-elements/htmlconstructor/newtarget.html": [
-   "39a7331d37056d0203fd771d797fd8da3d2bbefb",
+   "11b7927c9a2946c752f56e5b44cfb4051ab8b6d6",
    "testharness"
   ],
   "custom-elements/microtasks-and-constructors.html": [
    "088fcd47e328e30c6119a37bbf19768e7f14763d",
    "testharness"
   ],
   "custom-elements/parser/parser-constructs-custom-element-in-document-write.html": [
    "b338f193a803ea679bbf0e041f71daf1e6d703f6",
--- a/testing/web-platform/mozilla/meta/MANIFEST.json
+++ b/testing/web-platform/mozilla/meta/MANIFEST.json
@@ -976,17 +976,17 @@
   }
  },
  "paths": {
   "./placeholder": [
    "74e16eb87ecdfeb2dfc28f36e0c73a584abdf9c2",
    "support"
   ],
   "dom/classList.html": [
-   "17c65652a2943738a0cc5152aec737f243a02d3d",
+   "5aa8aa335e998e0033b72dfc259f0fe6608182f5",
    "testharness"
   ],
   "dom/throttling/resources/test.html": [
    "0898e3efa5dbcc74138bdf27ff2787d1f1a2d4d8",
    "support"
   ],
   "dom/throttling/resources/throttling.js": [
    "e0bf1a7c5a0d2c8be2b793c786bb9484779dcbbf",
deleted file mode 100644
--- a/testing/web-platform/tests/css/cssom-view/cssom-getBoxQuads-001.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<!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>