Backed out changeset 58ef1accf6e7 (bug 1908439) for causing mochitest failures @test_tabbrowser.xhtml. CLOSED TREE

This commit is contained in:
Goloman Adrian
2025-03-07 02:42:12 +02:00
parent 224943f63c
commit e5e07cd91e
6 changed files with 92 additions and 195 deletions

View File

@@ -51,7 +51,6 @@
orient="horizontal"
stopwatchid="FX_TAB_CLICK_MS">
<hbox class="tab-drop-indicator" hidden="true"/>
<html:span id="tab-drag-empty-feedback"/>
# If the name (tabbrowser-arrowscrollbox) or structure of this changes
# significantly, there is an optimization in
# DisplayPortUtils::MaybeCreateDisplayPortInFirstScrollFrameEncountered based

View File

@@ -5578,7 +5578,7 @@ var SessionStoreInternal = {
for (let i = 0; i < initialTabs.length; i++) {
tabbrowser.unpinTab(initialTabs[i]);
tabbrowser.moveTabTo(initialTabs[i], endPosition, {
forceUngrouped: true,
forceStandaloneTab: true,
});
}
}

View File

@@ -33,21 +33,6 @@
const DIRECTION_FORWARD = 1;
const DIRECTION_BACKWARD = -1;
/**
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} element
* @returns {boolean}
* `true` if element is a `<tab>`
*/
const isTab = element => !!(element?.tagName == "tab");
/**
* @param {MozTabbrowserTab|MozTextLabel} element
* @returns {boolean}
* `true` if element is the `<label>` in a `<tab-group>`
*/
const isTabGroupLabel = element =>
!!element?.classList?.contains("tab-group-label");
/**
* Updates the User Context UI indicators if the browser is in a non-default context
*/
@@ -834,7 +819,7 @@
this.verticalPinnedTabsContainer.appendChild(aTab)
);
} else {
this.moveTabTo(aTab, this.pinnedTabCount, { forceUngrouped: true });
this.moveTabTo(aTab, this.pinnedTabCount, { forceStandaloneTab: true });
}
aTab.setAttribute("pinned", "true");
this._updateTabBarForPinnedTabs();
@@ -856,7 +841,7 @@
});
} else {
this.moveTabTo(aTab, this.pinnedTabCount - 1, {
forceUngrouped: true,
forceStandaloneTab: true,
});
aTab.removeAttribute("pinned");
}
@@ -5815,38 +5800,30 @@
}
/**
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} aTab
* The tab or tab group to move. Also accepts a tab group label as a
* stand-in for its group.
* @param {MozTabbrowserTab} aTab
* @param {number} aIndex
* @param {object} [options]
* @param {boolean} [options.forceUngrouped=false]
* @param {boolean} [options.forceStandaloneTab=false]
* Force `aTab` to move into position as a standalone tab, overriding
* any possibility of entering a tab group. For example, setting `true`
* ensures that a pinned tab will not accidentally be placed inside of
* a tab group, since pinned tabs are presently not allowed in tab groups.
* @returns {void}
*/
moveTabTo(aTab, aIndex, { forceUngrouped = false } = {}) {
if (isTab(aTab)) {
// Don't allow mixing pinned and unpinned tabs.
if (aTab.pinned) {
aIndex = Math.min(aIndex, this.pinnedTabCount - 1);
} else {
aIndex = Math.max(aIndex, this.pinnedTabCount);
}
if (aTab._tPos == aIndex && !(aTab.group && forceUngrouped)) {
return;
}
moveTabTo(aTab, aIndex, { forceStandaloneTab = false } = {}) {
// Don't allow mixing pinned and unpinned tabs.
if (aTab.pinned) {
aIndex = Math.min(aIndex, this.pinnedTabCount - 1);
} else {
forceUngrouped = true;
if (isTabGroupLabel(aTab)) {
aTab = aTab.group;
}
aIndex = Math.max(aIndex, this.pinnedTabCount);
}
if (aTab._tPos == aIndex && !(aTab.group && forceStandaloneTab)) {
return;
}
this.#handleTabMove(aTab, () => {
let neighbor = this.tabs[aIndex];
if (forceUngrouped && neighbor.group) {
if (forceStandaloneTab && neighbor.group) {
neighbor = neighbor.group;
}
if (neighbor && aIndex > aTab._tPos) {
@@ -5858,7 +5835,7 @@
}
/**
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} tab
* @param {MozTabbrowserTab} tab
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} targetElement
*/
moveTabBefore(tab, targetElement) {
@@ -5866,7 +5843,7 @@
}
/**
* @param {MozTabbrowserTab|MozTabbrowserTabGroup[]} tabs
* @param {MozTabbrowserTab[]} tabs
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} targetElement
*/
moveTabsBefore(tabs, targetElement) {
@@ -5874,7 +5851,7 @@
}
/**
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} tab
* @param {MozTabbrowserTab} tab
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} targetElement
*/
moveTabAfter(tab, targetElement) {
@@ -5882,7 +5859,7 @@
}
/**
* @param {MozTabbrowserTab|MozTabbrowserTabGroup[]} tabs
* @param {MozTabbrowserTab[]} tabs
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} targetElement
*/
moveTabsAfter(tabs, targetElement) {
@@ -5890,27 +5867,17 @@
}
/**
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} tab
* The tab or tab group to move. Also accepts a tab group label as a
* stand-in for its group.
* @param {MozTabbrowserTab} tab
* @param {MozTabbrowserTab|MozTabbrowserTabGroup} targetElement
* @param {boolean} moveBefore
*/
#moveTabNextTo(tab, targetElement, moveBefore = false) {
if (isTabGroupLabel(tab)) {
tab = tab.group;
if (targetElement?.group) {
targetElement = targetElement.group;
}
}
let getContainer = () => {
if (tab.pinned && this.tabContainer.verticalMode) {
return this.tabContainer.verticalPinnedTabsContainer;
}
return this.tabContainer;
};
this.#handleTabMove(tab, () => {
if (moveBefore) {
getContainer().insertBefore(tab, targetElement);
@@ -5955,7 +5922,7 @@
*/
#handleTabMove(aTab, moveActionCallback) {
let wasFocused = document.activeElement == this.selectedTab;
let oldPosition = isTab(aTab) && aTab.elementIndex;
let oldPosition = aTab._tPos;
moveActionCallback();
@@ -5978,11 +5945,12 @@
}
// Pinning/unpinning vertical tabs, and moving tabs into tab groups, both bypass moveTabTo.
// We still want to check whether its worth dispatching an event.
if (isTab(aTab) && oldPosition != aTab.elementIndex) {
let evt = document.createEvent("UIEvents");
evt.initUIEvent("TabMove", true, false, window, oldPosition);
aTab.dispatchEvent(evt);
if (oldPosition == aTab._tPos) {
return;
}
var evt = document.createEvent("UIEvents");
evt.initUIEvent("TabMove", true, false, window, oldPosition);
aTab.dispatchEvent(evt);
}
/**
@@ -6107,11 +6075,11 @@
}
moveTabToStart(aTab = this.selectedTab) {
this.moveTabTo(aTab, 0, { forceUngrouped: true });
this.moveTabTo(aTab, 0, { forceStandaloneTab: true });
}
moveTabToEnd(aTab = this.selectedTab) {
this.moveTabTo(aTab, this.tabs.length - 1, { forceUngrouped: true });
this.moveTabTo(aTab, this.tabs.length - 1, { forceStandaloneTab: true });
}
/**

View File

@@ -57,21 +57,18 @@
this.initializeAttributeInheritance();
this.#labelElement = this.querySelector(".tab-group-label");
// Mirroring MozTabbrowserTab
this.#labelElement.container = gBrowser.tabContainer;
this.#labelElement.group = this;
this.#labelElement.addEventListener("click", this);
this.#labelElement.addEventListener("contextmenu", e => {
e.preventDefault();
gBrowser.tabGroupMenu.openEditModal(this);
return false;
});
this.#updateLabelAriaAttributes();
this.#updateCollapsedAriaAttributes();
this.addEventListener("TabSelect", this);
this.#labelElement.addEventListener("contextmenu", e => {
e.preventDefault();
gBrowser.tabGroupMenu.openEditModal(this);
return false;
});
}
disconnectedCallback() {
@@ -177,12 +174,6 @@
if (!!val == this.collapsed) {
return;
}
if (val) {
for (let tab of this.tabs) {
// Unlock tab sizes.
tab.style.maxWidth = "";
}
}
this.toggleAttribute("collapsed", val);
this.#updateCollapsedAriaAttributes();
const eventName = val ? "TabGroupCollapse" : "TabGroupExpand";
@@ -212,6 +203,7 @@
}
);
this.#labelElement?.setAttribute("aria-label", tabGroupName);
this.#labelElement.group = this;
this.#labelElement?.setAttribute("aria-description", tabGroupDescription);
}

View File

@@ -682,12 +682,8 @@
}
on_dragstart(event) {
if (this._isCustomizing) {
return;
}
var tab = this._getDragTargetTab(event);
if (!tab) {
if (!tab || this._isCustomizing) {
return;
}
@@ -715,36 +711,34 @@
}
let dataTransferOrderedTabs;
if (fromTabList || isTabGroupLabel(tab)) {
// Dragging a group label or an item in the all tabs menu doesn't
// change the currently selected tabs, and it's not possible to select
// multiple tabs from the list, thus handle only the dragged tab in
// this case.
dataTransferOrderedTabs = [tab];
} else {
if (!fromTabList) {
let selectedTabs = gBrowser.selectedTabs;
let otherSelectedTabs = selectedTabs.filter(
selectedTab => selectedTab != tab
);
dataTransferOrderedTabs = [tab].concat(otherSelectedTabs);
} else {
// Dragging an item in the tabs list doesn't change the currently
// selected tabs, and it's not possible to select multiple tabs from
// the list, thus handle only the dragged tab in this case.
dataTransferOrderedTabs = [tab];
}
let dt = event.dataTransfer;
for (let i = 0; i < dataTransferOrderedTabs.length; i++) {
let dtTab = dataTransferOrderedTabs[i];
dt.mozSetDataAt(TAB_DROP_TYPE, dtTab, i);
if (isTab(dtTab)) {
let dtBrowser = dtTab.linkedBrowser;
// We must not set text/x-moz-url or text/plain data here,
// otherwise trying to detach the tab by dropping it on the desktop
// may result in an "internet shortcut"
dt.mozSetDataAt(
"text/x-moz-text-internal",
dtBrowser.currentURI.spec,
i
);
}
dt.mozSetDataAt(TAB_DROP_TYPE, dtTab, i);
let dtBrowser = dtTab.linkedBrowser;
// We must not set text/x-moz-url or text/plain data here,
// otherwise trying to detach the tab by dropping it on the desktop
// may result in an "internet shortcut"
dt.mozSetDataAt(
"text/x-moz-text-internal",
dtBrowser.currentURI.spec,
i
);
}
// Set the cursor to an arrow during tab drags.
@@ -754,20 +748,8 @@
// node to deliver the `dragend` event. See bug 1345473.
dt.addElement(tab);
let expandedTabGroups;
if (tab.multiselected) {
this.#moveTogetherSelectedTabs(tab);
} else if (isTabGroupLabel(tab)) {
expandedTabGroups = gBrowser.tabGroups.filter(
group => !group.collapsed
);
if (expandedTabGroups.length) {
this._lockTabSizing();
this.#keepTabSizeLocked = true;
}
for (let group of expandedTabGroups) {
group.collapsed = true;
}
}
// Create a canvas to which we capture the current tab.
@@ -790,10 +772,8 @@
canvas.height = 90 * scale;
let toDrag = canvas;
let dragImageOffset = -16;
let browser = isTab(tab) && tab.linkedBrowser;
if (isTabGroupLabel(tab)) {
toDrag = document.getElementById("tab-drag-empty-feedback");
} else if (gMultiProcessBrowser) {
let browser = tab.linkedBrowser;
if (gMultiProcessBrowser) {
var context = canvas.getContext("2d");
context.fillStyle = "white";
context.fillRect(0, 0, canvas.width, canvas.height);
@@ -871,7 +851,6 @@
),
fromTabList,
tabGroupCreationColor: gBrowser.tabGroupMenu.nextUnusedColor,
expandedTabGroups,
};
event.stopPropagation();
@@ -918,7 +897,7 @@
let draggedTab = event.dataTransfer.mozGetDataAt(TAB_DROP_TYPE, 0);
if (
(effects == "move" || effects == "copy") &&
document == draggedTab.ownerDocument &&
this == draggedTab.container &&
!draggedTab._dragData.fromTabList
) {
ind.hidden = true;
@@ -1138,16 +1117,12 @@
if (shouldTranslate) {
let translationPromises = [];
for (let item of movingTabs) {
if (isTabGroupLabel(item)) {
// Shift the `.tab-group-label-container` to shift the label element.
item = item.parentElement;
}
for (let tab of movingTabs) {
let translationPromise = new Promise(resolve => {
item.toggleAttribute("tabdrop-samewindow", true);
item.style.transform = `translate(${newTranslateX}px, ${newTranslateY}px)`;
tab.toggleAttribute("tabdrop-samewindow", true);
tab.style.transform = `translate(${newTranslateX}px, ${newTranslateY}px)`;
let postTransitionCleanup = () => {
item.removeAttribute("tabdrop-samewindow");
tab.removeAttribute("tabdrop-samewindow");
resolve();
};
if (gReduceMotion) {
@@ -1156,15 +1131,15 @@
let onTransitionEnd = transitionendEvent => {
if (
transitionendEvent.propertyName != "transform" ||
transitionendEvent.originalTarget != item
transitionendEvent.originalTarget != tab
) {
return;
}
item.removeEventListener("transitionend", onTransitionEnd);
tab.removeEventListener("transitionend", onTransitionEnd);
postTransitionCleanup();
};
item.addEventListener("transitionend", onTransitionEnd);
tab.addEventListener("transitionend", onTransitionEnd);
}
});
translationPromises.push(translationPromise);
@@ -1282,13 +1257,6 @@
}
if (draggedTab) {
if (draggedTab._dragData.expandedTabGroups?.length) {
for (let group of draggedTab._dragData.expandedTabGroups) {
group.collapsed = false;
}
this.#keepTabSizeLocked = true;
this._unlockTabSizing();
}
delete draggedTab._dragData;
}
}
@@ -1893,12 +1861,10 @@
selectedTab._notselectedsinceload = false;
}
#keepTabSizeLocked;
/**
* Try to keep the active tab's close button under the mouse cursor
*/
_lockTabSizing(aClosingTab, aTabWidth) {
_lockTabSizing(aTab, aTabWidth) {
if (this.verticalMode) {
return;
}
@@ -1908,23 +1874,17 @@
return;
}
let numPinned = gBrowser.pinnedTabCount;
let isEndTab = aClosingTab && aClosingTab._tPos > tabs.at(-1)._tPos;
var isEndTab = aTab._tPos > tabs.at(-1)._tPos;
if (!this._tabDefaultMaxWidth) {
this._tabDefaultMaxWidth = parseFloat(
window.getComputedStyle(tabs[numPinned]).maxWidth
window.getComputedStyle(aTab).maxWidth
);
}
this._lastTabClosedByMouse = true;
this._scrollButtonWidth = window.windowUtils.getBoundsWithoutFlushing(
this.arrowScrollbox._scrollButtonDown
).width;
if (aTabWidth === undefined) {
aTabWidth = window.windowUtils.getBoundsWithoutFlushing(
tabs[numPinned]
).width;
}
if (this.overflowing) {
// Don't need to do anything if we're in overflow mode and aren't scrolled
@@ -1935,15 +1895,17 @@
// If the tab has an owner that will become the active tab, the owner will
// be to the left of it, so we actually want the left tab to slide over.
// This can't be done as easily in non-overflow mode, so we don't bother.
if (aClosingTab?.owner) {
if (aTab.owner) {
return;
}
this._expandSpacerBy(aTabWidth);
} /* non-overflow mode */ else {
} else {
// non-overflow mode
// Locking is neither in effect nor needed, so let tabs expand normally.
if (isEndTab && !this._hasTabTempMaxWidth) {
// Locking is neither in effect nor needed, so let tabs expand normally.
return;
}
let numPinned = gBrowser.pinnedTabCount;
// Force tabs to stay the same width, unless we're closing the last tab,
// which case we need to let them expand just enough so that the overall
// tabbar width is the same.
@@ -1993,10 +1955,6 @@
}
_unlockTabSizing() {
if (this.#keepTabSizeLocked) {
return;
}
gBrowser.removeEventListener("mousemove", this);
window.removeEventListener("mouseout", this);
@@ -2385,12 +2343,8 @@
let lastBound = endEdge(lastTab) - lastMovingTabScreen;
translate = Math.min(Math.max(translate, firstBound), lastBound);
for (let item of movingTabs) {
if (isTabGroupLabel(item)) {
// Shift the `.tab-group-label-container` to shift the label element.
item = item.parentElement;
}
item.style.transform = `${translateAxis}(${translate}px)`;
for (let tab of movingTabs) {
tab.style.transform = `${translateAxis}(${translate}px)`;
}
dragData.translatePos = translate;
@@ -2608,7 +2562,7 @@
}
}
if (gBrowser._tabGroupsEnabled && isTab(draggedTab) && !isPinned) {
if (gBrowser._tabGroupsEnabled && !isPinned) {
let dragOverGroupingThreshold = 1 - moveOverThreshold;
// When dragging tab(s) over an ungrouped tab, signal to the user
@@ -2948,10 +2902,7 @@
}
// fall through
case "mousemove":
if (
document.getElementById("tabContextMenu").state != "open" &&
!this.hasAttribute("movingtab")
) {
if (document.getElementById("tabContextMenu").state != "open") {
this._unlockTabSizing();
}
break;
@@ -3076,30 +3027,28 @@
*/
_getDragTargetTab(event, { ignoreTabSides = false } = {}) {
let { target } = event;
while (target) {
if (isTab(target) || isTabGroupLabel(target)) {
break;
}
target = target.parentNode;
if (target.nodeType != Node.ELEMENT_NODE) {
target = target.parentElement;
}
if (target && ignoreTabSides) {
let { width, height } = target.getBoundingClientRect();
let tab = target?.closest("tab");
if (tab && ignoreTabSides) {
let { width, height } = tab.getBoundingClientRect();
if (
event.screenX < target.screenX + width * 0.25 ||
event.screenX > target.screenX + width * 0.75 ||
((event.screenY < target.screenY + height * 0.25 ||
event.screenY > target.screenY + height * 0.75) &&
event.screenX < tab.screenX + width * 0.25 ||
event.screenX > tab.screenX + width * 0.75 ||
((event.screenY < tab.screenY + height * 0.25 ||
event.screenY > tab.screenY + height * 0.75) &&
this.verticalMode)
) {
return null;
}
}
return target;
return tab;
}
_getDropIndex(event) {
let tab = this._getDragTargetTab(event);
if (!isTab(tab)) {
if (!tab) {
return this.allTabs.length;
}
let isBeforeMiddle;
@@ -3131,10 +3080,12 @@
if (isMovingTabs) {
let sourceNode = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
if (
(isTab(sourceNode) || isTabGroupLabel(sourceNode)) &&
XULElement.isInstance(sourceNode) &&
sourceNode.localName == "tab" &&
sourceNode.ownerGlobal.isChromeWindow &&
sourceNode.ownerDocument.documentElement.getAttribute("windowtype") ==
"navigator:browser"
"navigator:browser" &&
sourceNode.ownerGlobal.gBrowser.tabContainer == sourceNode.container
) {
// Do not allow transfering a private tab to a non-private window
// and vice versa.

View File

@@ -218,7 +218,7 @@
display: block;
}
#tabbrowser-tabs[movingtab] &:is(:active, [multiselected]) {
#tabbrowser-tabs[movingtab] &:is([selected], [multiselected]) {
position: relative;
z-index: 2;
pointer-events: none; /* avoid blocking dragover events on scroll buttons */
@@ -838,7 +838,7 @@
display: flex;
}
#tabbrowser-tabs[movingtab] &:is(:active,[multiselected]) {
#tabbrowser-tabs[movingtab] &:is([selected],[multiselected]) {
display: flex;
background-color: light-dark(var(--dragover-tab-group-color), var(--dragover-tab-group-color-invert));
border-radius: 1px;
@@ -901,11 +901,6 @@
}
.tab-group-label-container {
#tabbrowser-tabs[movingtab] &:active {
position: relative;
z-index: 2;
pointer-events: none; /* avoid blocking dragover events on scroll buttons */
}
@media (prefers-reduced-motion: no-preference) {
#tabbrowser-tabs[movingtab] &,
&[multiselected-move-together],
@@ -1002,14 +997,6 @@
}
}
#tab-drag-empty-feedback {
background: rgba(0,0,0,0.01);
width: 1px;
height: 1px;
position: absolute;
pointer-events: none;
}
.tab-group-editor-panel {
--panel-width: 20em;
--panel-padding: var(--space-large);