Bug 1428701 - (Part 2) Handle the drop-down and the roll-up actions for content-select
MozReview-Commit-ID: JyOKWi5qTca
--- 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));