Bug 1398963 - Create a prototype "emulate -moz-box with modern flexbox" patch, to help prototype/discover any needed frontend changes for modern flexbox draft
authorDaniel Holbert <dholbert@cs.stanford.edu>
Thu, 26 Oct 2017 11:12:17 -0700
changeset 686987 87f3bbd6ee0ac1aa6505f9cbbb2c252a25e01c0f
parent 685447 967c95cee709756596860ed2a3e6ac06ea3a053f
child 737540 68dca9550746f382b86e1ab3c43887f438c1b7b1
push id86372
push userbgrinstead@mozilla.com
push dateThu, 26 Oct 2017 18:12:24 +0000
bugs1398963
milestone58.0a1
Bug 1398963 - Create a prototype "emulate -moz-box with modern flexbox" patch, to help prototype/discover any needed frontend changes for modern flexbox MozReview-Commit-ID: 3g2W9o3t23H
browser/base/content/browser-tabsintitlebar.js
browser/base/content/browser.css
browser/themes/shared/controlcenter/panel.inc.css
browser/themes/shared/customizableui/panelUI.inc.css
browser/themes/shared/tabs.inc.css
layout/base/nsCSSFrameConstructor.cpp
layout/generic/nsFlexContainerFrame.cpp
toolkit/content/textbox.css
toolkit/content/xul.css
toolkit/themes/linux/global/global.css
toolkit/themes/osx/global/global.css
toolkit/themes/windows/global/global.css
--- a/browser/base/content/browser-tabsintitlebar.js
+++ b/browser/base/content/browser-tabsintitlebar.js
@@ -270,17 +270,17 @@ var TabsInTitlebar = {
 
     if (document.documentElement.hasAttribute("customizing")) {
       gCustomizeMode.updateLWTStyling();
     }
   },
 
   _sizePlaceholder(type, width) {
     Array.forEach(document.querySelectorAll(".titlebar-placeholder[type='" + type + "']"),
-                  function(node) { node.width = width; });
+                  function(node) { node.style.width = width + "px"; });
   },
 
   uninit() {
     this._initialized = false;
     removeEventListener("resolutionchange", this);
     Services.prefs.removeObserver(this._prefName, this);
     this._menuObserver.disconnect();
     CustomizableUI.removeListener(this);
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -105,16 +105,17 @@ panelview:not([title]) > .panel-header {
   display: none;
 }
 
 tabbrowser {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
 }
 
 #tabbrowser-tabs {
+  width: 0;
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
 }
 
 #tabbrowser-tabs:not([overflow="true"]) ~ #alltabs-button,
 #tabbrowser-tabs[hasadjacentnewtabbutton]:not([overflow="true"]) ~ #new-tab-button,
 #tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
 #tabbrowser-tabs:not([hasadjacentnewtabbutton]) > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
 #TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
@@ -128,17 +129,16 @@ tabbrowser {
 .tabbrowser-tab {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
 }
 
 .tabbrowser-tab:not([pinned]) {
   -moz-box-flex: 100;
   max-width: 225px;
   min-width: var(--tab-min-width);
-  width: 0;
   transition: min-width 100ms ease-out,
               max-width 100ms ease-out;
 }
 
 :root[uidensity=touch] .tabbrowser-tab:not([pinned]) {
   /* Touch mode needs additional space for the close button. */
   min-width: calc(var(--tab-min-width) + 10px);
 }
--- a/browser/themes/shared/controlcenter/panel.inc.css
+++ b/browser/themes/shared/controlcenter/panel.inc.css
@@ -358,17 +358,16 @@ description#identity-popup-content-verif
 #tracking-protection-content:not([state]) > #tracking-actions {
   display: none;
 }
 
 /* PERMISSIONS */
 
 #identity-popup-permissions-content {
   background-image: url(chrome://browser/skin/controlcenter/permissions.svg);
-  padding-bottom: 1.5em;
 }
 
 #identity-popup-permissions-headline {
   /* Make sure the label is as tall as the icon so that the permission list
      which is aligned with the icon doesn't cover it up. */
   min-height: 24px;
 }
 
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -343,17 +343,17 @@ panel[photon] > .panel-arrowcontainer > 
 }
 
 #PanelUI-contents {
   max-width: @menuPanelWidth@;
 }
 
 #BMB_bookmarksPopup,
 .panel-mainview:not([panelid="PanelUI-popup"]) {
-  max-width: @standaloneSubviewWidth@;
+  width: @standaloneSubviewWidth@;
 }
 
 #pageActionFeedback > .panel-arrowcontainer > .panel-arrowbox {
   /* Don't display the arrow but keep the popup at the same vertical
      offset as other arrow panels. */
   visibility: hidden;
 }
 
--- a/browser/themes/shared/tabs.inc.css
+++ b/browser/themes/shared/tabs.inc.css
@@ -39,16 +39,17 @@ tabbrowser {
 #tabbrowser-tabs,
 #tabbrowser-tabs > .tabbrowser-arrowscrollbox,
 #tabbrowser-tabs[positionpinnedtabs] > .tabbrowser-tab[pinned] {
   min-height: var(--tab-min-height);
 }
 
 .tab-stack {
   min-height: inherit;
+  width: 0;
 }
 
 .tabbrowser-tab {
   -moz-appearance: none;
   background-color: transparent;
   border-radius: 0;
   border-width: 0;
   margin: 0;
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -2707,17 +2707,18 @@ nsCSSFrameConstructor::ConstructDocEleme
     nsFrameItems frameItems;
     contentFrame = static_cast<nsContainerFrame*>(
       ConstructOuterSVG(state, item, mDocElementContainingBlock,
                         styleContext->StyleDisplay(),
                         frameItems));
     newFrame = frameItems.FirstChild();
     NS_ASSERTION(frameItems.OnlyChild(), "multiple root element frames");
   } else if (display->mDisplay == StyleDisplay::Flex ||
-             display->mDisplay == StyleDisplay::WebkitBox) {
+             display->mDisplay == StyleDisplay::WebkitBox ||
+             display->mDisplay == StyleDisplay::MozBox) {
     contentFrame = NS_NewFlexContainerFrame(mPresShell, styleContext);
     InitAndRestoreFrame(state, aDocElement, mDocElementContainingBlock,
                         contentFrame);
     newFrame = contentFrame;
     processChildren = true;
 
     newFrame->AddStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
     if (display->IsAbsPosContainingBlock(newFrame)) {
@@ -4418,24 +4419,25 @@ nsCSSFrameConstructor::GetAnonymousConte
   }
 
   return NS_OK;
 }
 
 static
 bool IsXULDisplayType(const nsStyleDisplay* aDisplay)
 {
-  return (aDisplay->mDisplay == StyleDisplay::MozInlineBox ||
+  return (
+//aDisplay->mDisplay == StyleDisplay::MozInlineBox ||
 #ifdef MOZ_XUL
           aDisplay->mDisplay == StyleDisplay::MozInlineGrid ||
           aDisplay->mDisplay == StyleDisplay::MozInlineStack ||
 #endif
-          aDisplay->mDisplay == StyleDisplay::MozBox
+//          aDisplay->mDisplay == StyleDisplay::MozBox
 #ifdef MOZ_XUL
-          || aDisplay->mDisplay == StyleDisplay::MozGrid ||
+          aDisplay->mDisplay == StyleDisplay::MozGrid ||
           aDisplay->mDisplay == StyleDisplay::MozStack ||
           aDisplay->mDisplay == StyleDisplay::MozGridGroup ||
           aDisplay->mDisplay == StyleDisplay::MozGridLine ||
           aDisplay->mDisplay == StyleDisplay::MozDeck ||
           aDisplay->mDisplay == StyleDisplay::MozPopup ||
           aDisplay->mDisplay == StyleDisplay::MozGroupbox
 #endif
           );
@@ -4666,16 +4668,23 @@ nsCSSFrameConstructor::FindXULDisplayDat
       FCDATA_DECL(FCDATA_DISALLOW_OUT_OF_FLOW | FCDATA_IS_POPUP |
                   FCDATA_SKIP_ABSPOS_PUSH, NS_NewMenuPopupFrame))
 #endif /* MOZ_XUL */
   };
 
   if (aDisplay->mDisplay < StyleDisplay::MozBox) {
     return nullptr;
   }
+  // let scrollcorners be true moz-boxes
+  if (aElement && !aElement->IsXULElement(nsGkAtoms::scrollcorner) &&
+      (aDisplay->mDisplay == StyleDisplay::MozBox ||
+       aDisplay->mDisplay == StyleDisplay::MozInlineBox)) {
+    return nullptr;
+  }
+
 
   MOZ_ASSERT(aDisplay->mDisplay <= StyleDisplay::MozPopup,
              "Someone added a new display value?");
 
   const FrameConstructionDataByDisplay& data =
     sXULDisplayData[size_t(aDisplay->mDisplay) - size_t(StyleDisplay::MozBox)];
   MOZ_ASSERT(aDisplay->mDisplay == data.mDisplay,
              "Did someone mess with the order?");
@@ -4893,17 +4902,18 @@ nsCSSFrameConstructor::FindDisplayData(c
     return &sNonScrollableBlockData[suppressScrollFrame][caption];
   }
 
   // If this is for a <body> node and we've propagated the scroll-frame to the
   // viewport, we need to make sure not to add another layer of scrollbars, so
   // we use a different FCData struct without FCDATA_MAY_NEED_SCROLLFRAME.
   if (propagatedScrollToViewport && aDisplay->IsScrollableOverflow()) {
     if (aDisplay->mDisplay == StyleDisplay::Flex ||
-        aDisplay->mDisplay == StyleDisplay::WebkitBox) {
+        aDisplay->mDisplay == StyleDisplay::WebkitBox ||
+        aDisplay->mDisplay == StyleDisplay::MozBox) {
       static const FrameConstructionData sNonScrollableFlexData =
         FCDATA_DECL(0, NS_NewFlexContainerFrame);
       return &sNonScrollableFlexData;
     }
     if (aDisplay->mDisplay == StyleDisplay::Grid) {
       static const FrameConstructionData sNonScrollableGridData =
         FCDATA_DECL(0, NS_NewGridContainerFrame);
       return &sNonScrollableGridData;
@@ -4987,18 +4997,22 @@ nsCSSFrameConstructor::FindDisplayData(c
       FCDATA_DECL(FCDATA_DESIRED_PARENT_TYPE_TO_BITS(eTypeRuby),
                   NS_NewRubyTextContainerFrame)),
     FCDATA_FOR_DISPLAY(StyleDisplay::Contents,
       FULL_CTOR_FCDATA(FCDATA_IS_CONTENTS, nullptr/*never called*/)),
     FCDATA_FOR_DISPLAY(StyleDisplay::WebkitBox,
       FCDATA_DECL(FCDATA_MAY_NEED_SCROLLFRAME, NS_NewFlexContainerFrame)),
     FCDATA_FOR_DISPLAY(StyleDisplay::WebkitInlineBox,
       FCDATA_DECL(FCDATA_MAY_NEED_SCROLLFRAME, NS_NewFlexContainerFrame)),
+    FCDATA_FOR_DISPLAY(StyleDisplay::MozBox,
+      FCDATA_DECL(FCDATA_MAY_NEED_SCROLLFRAME, NS_NewFlexContainerFrame)),
+    FCDATA_FOR_DISPLAY(StyleDisplay::MozInlineBox,
+      FCDATA_DECL(FCDATA_MAY_NEED_SCROLLFRAME, NS_NewFlexContainerFrame)),
   };
-  static_assert(ArrayLength(sDisplayData) == size_t(StyleDisplay::WebkitInlineBox) + 1,
+  static_assert(ArrayLength(sDisplayData) == size_t(StyleDisplay::MozInlineBox) + 1,
                 "Be sure to update sDisplayData if you touch StyleDisplay");
 
   MOZ_ASSERT(size_t(aDisplay->mDisplay) < ArrayLength(sDisplayData),
              "XUL display data should have already been handled");
 
   // See the mDisplay fixup code in nsRuleNode::ComputeDisplayData.
   MOZ_ASSERT(aDisplay->mDisplay != StyleDisplay::Contents ||
              !aElement->IsRootOfNativeAnonymousSubtree(),
@@ -10981,18 +10995,18 @@ VerifyGridFlexContainerChildren(nsIFrame
   auto parentType = aParentFrame->Type();
   if (parentType != LayoutFrameType::FlexContainer &&
       parentType != LayoutFrameType::GridContainer) {
     return;
   }
 
   bool prevChildWasAnonItem = false;
   for (const nsIFrame* child : aChildren) {
-    MOZ_ASSERT(!FrameWantsToBeInAnonymousItem(aParentFrame, child),
-               "frame wants to be inside an anonymous item, but it isn't");
+    NS_ASSERTION(!FrameWantsToBeInAnonymousItem(aParentFrame, child),
+                 "frame wants to be inside an anonymous item, but it isn't");
     if (IsAnonymousFlexOrGridItem(child)) {
       AssertAnonymousFlexOrGridItemParent(child, aParentFrame);
       MOZ_ASSERT(!prevChildWasAnonItem, "two anon items in a row");
       nsIFrame* firstWrappedChild = child->PrincipalChildList().FirstChild();
       MOZ_ASSERT(firstWrappedChild, "anonymous item shouldn't be empty");
       prevChildWasAnonItem = true;
     } else {
       prevChildWasAnonItem = false;
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -82,31 +82,65 @@ kAxisOrientationToSidesMap[eNumAxisOrien
 
 // Helper structs / classes / methods
 // ==================================
 // Returns true iff the given nsStyleDisplay has display:-webkit-{inline-}-box.
 static inline bool
 IsDisplayValueLegacyBox(const nsStyleDisplay* aStyleDisp)
 {
   return aStyleDisp->mDisplay == mozilla::StyleDisplay::WebkitBox ||
-    aStyleDisp->mDisplay == mozilla::StyleDisplay::WebkitInlineBox;
+    aStyleDisp->mDisplay == mozilla::StyleDisplay::WebkitInlineBox ||
+    aStyleDisp->mDisplay == mozilla::StyleDisplay::MozBox ||
+    aStyleDisp->mDisplay == mozilla::StyleDisplay::MozInlineBox;
 }
 
 // Returns true if aFlexContainer is the frame for an element with
 // "display:-webkit-box" or "display:-webkit-inline-box". aFlexContainer is
 // expected to be an instance of nsFlexContainerFrame (enforced with an assert);
 // otherwise, this function's state-bit-check here is bogus.
 static bool
 IsLegacyBox(const nsIFrame* aFlexContainer)
 {
   MOZ_ASSERT(aFlexContainer->IsFlexContainerFrame(),
              "only flex containers may be passed to this function");
   return aFlexContainer->HasAnyStateBits(NS_STATE_FLEX_IS_LEGACY_WEBKIT_BOX);
 }
 
+// This should return true if we are the nsFlexContainerFrame for a -moz-box or
+// a -moz-inline-box.
+static bool
+ShouldUseLegacyCollapseBehavior(const nsIFrame* aFlexContainer,
+                                const nsStyleDisplay* aFlexStyleDisp)
+{
+  // Quick filter to screen out modern-flexbox using state bit:
+  if (!IsLegacyBox(aFlexContainer)) {
+    return false;
+  }
+
+  // Check our own display value:
+  if (aFlexStyleDisp->mDisplay == mozilla::StyleDisplay::MozBox ||
+      aFlexStyleDisp->mDisplay == mozilla::StyleDisplay::MozInlineBox) {
+    return true;
+  }
+
+  // Check our parent's display value, if we're an anonymous box (with a
+  // potentially-untrustworthy display value):
+  auto pseudoType = aFlexContainer->StyleContext()->GetPseudo();
+  if (pseudoType == nsCSSAnonBoxes::scrolledContent ||
+      pseudoType == nsCSSAnonBoxes::buttonContent) {
+    const nsStyleDisplay* disp = aFlexContainer->GetParent()->StyleDisplay();
+    if (disp->mDisplay == mozilla::StyleDisplay::MozBox ||
+        disp->mDisplay == mozilla::StyleDisplay::MozInlineBox) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 // Returns the OrderingProperty enum that we should pass to
 // CSSOrderAwareFrameIterator (depending on whether it's a legacy box).
 static CSSOrderAwareFrameIterator::OrderingProperty
 OrderingPropertyForIter(const nsFlexContainerFrame* aFlexContainer)
 {
   return IsLegacyBox(aFlexContainer)
     ? CSSOrderAwareFrameIterator::OrderingProperty::eUseBoxOrdinalGroup
     : CSSOrderAwareFrameIterator::OrderingProperty::eUseOrder;
@@ -3573,34 +3607,42 @@ nsFlexContainerFrame::GenerateFlexLines(
                                   OrderingPropertyForIter(this));
 
   if (iter.ItemsAreAlreadyInOrder()) {
     AddStateBits(NS_STATE_FLEX_NORMAL_FLOW_CHILDREN_IN_CSS_ORDER);
   } else {
     RemoveStateBits(NS_STATE_FLEX_NORMAL_FLOW_CHILDREN_IN_CSS_ORDER);
   }
 
+  const bool useLegacyCollapseBehavior =
+    ShouldUseLegacyCollapseBehavior(this, aReflowInput.mStyleDisplay);
+
   for (; !iter.AtEnd(); iter.Next()) {
     nsIFrame* childFrame = *iter;
     // Don't create flex items / lines for placeholder frames:
     if (childFrame->IsPlaceholderFrame()) {
       aPlaceholders.AppendElement(childFrame);
       continue;
     }
 
     // Honor "page-break-before", if we're multi-line and this line isn't empty:
     if (!isSingleLine && !curLine->IsEmpty() &&
         childFrame->StyleDisplay()->mBreakBefore) {
       curLine = AddNewFlexLineToList(aLines, shouldInsertAtFront);
     }
 
     UniquePtr<FlexItem> item;
-    if (nextStrutIdx < aStruts.Length() &&
-        aStruts[nextStrutIdx].mItemIdx == itemIdxInContainer) {
-
+    if (useLegacyCollapseBehavior &&
+        (NS_STYLE_VISIBILITY_COLLAPSE ==
+         childFrame->StyleVisibility()->mVisible)) {
+      // Legacy visibility:collapse behavior: make a 0-sized strut. (No need to
+      // bother with aStruts and remembering cross size.)      
+      item = MakeUnique<FlexItem>(childFrame, 0, aReflowInput.GetWritingMode());
+    } else if (nextStrutIdx < aStruts.Length() &&
+               aStruts[nextStrutIdx].mItemIdx == itemIdxInContainer) {
       // Use the simplified "strut" FlexItem constructor:
       item = MakeUnique<FlexItem>(childFrame, aStruts[nextStrutIdx].mStrutCrossSize,
                                   aReflowInput.GetWritingMode());
       nextStrutIdx++;
     } else {
       item = GenerateFlexItemForChild(aPresContext, childFrame,
                                       aReflowInput, aAxisTracker);
     }
@@ -4212,17 +4254,18 @@ nsFlexContainerFrame::DoFlexLayout(nsPre
     crossAxisPosnTracker(lines.getFirst(),
                          aReflowInput, contentBoxCrossSize,
                          isCrossSizeDefinite, aAxisTracker);
 
   // Now that we know the cross size of each line (including
   // "align-content:stretch" adjustments, from the CrossAxisPositionTracker
   // constructor), we can create struts for any flex items with
   // "visibility: collapse" (and restart flex layout).
-  if (aStruts.IsEmpty()) { // (Don't make struts if we already did)
+  if (aStruts.IsEmpty() && // (Don't make struts if we already did)
+      !ShouldUseLegacyCollapseBehavior(this, aReflowInput.mStyleDisplay)) {
     BuildStrutInfoFromCollapsedItems(lines.getFirst(), aStruts);
     if (!aStruts.IsEmpty()) {
       // Restart flex layout, using our struts.
       return;
     }
   }
 
   // If the container should derive its baseline from the first FlexLine,
@@ -4637,30 +4680,37 @@ nsFlexContainerFrame::GetMinISize(gfxCon
   nscoord minISize = 0;
   DISPLAY_MIN_WIDTH(this, minISize);
 
   RenumberList();
 
   const nsStylePosition* stylePos = StylePosition();
   const FlexboxAxisTracker axisTracker(this, GetWritingMode());
 
+  const bool useLegacyCollapseBehavior =
+    ShouldUseLegacyCollapseBehavior(this, StyleDisplay());
+
   for (nsIFrame* childFrame : mFrames) {
-    nscoord childMinISize =
-      nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame,
-                                           nsLayoutUtils::MIN_ISIZE);
-    // For a horizontal single-line flex container, the intrinsic min
-    // isize is the sum of its items' min isizes.
-    // For a column-oriented flex container, or for a multi-line row-
-    // oriented flex container, the intrinsic min isize is the max of
-    // its items' min isizes.
-    if (axisTracker.IsRowOriented() &&
-        NS_STYLE_FLEX_WRAP_NOWRAP == stylePos->mFlexWrap) {
-      minISize += childMinISize;
-    } else {
-      minISize = std::max(minISize, childMinISize);
+    if (!useLegacyCollapseBehavior ||
+        (NS_STYLE_VISIBILITY_COLLAPSE !=
+         childFrame->StyleVisibility()->mVisible)) {
+      nscoord childMinISize =
+        nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame,
+                                             nsLayoutUtils::MIN_ISIZE);
+      // For a horizontal single-line flex container, the intrinsic min
+      // isize is the sum of its items' min isizes.
+      // For a column-oriented flex container, or for a multi-line row-
+      // oriented flex container, the intrinsic min isize is the max of
+      // its items' min isizes.
+      if (axisTracker.IsRowOriented() &&
+          NS_STYLE_FLEX_WRAP_NOWRAP == stylePos->mFlexWrap) {
+        minISize += childMinISize;
+      } else {
+        minISize = std::max(minISize, childMinISize);
+      }
     }
   }
   return minISize;
 }
 
 /* virtual */ nscoord
 nsFlexContainerFrame::GetPrefISize(gfxContext* aRenderingContext)
 {
@@ -4671,20 +4721,27 @@ nsFlexContainerFrame::GetPrefISize(gfxCo
 
   // XXXdholbert Optimization: We could cache our intrinsic widths like
   // nsBlockFrame does (and return it early from this function if it's set).
   // Whenever anything happens that might change it, set it to
   // NS_INTRINSIC_WIDTH_UNKNOWN (like nsBlockFrame::MarkIntrinsicISizesDirty
   // does)
   const FlexboxAxisTracker axisTracker(this, GetWritingMode());
 
+  const bool useLegacyCollapseBehavior =
+    ShouldUseLegacyCollapseBehavior(this, StyleDisplay());
+
   for (nsIFrame* childFrame : mFrames) {
-    nscoord childPrefISize =
-      nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame,
-                                           nsLayoutUtils::PREF_ISIZE);
-    if (axisTracker.IsRowOriented()) {
-      prefISize += childPrefISize;
-    } else {
-      prefISize = std::max(prefISize, childPrefISize);
+    if (!useLegacyCollapseBehavior ||
+        (NS_STYLE_VISIBILITY_COLLAPSE !=
+         childFrame->StyleVisibility()->mVisible)) {
+      nscoord childPrefISize =
+        nsLayoutUtils::IntrinsicForContainer(aRenderingContext, childFrame,
+                                             nsLayoutUtils::PREF_ISIZE);
+      if (axisTracker.IsRowOriented()) {
+        prefISize += childPrefISize;
+      } else {
+        prefISize = std::max(prefISize, childPrefISize);
+      }
     }
   }
   return prefISize;
 }
--- a/toolkit/content/textbox.css
+++ b/toolkit/content/textbox.css
@@ -6,23 +6,29 @@
 @namespace html url("http://www.w3.org/1999/xhtml"); /* namespace for HTML elements */
 
 html|*.textbox-input {
   -moz-appearance: none !important;
   text-align: inherit;
   text-shadow: inherit;
   box-sizing: border-box;
   -moz-box-flex: 1;
+  /* Be block-level, so that -moz-box-flex can take effect, when we are an item
+     in a -moz-box being emulated by modified modern flex. */
+  display: block;
 }
 
 html|*.textbox-textarea {
   -moz-appearance: none !important;
   text-shadow: inherit;
   box-sizing: border-box;
   -moz-box-flex: 1;
+  /* Be block-level, so that -moz-box-flex can take effect, when we are an item
+     in a -moz-box being emulated by modified modern flex. */
+  display: block;
 }
 
 /*
 html|*.textbox-input::placeholder,
 html|*.textbox-textarea::placeholder {
   text-align: left;
   direction: ltr;
 }
--- a/toolkit/content/xul.css
+++ b/toolkit/content/xul.css
@@ -161,17 +161,19 @@ toolbar[mode="text"] .toolbarbutton-icon
   -moz-binding: none;
 }
 
 /******** browser, editor, iframe ********/
 
 browser,
 editor,
 iframe {
-  display: inline;
+  /* Old and new flex are different in this case... emulation for webkit requires inline children to
+     **not** be converted to block. */
+  display: block;
 }
 
 browser {
   -moz-binding: url("chrome://global/content/bindings/browser.xml#browser");
 }
 
 browser[remote=true]:not(.lightweight) {
   -moz-binding: url("chrome://global/content/bindings/remote-browser.xml#remote-browser");
@@ -300,28 +302,30 @@ toolbar[customizing="true"][hidden="true
      Override it while customizing. */
   display: -moz-box;
 }
 
 %ifdef XP_MACOSX
 toolbar[type="menubar"] {
   min-height: 0 !important;
   border: 0 !important;
+  padding: 0 !important;
 }
 %else
 toolbar[type="menubar"][autohide="true"] {
   -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-menubar-autohide");
   overflow: hidden;
 }
 
 toolbar[type="menubar"][autohide="true"][inactive="true"]:not([customizing="true"]) {
   min-height: 0 !important;
   height: 0 !important;
   -moz-appearance: none !important;
   border-style: none !important;
+  padding: 0 !important;
 }
 %endif
 
 toolbarseparator {
   -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbardecoration");
 }
 
 toolbarspacer {
@@ -1223,8 +1227,45 @@ tabmodalprompt {
 .button-highlightable-text:not([highlightable="true"]),
 .button-text[highlightable="true"],
 .menulist-highlightable-label:not([highlightable="true"]),
 .menulist-label[highlightable="true"],
 .menu-iconic-highlightable-text:not([highlightable="true"]),
 .menu-iconic-text[highlightable="true"] {
   display: none;
 }
+
+[flex="1"] { -moz-box-flex: 1; }
+[flex="2"] { -moz-box-flex: 2; }
+[flex="3"] { -moz-box-flex: 3; }
+[flex="4"] { -moz-box-flex: 4; }
+[flex="5"] { -moz-box-flex: 5; }
+[flex="6"] { -moz-box-flex: 6; }
+[flex="7"] { -moz-box-flex: 7; }
+[flex="8"] { -moz-box-flex: 8; }
+[flex="9"] { -moz-box-flex: 9; }
+[flex="400"] { -moz-box-flex: 400; }
+[flex="1000"] { -moz-box-flex: 1000; }
+
+[ordinal="1"] { -moz-box-ordinal-group: 1; }
+[ordinal="2"] { -moz-box-ordinal-group: 2; }
+[ordinal="3"] { -moz-box-ordinal-group: 3; }
+[ordinal="4"] { -moz-box-ordinal-group: 4; }
+[ordinal="5"] { -moz-box-ordinal-group: 5; }
+[ordinal="6"] { -moz-box-ordinal-group: 6; }
+[ordinal="7"] { -moz-box-ordinal-group: 7; }
+[ordinal="8"] { -moz-box-ordinal-group: 8; }
+[ordinal="9"] { -moz-box-ordinal-group: 9; }
+
+[orient="vertical"] { -moz-box-orient: vertical; }
+[orient="horizontal"] { -moz-box-orient: horizontal; }
+
+[dir="reverse"] { -moz-box-direction: reverse; }
+
+[align="start"] { -moz-box-align: start; }
+[align="center"] { -moz-box-align: center; }
+[align="end"] { -moz-box-align: end; }
+[align="baseline"] { -moz-box-align: baseline; }
+[align="stretch"] { -moz-box-align: stretch; }
+
+[pack="start"] { -moz-box-pack: start; }
+[pack="center"] { -moz-box-pack: center; }
+[pack="end"] { -moz-box-pack: end; }
--- a/toolkit/themes/linux/global/global.css
+++ b/toolkit/themes/linux/global/global.css
@@ -82,17 +82,16 @@ window.dialog {
 .authentication-icon {
   list-style-image: url("chrome://global/skin/icons/Authentication.png");
 }
 
 /* ::::: iframe ::::: */
 
 iframe {
   border: none;
-  width: 100px;
   height: 100px;
   min-width: 10px;
   min-height: 10px;
 }
 
 /* ::::: statusbar ::::: */
 
 statusbar {
--- a/toolkit/themes/osx/global/global.css
+++ b/toolkit/themes/osx/global/global.css
@@ -80,17 +80,16 @@ window.dialog {
 .question-icon {
   list-style-image: url("chrome://global/skin/icons/question-64.png");
 }
 
 /* ::::: iframe ::::: */
 
 iframe {
   border: none;
-  width: 100px;
   height: 100px;
   min-width: 10px;
   min-height: 10px;
 }
 
 /* ::::: statusbar ::::: */
 
 statusbar {
--- a/toolkit/themes/windows/global/global.css
+++ b/toolkit/themes/windows/global/global.css
@@ -76,17 +76,16 @@ window.dialog {
 .question-icon {
   list-style-image: url("chrome://global/skin/icons/Question.png");
 }
 
 /* ::::: iframe ::::: */
 
 iframe {
   border: none;
-  width: 100px;
   height: 100px;
   min-width: 10px;
   min-height: 10px;
 }
 
 /* ::::: statusbar ::::: */
 
 statusbar {