зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1899346 - Move CUI widgets out of the horizontal tabstrip when in vertical tabs mode. r=sidebar-reviewers,mconley,sclements,webdriver-reviewers,whimboo,tabbrowser-reviewers
* Ensure tabstrip widgets are temporarily removeable at browser init so the CUI placements are correctly applied * Shuffle placements during initialization to build the correct toolbars for the verticalTabs pref value * Notify on the 'tabstrip-orientation-change' topic when the verticalTabs pref changes and CUI placements have been updated * Add tests for switching tabstrip orientation, and for initializing in verticalTabs mode Differential Revision: https://phabricator.services.mozilla.com/D217161
This commit is contained in:
Родитель
21b890d440
Коммит
f96c44d7b0
|
@ -143,6 +143,18 @@ var gBrowserInit = {
|
|||
gNavToolbox.palette = document.getElementById(
|
||||
"BrowserToolbarPalette"
|
||||
).content;
|
||||
|
||||
// We don't want these normally non-removable elements to get put back into the
|
||||
// tabstrip if we're initializing with vertical tabs
|
||||
let nonRemovables = [
|
||||
gBrowser.tabContainer,
|
||||
document.getElementById("alltabs-button"),
|
||||
];
|
||||
for (let elem of nonRemovables) {
|
||||
elem.setAttribute("removable", "true");
|
||||
// tell CUI to ignore this element when it builds the toolbar areas
|
||||
elem.setAttribute("skipintoolbarset", "true");
|
||||
}
|
||||
for (let area of CustomizableUI.areas) {
|
||||
let type = CustomizableUI.getAreaType(area);
|
||||
if (type == CustomizableUI.TYPE_TOOLBAR) {
|
||||
|
@ -150,6 +162,11 @@ var gBrowserInit = {
|
|||
CustomizableUI.registerToolbarNode(node);
|
||||
}
|
||||
}
|
||||
for (let elem of nonRemovables) {
|
||||
elem.setAttribute("removable", "false");
|
||||
elem.removeAttribute("skipintoolbarset");
|
||||
}
|
||||
|
||||
BrowserSearch.initPlaceHolder();
|
||||
|
||||
// Hack to ensure that the various initial pages favicon is loaded
|
||||
|
|
|
@ -30,6 +30,10 @@ const kDefaultThemeID = "default-theme@mozilla.org";
|
|||
const kSpecialWidgetPfx = "customizableui-special-";
|
||||
|
||||
const kPrefCustomizationState = "browser.uiCustomization.state";
|
||||
const kPrefCustomizationHorizontalTabstrip =
|
||||
"browser.uiCustomization.horizontalTabstrip";
|
||||
const kPrefCustomizationHorizontalTabsBackup =
|
||||
"browser.uiCustomization.horizontalTabsBackup";
|
||||
const kPrefCustomizationAutoAdd = "browser.uiCustomization.autoAdd";
|
||||
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
|
||||
const kPrefDrawInTitlebar = "browser.tabs.inTitlebar";
|
||||
|
@ -175,6 +179,12 @@ var gUIStateBeforeReset = {
|
|||
autoTouchMode: null,
|
||||
};
|
||||
|
||||
/*
|
||||
* The current tab orientation: initially null until initialization,
|
||||
* true for vertical, false for horizontal
|
||||
*/
|
||||
var gCurrentVerticalTabs = null;
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"gDebuggingEnabled",
|
||||
|
@ -232,6 +242,26 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||
}
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"verticalTabsPref",
|
||||
"sidebar.verticalTabs",
|
||||
false,
|
||||
(pref, oldVal, newVal) => {
|
||||
lazy.log.debug(
|
||||
`sidebar.verticalTabs change handler, calling updateTabStripOrientation with value: ${newVal}, gCurrentVerticalTabs: ${gCurrentVerticalTabs}`
|
||||
);
|
||||
CustomizableUIInternal.updateTabStripOrientation();
|
||||
}
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
"horizontalPlacementsPref",
|
||||
kPrefCustomizationHorizontalTabstrip,
|
||||
""
|
||||
);
|
||||
|
||||
ChromeUtils.defineLazyGetter(lazy, "log", () => {
|
||||
let { ConsoleAPI } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/Console.sys.mjs"
|
||||
|
@ -306,6 +336,11 @@ var CustomizableUIInternal = {
|
|||
type: CustomizableUI.TYPE_TOOLBAR,
|
||||
overflowable: true,
|
||||
defaultPlacements: navbarPlacements,
|
||||
verticalTabsDefaultPlacements: [
|
||||
"firefox-view-button",
|
||||
"new-tab-button",
|
||||
"alltabs-button",
|
||||
],
|
||||
defaultCollapsed: false,
|
||||
},
|
||||
true
|
||||
|
@ -333,10 +368,23 @@ var CustomizableUIInternal = {
|
|||
"new-tab-button",
|
||||
"alltabs-button",
|
||||
],
|
||||
verticalTabsDefaultPlacements: [],
|
||||
defaultCollapsed: null,
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
this.registerArea(
|
||||
CustomizableUI.AREA_VERTICAL_TABSTRIP,
|
||||
{
|
||||
type: "toolbar",
|
||||
defaultPlacements: [],
|
||||
verticalTabsDefaultPlacements: ["tabbrowser-tabs"],
|
||||
defaultCollapsed: null,
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
this.registerArea(
|
||||
CustomizableUI.AREA_BOOKMARKS,
|
||||
{
|
||||
|
@ -346,12 +394,20 @@ var CustomizableUIInternal = {
|
|||
},
|
||||
true
|
||||
);
|
||||
lazy.log.debug(`All the areas registered: ${[...gAreas.keys()]}`);
|
||||
|
||||
// At initialization, if we find vertical tabs enabled but not sidebar.revamp
|
||||
// we'll enable revamp rather than disable vertical tabs.
|
||||
this.reconcileSidebarPrefs(kPrefSidebarVerticalTabsEnabled);
|
||||
|
||||
this.initializeForTabsOrientation(CustomizableUI.verticalTabsEnabled);
|
||||
|
||||
SearchWidgetTracker.init();
|
||||
|
||||
Services.obs.addObserver(this, "browser-set-toolbar-visibility");
|
||||
|
||||
Services.prefs.addObserver(kPrefSidebarVerticalTabsEnabled, this);
|
||||
Services.prefs.addObserver(kPrefSidebarRevampEnabled, this);
|
||||
},
|
||||
|
||||
onEnabled(addon) {
|
||||
|
@ -811,7 +867,17 @@ var CustomizableUIInternal = {
|
|||
let futurePlacedWidgets = gFuturePlacements.get(aArea);
|
||||
let savedPlacements =
|
||||
gSavedState && gSavedState.placements && gSavedState.placements[aArea];
|
||||
let defaultPlacements = gAreas.get(aArea).get("defaultPlacements");
|
||||
let defaultPlacements;
|
||||
if (
|
||||
CustomizableUI.verticalTabsEnabled &&
|
||||
gAreas.get(aArea).has("verticalTabsDefaultPlacements")
|
||||
) {
|
||||
defaultPlacements = gAreas
|
||||
.get(aArea)
|
||||
.get("verticalTabsDefaultPlacements");
|
||||
} else {
|
||||
defaultPlacements = gAreas.get(aArea).get("defaultPlacements");
|
||||
}
|
||||
if (
|
||||
!savedPlacements ||
|
||||
!savedPlacements.length ||
|
||||
|
@ -982,6 +1048,9 @@ var CustomizableUIInternal = {
|
|||
props.get("type") == CustomizableUI.TYPE_TOOLBAR &&
|
||||
!gPlacements.has(aName)
|
||||
) {
|
||||
lazy.log.debug(
|
||||
`registerArea ${aName}, no gPlacements yet, nothing to restore`
|
||||
);
|
||||
// Guarantee this area exists in gFuturePlacements, to avoid checking it in
|
||||
// various places elsewhere.
|
||||
if (!gFuturePlacements.has(aName)) {
|
||||
|
@ -1121,6 +1190,9 @@ var CustomizableUIInternal = {
|
|||
this.getCustomizationTarget(aToolbar)
|
||||
);
|
||||
} finally {
|
||||
lazy.log.debug(
|
||||
`registerToolbarNode for ${area}, tabstripAreasReady? ${this.tabstripAreasReady}`
|
||||
);
|
||||
this.endBatchUpdate();
|
||||
}
|
||||
},
|
||||
|
@ -1798,6 +1870,10 @@ var CustomizableUIInternal = {
|
|||
},
|
||||
|
||||
isSpecialWidget(aId) {
|
||||
if (aId === null) {
|
||||
lazy.log.debug("isSpecialWidget was passed null");
|
||||
return false;
|
||||
}
|
||||
aId = this._getSpecialIdForNode(aId);
|
||||
return (
|
||||
aId.startsWith(kSpecialWidgetPfx) ||
|
||||
|
@ -2647,6 +2723,22 @@ var CustomizableUIInternal = {
|
|||
);
|
||||
},
|
||||
|
||||
getSavedHorizontalSnapshotState() {
|
||||
let state = null;
|
||||
let prefValue = lazy.horizontalPlacementsPref;
|
||||
if (prefValue) {
|
||||
try {
|
||||
state = JSON.parse(prefValue);
|
||||
} catch (e) {
|
||||
lazy.log.warn(
|
||||
`Failed to parse value of ${kPrefCustomizationHorizontalTabstrip}`,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
return state;
|
||||
},
|
||||
|
||||
// Note that this does not populate gPlacements, which is done lazily.
|
||||
// The panel area is an exception here.
|
||||
loadSavedState() {
|
||||
|
@ -2714,6 +2806,16 @@ var CustomizableUIInternal = {
|
|||
if (!restored) {
|
||||
lazy.log.debug("Restoring " + aArea + " from default state");
|
||||
let defaults = gAreas.get(aArea).get("defaultPlacements");
|
||||
if (
|
||||
CustomizableUI.verticalTabsEnabled &&
|
||||
gAreas.get(aArea).has("verticalTabsDefaultPlacements")
|
||||
) {
|
||||
lazy.log.debug(
|
||||
"Using verticalTabsDefaultPlacements to restore " + aArea
|
||||
);
|
||||
defaults = gAreas.get(aArea).get("verticalTabsDefaultPlacements");
|
||||
}
|
||||
|
||||
if (defaults) {
|
||||
for (let id of defaults) {
|
||||
this.addWidgetToArea(id, aArea, null, true);
|
||||
|
@ -2749,31 +2851,115 @@ var CustomizableUIInternal = {
|
|||
}
|
||||
},
|
||||
|
||||
restoreSavedHorizontalTabStripState(
|
||||
savedPlacements = this.getSavedHorizontalSnapshotState(),
|
||||
isInitializing = false
|
||||
) {
|
||||
const tabstripAreaId = CustomizableUI.AREA_TABSTRIP;
|
||||
lazy.log.debug(
|
||||
`restoreSavedHorizontalTabStripState, ${kPrefCustomizationHorizontalTabstrip} contained:`,
|
||||
savedPlacements
|
||||
);
|
||||
// If there's no saved state, or it doesn't pass the sniff test, use
|
||||
// default placements instead
|
||||
if (
|
||||
!(
|
||||
Array.isArray(savedPlacements) &&
|
||||
savedPlacements.includes("tabbrowser-tabs")
|
||||
)
|
||||
) {
|
||||
savedPlacements = gAreas.get(tabstripAreaId).get("defaultPlacements");
|
||||
lazy.log.debug(`Using defaultPlacements for ${tabstripAreaId}`);
|
||||
}
|
||||
|
||||
lazy.log.debug(
|
||||
`Replacing existing placements: ${gPlacements.get(
|
||||
tabstripAreaId
|
||||
)}, with ${savedPlacements}.`
|
||||
);
|
||||
|
||||
// Restore the tabstrip to either saved or default placements
|
||||
this.beginBatchUpdate();
|
||||
for (let [index, widgetId] of savedPlacements.entries()) {
|
||||
this.addWidgetToArea(widgetId, tabstripAreaId, index, isInitializing);
|
||||
}
|
||||
|
||||
// Wipe the pref now that state is restored
|
||||
Services.prefs.clearUserPref(kPrefCustomizationHorizontalTabstrip);
|
||||
|
||||
// The vertical tabstrip area is supposed to be empty when we switch back to horizontal
|
||||
if (gPlacements.get(CustomizableUI.AREA_VERTICAL_TABSTRIP)?.length) {
|
||||
lazy.log.warn(
|
||||
`Widgets remain in ${CustomizableUI.AREA_VERTICAL_TABSTRIP}:`,
|
||||
gPlacements.get(CustomizableUI.AREA_VERTICAL_TABSTRIP)
|
||||
);
|
||||
}
|
||||
|
||||
this.endBatchUpdate();
|
||||
},
|
||||
|
||||
saveHorizontalTabStripState(placements = []) {
|
||||
if (!placements.length) {
|
||||
placements = this.getAreaPlacementsForSaving(
|
||||
CustomizableUI.AREA_TABSTRIP
|
||||
);
|
||||
}
|
||||
let serialized = JSON.stringify(placements, this.serializerHelper);
|
||||
lazy.log.debug("Saving horizontal tabstrip state.", serialized);
|
||||
Services.prefs.setCharPref(
|
||||
kPrefCustomizationHorizontalTabstrip,
|
||||
serialized
|
||||
);
|
||||
},
|
||||
|
||||
getAreaPlacementsForSaving(area) {
|
||||
// An early call to saveState can occur before all the lazy-area building is complete
|
||||
let placements;
|
||||
if (this.isAreaLazy(area) && gFuturePlacements.has(area)) {
|
||||
placements = [...gFuturePlacements.get(area)];
|
||||
} else if (gPlacements.has(area)) {
|
||||
placements = gPlacements.get(area);
|
||||
}
|
||||
|
||||
// Merge in previously saved areas if not present in gPlacements/gFuturePlacements.
|
||||
// This way, state is still persisted for e.g. temporarily disabled
|
||||
// add-ons - see bug 989338.
|
||||
if (!placements && gSavedState && gSavedState.placements?.[area]) {
|
||||
placements = gSavedState.placements[area];
|
||||
}
|
||||
lazy.log.debug(
|
||||
`getAreaPlacementsForSaving for area: ${area}, gPlacements for area: ${gPlacements.get(
|
||||
area
|
||||
)}, returning: ${placements}`
|
||||
);
|
||||
return placements;
|
||||
},
|
||||
|
||||
saveState() {
|
||||
if (gInBatchStack || !gDirty) {
|
||||
return;
|
||||
}
|
||||
// Clone because we want to modify this map:
|
||||
let placements = new Map();
|
||||
// Because of Bug 989338 and the risk of having area ids that aren't yet registered,
|
||||
// we collect the areas from both gPlacements and gSavedState rather than gAreas.
|
||||
let allAreaIds = new Set([...gPlacements.keys()]);
|
||||
if (gSavedState?.placements) {
|
||||
for (let area of Object.keys(gSavedState.placements)) {
|
||||
allAreaIds.add(area);
|
||||
}
|
||||
}
|
||||
for (let area of allAreaIds) {
|
||||
placements.set(area, this.getAreaPlacementsForSaving(area));
|
||||
}
|
||||
let state = {
|
||||
placements: new Map(gPlacements),
|
||||
placements,
|
||||
seen: gSeenWidgets,
|
||||
dirtyAreaCache: gDirtyAreaCache,
|
||||
currentVersion: kVersion,
|
||||
newElementCount: gNewElementCount,
|
||||
};
|
||||
|
||||
// Merge in previously saved areas if not present in gPlacements.
|
||||
// This way, state is still persisted for e.g. temporarily disabled
|
||||
// add-ons - see bug 989338.
|
||||
if (gSavedState && gSavedState.placements) {
|
||||
for (let area of Object.keys(gSavedState.placements)) {
|
||||
if (!state.placements.has(area)) {
|
||||
let placements = gSavedState.placements[area];
|
||||
state.placements.set(area, placements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lazy.log.debug("Saving state.");
|
||||
let serialized = JSON.stringify(state, this.serializerHelper);
|
||||
lazy.log.debug("State saved as: " + serialized);
|
||||
|
@ -3041,7 +3227,7 @@ var CustomizableUIInternal = {
|
|||
|
||||
// Returns true if the area will eventually lazily restore (but hasn't yet).
|
||||
isAreaLazy(aArea) {
|
||||
if (gPlacements.has(aArea)) {
|
||||
if (gPlacements.has(aArea) || !gAreas.has(aArea)) {
|
||||
return false;
|
||||
}
|
||||
return gAreas.get(aArea).get("type") == CustomizableUI.TYPE_TOOLBAR;
|
||||
|
@ -3320,6 +3506,10 @@ var CustomizableUIInternal = {
|
|||
|
||||
reset() {
|
||||
gResetting = true;
|
||||
// CUI reset also implies resetting verticalTabs back to false.
|
||||
// We do this before the rest of the reset so widgets are reset to their non-vertical
|
||||
// positions.
|
||||
Services.prefs.setBoolPref("sidebar.verticalTabs", false);
|
||||
this._resetUIState();
|
||||
|
||||
// Rebuild each registered area (across windows) to reflect the state that
|
||||
|
@ -3651,6 +3841,9 @@ var CustomizableUIInternal = {
|
|||
},
|
||||
|
||||
get inDefaultState() {
|
||||
if (CustomizableUI.verticalTabsEnabled) {
|
||||
return false;
|
||||
}
|
||||
for (let [areaId, props] of gAreas) {
|
||||
let defaultPlacements = props
|
||||
.get("defaultPlacements")
|
||||
|
@ -3811,23 +4004,251 @@ var CustomizableUIInternal = {
|
|||
CustomizableUI.setToolbarVisibility(toolbar, visibility == "true");
|
||||
}
|
||||
|
||||
if (
|
||||
aTopic === "nsPref:changed" &&
|
||||
aData === kPrefSidebarVerticalTabsEnabled
|
||||
) {
|
||||
let sidebarRevampEnabled = Services.prefs.getBoolPref(
|
||||
kPrefSidebarRevampEnabled,
|
||||
false
|
||||
if (aTopic === "nsPref:changed") {
|
||||
this.reconcileSidebarPrefs(aData);
|
||||
}
|
||||
},
|
||||
|
||||
initializeForTabsOrientation(toVertical) {
|
||||
lazy.log.debug(
|
||||
`initializeForTabsOrientation, toVertical: ${toVertical}, gCurrentVerticalTabs: ${gCurrentVerticalTabs}`
|
||||
);
|
||||
if (!toVertical) {
|
||||
const savedPlacements = this.getSavedHorizontalSnapshotState();
|
||||
lazy.log.debug(
|
||||
"initializeForTabsOrientation, savedPlacements",
|
||||
savedPlacements
|
||||
);
|
||||
let verticalTabsEnabled = Services.prefs.getBoolPref(
|
||||
kPrefSidebarVerticalTabsEnabled,
|
||||
false
|
||||
if (savedPlacements) {
|
||||
// We're startup up with horizontal tabs, but there are saved placements for the
|
||||
// horizontal tab strip, so its possible the verticalTabs pref was updated outside
|
||||
// of normal use. Make sure to restore those tabstrip widget placements
|
||||
this.restoreSavedHorizontalTabStripState(savedPlacements, true);
|
||||
} else {
|
||||
// This is the default state and normal initialization will do everything necessary
|
||||
}
|
||||
gCurrentVerticalTabs = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the UI was already customized and saved, the earlier call to loadSavedState will
|
||||
// have populated gSavedState from the pref. If not, we need to move the tabs into the
|
||||
// vertical tabs area in the gSavedState. Then, the normal build-areas lifecycle
|
||||
// can populate the needed toolbar placements and elements.
|
||||
lazy.log.debug(
|
||||
"initializeForTabsOrientation, toVertical=true, gSavedState",
|
||||
gSavedState
|
||||
);
|
||||
|
||||
// If there are saved placement customizations, we need to manually move widgets
|
||||
// around before we restore this state
|
||||
let savedPlacements = gSavedState?.placements || {};
|
||||
if (!savedPlacements[CustomizableUI.AREA_VERTICAL_TABSTRIP]?.length) {
|
||||
savedPlacements[CustomizableUI.AREA_VERTICAL_TABSTRIP] =
|
||||
gAreas
|
||||
.get(CustomizableUI.AREA_VERTICAL_TABSTRIP)
|
||||
.get("verticalTabsDefaultPlacements") || [];
|
||||
lazy.log.debug(
|
||||
"initializeForTabsOrientation, using defaults for AREA_VERTICAL_TABSTRIP",
|
||||
savedPlacements[CustomizableUI.AREA_VERTICAL_TABSTRIP]
|
||||
);
|
||||
if (verticalTabsEnabled && !sidebarRevampEnabled) {
|
||||
Services.prefs.setBoolPref(kPrefSidebarRevampEnabled, true);
|
||||
}
|
||||
let tabstripPlacements =
|
||||
savedPlacements[CustomizableUI.AREA_TABSTRIP] || [];
|
||||
// also pick up any widgets already in gFuturePlacements so we can wipe that
|
||||
if (gFuturePlacements.has(CustomizableUI.AREA_TABSTRIP)) {
|
||||
for (let id of gFuturePlacements.get(CustomizableUI.AREA_TABSTRIP)) {
|
||||
if (!tabstripPlacements.includes(id)) {
|
||||
tabstripPlacements.push(id);
|
||||
}
|
||||
}
|
||||
gFuturePlacements.delete(CustomizableUI.AREA_TABSTRIP);
|
||||
}
|
||||
// Take a copy we can save and restore to, ensuring there's a sane default
|
||||
let savedTabstripPlacements = tabstripPlacements.length
|
||||
? [...tabstripPlacements]
|
||||
: gAreas.get(CustomizableUI.AREA_TABSTRIP).get("defaultPlacements");
|
||||
|
||||
// now we can remove the saved placements so they don't get picked back up again later in startup
|
||||
delete savedPlacements[CustomizableUI.AREA_TABSTRIP];
|
||||
|
||||
let widgetsMoved = [];
|
||||
for (let widgetId of tabstripPlacements) {
|
||||
if (widgetId == "tabbrowser-tabs") {
|
||||
lazy.log.debug(
|
||||
`Moving saved tabbrowser-tabs to AREA_VERTICAL_TABSTRIP`
|
||||
);
|
||||
this.addWidgetToArea(
|
||||
widgetId,
|
||||
CustomizableUI.AREA_VERTICAL_TABSTRIP,
|
||||
null,
|
||||
true
|
||||
);
|
||||
continue;
|
||||
}
|
||||
// if this is a extension, those are handled in a toolbarvisibilitychange handler in browser-addons.js
|
||||
if (CustomizableUI.isWebExtensionWidget(widgetId)) {
|
||||
lazy.log.debug(`Skipping a webextension saved placement ${widgetId}`);
|
||||
continue;
|
||||
}
|
||||
// Everything else gets moved to the nav-bar area while tabs are vertical
|
||||
lazy.log.debug(`Moving saved placement ${widgetId} to nav-bar`);
|
||||
this.addWidgetToArea(widgetId, CustomizableUI.AREA_NAVBAR, null, true);
|
||||
widgetsMoved.push(widgetId);
|
||||
}
|
||||
lazy.log.debug(
|
||||
"initializeForTabsOrientation, widgets moved:",
|
||||
widgetsMoved
|
||||
);
|
||||
if (widgetsMoved.length) {
|
||||
// We've updated the areas, so we don't need to do this again post-initialization
|
||||
gCurrentVerticalTabs = true;
|
||||
}
|
||||
|
||||
// If we've ended up with a non-default CUI state and vertical tabs enabled, ensure
|
||||
// there's a sane snapshot to revert to
|
||||
if (!lazy.horizontalPlacementsPref) {
|
||||
lazy.log.debug(
|
||||
`verticalTabsEnabled but ${kPrefCustomizationHorizontalTabstrip} is empty`
|
||||
);
|
||||
CustomizableUIInternal.saveHorizontalTabStripState(
|
||||
savedTabstripPlacements
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
reconcileSidebarPrefs(prefChanged) {
|
||||
let sidebarRevampEnabled = Services.prefs.getBoolPref(
|
||||
kPrefSidebarRevampEnabled,
|
||||
false
|
||||
);
|
||||
let verticalTabsEnabled = Services.prefs.getBoolPref(
|
||||
kPrefSidebarVerticalTabsEnabled,
|
||||
false
|
||||
);
|
||||
lazy.log.debug(
|
||||
`reconcileSidebarPrefs, kPrefSidebarRevampEnabled: {sidebarRevampEnabled}, kPrefSidebarVerticalTabsEnabled: ${verticalTabsEnabled}`
|
||||
);
|
||||
switch (prefChanged) {
|
||||
case kPrefSidebarVerticalTabsEnabled: {
|
||||
// We need to also enable sidebar.revamp if vertical tabs gets enabled
|
||||
if (verticalTabsEnabled && !sidebarRevampEnabled) {
|
||||
Services.prefs.setBoolPref(kPrefSidebarRevampEnabled, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kPrefSidebarRevampEnabled: {
|
||||
// We need to also disable vertical tabs if sidebar.revamp is no longer enabled
|
||||
if (!sidebarRevampEnabled && verticalTabsEnabled) {
|
||||
lazy.log.debug(
|
||||
`{kPrefSidebarRevampEnabled} disabled, so also disabling ${kPrefSidebarVerticalTabsEnabled}`
|
||||
);
|
||||
Services.prefs.setBoolPref(kPrefSidebarVerticalTabsEnabled, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
get tabstripAreasReady() {
|
||||
return (
|
||||
gBuildAreas.get(CustomizableUI.AREA_TABSTRIP)?.size &&
|
||||
gBuildAreas.get(CustomizableUI.AREA_VERTICAL_TABSTRIP)?.size
|
||||
);
|
||||
},
|
||||
|
||||
updateTabStripOrientation() {
|
||||
if (!this.tabstripAreasReady) {
|
||||
lazy.log.debug("tabstrip build areas not yet ready");
|
||||
return;
|
||||
}
|
||||
let toVertical = CustomizableUI.verticalTabsEnabled;
|
||||
if (toVertical === gCurrentVerticalTabs) {
|
||||
lazy.log.debug("early return as the value hasn't changed");
|
||||
return;
|
||||
}
|
||||
lazy.log.debug(
|
||||
`verticalTabs changed, from ${gCurrentVerticalTabs}, to ${toVertical}`
|
||||
);
|
||||
|
||||
if (toVertical && gCurrentVerticalTabs !== null) {
|
||||
// Stash current placements as a state we can restore to when going back to horizontal tabs
|
||||
lazy.log.debug(
|
||||
"Switching to vertical tabs post-initialization, so capturing tabstrip placements snapshot"
|
||||
);
|
||||
CustomizableUIInternal.saveHorizontalTabStripState();
|
||||
}
|
||||
gCurrentVerticalTabs = toVertical;
|
||||
|
||||
function changeWidgetRemovability(widgetId, removable) {
|
||||
let widget = CustomizableUI.getWidget(widgetId);
|
||||
for (let { node } of widget.instances) {
|
||||
if (node) {
|
||||
node.setAttribute("removable", removable.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Normally these aren't removable, but for this operation only we need to move them
|
||||
changeWidgetRemovability("tabbrowser-tabs", true);
|
||||
changeWidgetRemovability("alltabs-button", true);
|
||||
|
||||
if (toVertical) {
|
||||
lazy.log.debug(
|
||||
`Switching to verticalTabs=true in updateTabStripOrientation`
|
||||
);
|
||||
gDirty = true;
|
||||
|
||||
if (
|
||||
!Services.prefs.getCharPref(kPrefCustomizationHorizontalTabsBackup, "")
|
||||
) {
|
||||
// Before we switch for the first time, take a back up just in case we need an escape hatch
|
||||
Services.prefs.setCharPref(
|
||||
kPrefCustomizationHorizontalTabsBackup,
|
||||
Services.prefs.getCharPref(kPrefCustomizationState, "")
|
||||
);
|
||||
}
|
||||
|
||||
CustomizableUI.beginBatchUpdate();
|
||||
// Remove non-default widgets to the nav-bar
|
||||
for (let id of CustomizableUI.getWidgetIdsInArea("TabsToolbar")) {
|
||||
if (id == "tabbrowser-tabs") {
|
||||
CustomizableUI.addWidgetToArea(
|
||||
id,
|
||||
CustomizableUI.AREA_VERTICAL_TABSTRIP
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (!CustomizableUI.isWidgetRemovable(id)) {
|
||||
continue;
|
||||
}
|
||||
// if this is a extension, those are handled in a toolbarvisibilitychange handler in browser-addons.js
|
||||
if (CustomizableUI.isWebExtensionWidget(id)) {
|
||||
continue;
|
||||
}
|
||||
// Everything else gets moved to the nav-bar area while tabs are vertical
|
||||
CustomizableUI.addWidgetToArea(id, CustomizableUI.AREA_NAVBAR);
|
||||
}
|
||||
CustomizableUI.endBatchUpdate();
|
||||
} else {
|
||||
// We're switching to vertical in this session; pull saved state from pref and update placements
|
||||
this.restoreSavedHorizontalTabStripState();
|
||||
}
|
||||
// Give the sidebar a chance to adjust before we show/hide the toolbars
|
||||
lazy.log.debug("CustomizableUI notifying tabstrip-orientation-change");
|
||||
Services.obs.notifyObservers(null, "tabstrip-orientation-change", {
|
||||
isVertical: toVertical,
|
||||
});
|
||||
|
||||
lazy.log.debug("Reverting widgets to be non-removable");
|
||||
changeWidgetRemovability("tabbrowser-tabs", false);
|
||||
changeWidgetRemovability("alltabs-button", false);
|
||||
|
||||
this.setToolbarVisibility(
|
||||
CustomizableUI.AREA_VERTICAL_TABSTRIP,
|
||||
toVertical
|
||||
);
|
||||
},
|
||||
};
|
||||
Object.freeze(CustomizableUIInternal);
|
||||
|
||||
|
@ -3844,6 +4265,12 @@ export var CustomizableUI = {
|
|||
* Constant reference to the ID of the tabstrip toolbar.
|
||||
*/
|
||||
AREA_TABSTRIP: "TabsToolbar",
|
||||
|
||||
/**
|
||||
* Constant reference to the ID of the vertical tabstrip toolbar.
|
||||
*/
|
||||
AREA_VERTICAL_TABSTRIP: "vertical-tabs",
|
||||
|
||||
/**
|
||||
* Constant reference to the ID of the bookmarks toolbar.
|
||||
*/
|
||||
|
@ -3920,6 +4347,10 @@ export var CustomizableUI = {
|
|||
},
|
||||
},
|
||||
|
||||
get verticalTabsEnabled() {
|
||||
return lazy.verticalTabsPref;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a listener object that will get fired for various events regarding
|
||||
* customization.
|
||||
|
@ -4437,7 +4868,7 @@ export var CustomizableUI = {
|
|||
throw new Error("Unknown customization area: " + aArea);
|
||||
}
|
||||
if (!gPlacements.has(aArea)) {
|
||||
throw new Error("Area not yet restored");
|
||||
throw new Error(`Area ${aArea} not yet restored`);
|
||||
}
|
||||
|
||||
// We need to clone this, as we don't want to let consumers muck with placements
|
||||
|
@ -4751,6 +5182,9 @@ export var CustomizableUI = {
|
|||
* @return true if the widget was provided by an extension, false otherwise.
|
||||
*/
|
||||
isWebExtensionWidget(aWidgetId) {
|
||||
if (typeof aWidgetId !== "string") {
|
||||
return false;
|
||||
}
|
||||
let widget = CustomizableUI.getWidget(aWidgetId);
|
||||
return widget?.webExtension || aWidgetId.endsWith("-browser-action");
|
||||
},
|
||||
|
@ -5563,6 +5997,7 @@ class OverflowableToolbar {
|
|||
if (!this.#initialized) {
|
||||
Services.obs.removeObserver(this, "browser-delayed-startup-finished");
|
||||
Services.prefs.removeObserver(kPrefSidebarVerticalTabsEnabled, this);
|
||||
Services.prefs.removeObserver(kPrefSidebarRevampEnabled, this);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -261,7 +261,7 @@ var SidebarController = {
|
|||
return this._toolbarButton;
|
||||
},
|
||||
|
||||
async init() {
|
||||
init() {
|
||||
// Initialize with side effects
|
||||
this.SidebarManager;
|
||||
|
||||
|
@ -318,9 +318,6 @@ var SidebarController = {
|
|||
this._mainResizeObserverAdded = true;
|
||||
}
|
||||
|
||||
if (this.sidebarVerticalTabsEnabled) {
|
||||
this.toggleTabstrip();
|
||||
}
|
||||
let newTabButton = document.getElementById("vertical-tabs-newtab-button");
|
||||
if (!this._verticalNewTabListenerAdded) {
|
||||
newTabButton.addEventListener("command", event => {
|
||||
|
@ -343,6 +340,11 @@ var SidebarController = {
|
|||
this._switcherListenersAdded = true;
|
||||
}
|
||||
}
|
||||
// We need to update the tab strip for vertical tabs during init
|
||||
// as there will be no tabstrip-orientation-change event
|
||||
if (CustomizableUI.verticalTabsEnabled) {
|
||||
this.toggleTabstrip();
|
||||
}
|
||||
|
||||
// sets the sidebar to the left or right, based on a pref
|
||||
this.setPosition();
|
||||
|
@ -353,6 +355,10 @@ var SidebarController = {
|
|||
Services.obs.addObserver(this, "intl:app-locales-changed");
|
||||
this._localesObserverAdded = true;
|
||||
}
|
||||
if (!this._tabstripOrientationObserverAdded) {
|
||||
Services.obs.addObserver(this, "tabstrip-orientation-change");
|
||||
this._tabstripOrientationObserverAdded = true;
|
||||
}
|
||||
|
||||
this._initDeferred.resolve();
|
||||
},
|
||||
|
@ -371,6 +377,8 @@ var SidebarController = {
|
|||
}
|
||||
|
||||
Services.obs.removeObserver(this, "intl:app-locales-changed");
|
||||
Services.obs.removeObserver(this, "tabstrip-orientation-change");
|
||||
delete this._tabstripOrientationObserverAdded;
|
||||
|
||||
if (this._observer) {
|
||||
this._observer.disconnect();
|
||||
|
@ -406,6 +414,11 @@ var SidebarController = {
|
|||
if (this.revampComponentsLoaded) {
|
||||
this.sidebarMain.requestUpdate();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "tabstrip-orientation-change": {
|
||||
this.promiseInitialized.then(() => this.toggleTabstrip());
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -592,7 +605,8 @@ var SidebarController = {
|
|||
if (!this._sidebars.get(this.lastOpenedId)) {
|
||||
this.lastOpenedId = this.DEFAULT_SIDEBAR_ID;
|
||||
}
|
||||
await this.init();
|
||||
this._inited = false;
|
||||
this.init();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1516,40 +1530,33 @@ var SidebarController = {
|
|||
},
|
||||
|
||||
toggleTabstrip() {
|
||||
let tabStrip = document.getElementById("tabbrowser-tabs");
|
||||
let toVerticalTabs = CustomizableUI.verticalTabsEnabled;
|
||||
let arrowScrollbox = gBrowser.tabContainer.arrowScrollbox;
|
||||
let verticalTabs = document.getElementById("vertical-tabs");
|
||||
let currentScrollOrientation = arrowScrollbox.getAttribute("orient");
|
||||
|
||||
let tabsToolbarWidgets = CustomizableUI.getWidgetIdsInArea("TabsToolbar");
|
||||
let tabstripPlacement = tabsToolbarWidgets.findIndex(
|
||||
item => item == "tabbrowser-tabs"
|
||||
);
|
||||
if (
|
||||
(!toVerticalTabs && currentScrollOrientation !== "vertical") ||
|
||||
(toVerticalTabs && currentScrollOrientation === "vertical")
|
||||
) {
|
||||
// Nothing to update
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.sidebarVerticalTabsEnabled) {
|
||||
let tabStrip = gBrowser.tabContainer;
|
||||
if (toVerticalTabs) {
|
||||
this.toggleExpanded(this._sidebarMain.expanded);
|
||||
arrowScrollbox.setAttribute("orient", "vertical");
|
||||
tabStrip.setAttribute("orient", "vertical");
|
||||
verticalTabs.append(tabStrip);
|
||||
} else {
|
||||
arrowScrollbox.setAttribute("orient", "horizontal");
|
||||
tabStrip.removeAttribute("expanded");
|
||||
tabStrip.setAttribute("orient", "horizontal");
|
||||
|
||||
// make sure we put the tabstrip back in its original position in the TabsToolbar
|
||||
if (tabstripPlacement < tabsToolbarWidgets.length) {
|
||||
document
|
||||
.getElementById("TabsToolbar-customization-target")
|
||||
.insertBefore(
|
||||
tabStrip,
|
||||
document.getElementById(tabsToolbarWidgets[tabstripPlacement + 1])
|
||||
);
|
||||
} else {
|
||||
document
|
||||
.getElementById("TabsToolbar-customization-target")
|
||||
.append(tabStrip);
|
||||
}
|
||||
}
|
||||
verticalTabs.toggleAttribute("visible", this.sidebarVerticalTabsEnabled);
|
||||
|
||||
let verticalToolbar = document.getElementById(
|
||||
CustomizableUI.AREA_VERTICAL_TABSTRIP
|
||||
);
|
||||
verticalToolbar.toggleAttribute("visible", toVerticalTabs);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -1602,10 +1609,5 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||
SidebarController,
|
||||
"sidebarVerticalTabsEnabled",
|
||||
"sidebar.verticalTabs",
|
||||
false,
|
||||
() => {
|
||||
if (!SidebarController.uninitializing) {
|
||||
SidebarController.toggleTabstrip();
|
||||
}
|
||||
}
|
||||
false
|
||||
);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
# 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/.
|
||||
|
||||
MARIONETTE_MANIFESTS += ["tests/marionette/manifest.toml"]
|
||||
|
||||
JAR_MANIFESTS += ["jar.mn"]
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ["tests/browser/browser.toml"]
|
||||
|
|
|
@ -40,6 +40,10 @@ run-if = ["os == 'mac'"] # Mac only feature
|
|||
|
||||
["browser_toolbar_sidebar_button.js"]
|
||||
|
||||
["browser_verticalTabs_widget_placements.js"]
|
||||
|
||||
["browser_vertical_tabs.js"]
|
||||
|
||||
["browser_vertical_tabs_cui_reset.js"]
|
||||
|
||||
["browser_view_sidebar_menu.js"]
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
registerCleanupFunction(async function resetToolbar() {
|
||||
await CustomizableUI.reset();
|
||||
Services.prefs.clearUserPref(kPrefCustomizationState);
|
||||
Services.prefs.clearUserPref(kPrefCustomizationHorizontalTabstrip);
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that with some widgets customized into the TabsToolbar,
|
||||
* they are moved to the nav-bar as expected when the verticalTabs pref is enabled,
|
||||
* and confirm everything was restored as expected when we flip back.
|
||||
*/
|
||||
add_task(async function moveAndRestoreTabsToolbarWidgets() {
|
||||
const defaultNavbarPlacements = CustomizableUI.getWidgetIdsInArea(
|
||||
CustomizableUI.AREA_NAVBAR
|
||||
);
|
||||
const defaultHorizontalTabStripPlacements = CustomizableUI.getWidgetIdsInArea(
|
||||
CustomizableUI.AREA_TABSTRIP
|
||||
);
|
||||
CustomizableUI.addWidgetToArea(
|
||||
"home-button",
|
||||
CustomizableUI.AREA_TABSTRIP,
|
||||
0
|
||||
);
|
||||
CustomizableUI.addWidgetToArea("panic-button", CustomizableUI.AREA_TABSTRIP);
|
||||
CustomizableUI.addWidgetToArea(
|
||||
"privatebrowsing-button",
|
||||
CustomizableUI.AREA_TABSTRIP
|
||||
);
|
||||
|
||||
const horizontalTabStripPlacements = CustomizableUI.getWidgetIdsInArea(
|
||||
CustomizableUI.AREA_TABSTRIP
|
||||
);
|
||||
Assert.equal(
|
||||
horizontalTabStripPlacements.length,
|
||||
defaultHorizontalTabStripPlacements.length + 3,
|
||||
"tabstrip has 3 new widget placements"
|
||||
);
|
||||
await SpecialPowers.pushPrefEnv({ set: [["sidebar.verticalTabs", true]] });
|
||||
|
||||
Assert.ok(
|
||||
CustomizableUI.verticalTabsEnabled,
|
||||
"CustomizableUI verticalTabsEnabled getter reflects pref value"
|
||||
);
|
||||
Assert.ok(
|
||||
BrowserTestUtils.isVisible(document.getElementById("TabsToolbar")),
|
||||
"#TabsToolbar is still visible"
|
||||
);
|
||||
|
||||
// The tabs-widget should be in the vertical tabs area
|
||||
Assert.ok(
|
||||
CustomizableUI.getWidgetIdsInArea(
|
||||
CustomizableUI.AREA_VERTICAL_TABSTRIP
|
||||
).includes("tabbrowser-tabs"),
|
||||
"The tabs container moved to the vertical tabs area"
|
||||
);
|
||||
|
||||
// The widgets we added to TabsToolbar should have been appened to nav-bar
|
||||
let newNavbarPlacements = CustomizableUI.getWidgetIdsInArea(
|
||||
CustomizableUI.AREA_NAVBAR
|
||||
);
|
||||
let expectedMovedWidgetIds = [
|
||||
"alltabs-button",
|
||||
"panic-button",
|
||||
"privatebrowsing-button",
|
||||
];
|
||||
Assert.deepEqual(
|
||||
newNavbarPlacements.slice(
|
||||
newNavbarPlacements.length - expectedMovedWidgetIds.length
|
||||
),
|
||||
expectedMovedWidgetIds,
|
||||
"All the tabstrip widgets were appended to the nav-bar"
|
||||
);
|
||||
|
||||
let prefSnapshot = JSON.parse(
|
||||
Services.prefs.getStringPref("browser.uiCustomization.horizontalTabstrip")
|
||||
);
|
||||
Assert.deepEqual(
|
||||
prefSnapshot,
|
||||
horizontalTabStripPlacements,
|
||||
"The previous tab strip placements were stored in the pref"
|
||||
);
|
||||
|
||||
await SpecialPowers.pushPrefEnv({ set: [["sidebar.verticalTabs", false]] });
|
||||
|
||||
Assert.ok(
|
||||
!CustomizableUI.verticalTabsEnabled,
|
||||
"CustomizableUI verticalTabsEnabled getter reflects pref value"
|
||||
);
|
||||
Assert.ok(
|
||||
BrowserTestUtils.isVisible(document.getElementById("TabsToolbar")),
|
||||
"#TabsToolbar is now visible"
|
||||
);
|
||||
Assert.ok(
|
||||
CustomizableUI.getWidgetIdsInArea(CustomizableUI.AREA_TABSTRIP).includes(
|
||||
"tabbrowser-tabs"
|
||||
),
|
||||
"The tabs container moved back to the tab strip"
|
||||
);
|
||||
|
||||
Assert.deepEqual(
|
||||
CustomizableUI.getWidgetIdsInArea(CustomizableUI.AREA_TABSTRIP),
|
||||
horizontalTabStripPlacements,
|
||||
"The tabstrip widgets were restored in the expected order"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
CustomizableUI.getWidgetIdsInArea(CustomizableUI.AREA_NAVBAR),
|
||||
defaultNavbarPlacements,
|
||||
"The nav-bar widgets are back in their original state"
|
||||
);
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
add_setup(() =>
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [["sidebar.verticalTabs", true]],
|
||||
})
|
||||
);
|
||||
|
||||
add_task(async function test_cui_reset_vertical_tabs() {
|
||||
ok(
|
||||
Services.prefs.getBoolPref("sidebar.verticalTabs"),
|
||||
"Vertical tabs enabled"
|
||||
);
|
||||
CustomizableUI.reset();
|
||||
ok(
|
||||
!Services.prefs.getBoolPref("sidebar.verticalTabs"),
|
||||
"Vertical tabs disabled"
|
||||
);
|
||||
});
|
|
@ -14,6 +14,13 @@ function imageBufferFromDataURI(encodedImageData) {
|
|||
return Uint8Array.from(decodedImageData, byte => byte.charCodeAt(0)).buffer;
|
||||
}
|
||||
|
||||
const kPrefCustomizationState = "browser.uiCustomization.state";
|
||||
const kPrefCustomizationHorizontalTabstrip =
|
||||
"browser.uiCustomization.horizontalTabstrip";
|
||||
// Ensure we clear any previous uiCustomization pref values
|
||||
Services.prefs.clearUserPref(kPrefCustomizationState);
|
||||
Services.prefs.clearUserPref(kPrefCustomizationHorizontalTabstrip);
|
||||
|
||||
/* global browser */
|
||||
const extData = {
|
||||
manifest: {
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
[DEFAULT]
|
||||
tags = "local"
|
||||
|
||||
["test_initialize_vertical_tabs.py"]
|
|
@ -0,0 +1,154 @@
|
|||
# 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/.
|
||||
|
||||
import json
|
||||
|
||||
from marionette_harness import MarionetteTestCase
|
||||
|
||||
vertical_parent_id = "vertical-tabs"
|
||||
horizontal_parent_id = "TabsToolbar-customization-target"
|
||||
snapshot_pref = "browser.uiCustomization.horizontalTabstrip"
|
||||
customization_pref = "browser.uiCustomization.state"
|
||||
|
||||
|
||||
class TestInitializeVerticalTabs(MarionetteTestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.marionette.set_context("chrome")
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Make sure subsequent tests get a clean profile
|
||||
self.marionette.restart(in_app=False, clean=True)
|
||||
finally:
|
||||
super().tearDown()
|
||||
|
||||
def restart_with_prefs(self, prefs):
|
||||
# We need to quit the browser and restart with the prefs already set
|
||||
# in order to examine the startup behavior
|
||||
for name, value in prefs.items():
|
||||
if value is None:
|
||||
self.marionette.clear_pref(name)
|
||||
else:
|
||||
self.marionette.set_pref(name, value)
|
||||
self.marionette.restart(clean=False, in_app=True)
|
||||
self.marionette.set_context("chrome")
|
||||
|
||||
def get_area_widgets(self, area):
|
||||
return self.marionette.execute_script(
|
||||
f"return CustomizableUI.getWidgetIdsInArea(CustomizableUI.{area})"
|
||||
)
|
||||
|
||||
def test_vertical_widgets_in_area(self):
|
||||
# A clean startup in verticalTabs mode; we should get all the defaults
|
||||
self.restart_with_prefs(
|
||||
{
|
||||
"sidebar.revamp": True,
|
||||
"sidebar.verticalTabs": True,
|
||||
customization_pref: None,
|
||||
snapshot_pref: None,
|
||||
}
|
||||
)
|
||||
horiz_tab_ids = self.get_area_widgets("AREA_TABSTRIP")
|
||||
vertical_tab_ids = self.get_area_widgets("AREA_VERTICAL_TABSTRIP")
|
||||
|
||||
self.assertEqual(
|
||||
len(horiz_tab_ids),
|
||||
0,
|
||||
msg="The horizontal tabstrip area is empty",
|
||||
)
|
||||
self.assertEqual(
|
||||
len(vertical_tab_ids),
|
||||
1,
|
||||
msg="The vertical tabstrip area has a single widget in it",
|
||||
)
|
||||
|
||||
# Check we're able to recover if we initialize with vertical tabs enabled
|
||||
# and no saved pref for the horizontal tab strip placements
|
||||
self.marionette.set_pref("sidebar.verticalTabs", False)
|
||||
|
||||
horiz_tab_ids = self.get_area_widgets("AREA_TABSTRIP")
|
||||
vertical_tab_ids = self.get_area_widgets("AREA_VERTICAL_TABSTRIP")
|
||||
|
||||
# Make sure we ended up with sensible defaults
|
||||
self.assertEqual(
|
||||
horiz_tab_ids,
|
||||
[
|
||||
"firefox-view-button",
|
||||
"tabbrowser-tabs",
|
||||
"new-tab-button",
|
||||
"alltabs-button",
|
||||
],
|
||||
msg="The tabstrip was populated with the expected defaults",
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
len(vertical_tab_ids),
|
||||
0,
|
||||
msg="The vertical tabstrip area was emptied",
|
||||
)
|
||||
|
||||
def test_restore_tabstrip_customizations(self):
|
||||
fixture_prefs = {
|
||||
"sidebar.revamp": True,
|
||||
"sidebar.verticalTabs": False,
|
||||
}
|
||||
self.restart_with_prefs(
|
||||
{
|
||||
**fixture_prefs,
|
||||
customization_pref: None,
|
||||
snapshot_pref: None,
|
||||
}
|
||||
)
|
||||
|
||||
# Add a widget at the start of the horizontal tabstrip
|
||||
# This is synchronous and should result in updating the UI and the saved state in uiCustomization pref
|
||||
self.marionette.execute_script(
|
||||
"CustomizableUI.addWidgetToArea('panic-button', CustomizableUI.AREA_TABSTRIP, 0)"
|
||||
)
|
||||
|
||||
saved_state = json.loads(self.marionette.get_pref(customization_pref))
|
||||
horiz_tab_ids = self.get_area_widgets("AREA_TABSTRIP")
|
||||
self.assertTrue(
|
||||
"panic-button" in horiz_tab_ids, "The widget we added is in the tabstrip"
|
||||
)
|
||||
|
||||
self.assertTrue(
|
||||
"panic-button" in saved_state["placements"]["TabsToolbar"],
|
||||
"The widget we added is included in the saved customization state",
|
||||
)
|
||||
|
||||
# Restart with vertical tabs enabled, leaving the uiCustomizations prefs as-is
|
||||
# We want to ensure initialization puts us in a good state without needing user
|
||||
# input to trigger the orientation change
|
||||
fixture_prefs["sidebar.verticalTabs"] = True
|
||||
self.restart_with_prefs(fixture_prefs)
|
||||
|
||||
saved_state = json.loads(self.marionette.get_pref(customization_pref))
|
||||
|
||||
horiz_tab_ids = self.get_area_widgets("AREA_TABSTRIP")
|
||||
nav_bar_ids = self.get_area_widgets("AREA_NAVBAR")
|
||||
|
||||
self.assertEqual(
|
||||
len(horiz_tab_ids),
|
||||
0,
|
||||
msg="The horizontal tabstrip area is empty",
|
||||
)
|
||||
self.assertTrue(
|
||||
"panic-button" in nav_bar_ids, "The widget we added has moved to the navbar"
|
||||
)
|
||||
|
||||
# Restart with horizontal tabs enabled. We want to ensure customizing the
|
||||
# panic-button into the tabstrip is correctly restored at initialization,
|
||||
# without needing user-input to trigger the orientation change
|
||||
fixture_prefs["sidebar.verticalTabs"] = False
|
||||
self.restart_with_prefs(fixture_prefs)
|
||||
|
||||
horiz_tab_ids = self.get_area_widgets("AREA_TABSTRIP")
|
||||
|
||||
self.assertEqual(
|
||||
horiz_tab_ids[0],
|
||||
"panic-button",
|
||||
msg="The customization was preserved after restarting in horizontal tabs mode",
|
||||
)
|
|
@ -19,6 +19,7 @@
|
|||
["include:../../../../../browser/components/places/tests/marionette/manifest.toml"]
|
||||
["include:../../../../../browser/components/search/test/marionette/manifest.toml"]
|
||||
["include:../../../../../browser/components/sessionstore/test/marionette/manifest.toml"]
|
||||
["include:../../../../../browser/components/sidebar/tests/marionette/manifest.toml"]
|
||||
["include:../../../../../browser/components/tests/marionette/manifest.toml"]
|
||||
|
||||
# DOM tests
|
||||
|
|
Загрузка…
Ссылка в новой задаче