Bug 1116865, add an attribute to popups to allow them to not rollup when clicking on the anchor, this is used for the new search field, r=neil, felipe

This commit is contained in:
Neil Deakin 2015-02-02 15:53:53 -05:00
parent 11cfd64eba
commit ffec61253c
3 changed files with 49 additions and 26 deletions

View File

@ -911,7 +911,7 @@
<body><![CDATA[
var popup = this.popup;
if (!popup.mPopupOpen) {
// Initially the panel used for the searchbar (PopupAutoComplete
// Initially the panel used for the searchbar (PopupSearchAutoComplete
// in browser.xul) is hidden to avoid impacting startup / new
// window performance. The base binding's openPopup would normally
// call the overriden openAutocompletePopup in urlbarBindings.xml's
@ -920,6 +920,11 @@
// ourselves.
popup.hidden = false;
// Don't roll up on mouse click in the anchor for the search UI.
if (popup.id == "PopupSearchAutoComplete") {
popup.setAttribute("norolluponanchor", "true");
}
popup.mInput = this;
popup.view = this.controller.QueryInterface(Components.interfaces.nsITreeView);
popup.invalidate();

View File

@ -492,7 +492,6 @@ GK_ATOM(itemref, "itemref")
GK_ATOM(itemscope, "itemscope")
GK_ATOM(itemtype, "itemtype")
GK_ATOM(kbd, "kbd")
GK_ATOM(noautofocus, "noautofocus")
GK_ATOM(keepcurrentinview, "keepcurrentinview")
GK_ATOM(keepobjectsalive, "keepobjectsalive")
GK_ATOM(key, "key")
@ -632,7 +631,9 @@ GK_ATOM(_new, "new")
GK_ATOM(newline, "newline")
GK_ATOM(nextBidi, "NextBidi")
GK_ATOM(no, "no")
GK_ATOM(noautofocus, "noautofocus")
GK_ATOM(noautohide, "noautohide")
GK_ATOM(norolluponanchor, "norolluponanchor")
GK_ATOM(nobr, "nobr")
GK_ATOM(node, "node")
GK_ATOM(nodefaultsrc, "nodefaultsrc")

View File

@ -205,10 +205,19 @@ nsXULPopupManager::Rollup(uint32_t aCount, bool aFlush,
ConsumeOutsideClicksResult consumeResult = item->Frame()->ConsumeOutsideClicks();
consume = (consumeResult == ConsumeOutsideClicks_True);
// If ConsumeOutsideClicks_ParentOnly was returned, then only consume the
// click is it was over the anchor. This way, clicking on a menu doesn't
bool rollup = true;
// If norolluponanchor is true, then don't rollup when clicking the anchor.
// This would be used to allow adjusting the caret position in an
// autocomplete field without hiding the popup for example.
bool noRollupOnAnchor = (!consume && pos &&
item->Frame()->GetContent()->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::norolluponanchor, nsGkAtoms::_true, eCaseMatters));
// When ConsumeOutsideClicks_ParentOnly is used, always consume the click
// when the click was over the anchor. This way, clicking on a menu doesn't
// reopen the menu.
if (consumeResult == ConsumeOutsideClicks_ParentOnly && pos) {
if ((consumeResult == ConsumeOutsideClicks_ParentOnly || noRollupOnAnchor) && pos) {
nsCOMPtr<nsIContent> anchor = item->Frame()->GetAnchor();
// Check if the anchor has indicated another node to use for checking
@ -234,34 +243,42 @@ nsXULPopupManager::Rollup(uint32_t aCount, bool aFlush,
// event will get consumed, so here only a quick coordinates check is
// done rather than a slower complete check of what is at that location.
if (anchor->GetPrimaryFrame()->GetScreenRect().Contains(*pos)) {
consume = true;
if (consumeResult == ConsumeOutsideClicks_ParentOnly) {
consume = true;
}
if (noRollupOnAnchor) {
rollup = false;
}
}
}
}
// if a number of popups to close has been specified, determine the last
// popup to close
nsIContent* lastPopup = nullptr;
if (aCount != UINT32_MAX) {
nsMenuChainItem* last = item;
while (--aCount && last->GetParent()) {
last = last->GetParent();
if (rollup) {
// if a number of popups to close has been specified, determine the last
// popup to close
nsIContent* lastPopup = nullptr;
if (aCount != UINT32_MAX) {
nsMenuChainItem* last = item;
while (--aCount && last->GetParent()) {
last = last->GetParent();
}
if (last) {
lastPopup = last->Content();
}
}
if (last) {
lastPopup = last->Content();
nsPresContext* presContext = item->Frame()->PresContext();
nsRefPtr<nsViewManager> viewManager = presContext->PresShell()->GetViewManager();
HidePopup(item->Content(), true, true, false, true, lastPopup);
if (aFlush) {
// The popup's visibility doesn't update until the minimize animation has
// finished, so call UpdateWidgetGeometry to update it right away.
viewManager->UpdateWidgetGeometry();
}
}
nsPresContext* presContext = item->Frame()->PresContext();
nsRefPtr<nsViewManager> viewManager = presContext->PresShell()->GetViewManager();
HidePopup(item->Content(), true, true, false, true, lastPopup);
if (aFlush) {
// The popup's visibility doesn't update until the minimize animation has
// finished, so call UpdateWidgetGeometry to update it right away.
viewManager->UpdateWidgetGeometry();
}
}
return consume;