зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1026310
, set the open state only once the opening transition is finished, rename the internal popup states to be clearer, fix UITour.jsm to check the showing state, r=MattN,neil
This commit is contained in:
Родитель
6770de9ed0
Коммит
e9a4f0f8d4
|
@ -842,7 +842,7 @@ this.UITour = {
|
||||||
highlighter.style.width = highlightWidth + "px";
|
highlighter.style.width = highlightWidth + "px";
|
||||||
|
|
||||||
// Close a previous highlight so we can relocate the panel.
|
// Close a previous highlight so we can relocate the panel.
|
||||||
if (highlighter.parentElement.state == "open") {
|
if (highlighter.parentElement.state == "showing" || highlighter.parentElement.state == "open") {
|
||||||
highlighter.parentElement.hidePopup();
|
highlighter.parentElement.hidePopup();
|
||||||
}
|
}
|
||||||
/* The "overlap" position anchors from the top-left but we want to centre highlights at their
|
/* The "overlap" position anchors from the top-left but we want to centre highlights at their
|
||||||
|
@ -909,7 +909,7 @@ this.UITour = {
|
||||||
let tooltipIcon = document.getElementById("UITourTooltipIcon");
|
let tooltipIcon = document.getElementById("UITourTooltipIcon");
|
||||||
let tooltipButtons = document.getElementById("UITourTooltipButtons");
|
let tooltipButtons = document.getElementById("UITourTooltipButtons");
|
||||||
|
|
||||||
if (tooltip.state == "open") {
|
if (tooltip.state == "showing" || tooltip.state == "open") {
|
||||||
tooltip.hidePopup();
|
tooltip.hidePopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -333,6 +333,12 @@ nsMenuPopupFrame::GetShadowStyle()
|
||||||
|
|
||||||
NS_IMETHODIMP nsXULPopupShownEvent::Run()
|
NS_IMETHODIMP nsXULPopupShownEvent::Run()
|
||||||
{
|
{
|
||||||
|
nsMenuPopupFrame* popup = do_QueryFrame(mPopup->GetPrimaryFrame());
|
||||||
|
// Set the state to visible if the popup is still open.
|
||||||
|
if (popup && popup->IsOpen()) {
|
||||||
|
popup->SetPopupState(ePopupShown);
|
||||||
|
}
|
||||||
|
|
||||||
WidgetMouseEvent event(true, NS_XUL_POPUP_SHOWN, nullptr,
|
WidgetMouseEvent event(true, NS_XUL_POPUP_SHOWN, nullptr,
|
||||||
WidgetMouseEvent::eReal);
|
WidgetMouseEvent::eReal);
|
||||||
return EventDispatcher::Dispatch(mPopup, mPresContext, &event);
|
return EventDispatcher::Dispatch(mPopup, mPresContext, &event);
|
||||||
|
@ -486,8 +492,11 @@ nsMenuPopupFrame::LayoutPopup(nsBoxLayoutState& aState, nsIFrame* aParentMenu,
|
||||||
rect.x = rect.y = 0;
|
rect.x = rect.y = 0;
|
||||||
viewManager->ResizeView(view, rect);
|
viewManager->ResizeView(view, rect);
|
||||||
|
|
||||||
|
if (mPopupState == ePopupOpening) {
|
||||||
|
mPopupState = ePopupVisible;
|
||||||
|
}
|
||||||
|
|
||||||
viewManager->SetViewVisibility(view, nsViewVisibility_kShow);
|
viewManager->SetViewVisibility(view, nsViewVisibility_kShow);
|
||||||
mPopupState = ePopupOpenAndVisible;
|
|
||||||
nsContainerFrame::SyncFrameViewProperties(pc, this, nullptr, view, 0);
|
nsContainerFrame::SyncFrameViewProperties(pc, this, nullptr, view, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,7 +783,7 @@ nsMenuPopupFrame::ShowPopup(bool aIsContextMenu, bool aSelectFirstItem)
|
||||||
InvalidateFrameSubtree();
|
InvalidateFrameSubtree();
|
||||||
|
|
||||||
if (mPopupState == ePopupShowing) {
|
if (mPopupState == ePopupShowing) {
|
||||||
mPopupState = ePopupOpen;
|
mPopupState = ePopupOpening;
|
||||||
mIsOpenChanged = true;
|
mIsOpenChanged = true;
|
||||||
|
|
||||||
nsMenuFrame* menuFrame = do_QueryFrame(GetParent());
|
nsMenuFrame* menuFrame = do_QueryFrame(GetParent());
|
||||||
|
@ -1980,12 +1989,13 @@ nsMenuPopupFrame::MoveToAnchor(nsIContent* aAnchorContent,
|
||||||
int32_t aXPos, int32_t aYPos,
|
int32_t aXPos, int32_t aYPos,
|
||||||
bool aAttributesOverride)
|
bool aAttributesOverride)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mPopupState == ePopupOpenAndVisible, "popup must be open to move it");
|
NS_ASSERTION(IsVisible(), "popup must be visible to move it");
|
||||||
|
|
||||||
|
nsPopupState oldstate = mPopupState;
|
||||||
InitializePopup(aAnchorContent, mTriggerContent, aPosition,
|
InitializePopup(aAnchorContent, mTriggerContent, aPosition,
|
||||||
aXPos, aYPos, aAttributesOverride);
|
aXPos, aYPos, aAttributesOverride);
|
||||||
// InitializePopup changed the state so reset it.
|
// InitializePopup changed the state so reset it.
|
||||||
mPopupState = ePopupOpenAndVisible;
|
mPopupState = oldstate;
|
||||||
|
|
||||||
// Pass false here so that flipping and adjusting to fit on the screen happen.
|
// Pass false here so that flipping and adjusting to fit on the screen happen.
|
||||||
SetPopupPosition(nullptr, false, false);
|
SetPopupPosition(nullptr, false, false);
|
||||||
|
|
|
@ -27,10 +27,15 @@ class nsIWidget;
|
||||||
// state changes as follows:
|
// state changes as follows:
|
||||||
// ePopupClosed - initial state
|
// ePopupClosed - initial state
|
||||||
// ePopupShowing - during the period when the popupshowing event fires
|
// ePopupShowing - during the period when the popupshowing event fires
|
||||||
// ePopupOpen - between the popupshowing event and being visible. Creation
|
// ePopupOpening - between the popupshowing event and being visible. Creation
|
||||||
// of the child frames, layout and reflow occurs in this state.
|
// of the child frames, layout and reflow occurs in this
|
||||||
// ePopupOpenAndVisible - layout is done and the popup's view and widget are
|
// state. The popup is stored in the popup manager's list of
|
||||||
// made visible. The popupshown event fires.
|
// open popups during this state.
|
||||||
|
// ePopupVisible - layout is done and the popup's view and widget are made
|
||||||
|
// visible. The popup is visible on screen but may be
|
||||||
|
// transitioning. The popupshown event has not yet fired.
|
||||||
|
// ePopupShown - the popup has been shown and is fully ready. This state is
|
||||||
|
// assigned just before the popupshown event fires.
|
||||||
// When closing a popup:
|
// When closing a popup:
|
||||||
// ePopupHidden - during the period when the popuphiding event fires and
|
// ePopupHidden - during the period when the popuphiding event fires and
|
||||||
// the popup is removed.
|
// the popup is removed.
|
||||||
|
@ -42,9 +47,11 @@ enum nsPopupState {
|
||||||
// popupshowing event has been fired.
|
// popupshowing event has been fired.
|
||||||
ePopupShowing,
|
ePopupShowing,
|
||||||
// state while a popup is open but the widget is not yet visible
|
// state while a popup is open but the widget is not yet visible
|
||||||
ePopupOpen,
|
ePopupOpening,
|
||||||
|
// state while a popup is visible and waiting for the popupshown event
|
||||||
|
ePopupVisible,
|
||||||
// state while a popup is open and visible on screen
|
// state while a popup is open and visible on screen
|
||||||
ePopupOpenAndVisible,
|
ePopupShown,
|
||||||
// state from when a popup is requested to be hidden to when it is closed.
|
// state from when a popup is requested to be hidden to when it is closed.
|
||||||
ePopupHiding,
|
ePopupHiding,
|
||||||
// state which indicates that the popup was hidden without firing the
|
// state which indicates that the popup was hidden without firing the
|
||||||
|
@ -251,7 +258,11 @@ public:
|
||||||
|
|
||||||
nsPopupType PopupType() const { return mPopupType; }
|
nsPopupType PopupType() const { return mPopupType; }
|
||||||
bool IsMenu() MOZ_OVERRIDE { return mPopupType == ePopupTypeMenu; }
|
bool IsMenu() MOZ_OVERRIDE { return mPopupType == ePopupTypeMenu; }
|
||||||
bool IsOpen() MOZ_OVERRIDE { return mPopupState == ePopupOpen || mPopupState == ePopupOpenAndVisible; }
|
bool IsOpen() MOZ_OVERRIDE { return mPopupState == ePopupOpening ||
|
||||||
|
mPopupState == ePopupVisible ||
|
||||||
|
mPopupState == ePopupShown; }
|
||||||
|
bool IsVisible() { return mPopupState == ePopupVisible ||
|
||||||
|
mPopupState == ePopupShown; }
|
||||||
|
|
||||||
bool IsMouseTransparent() { return mMouseTransparent; }
|
bool IsMouseTransparent() { return mMouseTransparent; }
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ nsPopupBoxObject::MoveToAnchor(nsIDOMElement* aAnchorElement,
|
||||||
nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement));
|
nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement));
|
||||||
|
|
||||||
nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(mContent->GetPrimaryFrame());
|
nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(mContent->GetPrimaryFrame());
|
||||||
if (menuPopupFrame && menuPopupFrame->PopupState() == ePopupOpenAndVisible) {
|
if (menuPopupFrame && menuPopupFrame->IsVisible()) {
|
||||||
menuPopupFrame->MoveToAnchor(anchorContent, aPosition, aXPos, aYPos, aAttributesOverride);
|
menuPopupFrame->MoveToAnchor(anchorContent, aPosition, aXPos, aYPos, aAttributesOverride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,13 +226,14 @@ nsPopupBoxObject::GetPopupState(nsAString& aState)
|
||||||
nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
|
nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
|
||||||
if (menuPopupFrame) {
|
if (menuPopupFrame) {
|
||||||
switch (menuPopupFrame->PopupState()) {
|
switch (menuPopupFrame->PopupState()) {
|
||||||
case ePopupShowing:
|
case ePopupShown:
|
||||||
case ePopupOpen:
|
|
||||||
aState.AssignLiteral("showing");
|
|
||||||
break;
|
|
||||||
case ePopupOpenAndVisible:
|
|
||||||
aState.AssignLiteral("open");
|
aState.AssignLiteral("open");
|
||||||
break;
|
break;
|
||||||
|
case ePopupShowing:
|
||||||
|
case ePopupOpening:
|
||||||
|
case ePopupVisible:
|
||||||
|
aState.AssignLiteral("showing");
|
||||||
|
break;
|
||||||
case ePopupHiding:
|
case ePopupHiding:
|
||||||
case ePopupInvisible:
|
case ePopupInvisible:
|
||||||
aState.AssignLiteral("hiding");
|
aState.AssignLiteral("hiding");
|
||||||
|
@ -284,13 +285,9 @@ nsPopupBoxObject::GetOuterScreenRect(nsIDOMClientRect** aRect)
|
||||||
|
|
||||||
NS_ADDREF(*aRect = rect);
|
NS_ADDREF(*aRect = rect);
|
||||||
|
|
||||||
nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false));
|
|
||||||
if (!menuPopupFrame)
|
|
||||||
return NS_OK;
|
|
||||||
|
|
||||||
// Return an empty rectangle if the popup is not open.
|
// Return an empty rectangle if the popup is not open.
|
||||||
nsPopupState state = menuPopupFrame->PopupState();
|
nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false));
|
||||||
if (state != ePopupOpen && state != ePopupOpenAndVisible)
|
if (!menuPopupFrame || !menuPopupFrame->IsOpen())
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
nsView* view = menuPopupFrame->GetView();
|
nsView* view = menuPopupFrame->GetView();
|
||||||
|
|
|
@ -394,7 +394,7 @@ nsMenuPopupFrame* GetPopupToMoveOrResize(nsIFrame* aFrame)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// no point moving or resizing hidden popups
|
// no point moving or resizing hidden popups
|
||||||
if (menuPopupFrame->PopupState() != ePopupOpenAndVisible)
|
if (!menuPopupFrame->IsVisible())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
nsIWidget* widget = menuPopupFrame->GetWidget();
|
nsIWidget* widget = menuPopupFrame->GetWidget();
|
||||||
|
@ -1390,7 +1390,11 @@ nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
|
||||||
// from hiding.
|
// from hiding.
|
||||||
if (status == nsEventStatus_eConsumeNoDefault &&
|
if (status == nsEventStatus_eConsumeNoDefault &&
|
||||||
!popupFrame->IsInContentShell()) {
|
!popupFrame->IsInContentShell()) {
|
||||||
popupFrame->SetPopupState(ePopupOpenAndVisible);
|
// XXXndeakin
|
||||||
|
// If an attempt was made to hide this popup before the popupshown event
|
||||||
|
// fired, then ePopupShown is set here even though it should be
|
||||||
|
// ePopupVisible. This probably isn't worth the hassle of handling.
|
||||||
|
popupFrame->SetPopupState(ePopupShown);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// If the popup has an animate attribute and it is not set to false, assume
|
// If the popup has an animate attribute and it is not set to false, assume
|
||||||
|
@ -1503,10 +1507,9 @@ nsXULPopupManager::GetVisiblePopups(nsTArray<nsIFrame *>& aPopups)
|
||||||
nsMenuChainItem* item = mPopups;
|
nsMenuChainItem* item = mPopups;
|
||||||
for (int32_t list = 0; list < 2; list++) {
|
for (int32_t list = 0; list < 2; list++) {
|
||||||
while (item) {
|
while (item) {
|
||||||
// Skip panels which are not open and visible as well as popups that
|
// Skip panels which are not visible as well as popups that
|
||||||
// are transparent to mouse events.
|
// are transparent to mouse events.
|
||||||
if (item->Frame()->PopupState() == ePopupOpenAndVisible &&
|
if (item->Frame()->IsVisible() && !item->Frame()->IsMouseTransparent()) {
|
||||||
!item->Frame()->IsMouseTransparent()) {
|
|
||||||
aPopups.AppendElement(item->Frame());
|
aPopups.AppendElement(item->Frame());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,10 +186,12 @@ function nextTest()
|
||||||
transitions++;
|
transitions++;
|
||||||
// Two properties transition so continue on the second one finishing.
|
// Two properties transition so continue on the second one finishing.
|
||||||
if (!(transitions % 2)) {
|
if (!(transitions % 2)) {
|
||||||
|
is($("animatepanel").state, "open", "state is open after transitionend");
|
||||||
ok(animatedPopupShown, "popupshown now fired")
|
ok(animatedPopupShown, "popupshown now fired")
|
||||||
SimpleTest.executeSoon(() => runNextTest.next());
|
SimpleTest.executeSoon(() => runNextTest.next());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
is($("animatepanel").state, "showing", "state is showing during transitionend");
|
||||||
ok(!animatedPopupShown, "popupshown not fired yet")
|
ok(!animatedPopupShown, "popupshown not fired yet")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,6 +199,7 @@ function nextTest()
|
||||||
// Check that the transition occurs for an arrow panel with animate="true"
|
// Check that the transition occurs for an arrow panel with animate="true"
|
||||||
window.addEventListener("transitionend", transitionEnded, false);
|
window.addEventListener("transitionend", transitionEnded, false);
|
||||||
$("animatepanel").openPopup($("topleft"), "after_start", 0, 0, false, false, null, "start");
|
$("animatepanel").openPopup($("topleft"), "after_start", 0, 0, false, false, null, "start");
|
||||||
|
is($("animatepanel").state, "showing", "state is showing");
|
||||||
yield;
|
yield;
|
||||||
window.removeEventListener("transitionend", transitionEnded, false);
|
window.removeEventListener("transitionend", transitionEnded, false);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче