зеркало из https://github.com/mozilla/gecko-dev.git
Bug 610545, arrow panels should animate when opening and when cancelling, r=neil,dao
This commit is contained in:
Родитель
87ad440e7c
Коммит
093ce2fa02
|
@ -7,6 +7,7 @@
|
|||
type="arrow"
|
||||
hidden="true"
|
||||
flip="slide"
|
||||
animate="false"
|
||||
position="bottomcenter topright"
|
||||
noautofocus="true">
|
||||
<panelmultiview id="PanelUI-multiView" mainViewId="PanelUI-mainView">
|
||||
|
|
|
@ -296,7 +296,7 @@ nsXULPopupListener::ClosePopup()
|
|||
// fire events during destruction.
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm)
|
||||
pm->HidePopup(mPopupContent, false, true, true);
|
||||
pm->HidePopup(mPopupContent, false, true, true, false);
|
||||
mPopupContent = nullptr; // release the popup
|
||||
}
|
||||
} // ClosePopup
|
||||
|
|
|
@ -238,7 +238,7 @@ nsMenuBarFrame::FindMenuWithShortcut(nsIDOMKeyEvent* aKeyEvent)
|
|||
if (pm) {
|
||||
nsIFrame* popup = pm->GetTopPopup(ePopupTypeAny);
|
||||
if (popup)
|
||||
pm->HidePopup(popup->GetContent(), true, true, true);
|
||||
pm->HidePopup(popup->GetContent(), true, true, true, false);
|
||||
}
|
||||
|
||||
SetCurrentMenuItem(nullptr);
|
||||
|
@ -308,7 +308,7 @@ public:
|
|||
|
||||
if (mOldMenu) {
|
||||
nsWeakFrame weakMenuBar(menubar);
|
||||
pm->HidePopup(mOldMenu, false, false, false);
|
||||
pm->HidePopup(mOldMenu, false, false, false, false);
|
||||
// clear the flag again
|
||||
if (mNewMenu && weakMenuBar.IsAlive())
|
||||
menubar->SetStayActive(false);
|
||||
|
|
|
@ -106,7 +106,7 @@ nsMenuBarListener::ToggleMenuActiveState()
|
|||
if (pm && closemenu) {
|
||||
nsMenuPopupFrame* popupFrame = closemenu->GetPopup();
|
||||
if (popupFrame)
|
||||
pm->HidePopup(popupFrame->GetContent(), false, false, true);
|
||||
pm->HidePopup(popupFrame->GetContent(), false, false, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ NS_IMETHODIMP nsMenuBoxObject::OpenMenu(bool aOpenFlag)
|
|||
if (menu) {
|
||||
nsMenuPopupFrame* popupFrame = menu->GetPopup();
|
||||
if (popupFrame)
|
||||
pm->HidePopup(popupFrame->GetContent(), false, true, false);
|
||||
pm->HidePopup(popupFrame->GetContent(), false, true, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -713,7 +713,7 @@ nsMenuFrame::CloseMenu(bool aDeselectMenu)
|
|||
// Close the menu asynchronously
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm && HasPopup())
|
||||
pm->HidePopup(GetPopup()->GetContent(), false, aDeselectMenu, true);
|
||||
pm->HidePopup(GetPopup()->GetContent(), false, aDeselectMenu, true, false);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -807,7 +807,7 @@ nsMenuFrame::Enter(WidgetGUIEvent* aEvent)
|
|||
if (pm) {
|
||||
nsIFrame* popup = pm->GetTopPopup(ePopupTypeAny);
|
||||
if (popup)
|
||||
pm->HidePopup(popup->GetContent(), true, true, true);
|
||||
pm->HidePopup(popup->GetContent(), true, true, true, false);
|
||||
}
|
||||
}
|
||||
#endif // #ifdef XP_WIN
|
||||
|
|
|
@ -50,7 +50,7 @@ nsPopupBoxObject::HidePopup()
|
|||
{
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm && mContent)
|
||||
pm->HidePopup(mContent, false, true, false);
|
||||
pm->HidePopup(mContent, false, true, false, false);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ nsXULPopupManager::Rollup(uint32_t aCount, const nsIntPoint* pos, nsIContent** a
|
|||
}
|
||||
}
|
||||
|
||||
HidePopup(item->Content(), true, true, false, lastPopup);
|
||||
HidePopup(item->Content(), true, true, false, true, lastPopup);
|
||||
}
|
||||
|
||||
return consume;
|
||||
|
@ -822,6 +822,7 @@ nsXULPopupManager::HidePopup(nsIContent* aPopup,
|
|||
bool aHideChain,
|
||||
bool aDeselectMenu,
|
||||
bool aAsynchronous,
|
||||
bool aIsRollup,
|
||||
nsIContent* aLastPopup)
|
||||
{
|
||||
// if the popup is on the nohide panels list, remove it but don't close any
|
||||
|
@ -914,23 +915,59 @@ nsXULPopupManager::HidePopup(nsIContent* aPopup,
|
|||
if (aAsynchronous) {
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
new nsXULPopupHidingEvent(popupToHide, nextPopup, lastPopup,
|
||||
type, deselectMenu);
|
||||
type, deselectMenu, aIsRollup);
|
||||
NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
else {
|
||||
FirePopupHidingEvent(popupToHide, nextPopup, lastPopup,
|
||||
popupFrame->PresContext(), type, deselectMenu);
|
||||
popupFrame->PresContext(), type, deselectMenu, aIsRollup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is used to hide the popup after a transition finishes.
|
||||
class TransitionEnder : public nsIDOMEventListener
|
||||
{
|
||||
public:
|
||||
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
bool mDeselectMenu;
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
TransitionEnder(nsIContent* aContent, bool aDeselectMenu)
|
||||
: mContent(aContent), mDeselectMenu(aDeselectMenu)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~TransitionEnder() { }
|
||||
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) MOZ_OVERRIDE
|
||||
{
|
||||
mContent->RemoveSystemEventListener(NS_LITERAL_STRING("transitionend"), this, false);
|
||||
|
||||
// Now hide the popup. There could be other properties transitioning, but
|
||||
// we'll assume they all end at the same time and just hide the popup upon
|
||||
// the first one ending.
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm) {
|
||||
pm->HidePopupFrame(mContent, mDeselectMenu);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(TransitionEnder, nsIDOMEventListener)
|
||||
|
||||
void
|
||||
nsXULPopupManager::HidePopupCallback(nsIContent* aPopup,
|
||||
nsMenuPopupFrame* aPopupFrame,
|
||||
nsIContent* aNextPopup,
|
||||
nsIContent* aLastPopup,
|
||||
nsPopupType aPopupType,
|
||||
bool aDeselectMenu)
|
||||
bool aDeselectMenu,
|
||||
bool aIsRollup)
|
||||
{
|
||||
if (mCloseTimer && mTimerMenu == aPopupFrame) {
|
||||
mCloseTimer->Cancel();
|
||||
|
@ -966,18 +1003,31 @@ nsXULPopupManager::HidePopupCallback(nsIContent* aPopup,
|
|||
|
||||
delete item;
|
||||
|
||||
nsWeakFrame weakFrame(aPopupFrame);
|
||||
aPopupFrame->HidePopup(aDeselectMenu, ePopupClosed);
|
||||
ENSURE_TRUE(weakFrame.IsAlive());
|
||||
// If the popup has an animate attribute and it is not set to false, assume
|
||||
// that it has a closing transition and wait for it to finish. The transition
|
||||
// may still occur either way, but the view will be hidden and you won't be
|
||||
// able to see it. If there is a next popup, indicating that mutliple popups
|
||||
// are rolling up, don't wait and hide the popup right away since the effect
|
||||
// would likely be undesirable. This also does a quick check to see if the
|
||||
// popup has a transition defined, and skips the wait if not.
|
||||
if (!aNextPopup && aPopup->HasAttr(kNameSpaceID_None, nsGkAtoms::animate) &&
|
||||
aPopupFrame->StyleDisplay()->mTransitionPropertyCount > 0) {
|
||||
nsAutoString animate;
|
||||
aPopup->GetAttr(kNameSpaceID_None, nsGkAtoms::animate, animate);
|
||||
|
||||
// send the popuphidden event synchronously. This event has no default
|
||||
// behaviour.
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
WidgetMouseEvent event(true, NS_XUL_POPUP_HIDDEN, nullptr,
|
||||
WidgetMouseEvent::eReal);
|
||||
EventDispatcher::Dispatch(aPopup, aPopupFrame->PresContext(),
|
||||
&event, nullptr, &status);
|
||||
ENSURE_TRUE(weakFrame.IsAlive());
|
||||
// If animate="false" then don't transition at all. If animate="cancel",
|
||||
// only show the transition if cancelling the popup or rolling up.
|
||||
// Otherwise, always show the transition.
|
||||
if (!animate.EqualsLiteral("false") &&
|
||||
(!animate.EqualsLiteral("cancel") || aIsRollup)) {
|
||||
nsCOMPtr<TransitionEnder> ender = new TransitionEnder(aPopup, aDeselectMenu);
|
||||
aPopup->AddSystemEventListener(NS_LITERAL_STRING("transitionend"),
|
||||
ender, false, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
HidePopupFrame(aPopup, aDeselectMenu);
|
||||
|
||||
// if there are more popups to close, look for the next one
|
||||
if (aNextPopup && aPopup != aLastPopup) {
|
||||
|
@ -1014,17 +1064,37 @@ nsXULPopupManager::HidePopupCallback(nsIContent* aPopup,
|
|||
|
||||
FirePopupHidingEvent(popupToHide, nextPopup, aLastPopup,
|
||||
popupFrame->PresContext(),
|
||||
foundMenu->PopupType(), aDeselectMenu);
|
||||
foundMenu->PopupType(), aDeselectMenu, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPopupManager::HidePopupFrame(nsIContent* aPopup, bool aDeselectMenu)
|
||||
{
|
||||
nsMenuPopupFrame* popupFrame = do_QueryFrame(aPopup->GetPrimaryFrame());
|
||||
if (!popupFrame)
|
||||
return;
|
||||
|
||||
nsWeakFrame weakFrame(popupFrame);
|
||||
popupFrame->HidePopup(aDeselectMenu, ePopupClosed);
|
||||
ENSURE_TRUE(weakFrame.IsAlive());
|
||||
|
||||
// send the popuphidden event synchronously. This event has no default
|
||||
// behaviour.
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
WidgetMouseEvent event(true, NS_XUL_POPUP_HIDDEN, nullptr,
|
||||
WidgetMouseEvent::eReal);
|
||||
EventDispatcher::Dispatch(aPopup, popupFrame->PresContext(),
|
||||
&event, nullptr, &status);
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPopupManager::HidePopup(nsIFrame* aFrame)
|
||||
{
|
||||
nsMenuPopupFrame* popup = do_QueryFrame(aFrame);
|
||||
if (popup)
|
||||
HidePopup(aFrame->GetContent(), false, true, false);
|
||||
HidePopup(aFrame->GetContent(), false, true, false, false);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1283,7 +1353,8 @@ nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
|
|||
nsIContent* aLastPopup,
|
||||
nsPresContext *aPresContext,
|
||||
nsPopupType aPopupType,
|
||||
bool aDeselectMenu)
|
||||
bool aDeselectMenu,
|
||||
bool aIsRollup)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell = aPresContext->PresShell();
|
||||
|
||||
|
@ -1323,7 +1394,7 @@ nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
|
|||
}
|
||||
else {
|
||||
HidePopupCallback(aPopup, popupFrame, aNextPopup, aLastPopup,
|
||||
aPopupType, aDeselectMenu);
|
||||
aPopupType, aDeselectMenu, aIsRollup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1576,7 +1647,7 @@ nsXULPopupManager::PopupDestroyed(nsMenuPopupFrame* aPopup)
|
|||
else {
|
||||
// HidePopup will take care of hiding any of its children, so
|
||||
// break out afterwards
|
||||
HidePopup(child->Content(), false, false, true);
|
||||
HidePopup(child->Content(), false, false, true, false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1776,7 +1847,7 @@ nsXULPopupManager::KillMenuTimer()
|
|||
mCloseTimer = nullptr;
|
||||
|
||||
if (mTimerMenu->IsOpen())
|
||||
HidePopup(mTimerMenu->GetContent(), false, false, true);
|
||||
HidePopup(mTimerMenu->GetContent(), false, false, true, false);
|
||||
}
|
||||
|
||||
mTimerMenu = nullptr;
|
||||
|
@ -1972,7 +2043,7 @@ nsXULPopupManager::HandleKeyboardNavigationInPopup(nsMenuChainItem* item,
|
|||
// close a submenu when Left is pressed
|
||||
nsMenuPopupFrame* popupFrame = currentMenu->GetPopup();
|
||||
if (popupFrame)
|
||||
HidePopup(popupFrame->GetContent(), false, false, false);
|
||||
HidePopup(popupFrame->GetContent(), false, false, false, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1992,7 +2063,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode(
|
|||
if (aTopVisibleMenuItem &&
|
||||
aTopVisibleMenuItem->PopupType() != ePopupTypeMenu) {
|
||||
if (keyCode == nsIDOMKeyEvent::DOM_VK_ESCAPE) {
|
||||
HidePopup(aTopVisibleMenuItem->Content(), false, false, false);
|
||||
HidePopup(aTopVisibleMenuItem->Content(), false, false, false, true);
|
||||
aKeyEvent->StopPropagation();
|
||||
aKeyEvent->PreventDefault();
|
||||
}
|
||||
|
@ -2016,7 +2087,7 @@ nsXULPopupManager::HandleKeyboardEventWithKeyCode(
|
|||
// though in this latter case, a menu didn't actually close, the effect
|
||||
// ends up being the same. Similar for the tab key below.
|
||||
if (aTopVisibleMenuItem) {
|
||||
HidePopup(aTopVisibleMenuItem->Content(), false, false, false);
|
||||
HidePopup(aTopVisibleMenuItem->Content(), false, false, false, true);
|
||||
} else if (mActiveMenuBar) {
|
||||
mActiveMenuBar->MenuClosed();
|
||||
}
|
||||
|
@ -2323,7 +2394,7 @@ nsXULPopupHidingEvent::Run()
|
|||
nsPresContext* context = presShell->GetPresContext();
|
||||
if (context) {
|
||||
pm->FirePopupHidingEvent(mPopup, mNextPopup, mLastPopup,
|
||||
context, mPopupType, mDeselectMenu);
|
||||
context, mPopupType, mDeselectMenu, mIsRollup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2384,7 +2455,7 @@ nsXULMenuCommandEvent::Run()
|
|||
}
|
||||
|
||||
if (popup && mCloseMenuMode != CloseMenuMode_None)
|
||||
pm->HidePopup(popup, mCloseMenuMode == CloseMenuMode_Auto, true, false);
|
||||
pm->HidePopup(popup, mCloseMenuMode == CloseMenuMode_Auto, true, false, false);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -204,12 +204,14 @@ public:
|
|||
nsIContent* aNextPopup,
|
||||
nsIContent* aLastPopup,
|
||||
nsPopupType aPopupType,
|
||||
bool aDeselectMenu)
|
||||
bool aDeselectMenu,
|
||||
bool aIsRollup)
|
||||
: mPopup(aPopup),
|
||||
mNextPopup(aNextPopup),
|
||||
mLastPopup(aLastPopup),
|
||||
mPopupType(aPopupType),
|
||||
mDeselectMenu(aDeselectMenu)
|
||||
mDeselectMenu(aDeselectMenu),
|
||||
mIsRollup(aIsRollup)
|
||||
{
|
||||
NS_ASSERTION(aPopup, "null popup supplied to nsXULPopupHidingEvent constructor");
|
||||
// aNextPopup and aLastPopup may be null
|
||||
|
@ -223,6 +225,7 @@ private:
|
|||
nsCOMPtr<nsIContent> mLastPopup;
|
||||
nsPopupType mPopupType;
|
||||
bool mDeselectMenu;
|
||||
bool mIsRollup;
|
||||
};
|
||||
|
||||
// this class is used for dispatching menu command events asynchronously.
|
||||
|
@ -276,6 +279,7 @@ public:
|
|||
friend class nsXULPopupShowingEvent;
|
||||
friend class nsXULPopupHidingEvent;
|
||||
friend class nsXULMenuCommandEvent;
|
||||
friend class TransitionEnder;
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
@ -433,6 +437,7 @@ public:
|
|||
* aAsynchronous - true if the first popuphiding event should be sent
|
||||
* asynchrously. This should be true if HidePopup is called
|
||||
* from a frame.
|
||||
* aIsRollup - true if this popup is hiding due to a rollup or escape keypress.
|
||||
* aLastPopup - optional popup to close last when hiding a chain of menus.
|
||||
* If null, then all popups will be closed.
|
||||
*/
|
||||
|
@ -440,6 +445,7 @@ public:
|
|||
bool aHideChain,
|
||||
bool aDeselectMenu,
|
||||
bool aAsynchronous,
|
||||
bool aIsRollup,
|
||||
nsIContent* aLastPopup = nullptr);
|
||||
|
||||
/**
|
||||
|
@ -634,7 +640,9 @@ protected:
|
|||
nsIContent* aNextPopup,
|
||||
nsIContent* aLastPopup,
|
||||
nsPopupType aPopupType,
|
||||
bool aDeselectMenu);
|
||||
bool aDeselectMenu,
|
||||
bool aIsRollup);
|
||||
void HidePopupFrame(nsIContent* aPopup, bool aDeselectMenu);
|
||||
|
||||
/**
|
||||
* Fire a popupshowing event on the popup and then open the popup.
|
||||
|
@ -664,13 +672,15 @@ protected:
|
|||
* aPresContext - nsPresContext for the popup's frame
|
||||
* aPopupType - the PopupType of the frame.
|
||||
* aDeselectMenu - true to unhighlight the menu when hiding it
|
||||
* aIsRollup - true if this popup is hiding due to a rollup or escape keypress
|
||||
*/
|
||||
void FirePopupHidingEvent(nsIContent* aPopup,
|
||||
nsIContent* aNextPopup,
|
||||
nsIContent* aLastPopup,
|
||||
nsPresContext *aPresContext,
|
||||
nsPopupType aPopupType,
|
||||
bool aDeselectMenu);
|
||||
bool aDeselectMenu,
|
||||
bool aIsRollup);
|
||||
|
||||
/**
|
||||
* Handle keyboard navigation within a menu popup specified by aItem.
|
||||
|
|
|
@ -522,7 +522,7 @@ nsXULTooltipListener::HideTooltip()
|
|||
if (currentTooltip) {
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm)
|
||||
pm->HidePopup(currentTooltip, false, false, false);
|
||||
pm->HidePopup(currentTooltip, false, false, false, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||
|
||||
<stack flex="1">
|
||||
<label id="topleft" value="Top Left Corner" left="15" top="15"/>
|
||||
|
@ -21,14 +23,21 @@
|
|||
src="data:text/html,<input id='input'>" width="100" height="100" left="225" top="120"/>
|
||||
</stack>
|
||||
|
||||
<panel id="panel" type="arrow" onpopupshown="checkPanelPosition(this)" onpopuphidden="runNextTest.next()">
|
||||
<panel id="panel" type="arrow" animate="false"
|
||||
onpopupshown="checkPanelPosition(this)" onpopuphidden="runNextTest.next()">
|
||||
<label id="panellabel" value="This is some text..." height="65"/>
|
||||
</panel>
|
||||
|
||||
<panel id="bigpanel" type="arrow" onpopupshown="checkBigPanel(this)" onpopuphidden="runNextTest.next()">
|
||||
<panel id="bigpanel" type="arrow" animate="false"
|
||||
onpopupshown="checkBigPanel(this)" onpopuphidden="runNextTest.next()">
|
||||
<button label="This is some text..." height="3000"/>
|
||||
</panel>
|
||||
|
||||
<panel id="animatepanel" type="arrow"
|
||||
onpopuphidden="animatedPopupHidden = true; runNextTest.next();">
|
||||
<label value="Animate Closed" height="40"/>
|
||||
</panel>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
|
@ -37,6 +46,7 @@ SimpleTest.waitForExplicitFinish();
|
|||
var expectedAnchor = null;
|
||||
var expectedSide = "", expectedAnchorEdge = "", expectedPack = "", expectedAlignment = "";
|
||||
var zoomFactor = 1;
|
||||
var animatedPopupHidden = false;
|
||||
var runNextTest;
|
||||
|
||||
function startTest()
|
||||
|
@ -166,7 +176,25 @@ function nextTest()
|
|||
$("bottomright").removeAttribute("right");
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
var transitions = 0;
|
||||
function transitionEnded(event) {
|
||||
transitions++;
|
||||
// Two properties transition so continue on the second one finishing.
|
||||
if (!(transitions % 2)) {
|
||||
SimpleTest.executeSoon(() => runNextTest.next());
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the transition occurs for an arrow panel with animate="true"
|
||||
window.addEventListener("transitionend", transitionEnded, false);
|
||||
$("animatepanel").openPopup($("topleft"), "after_start", 0, 0, false, false, null, "start");
|
||||
yield;
|
||||
window.removeEventListener("transitionend", transitionEnded, false);
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
ok(!animatedPopupHidden, "animated popup not hidden yet");
|
||||
yield;
|
||||
|
||||
SimpleTest.finish()
|
||||
yield;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
<panel id="testPanel"
|
||||
type="arrow"
|
||||
animate="false"
|
||||
noautohide="true">
|
||||
</panel>
|
||||
|
||||
|
|
|
@ -379,6 +379,9 @@
|
|||
|
||||
var position = this.alignmentPosition;
|
||||
var offset = this.alignmentOffset;
|
||||
|
||||
this.setAttribute("arrowposition", position);
|
||||
|
||||
// if this panel has a "sliding" arrow, we may have previously set margins...
|
||||
arrowbox.style.removeProperty("transform");
|
||||
if (position.indexOf("start_") == 0 || position.indexOf("end_") == 0) {
|
||||
|
@ -432,34 +435,39 @@
|
|||
<handler event="popupshowing" phase="target">
|
||||
<![CDATA[
|
||||
this.adjustArrowPosition();
|
||||
if (this.getAttribute("animate") != "false") {
|
||||
this.setAttribute("animate", "open");
|
||||
}
|
||||
|
||||
// set fading
|
||||
var fade = this.getAttribute("fade");
|
||||
var fadeDelay = (fade == "fast") ? 1 : fade == "slow" ? 4000 : 0;
|
||||
if (fadeDelay) {
|
||||
this._fadeTimer = setTimeout(function (self) {
|
||||
self.style.opacity = 0.2;
|
||||
}, fadeDelay, this);
|
||||
this._fadeTimer = setTimeout(() => this.hidePopup(), fadeDelay, this);
|
||||
}
|
||||
]]>
|
||||
</handler>
|
||||
<handler event="popuphiding" phase="target">
|
||||
clearTimeout(this._fadeTimer);
|
||||
this.style.removeProperty("opacity");
|
||||
</handler>
|
||||
<handler event="transitionend" phase="target">
|
||||
<![CDATA[
|
||||
if (event.propertyName == "opacity" &&
|
||||
event.originalTarget == this) {
|
||||
this.hidePopup();
|
||||
this.style.removeProperty("opacity");
|
||||
let animate = (this.getAttribute("animate") != "false");
|
||||
|
||||
if (this._fadeTimer) {
|
||||
clearTimeout(this._fadeTimer);
|
||||
if (animate) {
|
||||
this.setAttribute("animate", "fade");
|
||||
}
|
||||
}
|
||||
else if (animate) {
|
||||
this.setAttribute("animate", "cancel");
|
||||
}
|
||||
]]>
|
||||
</handler>
|
||||
<handler event="popupshown" phase="target">
|
||||
this.setAttribute("panelopen", "true");
|
||||
</handler>
|
||||
<handler event="popuphidden" phase="target">
|
||||
this.removeAttribute("panelopen");
|
||||
if (this.getAttribute("animate") != "false") {
|
||||
this.removeAttribute("animate");
|
||||
}
|
||||
</handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
|
|
|
@ -426,6 +426,65 @@ panel[type="arrow"] {
|
|||
-moz-binding: url("chrome://global/content/bindings/popup.xml#arrowpanel");
|
||||
}
|
||||
|
||||
panel[type="arrow"]:not([animate="false"]) {
|
||||
transform: scale(.1);
|
||||
opacity: 0;
|
||||
transition-property: transform, opacity;
|
||||
transition-duration: 0.25s;
|
||||
transition-timing-function: cubic-bezier(.6, 1.0, .65, 1.0), ease;
|
||||
}
|
||||
|
||||
panel[type="arrow"][animate="open"] {
|
||||
transform: none;
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
panel[arrowposition="after_start"] {
|
||||
transform-origin: 20px top;
|
||||
}
|
||||
|
||||
panel[arrowposition="after_end"] {
|
||||
transform-origin: calc(100% - 20px) top;
|
||||
}
|
||||
|
||||
panel[arrowposition="before_start"] {
|
||||
transform-origin: 20px bottom;
|
||||
}
|
||||
|
||||
panel[arrowposition="before_end"] {
|
||||
transform-origin: calc(100% - 20px) bottom;
|
||||
}
|
||||
|
||||
panel[arrowposition="start_before"] {
|
||||
transform-origin: right 20px;
|
||||
}
|
||||
|
||||
panel[arrowposition="start_after"] {
|
||||
transform-origin: right calc(100% - 20px);
|
||||
}
|
||||
|
||||
panel[arrowposition="end_before"] {
|
||||
transform-origin: left 20px;
|
||||
}
|
||||
|
||||
panel[arrowposition="end_after"] {
|
||||
transform-origin: left calc(100% - 20px);
|
||||
}
|
||||
|
||||
panel[arrowposition="after_start"][animate="cancel"],
|
||||
panel[arrowposition="before_end"][animate="cancel"],
|
||||
panel[arrowposition="end_before"][animate="cancel"],
|
||||
panel[arrowposition="start_after"][animate="cancel"] {
|
||||
transform: scale(.1) skew(30deg, 20deg);
|
||||
}
|
||||
|
||||
panel[arrowposition="after_end"][animate="cancel"],
|
||||
panel[arrowposition="before_start"][animate="cancel"],
|
||||
panel[arrowposition="start_before"][animate="cancel"],
|
||||
panel[arrowposition="end_after"][animate="cancel"] {
|
||||
transform: scale(.1) skew(-30deg, -20deg);
|
||||
}
|
||||
|
||||
%ifdef XP_MACOSX
|
||||
.statusbar-resizerpanel {
|
||||
display: none;
|
||||
|
|
|
@ -16,7 +16,6 @@ panel {
|
|||
/* ::::: arrow panel ::::: */
|
||||
|
||||
panel[type="arrow"] {
|
||||
transition: opacity 300ms;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,33 +25,6 @@ panel[titlebar] {
|
|||
panel[type="arrow"] {
|
||||
-moz-appearance: none;
|
||||
background: transparent;
|
||||
transition: opacity 300ms;
|
||||
}
|
||||
|
||||
.panel-arrowcontainer[panelopen] {
|
||||
transition-duration: 200ms, 150ms;
|
||||
transition-property: opacity, transform;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen]) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen])[side="top"] {
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen])[side="bottom"] {
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen])[side="left"] {
|
||||
transform: translateX(-20px);
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen])[side="right"] {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
panel[type="arrow"][side="top"],
|
||||
|
|
|
@ -33,33 +33,6 @@ panel[type="arrow"] {
|
|||
-moz-appearance: none;
|
||||
background: transparent;
|
||||
border: none;
|
||||
transition: opacity 300ms;
|
||||
}
|
||||
|
||||
.panel-arrowcontainer[panelopen] {
|
||||
transition-duration: 200ms, 150ms;
|
||||
transition-property: opacity, transform;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen]) {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen])[side="top"] {
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen])[side="bottom"] {
|
||||
transform: translateY(20px);
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen])[side="left"] {
|
||||
transform: translateX(-20px);
|
||||
}
|
||||
|
||||
.panel-arrowcontainer:not([panelopen])[side="right"] {
|
||||
transform: translateX(20px);
|
||||
}
|
||||
|
||||
panel[type="arrow"][side="top"],
|
||||
|
|
|
@ -1024,7 +1024,7 @@ nsView::RequestWindowClose(nsIWidget* aWidget)
|
|||
mFrame->GetType() == nsGkAtoms::menuPopupFrame) {
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm) {
|
||||
pm->HidePopup(mFrame->GetContent(), false, true, false);
|
||||
pm->HidePopup(mFrame->GetContent(), false, true, false, false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -339,7 +339,7 @@ nsBaseDragService::EndDragSession(bool aDoneDrag)
|
|||
if (mDragPopup) {
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm) {
|
||||
pm->HidePopup(mDragPopup, false, true, false);
|
||||
pm->HidePopup(mDragPopup, false, true, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче