mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1815769 - Add optional anchor lookup to PopupNotifications - r=Gijs,adw
Differential Revision: https://phabricator.services.mozilla.com/D169814
This commit is contained in:
parent
9234f5fbb8
commit
4feaf446ef
@ -439,11 +439,28 @@ XPCOMUtils.defineLazyGetter(this, "PopupNotifications", () => {
|
||||
);
|
||||
};
|
||||
|
||||
// Before a Popup is shown, check that its anchor is visible.
|
||||
// If the anchor is not visible, use one of the fallbacks.
|
||||
// If no fallbacks are visible, return null.
|
||||
const getVisibleAnchorElement = anchorElement => {
|
||||
// If the anchor element is present in the Urlbar,
|
||||
// ensure that both the anchor and page URL are visible.
|
||||
gURLBar.maybeHandleRevertFromPopup(anchorElement);
|
||||
if (anchorElement?.checkVisibility()) {
|
||||
return anchorElement;
|
||||
}
|
||||
let fallback = [
|
||||
document.getElementById("identity-icon"),
|
||||
document.getElementById("urlbar-search-button"),
|
||||
];
|
||||
return fallback.find(element => element?.checkVisibility()) ?? null;
|
||||
};
|
||||
|
||||
return new PopupNotifications(
|
||||
gBrowser,
|
||||
document.getElementById("notification-popup"),
|
||||
document.getElementById("notification-popup-box"),
|
||||
{ shouldSuppress }
|
||||
{ shouldSuppress, getVisibleAnchorElement }
|
||||
);
|
||||
} catch (ex) {
|
||||
console.error(ex);
|
||||
|
@ -764,6 +764,16 @@ export class UrlbarInput {
|
||||
}
|
||||
}
|
||||
|
||||
maybeHandleRevertFromPopup(anchorElement) {
|
||||
if (
|
||||
anchorElement?.closest("#urlbar") &&
|
||||
this.window.gBrowser.selectedBrowser.searchTerms
|
||||
) {
|
||||
this.handleRevert(true);
|
||||
// TODO: Bug 1815971, add telemetry.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by inputs that resemble search boxes, but actually hand input off
|
||||
* to the Urlbar. We use these fake inputs on the new tab page and
|
||||
|
@ -212,6 +212,10 @@ Notification.prototype = {
|
||||
* If this function returns true, then all notifications are
|
||||
* suppressed for this window. This state is checked on construction
|
||||
* and when the "anchorVisibilityChange" method is called.
|
||||
* getVisibleAnchorElement(anchorElement):
|
||||
* A function which takes an anchor element as input and should return
|
||||
* either the anchor if it's visible, a fallback anchor element, or if
|
||||
* no fallback exists, a null element.
|
||||
* }
|
||||
*/
|
||||
export function PopupNotifications(tabbrowser, panel, iconBox, options = {}) {
|
||||
@ -228,6 +232,8 @@ export function PopupNotifications(tabbrowser, panel, iconBox, options = {}) {
|
||||
this._shouldSuppress = options.shouldSuppress || (() => false);
|
||||
this._suppress = this._shouldSuppress();
|
||||
|
||||
this._getVisibleAnchorElement = options.getVisibleAnchorElement;
|
||||
|
||||
this.window = tabbrowser.ownerGlobal;
|
||||
this.panel = panel;
|
||||
this.tabbrowser = tabbrowser;
|
||||
@ -1214,48 +1220,27 @@ PopupNotifications.prototype = {
|
||||
if (!notificationsToShow.length) {
|
||||
return;
|
||||
}
|
||||
// Bug 1812232: Interim fix to avoid the Urlbar showing persisted
|
||||
// terms as a Popup is trying to show. This isn't the best solution
|
||||
// since it couples PopupNotifications with browser components, so it
|
||||
// should be refactored (Bug 1815769) via dependency injection.
|
||||
if (this.window.gURLBar && this.tabbrowser.selectedBrowser.searchTerms) {
|
||||
this.window.gURLBar.handleRevert(true);
|
||||
}
|
||||
|
||||
let notificationIds = notificationsToShow.map(n => n.id);
|
||||
|
||||
this._refreshPanel(notificationsToShow);
|
||||
|
||||
function isNullOrHidden(elem) {
|
||||
if (!elem) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let anchorRect = elem.getBoundingClientRect();
|
||||
return anchorRect.width == 0 && anchorRect.height == 0;
|
||||
// The element the PopupNotification should anchor to might not be visible.
|
||||
// Check its visibility using a callback that returns the same anchor
|
||||
// element if its visible, or a fallback option that is visible.
|
||||
// If no fallbacks are visible, it should return null.
|
||||
if (this._getVisibleAnchorElement) {
|
||||
anchorElement = this._getVisibleAnchorElement(anchorElement);
|
||||
}
|
||||
|
||||
// If the anchor element is hidden or null, fall back to the identity icon.
|
||||
if (isNullOrHidden(anchorElement)) {
|
||||
anchorElement = this.window.document.getElementById("identity-icon");
|
||||
|
||||
if (isNullOrHidden(anchorElement)) {
|
||||
anchorElement = this.window.document.getElementById(
|
||||
"urlbar-search-button"
|
||||
);
|
||||
}
|
||||
|
||||
// If the identity and search icons are not available in this window, use
|
||||
// the tab as the anchor. We only ever show notifications for the current
|
||||
// browser, so we can just use the current tab.
|
||||
if (isNullOrHidden(anchorElement)) {
|
||||
anchorElement = this.tabbrowser.selectedTab;
|
||||
|
||||
// In case _getVisibleAnchorElement provided a non-visible element.
|
||||
if (!anchorElement?.checkVisibility()) {
|
||||
// We only ever show notifications for the current browser,
|
||||
// so we can just use the current tab.
|
||||
anchorElement = this.tabbrowser.selectedTab;
|
||||
if (!anchorElement?.checkVisibility()) {
|
||||
// If we're in an entirely chromeless environment, set the anchorElement
|
||||
// to null and let openPopup show the notification at (0,0) later.
|
||||
if (isNullOrHidden(anchorElement)) {
|
||||
anchorElement = null;
|
||||
}
|
||||
anchorElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user