Commit 018094db authored by Chris H-C's avatar Chris H-C
Browse files

Bug 1249664 - Save the combobox's dropped-down state across frame reconstruction. r=dbaron

We already restore the scroll-position state of the list control frame (via
nsHTMLScrollFrame), so the combobox control frame needs to add a suffix to
its state key so it doesn't overlap.

MozReview-Commit-ID: Eq0X0FCOciZ

--HG--
extra : rebase_source : 3d4b1a555f980ffaad59fbcbb72370117013812c
parent b72448db
Loading
Loading
Loading
Loading
+32 −17
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "nsIListControlFrame.h"
#include "nsPIDOMWindow.h"
#include "nsIPresShell.h"
#include "nsPresState.h"
#include "nsContentList.h"
#include "nsView.h"
#include "nsViewManager.h"
@@ -316,15 +317,16 @@ nsComboboxControlFrame::ShowPopup(bool aShowPopup)
    viewManager->ResizeView(view, emptyRect);
  }

  // fire a popup dom event
  // fire a popup dom event if it is safe to do so
  nsCOMPtr<nsIPresShell> shell = PresContext()->GetPresShell();
  if (shell && nsContentUtils::IsSafeToRunScript()) {
    nsEventStatus status = nsEventStatus_eIgnore;
    WidgetMouseEvent event(true, aShowPopup ? eXULPopupShowing : eXULPopupHiding,
                           nullptr, WidgetMouseEvent::eReal);

  nsCOMPtr<nsIPresShell> shell = PresContext()->GetPresShell();
  if (shell)
    shell->HandleDOMEventWithTarget(mContent, &event, &status);
  }
}

bool
nsComboboxControlFrame::ShowList(bool aShowList)
@@ -447,7 +449,7 @@ nsComboboxControlFrame::ReflowDropdown(nsPresContext* aPresContext,
                                         forcedISize));

  // ensure we start off hidden
  if (GetStateBits() & NS_FRAME_FIRST_REFLOW) {
  if (!mDroppedDown && GetStateBits() & NS_FRAME_FIRST_REFLOW) {
    nsView* view = mDropdownFrame->GetView();
    nsViewManager* viewManager = view->GetViewManager();
    viewManager->SetViewVisibility(view, nsViewVisibility_kHide);
@@ -1660,24 +1662,37 @@ nsComboboxControlFrame::OnContentReset()
NS_IMETHODIMP
nsComboboxControlFrame::SaveState(nsPresState** aState)
{
  if (!mListControlFrame)
    return NS_ERROR_FAILURE;

  nsIStatefulFrame* stateful = do_QueryFrame(mListControlFrame);
  return stateful->SaveState(aState);
  MOZ_ASSERT(!(*aState));
  (*aState) = new nsPresState();
  (*aState)->SetDroppedDown(mDroppedDown);
  return NS_OK;
}

NS_IMETHODIMP
nsComboboxControlFrame::RestoreState(nsPresState* aState)
{
  if (!mListControlFrame)
  if (!aState) {
    return NS_ERROR_FAILURE;

  nsIStatefulFrame* stateful = do_QueryFrame(mListControlFrame);
  NS_ASSERTION(stateful, "Must implement nsIStatefulFrame");
  return stateful->RestoreState(aState);
  }
  ShowList(aState->GetDroppedDown()); // might destroy us
  return NS_OK;
}

// Append a suffix so that the state key for the combobox is different
// from the state key the list control uses to sometimes save the scroll
// position for the same Element
NS_IMETHODIMP
nsComboboxControlFrame::GenerateStateKey(nsIContent* aContent,
                                        nsIDocument* aDocument,
                                        nsACString& aKey)
{
  nsresult rv = nsContentUtils::GenerateStateKey(aContent, aDocument, aKey);
  if (NS_FAILED(rv) || aKey.IsEmpty()) {
    return rv;
  }
  aKey.Append("CCF");
  return NS_OK;
}

// Fennec uses a custom combobox built-in widget.
//
+3 −0
Original line number Diff line number Diff line
@@ -204,6 +204,9 @@ public:
  //nsIStatefulFrame
  NS_IMETHOD SaveState(nsPresState** aState) override;
  NS_IMETHOD RestoreState(nsPresState* aState) override;
  NS_IMETHOD GenerateStateKey(nsIContent* aContent,
                              nsIDocument* aDocument,
                              nsACString& aKey) override;

  static bool ToolkitHasNativePopup();