Only flash sidebar when mouse leaves the browser, refactor flashSidebar

This commit is contained in:
brahim 2024-09-21 17:49:57 +02:00
parent b84a9418c2
commit be25636bc6

View file

@ -1,5 +1,5 @@
var gZenCompactModeManager = { var gZenCompactModeManager = {
_flashSidebarTimeout: null, _flashTimeouts: {},
init() { init() {
Services.prefs.addObserver('zen.view.compact', this._updateEvent.bind(this)); Services.prefs.addObserver('zen.view.compact', this._updateEvent.bind(this));
@ -8,6 +8,7 @@ var gZenCompactModeManager = {
gZenUIManager.addPopupTrackingAttribute(this.sidebar); gZenUIManager.addPopupTrackingAttribute(this.sidebar);
gZenUIManager.addPopupTrackingAttribute(document.getElementById('zen-appcontent-navbar-container')); gZenUIManager.addPopupTrackingAttribute(document.getElementById('zen-appcontent-navbar-container'));
Services.prefs.addObserver('zen.tabs.vertical.right-side', this._updateSidebarIsOnRight.bind(this));
this.addMouseActions(); this.addMouseActions();
}, },
@ -19,6 +20,13 @@ var gZenCompactModeManager = {
Services.prefs.setBoolPref('zen.view.compact', value); Services.prefs.setBoolPref('zen.view.compact', value);
}, },
get sidebarIsOnRight() {
if (this._sidebarIsOnRight) {
return this._sidebarIsOnRight;
}
return Services.prefs.getBoolPref('zen.tabs.vertical.right-side');
},
get sidebar() { get sidebar() {
if (!this._sidebar) { if (!this._sidebar) {
this._sidebar= document.getElementById('navigator-toolbox'); this._sidebar= document.getElementById('navigator-toolbox');
@ -38,6 +46,10 @@ var gZenCompactModeManager = {
this._flashSidebarDuration = Services.prefs.getIntPref('zen.view.compact.toolbar-flash-popup.duration'); this._flashSidebarDuration = Services.prefs.getIntPref('zen.view.compact.toolbar-flash-popup.duration');
}, },
_updateSidebarIsOnRight() {
this._sidebarIsOnRight = Services.prefs.getBoolPref('zen.tabs.vertical.right-side');
},
toggleSidebar() { toggleSidebar() {
this.sidebar.toggleAttribute('zen-user-show'); this.sidebar.toggleAttribute('zen-user-show');
}, },
@ -58,47 +70,100 @@ var gZenCompactModeManager = {
get hoverableElements() { get hoverableElements() {
return [ return [
this.sidebar, {
document.getElementById('zen-appcontent-navbar-container'), element: this.sidebar,
getScreenEdge: () => this.sidebarIsOnRight ? "right" : "left",
},
{
element: document.getElementById('zen-appcontent-navbar-container'),
getScreenEdge: () => "top",
}
]; ];
}, },
flashSidebar(element = null, duration = null) { flashSidebar(duration = this.flashSidebarDuration) {
if (!element) {
element = this.sidebar;
}
if (!duration) {
duration = this.flashSidebarDuration;
}
let tabPanels = document.getElementById('tabbrowser-tabpanels'); let tabPanels = document.getElementById('tabbrowser-tabpanels');
if (element.matches(':hover') || tabPanels.matches("[zen-split-view='true']")) { if (!tabPanels.matches("[zen-split-view='true']")) {
this.flashElement(this.sidebar, duration, this.sidebar.id);
}
},
flashElement(element, duration, id, attrName = 'flash-popup') {
if (element.matches(':hover')) {
return; return;
} }
if (this._flashSidebarTimeout) { if (this._flashTimeouts[id]) {
clearTimeout(this._flashSidebarTimeout); clearTimeout(this._flashTimeouts[id]);
} else { } else {
window.requestAnimationFrame(() => element.setAttribute('flash-popup', '')); requestAnimationFrame(() => element.setAttribute(attrName, ''));
} }
this._flashSidebarTimeout = setTimeout(() => { this._flashTimeouts[id] = setTimeout(() => {
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
element.removeAttribute('flash-popup'); element.removeAttribute(attrName);
this._flashSidebarTimeout = null; this._flashTimeouts[id] = null;
}); });
}, duration); }, duration);
}, },
clearFlashTimeout(id) {
clearTimeout(this._flashTimeouts[id]);
this._flashTimeouts[id] = null;
},
addMouseActions() { addMouseActions() {
for (let i = 0; i < this.hoverableElements.length; i++) { for (let i = 0; i < this.hoverableElements.length; i++) {
this.hoverableElements[i].addEventListener('mouseenter', (event) => { const target = this.hoverableElements[i].element;
let target = this.hoverableElements[i]; target.addEventListener('mouseenter', (event) => {
target.setAttribute('zen-user-hover', 'true'); target.setAttribute('zen-user-hover', 'true');
}); });
this.hoverableElements[i].addEventListener('mouseleave', (event) => { if (this.hoverableElements[i].keepHoverDuration) {
let target = this.hoverableElements[i]; target.addEventListener('mouseleave', (event) => {
this.flashSidebar(target, this.hideAfterHoverDuration); this.flashSidebar(target, keepHoverDuration, target.id, 'hover-timeout');
}); });
} }
}
document.body.addEventListener('mouseleave', (event) => {
for (let i = 0; i < this.hoverableElements.length; i++) {
const target = this.hoverableElements[i].element;
const edge = this.hoverableElements[i].getScreenEdge();
if (!edge) return;
const orient = (edge === "left" || edge === "right" ? "vertical" : "horizontal");
if (
this._getNearestEdge(document.body, event.pageX, event.pageY) === edge
&& this._positionIsAligned(orient, target, event.pageX, event.pageY, 7)
) {
this.flashElement(target, this.hideAfterHoverDuration, target.id);
document.addEventListener('mousemove', () => {
target.removeAttribute('flash-popup');
this.clearFlashTimeout(target.id);
}, {once: true});
}
}
});
},
_getNearestEdge(element, posX, posY) {
const targetBox = element.getBoundingClientRect();
let smallestDistance = Infinity;
let closestEdge = "";
for (let edge of ["top", "bottom", "left", "right"]) {
const onXAxis = edge === "left" || edge === "right";
const distance = Math.abs( (onXAxis ? posX : posY) - targetBox[edge]);
if (smallestDistance > distance) {
smallestDistance = distance;
closestEdge = edge;
}
}
return closestEdge;
},
_positionIsAligned(axis = "x", element, x, y, error = 0) {
const bBox = element.getBoundingClientRect();
if (axis === "x") return bBox.top - error < y && y < bBox.bottom + error;
else return bBox.left - error < x && x < bBox.right + error;
}, },
toggleToolbar() { toggleToolbar() {