forked from mirrors/gecko-dev
212 lines
5.3 KiB
JavaScript
212 lines
5.3 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
var { XPCOMUtils } = ChromeUtils.importESModule(
|
|
"resource://gre/modules/XPCOMUtils.sys.mjs"
|
|
);
|
|
|
|
const POPUP_OPTIONS = {
|
|
position: "bottomleft topleft",
|
|
x: 0,
|
|
y: -2,
|
|
};
|
|
|
|
/**
|
|
* Detailed preview card that displays when hovering a tab
|
|
*/
|
|
export default class TabHoverPreviewPanel {
|
|
constructor(panel) {
|
|
this._panel = panel;
|
|
this._win = panel.ownerGlobal;
|
|
this._tab = null;
|
|
this._thumbnailElement = null;
|
|
XPCOMUtils.defineLazyPreferenceGetter(
|
|
this,
|
|
"_prefDisableAutohide",
|
|
"ui.popup.disable_autohide",
|
|
false
|
|
);
|
|
XPCOMUtils.defineLazyPreferenceGetter(
|
|
this,
|
|
"_prefPreviewDelay",
|
|
"ui.tooltip.delay_ms"
|
|
);
|
|
XPCOMUtils.defineLazyPreferenceGetter(
|
|
this,
|
|
"_prefDisplayThumbnail",
|
|
"browser.tabs.cardPreview.showThumbnails",
|
|
false
|
|
);
|
|
XPCOMUtils.defineLazyPreferenceGetter(
|
|
this,
|
|
"_prefShowPidAndActiveness",
|
|
"browser.tabs.tooltipsShowPidAndActiveness",
|
|
false
|
|
);
|
|
this._timer = null;
|
|
}
|
|
|
|
getPrettyURI(uri) {
|
|
try {
|
|
const url = new URL(uri);
|
|
if (url.protocol === "about:") {
|
|
return url.href;
|
|
}
|
|
return `${url.hostname}`.replace(/^w{3}\./, "");
|
|
} catch {
|
|
return uri;
|
|
}
|
|
}
|
|
|
|
_needsThumbnailFor(tab) {
|
|
return !tab.selected;
|
|
}
|
|
|
|
_maybeRequestThumbnail() {
|
|
if (!this._prefDisplayThumbnail) {
|
|
return;
|
|
}
|
|
if (!this._needsThumbnailFor(this._tab)) {
|
|
return;
|
|
}
|
|
let tab = this._tab;
|
|
this._win.tabPreviews.get(tab).then(el => {
|
|
if (this._tab == tab && this._needsThumbnailFor(tab)) {
|
|
this._thumbnailElement = el;
|
|
this._updatePreview();
|
|
}
|
|
});
|
|
}
|
|
|
|
activate(tab) {
|
|
this._tab = tab;
|
|
this._thumbnailElement = null;
|
|
this._maybeRequestThumbnail();
|
|
if (this._panel.state == "open") {
|
|
this._updatePreview();
|
|
}
|
|
if (this._timer) {
|
|
return;
|
|
}
|
|
this._timer = this._win.setTimeout(() => {
|
|
this._timer = null;
|
|
this._panel.openPopup(this._tab, POPUP_OPTIONS);
|
|
}, this._prefPreviewDelay);
|
|
this._win.addEventListener("TabSelect", this);
|
|
this._win.addEventListener("blur", this);
|
|
this._panel.addEventListener("popupshowing", this);
|
|
}
|
|
|
|
deactivate(leavingTab = null) {
|
|
if (leavingTab) {
|
|
if (this._tab != leavingTab) {
|
|
return;
|
|
}
|
|
this._win.requestAnimationFrame(() => {
|
|
if (this._tab == leavingTab) {
|
|
this.deactivate();
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
this._tab = null;
|
|
this._thumbnailElement = null;
|
|
this._panel.removeEventListener("popupshowing", this);
|
|
this._win.removeEventListener("TabSelect", this);
|
|
if (!this._prefDisableAutohide) {
|
|
this._panel.hidePopup();
|
|
}
|
|
if (this._timer) {
|
|
this._win.clearTimeout(this._timer);
|
|
this._timer = null;
|
|
}
|
|
}
|
|
|
|
handleEvent(e) {
|
|
switch (e.type) {
|
|
case "popupshowing":
|
|
this._updatePreview();
|
|
break;
|
|
case "TabSelect":
|
|
if (this._thumbnailElement && !this._needsThumbnailFor(this._tab)) {
|
|
this._thumbnailElement.remove();
|
|
this._thumbnailElement = null;
|
|
}
|
|
break;
|
|
case "blur":
|
|
this.deactivate();
|
|
break;
|
|
}
|
|
}
|
|
|
|
_updatePreview() {
|
|
this._panel.querySelector(".tab-preview-title").textContent =
|
|
this._displayTitle;
|
|
this._panel.querySelector(".tab-preview-uri").textContent =
|
|
this._displayURI;
|
|
|
|
if (this._prefShowPidAndActiveness) {
|
|
this._panel.querySelector(".tab-preview-pid").textContent =
|
|
this._displayPids;
|
|
this._panel.querySelector(".tab-preview-activeness").textContent =
|
|
this._displayActiveness;
|
|
} else {
|
|
this._panel.querySelector(".tab-preview-pid").textContent = "";
|
|
this._panel.querySelector(".tab-preview-activeness").textContent = "";
|
|
}
|
|
|
|
let thumbnailContainer = this._panel.querySelector(
|
|
".tab-preview-thumbnail-container"
|
|
);
|
|
if (thumbnailContainer.firstChild != this._thumbnailElement) {
|
|
thumbnailContainer.replaceChildren();
|
|
if (this._thumbnailElement) {
|
|
thumbnailContainer.appendChild(this._thumbnailElement);
|
|
}
|
|
this._panel.dispatchEvent(
|
|
new CustomEvent("previewThumbnailUpdated", {
|
|
detail: {
|
|
thumbnail: this._thumbnailElement,
|
|
},
|
|
})
|
|
);
|
|
}
|
|
if (this._tab && this._panel.state == "open") {
|
|
this._panel.moveToAnchor(
|
|
this._tab,
|
|
POPUP_OPTIONS.position,
|
|
POPUP_OPTIONS.x,
|
|
POPUP_OPTIONS.y
|
|
);
|
|
}
|
|
}
|
|
|
|
get _displayTitle() {
|
|
if (!this._tab) {
|
|
return "";
|
|
}
|
|
return this._tab.textLabel.textContent;
|
|
}
|
|
|
|
get _displayURI() {
|
|
if (!this._tab) {
|
|
return "";
|
|
}
|
|
return this.getPrettyURI(this._tab.linkedBrowser.currentURI.spec);
|
|
}
|
|
|
|
get _displayPids() {
|
|
const pids = this._win.gBrowser.getTabPids(this._tab);
|
|
if (!pids.length) {
|
|
return "";
|
|
}
|
|
|
|
let pidLabel = pids.length > 1 ? "pids" : "pid";
|
|
return `${pidLabel}: ${pids.join(", ")}`;
|
|
}
|
|
|
|
get _displayActiveness() {
|
|
return this._tab.linkedBrowser.docShellIsActive ? "[A]" : "";
|
|
}
|
|
}
|