Bug 1525101 - Make the XULPopupManager caller to GenerateChildFrames sound. r=mats
☠☠ backed out by b6f75644ba86 ☠ ☠
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 12 Feb 2019 14:49:57 +0000
changeset 458752 7f9e50bfaad1
parent 458751 e4db508a2d78
child 458753 0f1f38a6dd4d
push id35548
push useropoprus@mozilla.com
push dateWed, 13 Feb 2019 09:48:26 +0000
treeherdermozilla-central@93e37c529818 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmats
bugs1525101
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1525101 - Make the XULPopupManager caller to GenerateChildFrames sound. r=mats It only works basically by chance with XBL and doesn't handle any kind of dynamic insertion. See comment 4 in the bug for the diagnostic. Differential Revision: https://phabricator.services.mozilla.com/D19489
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsMenuPopupFrame.h
layout/xul/nsXULPopupManager.cpp
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -53,16 +53,17 @@
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h"
 #include "mozilla/dom/KeyboardEvent.h"
 #include "mozilla/dom/KeyboardEventBinding.h"
 #include <algorithm>
 
 using namespace mozilla;
 using mozilla::dom::Event;
+using mozilla::dom::Document;
 using mozilla::dom::KeyboardEvent;
 
 int8_t nsMenuPopupFrame::sDefaultLevelIsTop = -1;
 
 DOMTimeStamp nsMenuPopupFrame::sLastKeyTime = 0;
 
 // XXX, kyle.yuan@sun.com, there are 4 definitions for the same purpose:
 //  nsMenuPopupFrame.h, nsListControlFrame.cpp, listbox.xml, tree.xml
@@ -386,25 +387,16 @@ NS_IMETHODIMP nsXULPopupShownEvent::Hand
 void nsXULPopupShownEvent::CancelListener() {
   mPopup->RemoveSystemEventListener(NS_LITERAL_STRING("transitionend"), this,
                                     false);
 }
 
 NS_IMPL_ISUPPORTS_INHERITED(nsXULPopupShownEvent, Runnable,
                             nsIDOMEventListener);
 
-void nsMenuPopupFrame::SetInitialChildList(ChildListID aListID,
-                                           nsFrameList& aChildList) {
-  // unless the list is empty, indicate that children have been generated.
-  if (aListID == kPrincipalList && aChildList.NotEmpty()) {
-    mGeneratedChildren = true;
-  }
-  nsBoxFrame::SetInitialChildList(aListID, aChildList);
-}
-
 bool nsMenuPopupFrame::IsLeafDynamic() const {
   if (mGeneratedChildren) return false;
 
   if (mPopupType != ePopupTypeMenu) {
     // any panel with a type attribute, such as the autocomplete popup,
     // is always generated right away.
     return !mContent->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::type);
   }
--- a/layout/xul/nsMenuPopupFrame.h
+++ b/layout/xul/nsMenuPopupFrame.h
@@ -242,19 +242,16 @@ class nsMenuPopupFrame final : public ns
   // Ensure that a widget has already been created for this view, and create
   // one if it hasn't. If aRecreate is true, destroys any existing widget and
   // creates a new one, regardless of whether one has already been created.
   void EnsureWidget(bool aRecreate = false);
 
   nsresult CreateWidgetForView(nsView* aView);
   uint8_t GetShadowStyle();
 
-  virtual void SetInitialChildList(ChildListID aListID,
-                                   nsFrameList& aChildList) override;
-
   virtual bool IsLeafDynamic() const override;
 
   virtual void UpdateWidgetProperties() override;
 
   // layout, position and display the popup as needed
   void LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu,
                    nsIFrame* aAnchor, bool aSizedToPopup);
 
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -1279,18 +1279,21 @@ void nsXULPopupManager::FirePopupShowing
   nsMenuPopupFrame* popupFrame = do_QueryFrame(aPopup->GetPrimaryFrame());
   if (!popupFrame) return;
 
   nsPresContext* presContext = popupFrame->PresContext();
   nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
   nsPopupType popupType = popupFrame->PopupType();
 
   // generate the child frames if they have not already been generated
-  if (!popupFrame->HasGeneratedChildren()) {
-    popupFrame->SetGeneratedChildren();
+  const bool generateFrames = popupFrame->IsLeaf();
+  MOZ_ASSERT_IF(generateFrames, !popupFrame->HasGeneratedChildren());
+  popupFrame->SetGeneratedChildren();
+  if (generateFrames) {
+    MOZ_ASSERT(popupFrame->PrincipalChildList().IsEmpty());
     presShell->FrameConstructor()->GenerateChildFrames(popupFrame);
   }
 
   // get the frame again
   nsIFrame* frame = aPopup->GetPrimaryFrame();
   if (!frame) return;
 
   presShell->FrameNeedsReflow(frame, nsIPresShell::eTreeChange,