Bug 1428701 - (Part 2) Handle the drop-down and the roll-up actions for content-select draft
authorKuoE0 <kuoe0.tw@gmail.com>
Wed, 10 Jan 2018 11:24:44 +0800
changeset 720312 c4ec255ad8da49f08ec65b93a6690913b154feaf
parent 720311 b1e061da56935d9b223c75484e8bbdbd35be9955
child 746027 eaf99fbd0d31b05f7b4c2dea19ce68eaeef05542
push id95503
push userbmo:kuoe0@mozilla.com
push dateMon, 15 Jan 2018 07:53:49 +0000
bugs1428701
milestone59.0a1
Bug 1428701 - (Part 2) Handle the drop-down and the roll-up actions for content-select MozReview-Commit-ID: JyOKWi5qTca
layout/forms/nsComboboxControlFrame.cpp
layout/forms/nsListControlFrame.cpp
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -9,16 +9,17 @@
 #include "gfxContext.h"
 #include "gfxUtils.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/PathHelpers.h"
 #include "nsCOMPtr.h"
 #include "nsFocusManager.h"
 #include "nsCheckboxRadioFrame.h"
 #include "nsGkAtoms.h"
+#include "nsCanvasFrame.h"
 #include "nsCSSAnonBoxes.h"
 #include "nsHTMLParts.h"
 #include "nsIFormControl.h"
 #include "nsNameSpaceManager.h"
 #include "nsIListControlFrame.h"
 #include "nsPIDOMWindow.h"
 #include "nsIPresShell.h"
 #include "nsPresState.h"
@@ -339,16 +340,25 @@ nsComboboxControlFrame::ShowList(bool aS
 {
 
   // TODO(kuoe0) Remove this function when content-select is enabled.
   //
   // This function is used to handle the widget/view stuff, so we just return
   // when content-select is enabled. And the following callee, ShowPopup(), will
   // also be ignored, it is only used to show and hide the widget.
   if (nsLayoutUtils::IsContentSelectEnabled()) {
+    mDroppedDown = aShowList;
+
+    // Update the dropdown frame in the canvas frame
+    nsCanvasFrame* canvasFrame = do_QueryFrame(mDropdownFrame->GetParent());
+    if (mDroppedDown) {
+      canvasFrame->SetDropdownFrame(mDropdownFrame);
+    } else {
+      canvasFrame->SetDropdownFrame(nullptr);
+    }
     return true;
   }
 
   nsView* view = mDropdownFrame->GetView();
   if (aShowList) {
     NS_ASSERTION(!view->HasWidget(),
                  "We shouldn't have a widget before we need to display the popup");
 
@@ -585,17 +595,20 @@ public:
 };
 
 void
 nsComboboxControlFrame::GetAvailableDropdownSpace(WritingMode aWM,
                                                   nscoord* aBefore,
                                                   nscoord* aAfter,
                                                   LogicalPoint* aTranslation)
 {
-  MOZ_ASSERT(!XRE_IsContentProcess());
+  if (!nsLayoutUtils::IsContentSelectEnabled()) {
+    // TODO(kuoe0) remove this assertion after content-select is enabled
+    MOZ_ASSERT(!XRE_IsContentProcess());
+  }
   // Note: At first glance, it appears that you could simply get the
   // absolute bounding box for the dropdown list by first getting its
   // view, then getting the view's nsIWidget, then asking the nsIWidget
   // for its AbsoluteBounds.
   // The problem with this approach, is that the dropdown list's bcoord
   // location can change based on whether the dropdown is placed after
   // or before the display frame.  The approach taken here is to get the
   // absolute position of the display frame and use its location to
@@ -653,17 +666,18 @@ nsComboboxControlFrame::GetAvailableDrop
 
   *aAfter = after;
   *aBefore = before;
 }
 
 nsComboboxControlFrame::DropDownPositionState
 nsComboboxControlFrame::AbsolutelyPositionDropDown()
 {
-  if (XRE_IsContentProcess()) {
+  if (!nsLayoutUtils::IsContentSelectEnabled() && XRE_IsContentProcess()) {
+    // TODO(kuoe0) remove this after content-select is enabled
     return eDropDownPositionSuppressed;
   }
 
   WritingMode wm = GetWritingMode();
   LogicalPoint translation(wm);
   nscoord before, after;
   mLastDropDownAfterScreenBCoord = nscoord_MIN;
   GetAvailableDropdownSpace(wm, &before, &after, &translation);
@@ -1185,16 +1199,23 @@ nsComboboxControlFrame::HandleEvent(nsPr
 
   // If we have style that affects how we are selected, feed event down to
   // nsFrame::HandleEvent so that selection takes place when appropriate.
   const nsStyleUserInterface* uiStyle = StyleUserInterface();
   if (uiStyle->mUserInput == StyleUserInput::None ||
       uiStyle->mUserInput == StyleUserInput::Disabled) {
     return nsBlockFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
   }
+
+  // We handle the drop-down and roll-up actions here.
+  if (nsLayoutUtils::IsContentSelectEnabled() &&
+      aEvent->mMessage == eMouseDown) {
+    ShowDropDown(!mDroppedDown);
+  }
+
   return NS_OK;
 }
 
 
 nsresult
 nsComboboxControlFrame::SetFormProperty(nsAtom* aName, const nsAString& aValue)
 {
   nsIFormControlFrame* fcFrame = do_QueryFrame(mDropdownFrame);
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -174,16 +174,21 @@ nsListControlFrame::BuildDisplayList(nsD
   // XXX why do we need this here? we should never reach this. Maybe
   // because these can have widgets? Hmm
   if (aBuilder->IsBackgroundOnly())
     return;
 
   DO_GLOBAL_REFLOW_COUNT_DSP("nsListControlFrame");
 
   if (IsInDropDownMode()) {
+    if (nsLayoutUtils::IsContentSelectEnabled() &&
+        !mComboboxFrame->IsDroppedDown()) {
+      // Don't build the display list when the list is not dropped down.
+      return;
+    }
     NS_ASSERTION(NS_GET_A(mLastDropdownBackstopColor) == 255,
                  "need an opaque backstop color");
     // XXX Because we have an opaque widget and we get called to paint with
     // this frame as the root of a stacking context we need make sure to draw
     // some opaque color over the whole widget. (Bug 511323)
     aLists.BorderBackground()->AppendToBottom(
       new (aBuilder) nsDisplaySolidColor(aBuilder,
         this, nsRect(aBuilder->ToReferenceFrame(this), GetSize()),
@@ -1845,16 +1850,19 @@ nsListControlFrame::MouseDown(nsIDOMEven
     CaptureMouseEvents(true);
     AutoWeakFrame weakFrame(this);
     bool change =
       HandleListSelection(aMouseEvent, selectedIndex); // might destroy us
     if (!weakFrame.IsAlive()) {
       return NS_OK;
     }
     mChangesSinceDragStart = change;
+  } else if (nsLayoutUtils::IsContentSelectEnabled()) {
+    // We handle the drop-down and roll-up action in the combo box.
+    return NS_OK;
   } else {
     // NOTE: the combo box is responsible for dropping it down
     if (mComboboxFrame) {
       // Ignore the click that occurs on the option element when one is
       // selected from the parent process popup.
       if (mComboboxFrame->IsOpenInParentProcess()) {
         nsCOMPtr<nsIDOMEventTarget> etarget;
         aMouseEvent->GetTarget(getter_AddRefs(etarget));