Bug 1941189 - Make vertical pinned tabs container adjustable r=desktop-theme-reviewers,tabbrowser-reviewers,sidebar-reviewers,jsudiaman,nsharpley,sfoster
Differential Revision: https://phabricator.services.mozilla.com/D246484
This commit is contained in:
committed by
kcochrane@mozilla.com
parent
19cb41d4a1
commit
40832e607b
@@ -57,7 +57,7 @@
|
|||||||
# DisplayPortUtils::MaybeCreateDisplayPortInFirstScrollFrameEncountered based
|
# DisplayPortUtils::MaybeCreateDisplayPortInFirstScrollFrameEncountered based
|
||||||
# the current structure that we may want to revisit.
|
# the current structure that we may want to revisit.
|
||||||
<arrowscrollbox id="vertical-pinned-tabs-container" orient="vertical" tabindex="-1"></arrowscrollbox>
|
<arrowscrollbox id="vertical-pinned-tabs-container" orient="vertical" tabindex="-1"></arrowscrollbox>
|
||||||
<html:div id="vertical-pinned-tabs-container-separator"></html:div>
|
<splitter orient="vertical" id="vertical-pinned-tabs-splitter" resizebefore="sibling" resizeafter="none" hidden="true"/>
|
||||||
<arrowscrollbox id="tabbrowser-arrowscrollbox" orient="horizontal" flex="1" clicktoscroll="" scrolledtostart="" scrolledtoend="">
|
<arrowscrollbox id="tabbrowser-arrowscrollbox" orient="horizontal" flex="1" clicktoscroll="" scrolledtostart="" scrolledtoend="">
|
||||||
<tab is="tabbrowser-tab" class="tabbrowser-tab" selected="true" visuallyselected="" fadein=""/>
|
<tab is="tabbrowser-tab" class="tabbrowser-tab" selected="true" visuallyselected="" fadein=""/>
|
||||||
<hbox id="tabbrowser-arrowscrollbox-periphery">
|
<hbox id="tabbrowser-arrowscrollbox-periphery">
|
||||||
|
|||||||
@@ -32,11 +32,20 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||||||
* When sidebar.visibility pref value is "always-show", the toolbar button serves to toggle this property
|
* When sidebar.visibility pref value is "always-show", the toolbar button serves to toggle this property
|
||||||
* @property {boolean} launcherDragActive
|
* @property {boolean} launcherDragActive
|
||||||
* Whether the launcher is currently being dragged.
|
* Whether the launcher is currently being dragged.
|
||||||
|
* @property {boolean} pinnedTabsDragActive
|
||||||
|
* Whether the pinned tabs container is currently being dragged.
|
||||||
* @property {boolean} launcherHoverActive
|
* @property {boolean} launcherHoverActive
|
||||||
* Whether the launcher is currently being hovered.
|
* Whether the launcher is currently being hovered.
|
||||||
* @property {number} launcherWidth
|
* @property {number} launcherWidth
|
||||||
* Current width of the sidebar launcher.
|
* Current width of the sidebar launcher.
|
||||||
* @property {number} expandedLauncherWidth
|
* @property {number} expandedLauncherWidth
|
||||||
|
* Width of the expanded launcher
|
||||||
|
* @property {number} pinnedTabsHeight
|
||||||
|
* Current height of the pinned tabs container
|
||||||
|
* @property {number} expandedPinnedTabsHeight
|
||||||
|
* Height of the pinned tabs container when the sidebar is expanded
|
||||||
|
* @property {number} collapsedPinnedTabsHeight
|
||||||
|
* Height of the pinned tabs container when the sidebar is collapsed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const LAUNCHER_MINIMUM_WIDTH = 100;
|
const LAUNCHER_MINIMUM_WIDTH = 100;
|
||||||
@@ -66,6 +75,7 @@ export class SidebarState {
|
|||||||
launcherHoverActive: false,
|
launcherHoverActive: false,
|
||||||
launcherVisible: false,
|
launcherVisible: false,
|
||||||
panelOpen: false,
|
panelOpen: false,
|
||||||
|
pinnedTabsDragActive: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -122,6 +132,26 @@ export class SidebarState {
|
|||||||
return this.#controller._box;
|
return this.#controller._box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the pinned tabs container element.
|
||||||
|
*
|
||||||
|
* @returns {XULElement}
|
||||||
|
*/
|
||||||
|
get #pinnedTabsContainerEl() {
|
||||||
|
return this.#controller._pinnedTabsContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the items-wrapper part of the pinned tabs container element.
|
||||||
|
*
|
||||||
|
* @returns {XULElement}
|
||||||
|
*/
|
||||||
|
get #pinnedTabsItemsWrapper() {
|
||||||
|
return this.#pinnedTabsContainerEl.shadowRoot.querySelector(
|
||||||
|
"[part=items-wrapper]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get window object from the controller.
|
* Get window object from the controller.
|
||||||
*/
|
*/
|
||||||
@@ -193,6 +223,10 @@ export class SidebarState {
|
|||||||
case "panelOpen":
|
case "panelOpen":
|
||||||
// we need to know if we have a command value before finalizing panelOpen
|
// we need to know if we have a command value before finalizing panelOpen
|
||||||
break;
|
break;
|
||||||
|
case "expandedPinnedTabsHeight":
|
||||||
|
case "collapsedPinnedTabsHeight":
|
||||||
|
this.#updatePinnedTabsHeight();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
this[key] = value;
|
this[key] = value;
|
||||||
}
|
}
|
||||||
@@ -240,6 +274,9 @@ export class SidebarState {
|
|||||||
expandedLauncherWidth: convertToInt(this.expandedLauncherWidth),
|
expandedLauncherWidth: convertToInt(this.expandedLauncherWidth),
|
||||||
launcherExpanded: this.launcherExpanded,
|
launcherExpanded: this.launcherExpanded,
|
||||||
launcherVisible: this.launcherVisible,
|
launcherVisible: this.launcherVisible,
|
||||||
|
pinnedTabsHeight: this.pinnedTabsHeight,
|
||||||
|
expandedPinnedTabsHeight: this.expandedPinnedTabsHeight,
|
||||||
|
collapsedPinnedTabsHeight: this.collapsedPinnedTabsHeight,
|
||||||
};
|
};
|
||||||
// omit any properties with undefined values'
|
// omit any properties with undefined values'
|
||||||
for (let [key, value] of Object.entries(props)) {
|
for (let [key, value] of Object.entries(props)) {
|
||||||
@@ -290,6 +327,24 @@ export class SidebarState {
|
|||||||
this.#launcherContainerEl.style.maxWidth = `calc(${SIDEBAR_MAXIMUM_WIDTH} - ${width}px)`;
|
this.#launcherContainerEl.style.maxWidth = `calc(${SIDEBAR_MAXIMUM_WIDTH} - ${width}px)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get expandedPinnedTabsHeight() {
|
||||||
|
return this.#props.expandedPinnedTabsHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
set expandedPinnedTabsHeight(height) {
|
||||||
|
this.#props.expandedPinnedTabsHeight = height;
|
||||||
|
this.#updatePinnedTabsHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
get collapsedPinnedTabsHeight() {
|
||||||
|
return this.#props.collapsedPinnedTabsHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
set collapsedPinnedTabsHeight(height) {
|
||||||
|
this.#props.collapsedPinnedTabsHeight = height;
|
||||||
|
this.#updatePinnedTabsHeight();
|
||||||
|
}
|
||||||
|
|
||||||
get defaultLauncherVisible() {
|
get defaultLauncherVisible() {
|
||||||
if (!this.revampEnabled) {
|
if (!this.revampEnabled) {
|
||||||
return false;
|
return false;
|
||||||
@@ -390,6 +445,12 @@ export class SidebarState {
|
|||||||
if (!this.launcherDragActive) {
|
if (!this.launcherDragActive) {
|
||||||
this.#updateLauncherWidth();
|
this.#updateLauncherWidth();
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
!this.pinnedTabsDragActive &&
|
||||||
|
this.#controller.sidebarRevampVisibility !== "expand-on-hover"
|
||||||
|
) {
|
||||||
|
this.#updatePinnedTabsHeight();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get launcherDragActive() {
|
get launcherDragActive() {
|
||||||
@@ -429,6 +490,34 @@ export class SidebarState {
|
|||||||
rootEl.toggleAttribute("sidebar-launcher-drag-active", active);
|
rootEl.toggleAttribute("sidebar-launcher-drag-active", active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get pinnedTabsDragActive() {
|
||||||
|
return this.#props.pinnedTabsDragActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
set pinnedTabsDragActive(active) {
|
||||||
|
this.#props.pinnedDragActive = active;
|
||||||
|
|
||||||
|
let itemsWrapperHeight =
|
||||||
|
this.#controllerGlobal.windowUtils.getBoundsWithoutFlushing(
|
||||||
|
this.#pinnedTabsItemsWrapper
|
||||||
|
).height;
|
||||||
|
if (this.pinnedTabsHeight > itemsWrapperHeight) {
|
||||||
|
this.pinnedTabsHeight = itemsWrapperHeight;
|
||||||
|
if (this.#props.launcherExpanded) {
|
||||||
|
this.expandedPinnedTabsHeight = this.pinnedTabsHeight;
|
||||||
|
} else {
|
||||||
|
this.collapsedPinnedTabsHeight = this.pinnedTabsHeight;
|
||||||
|
}
|
||||||
|
} else if (!active) {
|
||||||
|
// Store the user-preferred pinned tabs height.
|
||||||
|
if (this.#props.launcherExpanded) {
|
||||||
|
this.expandedPinnedTabsHeight = this.pinnedTabsHeight;
|
||||||
|
} else {
|
||||||
|
this.collapsedPinnedTabsHeight = this.pinnedTabsHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get launcherHoverActive() {
|
get launcherHoverActive() {
|
||||||
return this.#props.launcherHoverActive;
|
return this.#props.launcherHoverActive;
|
||||||
}
|
}
|
||||||
@@ -478,6 +567,31 @@ export class SidebarState {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get pinnedTabsHeight() {
|
||||||
|
return this.#props.pinnedTabsHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
set pinnedTabsHeight(height) {
|
||||||
|
this.#props.pinnedTabsHeight = height;
|
||||||
|
if (this.launcherExpanded) {
|
||||||
|
this.expandedPinnedTabsHeight = height;
|
||||||
|
} else {
|
||||||
|
this.collapsedPinnedTabsHeight = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When the sidebar is expanded/collapsed, resize the pinned tabs container to the user-preferred
|
||||||
|
* height (if available).
|
||||||
|
*/
|
||||||
|
#updatePinnedTabsHeight() {
|
||||||
|
if (this.launcherExpanded && this.expandedPinnedTabsHeight) {
|
||||||
|
this.#pinnedTabsContainerEl.style.height = `${this.expandedPinnedTabsHeight}px`;
|
||||||
|
} else if (!this.launcherExpanded && this.collapsedPinnedTabsHeight) {
|
||||||
|
this.#pinnedTabsContainerEl.style.height = `${this.collapsedPinnedTabsHeight}px`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#updateTabbrowser(isSidebarShown) {
|
#updateTabbrowser(isSidebarShown) {
|
||||||
this.#controllerGlobal.document
|
this.#controllerGlobal.document
|
||||||
.getElementById("tabbrowser-tabbox")
|
.getElementById("tabbrowser-tabbox")
|
||||||
|
|||||||
@@ -252,6 +252,8 @@ var SidebarController = {
|
|||||||
lastOpenedId: null,
|
lastOpenedId: null,
|
||||||
|
|
||||||
_box: null,
|
_box: null,
|
||||||
|
_pinnedTabsContainer: null,
|
||||||
|
_pinnedTabsItemsWrapper: null,
|
||||||
// The constructor of this label accesses the browser element due to the
|
// The constructor of this label accesses the browser element due to the
|
||||||
// control="sidebar" attribute, so avoid getting this label during startup.
|
// control="sidebar" attribute, so avoid getting this label during startup.
|
||||||
get _title() {
|
get _title() {
|
||||||
@@ -334,6 +336,10 @@ var SidebarController = {
|
|||||||
return this._launcherSplitter.getAttribute("state") === "dragging";
|
return this._launcherSplitter.getAttribute("state") === "dragging";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get isPinnedTabsDragging() {
|
||||||
|
return this._pinnedTabsSplitter.getAttribute("state") === "dragging";
|
||||||
|
},
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
// Initialize global state manager.
|
// Initialize global state manager.
|
||||||
this.SidebarManager;
|
this.SidebarManager;
|
||||||
@@ -343,11 +349,21 @@ var SidebarController = {
|
|||||||
this._state = new this.SidebarState(this);
|
this._state = new this.SidebarState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._pinnedTabsContainer = document.getElementById(
|
||||||
|
"vertical-pinned-tabs-container"
|
||||||
|
);
|
||||||
|
this._pinnedTabsItemsWrapper =
|
||||||
|
this._pinnedTabsContainer.shadowRoot.querySelector(
|
||||||
|
"[part=items-wrapper]"
|
||||||
|
);
|
||||||
this._box = document.getElementById("sidebar-box");
|
this._box = document.getElementById("sidebar-box");
|
||||||
this._splitter = document.getElementById("sidebar-splitter");
|
this._splitter = document.getElementById("sidebar-splitter");
|
||||||
this._launcherSplitter = document.getElementById(
|
this._launcherSplitter = document.getElementById(
|
||||||
"sidebar-launcher-splitter"
|
"sidebar-launcher-splitter"
|
||||||
);
|
);
|
||||||
|
this._pinnedTabsSplitter = document.getElementById(
|
||||||
|
"vertical-pinned-tabs-splitter"
|
||||||
|
);
|
||||||
this._reversePositionButton = document.getElementById(
|
this._reversePositionButton = document.getElementById(
|
||||||
"sidebar-reverse-position"
|
"sidebar-reverse-position"
|
||||||
);
|
);
|
||||||
@@ -416,6 +432,7 @@ var SidebarController = {
|
|||||||
this._splitter.addEventListener("command", this._browserResizeObserver);
|
this._splitter.addEventListener("command", this._browserResizeObserver);
|
||||||
}
|
}
|
||||||
this._enableLauncherDragging();
|
this._enableLauncherDragging();
|
||||||
|
this._enablePinnedTabsSplitterDragging();
|
||||||
|
|
||||||
// Record Glean metrics.
|
// Record Glean metrics.
|
||||||
this.recordVisibilitySetting();
|
this.recordVisibilitySetting();
|
||||||
@@ -436,6 +453,7 @@ var SidebarController = {
|
|||||||
this._switcherListenersAdded = true;
|
this._switcherListenersAdded = true;
|
||||||
}
|
}
|
||||||
this._disableLauncherDragging();
|
this._disableLauncherDragging();
|
||||||
|
this._disablePinnedTabsDragging();
|
||||||
}
|
}
|
||||||
// We need to update the tab strip for vertical tabs during init
|
// We need to update the tab strip for vertical tabs during init
|
||||||
// as there will be no tabstrip-orientation-change event
|
// as there will be no tabstrip-orientation-change event
|
||||||
@@ -514,6 +532,7 @@ var SidebarController = {
|
|||||||
}
|
}
|
||||||
this._splitter.removeEventListener("command", this._browserResizeObserver);
|
this._splitter.removeEventListener("command", this._browserResizeObserver);
|
||||||
this._disableLauncherDragging();
|
this._disableLauncherDragging();
|
||||||
|
this._disablePinnedTabsDragging();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1313,6 +1332,66 @@ var SidebarController = {
|
|||||||
this._launcherSplitter.hidden = false;
|
this._launcherSplitter.hidden = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable the splitter which can be used to resize the pinned tabs container.
|
||||||
|
*/
|
||||||
|
_enablePinnedTabsSplitterDragging() {
|
||||||
|
if (!this._pinnedTabsSplitter.hidden) {
|
||||||
|
// Already showing the launcher splitter with observers connected.
|
||||||
|
// Nothing to do.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._pinnedTabsResizeObserver = new ResizeObserver(([entry]) => {
|
||||||
|
if (this.isPinnedTabsDragging) {
|
||||||
|
this._state.pinnedTabsDragActive = true;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(entry.contentBoxSize[0].blockSize ===
|
||||||
|
this._state.expandedPinnedTabsHeight &&
|
||||||
|
this._state.launcherExpanded) ||
|
||||||
|
(entry.contentBoxSize[0].blockSize ===
|
||||||
|
this._state.collapsedPinnedTabsHeight &&
|
||||||
|
!this._state.launcherExpanded)
|
||||||
|
) {
|
||||||
|
// condition already met, no need to re-update
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._state.pinnedTabsHeight = entry.contentBoxSize[0].blockSize;
|
||||||
|
});
|
||||||
|
|
||||||
|
this._itemsWrapperResizeObserver = new ResizeObserver(async () => {
|
||||||
|
await window.promiseDocumentFlushed(() => {
|
||||||
|
// Adjust pinned tabs container height if needed
|
||||||
|
let itemsWrapperHeight = window.windowUtils.getBoundsWithoutFlushing(
|
||||||
|
this._pinnedTabsItemsWrapper
|
||||||
|
).height;
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
if (this._state.pinnedTabsHeight > itemsWrapperHeight) {
|
||||||
|
this._state.pinnedTabsHeight = itemsWrapperHeight;
|
||||||
|
if (this._state.launcherExpanded) {
|
||||||
|
this._state.expandedPinnedTabsHeight =
|
||||||
|
this._state.pinnedTabsHeight;
|
||||||
|
} else {
|
||||||
|
this._state.collapsedPinnedTabsHeight =
|
||||||
|
this._state.pinnedTabsHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this._pinnedTabsResizeObserver.observe(this._pinnedTabsContainer);
|
||||||
|
this._itemsWrapperResizeObserver.observe(this._pinnedTabsItemsWrapper);
|
||||||
|
|
||||||
|
this._pinnedTabsDropHandler = () =>
|
||||||
|
(this._state.pinnedTabsDragActive = false);
|
||||||
|
this._pinnedTabsSplitter.addEventListener(
|
||||||
|
"command",
|
||||||
|
this._pinnedTabsDropHandler
|
||||||
|
);
|
||||||
|
|
||||||
|
this._pinnedTabsSplitter.hidden = false;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disable the launcher splitter and remove any active observers.
|
* Disable the launcher splitter and remove any active observers.
|
||||||
*/
|
*/
|
||||||
@@ -1328,6 +1407,20 @@ var SidebarController = {
|
|||||||
this._launcherSplitter.hidden = true;
|
this._launcherSplitter.hidden = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the pinned tabs splitter and remove any active observers.
|
||||||
|
*/
|
||||||
|
_disablePinnedTabsDragging() {
|
||||||
|
if (this._pinnedTabsResizeObserver) {
|
||||||
|
this._pinnedTabsResizeObserver.disconnect();
|
||||||
|
}
|
||||||
|
if (this._itemsWrapperResizeObserver) {
|
||||||
|
this._itemsWrapperResizeObserver.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._pinnedTabsSplitter.hidden = true;
|
||||||
|
},
|
||||||
|
|
||||||
_loadSidebarExtension(commandID) {
|
_loadSidebarExtension(commandID) {
|
||||||
let sidebar = this.sidebars.get(commandID);
|
let sidebar = this.sidebars.get(commandID);
|
||||||
if (typeof sidebar?.onload === "function") {
|
if (typeof sidebar?.onload === "function") {
|
||||||
@@ -2020,6 +2113,11 @@ var SidebarController = {
|
|||||||
this.mouseOverTask?.finalize();
|
this.mouseOverTask?.finalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.documentElement.toggleAttribute(
|
||||||
|
"sidebar-expand-on-hover",
|
||||||
|
isEnabled
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2183,6 +2281,11 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||||||
!SidebarController.inSingleTabWindow
|
!SidebarController.inSingleTabWindow
|
||||||
) {
|
) {
|
||||||
SidebarController.recordTabsLayoutSetting(newValue);
|
SidebarController.recordTabsLayoutSetting(newValue);
|
||||||
|
if (newValue) {
|
||||||
|
SidebarController._enablePinnedTabsSplitterDragging();
|
||||||
|
} else {
|
||||||
|
SidebarController._disablePinnedTabsDragging();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ async function dragLauncher(deltaX, shouldExpand) {
|
|||||||
info(`Drag the launcher by ${deltaX} px.`);
|
info(`Drag the launcher by ${deltaX} px.`);
|
||||||
const { sidebarMain, _launcherSplitter: splitter } = SidebarController;
|
const { sidebarMain, _launcherSplitter: splitter } = SidebarController;
|
||||||
EventUtils.synthesizeMouseAtCenter(splitter, { type: "mousedown" });
|
EventUtils.synthesizeMouseAtCenter(splitter, { type: "mousedown" });
|
||||||
await mouseMoveInChunks(splitter, deltaX, 10);
|
await mouseMoveInChunksHorizontal(splitter, deltaX, 10);
|
||||||
EventUtils.synthesizeMouse(splitter, 0, 0, { type: "mouseup" });
|
EventUtils.synthesizeMouse(splitter, 0, 0, { type: "mouseup" });
|
||||||
|
|
||||||
info(`The sidebar should be ${shouldExpand ? "expanded" : "collapsed"}.`);
|
info(`The sidebar should be ${shouldExpand ? "expanded" : "collapsed"}.`);
|
||||||
@@ -44,7 +44,24 @@ async function dragLauncher(deltaX, shouldExpand) {
|
|||||||
AccessibilityUtils.resetEnv();
|
AccessibilityUtils.resetEnv();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function mouseMoveInChunks(el, deltaX, numberOfChunks) {
|
async function dragPinnedTabs(deltaY) {
|
||||||
|
AccessibilityUtils.setEnv({ mustHaveAccessibleRule: false });
|
||||||
|
|
||||||
|
// Let the pinned tabs splitter stabilize before attempting a drag-and-drop.
|
||||||
|
await waitForRepaint();
|
||||||
|
|
||||||
|
info(`Drag the launcher by ${deltaY} px.`);
|
||||||
|
const { _pinnedTabsSplitter: splitter } = SidebarController;
|
||||||
|
EventUtils.synthesizeMouseAtCenter(splitter, { type: "mousedown" });
|
||||||
|
await mouseMoveInChunksVertical(splitter, deltaY, 10);
|
||||||
|
EventUtils.synthesizeMouse(splitter, 0, 0, { type: "mouseup" });
|
||||||
|
|
||||||
|
info(`The pinned tabs container has been expanded.`);
|
||||||
|
|
||||||
|
AccessibilityUtils.resetEnv();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function mouseMoveInChunksHorizontal(el, deltaX, numberOfChunks) {
|
||||||
let chunkIndex = 0;
|
let chunkIndex = 0;
|
||||||
const chunkSize = deltaX / numberOfChunks;
|
const chunkSize = deltaX / numberOfChunks;
|
||||||
const finished = Promise.withResolvers();
|
const finished = Promise.withResolvers();
|
||||||
@@ -64,10 +81,35 @@ async function mouseMoveInChunks(el, deltaX, numberOfChunks) {
|
|||||||
await finished.promise;
|
await finished.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function mouseMoveInChunksVertical(el, deltaY, numberOfChunks) {
|
||||||
|
let chunkIndex = 0;
|
||||||
|
const chunkSize = deltaY / numberOfChunks;
|
||||||
|
const finished = Promise.withResolvers();
|
||||||
|
|
||||||
|
function synthesizeMouseMove() {
|
||||||
|
info(`chunkSize: ${chunkSize}`);
|
||||||
|
// mousemove by a single chunk. Queue up the next chunk if necessary.
|
||||||
|
EventUtils.synthesizeMouse(el, 0, chunkSize, { type: "mousemove" });
|
||||||
|
if (++chunkIndex === numberOfChunks) {
|
||||||
|
finished.resolve();
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(synthesizeMouseMove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await waitForRepaint();
|
||||||
|
requestAnimationFrame(synthesizeMouseMove);
|
||||||
|
await finished.promise;
|
||||||
|
}
|
||||||
|
|
||||||
function getLauncherWidth({ SidebarController } = window) {
|
function getLauncherWidth({ SidebarController } = window) {
|
||||||
return SidebarController.sidebarContainer.style.width;
|
return SidebarController.sidebarContainer.style.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPinnedTabsHeight({ SidebarController } = window) {
|
||||||
|
return SidebarController._pinnedTabsContainer.clientHeight;
|
||||||
|
}
|
||||||
|
|
||||||
add_task(async function test_drag_expand_and_collapse() {
|
add_task(async function test_drag_expand_and_collapse() {
|
||||||
await dragLauncher(200, true);
|
await dragLauncher(200, true);
|
||||||
ok(getLauncherWidth(), "Launcher width set.");
|
ok(getLauncherWidth(), "Launcher width set.");
|
||||||
@@ -159,4 +201,38 @@ add_task(async function test_resize_after_toggling_revamp() {
|
|||||||
parseInt(originalWidth),
|
parseInt(originalWidth),
|
||||||
"Vertical tab strip was resized."
|
"Vertical tab strip was resized."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await dragLauncher(-200, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
add_task(async function test_resize_of_pinned_tabs() {
|
||||||
|
await SidebarController.initializeUIState({
|
||||||
|
launcherExpanded: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
info("Open 10 new tabs using the new tab button.");
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
await BrowserTestUtils.openNewForegroundTab(
|
||||||
|
gBrowser,
|
||||||
|
`data:text/html,<title>${i + 1}</title>`
|
||||||
|
);
|
||||||
|
gBrowser.pinTab(gBrowser.selectedTab);
|
||||||
|
}
|
||||||
|
await SidebarController.waitUntilStable();
|
||||||
|
|
||||||
|
info("Resize the pinned tabs container.");
|
||||||
|
const originalHeight = getPinnedTabsHeight();
|
||||||
|
await dragPinnedTabs(200, true);
|
||||||
|
await SidebarController.waitUntilStable();
|
||||||
|
const newHeight = getPinnedTabsHeight();
|
||||||
|
info(`original: ${originalHeight}, new: ${newHeight}`);
|
||||||
|
Assert.greater(
|
||||||
|
parseInt(newHeight),
|
||||||
|
parseInt(originalHeight),
|
||||||
|
"Pinned tabs container was resized."
|
||||||
|
);
|
||||||
|
|
||||||
|
while (gBrowser.tabs.length > 1) {
|
||||||
|
BrowserTestUtils.removeTab(gBrowser.tabs.at(-1));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -201,9 +201,10 @@ add_task(async function test_expand_on_hover_pinned_tabs() {
|
|||||||
SidebarController.sidebarMain.hasAttribute("expanded"),
|
SidebarController.sidebarMain.hasAttribute("expanded"),
|
||||||
"The launcher is expanded"
|
"The launcher is expanded"
|
||||||
);
|
);
|
||||||
is(
|
Assert.less(
|
||||||
Math.round(parseInt(verticalTabsComputedStyle.width)),
|
Math.round(parseInt(verticalTabsComputedStyle.width)) %
|
||||||
Math.round(parseInt(pinnedTabComputedStyle.width)),
|
Math.round(parseInt(pinnedTabComputedStyle.width)),
|
||||||
|
10,
|
||||||
"The pinned tabs are full width when expanded"
|
"The pinned tabs are full width when expanded"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,8 @@
|
|||||||
--tab-group-color-gray-pale: #F2F9FF;
|
--tab-group-color-gray-pale: #F2F9FF;
|
||||||
|
|
||||||
--tab-group-label-text-dark: var(--color-gray-100);
|
--tab-group-label-text-dark: var(--color-gray-100);
|
||||||
|
/* 5px of padding-block are adding to .tabbrowser-tab */
|
||||||
|
--tab-height-with-margin-padding: calc(5px + var(--tab-min-height) + (2 * var(--tab-block-margin)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stylelint-disable-next-line media-query-no-invalid */
|
/* stylelint-disable-next-line media-query-no-invalid */
|
||||||
@@ -1351,7 +1353,8 @@ tab-group {
|
|||||||
/* Vertical tabs styling */
|
/* Vertical tabs styling */
|
||||||
|
|
||||||
#tabbrowser-arrowscrollbox[orient="vertical"] {
|
#tabbrowser-arrowscrollbox[orient="vertical"] {
|
||||||
min-height: 1px;
|
/* Don't allow resizing below the height of 3 tabs */
|
||||||
|
min-height: calc(3 * var(--tab-height-with-margin-padding));
|
||||||
|
|
||||||
&::part(scrollbutton-up),
|
&::part(scrollbutton-up),
|
||||||
&::part(scrollbutton-down) {
|
&::part(scrollbutton-down) {
|
||||||
@@ -1424,8 +1427,8 @@ tab-group {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#vertical-pinned-tabs-container {
|
#vertical-pinned-tabs-container {
|
||||||
/* Fit slightly more than 5 tabs + padding before overflowing */
|
/* Don't allow resizing below the height of 1 row of pinned tabs */
|
||||||
max-height: calc(5 * var(--tabstrip-min-height) + var(--space-large));
|
min-height: var(--tab-height-with-margin-padding);
|
||||||
|
|
||||||
&:empty {
|
&:empty {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -1473,6 +1476,10 @@ tab-group {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&::part(items-wrapper) {
|
||||||
|
flex: 0 1 0;
|
||||||
|
}
|
||||||
|
|
||||||
:root:not([sidebar-expand-on-hover]) & {
|
:root:not([sidebar-expand-on-hover]) & {
|
||||||
--tab-inline-padding: calc((var(--tab-collapsed-background-width) + 2 *
|
--tab-inline-padding: calc((var(--tab-collapsed-background-width) + 2 *
|
||||||
var(--tab-pinned-margin-inline-expanded) - var(--icon-size-default)) / 2);
|
var(--tab-pinned-margin-inline-expanded) - var(--icon-size-default)) / 2);
|
||||||
@@ -1488,6 +1495,7 @@ tab-group {
|
|||||||
minmax(var(--tab-pinned-min-width-expanded), auto)
|
minmax(var(--tab-pinned-min-width-expanded), auto)
|
||||||
);
|
);
|
||||||
display: grid;
|
display: grid;
|
||||||
|
grid-auto-rows: var(--tab-height-with-margin-padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-label-container {
|
.tab-label-container {
|
||||||
@@ -1524,23 +1532,29 @@ tab-group {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#vertical-pinned-tabs-container-separator {
|
#vertical-pinned-tabs-splitter {
|
||||||
display: block;
|
display: block;
|
||||||
border-bottom: var(--tabstrip-inner-border);
|
border-top: var(--tabstrip-inner-border);
|
||||||
margin-inline: var(--tab-inner-inline-margin);
|
margin-inline: var(--tab-inner-inline-margin);
|
||||||
|
min-height: 2px;
|
||||||
|
|
||||||
#vertical-pinned-tabs-container:empty + & {
|
#vertical-pinned-tabs-container:empty + & {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--focus-outline-color);
|
||||||
|
border-radius: var(--border-radius-medium);
|
||||||
|
}
|
||||||
|
|
||||||
/* stylelint-disable-next-line media-query-no-invalid */
|
/* stylelint-disable-next-line media-query-no-invalid */
|
||||||
@media not -moz-pref("sidebar.visibility", "expand-on-hover") {
|
@media not -moz-pref("sidebar.visibility", "expand-on-hover") {
|
||||||
/* We need these rules to apply at all times when the sidebar.visibility
|
/* We need these rules to apply at all times when the sidebar.visibility
|
||||||
pref is not set to "expand-on-hover" as opposed to when the "sidebar-expand-on-hover" attribute
|
pref is not set to "expand-on-hover" as opposed to when the "sidebar-expand-on-hover" attribute
|
||||||
has not been added to root. There are certain scenarios when that attribute is temporarily
|
has not been added to root. There are certain scenarios when that attribute is temporarily
|
||||||
removed from root such as when toggling the sidebar to expand with the toolbar button. */
|
removed from root such as when toggling the sidebar to expand with the toolbar button. */
|
||||||
#tabbrowser-tabs[expanded] > & {
|
#tabbrowser-tabs[expanded] > & {
|
||||||
display: none;
|
border: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user