Bug 1656277 - Show the bookmarks toolbar after migration if bookmarks were in the other browsers toolbar. r=MattN,Standard8

This is behind a pref so we can run a study on it.

Differential Revision: https://phabricator.services.mozilla.com/D85956
This commit is contained in:
Jared Wein 2020-08-14 15:56:36 +00:00
Родитель 9bbcae0e83
Коммит 972dd7e8cd
19 изменённых файлов: 358 добавлений и 140 удалений

Просмотреть файл

@ -1814,6 +1814,12 @@ pref("dom.ipc.processPrelaunch.enabled", true);
pref("browser.migrate.chrome.history.limit", 2000);
pref("browser.migrate.chrome.history.maxAgeInDays", 180);
#ifdef EARLY_BETA_OR_EARLIER
pref("browser.migrate.showBookmarksToolbarAfterMigration", true);
#else
pref("browser.migrate.showBookmarksToolbarAfterMigration", false);
#endif
pref("extensions.pocket.api", "api.getpocket.com");
pref("extensions.pocket.enabled", true);
pref("extensions.pocket.oAuthConsumerKey", "40249-e88c401e1b1f2242d9e441c4");

Просмотреть файл

@ -23,12 +23,6 @@ ChromeUtils.defineModuleGetter(
"resource://gre/modules/ActorManagerParent.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"CustomizableUI",
"resource:///modules/CustomizableUI.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"AboutNewTab",
@ -61,6 +55,12 @@ ChromeUtils.defineModuleGetter(
"resource://featuregates/FeatureGate.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"PlacesUIUtils",
"resource:///modules/PlacesUIUtils.jsm"
);
XPCOMUtils.defineLazyServiceGetter(
this,
"PushService",
@ -3028,7 +3028,7 @@ BrowserGlue.prototype = {
// New profiles may have existing bookmarks (imported from another browser or
// copied into the profile) and we want to show the bookmark toolbar for them
// in some cases.
this._maybeToggleBookmarkToolbarVisibility();
PlacesUIUtils.maybeToggleBookmarkToolbarVisibility();
} catch (ex) {
Cu.reportError(ex);
}
@ -3136,47 +3136,6 @@ BrowserGlue.prototype = {
);
},
/**
* Uncollapses PersonalToolbar if its collapsed status is not
* persisted, and user customized it or changed default bookmarks.
*
* If the user does not have a persisted value for the toolbar's
* "collapsed" attribute, try to determine whether it's customized.
*/
_maybeToggleBookmarkToolbarVisibility() {
const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
const NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE = 3;
let xulStore = Services.xulStore;
if (!xulStore.hasValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed")) {
// We consider the toolbar customized if it has more than NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
// children, or if it has a persisted currentset value.
let toolbarIsCustomized = xulStore.hasValue(
BROWSER_DOCURL,
"PersonalToolbar",
"currentset"
);
let getToolbarFolderCount = () => {
let toolbarFolder = PlacesUtils.getFolderContents(
PlacesUtils.bookmarks.toolbarGuid
).root;
let toolbarChildCount = toolbarFolder.childCount;
toolbarFolder.containerOpen = false;
return toolbarChildCount;
};
if (
toolbarIsCustomized ||
getToolbarFolderCount() > NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
CustomizableUI.setToolbarVisibility(
CustomizableUI.AREA_BOOKMARKS,
true
);
}
}
},
_migrateXULStoreForDocument(fromURL, toURL) {
Array.from(Services.xulStore.getIDsEnumerator(fromURL)).forEach(id => {
Array.from(Services.xulStore.getAttributeEnumerator(fromURL, id)).forEach(

Просмотреть файл

@ -283,6 +283,8 @@ var CustomizableUIInternal = {
);
SearchWidgetTracker.init();
Services.obs.addObserver(this, "browser-set-toolbar-visibility");
},
onEnabled(addon) {
@ -3363,6 +3365,13 @@ var CustomizableUIInternal = {
}
}
},
observe(aSubject, aTopic, aData) {
if (aTopic == "browser-set-toolbar-visibility") {
let [toolbar, visibility] = JSON.parse(aData);
CustomizableUI.setToolbarVisibility(toolbar, visibility == "true");
}
},
};
Object.freeze(CustomizableUIInternal);

Просмотреть файл

@ -12,6 +12,7 @@ const { FileUtils } = ChromeUtils.import(
"resource://gre/modules/FileUtils.jsm"
);
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { MigrationUtils, MigratorPrototype } = ChromeUtils.import(
"resource:///modules/MigrationUtils.jsm"
);
@ -21,6 +22,11 @@ ChromeUtils.defineModuleGetter(
"PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"PlacesUIUtils",
"resource:///modules/PlacesUIUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"Sqlite",
@ -138,6 +144,7 @@ Bookmarks.prototype = {
path: this._file.path,
});
let histogramBookmarkRoots = 0;
try {
let rows = await connection.execute(
`WITH RECURSIVE
@ -195,15 +202,26 @@ Bookmarks.prototype = {
}
if (toolbarBMs.length) {
histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_TOOLBAR;
let parentGuid = PlacesUtils.bookmarks.toolbarGuid;
if (!MigrationUtils.isStartupMigration) {
if (
!MigrationUtils.isStartupMigration &&
PlacesUtils.getChildCountForFolder(
PlacesUtils.bookmarks.toolbarGuid
) > PlacesUIUtils.NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
parentGuid = await MigrationUtils.createImportedBookmarksFolder(
"360se",
parentGuid
);
}
await MigrationUtils.insertManyBookmarksWrapper(toolbarBMs, parentGuid);
PlacesUIUtils.maybeToggleBookmarkToolbarVisibilityAfterMigration();
}
Services.telemetry
.getKeyedHistogramById("FX_MIGRATION_BOOKMARKS_ROOTS")
.add("360se", histogramBookmarkRoots);
})().then(
() => aCallback(true),
e => {

Просмотреть файл

@ -31,6 +31,12 @@ ChromeUtils.defineModuleGetter(
"resource://gre/modules/PlacesUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"PlacesUIUtils",
"resource:///modules/PlacesUIUtils.jsm"
);
/**
* Converts an array of chrome bookmark objects into one our own places code
* understands.
@ -106,7 +112,11 @@ ChromeProfileMigrator.prototype.getResources = async function Chrome_getResource
this.getBrowserKey()
).replace(/^source-name-/, "");
let possibleResourcePromises = [
GetBookmarksResource(profileFolder, localePropertySuffix),
GetBookmarksResource(
profileFolder,
localePropertySuffix,
this.getBrowserKey()
),
GetHistoryResource(profileFolder),
GetCookiesResource(profileFolder),
];
@ -204,7 +214,11 @@ Object.defineProperty(ChromeProfileMigrator.prototype, "sourceLocked", {
},
});
async function GetBookmarksResource(aProfileFolder, aLocalePropertySuffix) {
async function GetBookmarksResource(
aProfileFolder,
aLocalePropertySuffix,
aBrowserKey
) {
let bookmarksPath = OS.Path.join(aProfileFolder, "Bookmarks");
if (!(await OS.File.exists(bookmarksPath))) {
return null;
@ -224,16 +238,24 @@ async function GetBookmarksResource(aProfileFolder, aLocalePropertySuffix) {
encoding: "UTF-8",
});
let roots = JSON.parse(bookmarkJSON).roots;
let histogramBookmarkRoots = 0;
// Importing bookmark bar items
if (roots.bookmark_bar.children && roots.bookmark_bar.children.length) {
// Toolbar
histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_TOOLBAR;
let parentGuid = PlacesUtils.bookmarks.toolbarGuid;
let bookmarks = convertBookmarks(
roots.bookmark_bar.children,
errorGatherer
);
if (!MigrationUtils.isStartupMigration) {
if (
!MigrationUtils.isStartupMigration &&
PlacesUtils.getChildCountForFolder(
PlacesUtils.bookmarks.toolbarGuid
) > PlacesUIUtils.NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
parentGuid = await MigrationUtils.createImportedBookmarksFolder(
aLocalePropertySuffix,
parentGuid
@ -243,14 +265,21 @@ async function GetBookmarksResource(aProfileFolder, aLocalePropertySuffix) {
bookmarks,
parentGuid
);
PlacesUIUtils.maybeToggleBookmarkToolbarVisibilityAfterMigration();
}
// Importing bookmark menu items
if (roots.other.children && roots.other.children.length) {
// Bookmark menu
histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_MENU;
let parentGuid = PlacesUtils.bookmarks.menuGuid;
let bookmarks = convertBookmarks(roots.other.children, errorGatherer);
if (!MigrationUtils.isStartupMigration) {
if (
!MigrationUtils.isStartupMigration &&
PlacesUtils.getChildCountForFolder(PlacesUtils.bookmarks.menuGuid) >
PlacesUIUtils.NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
parentGuid = await MigrationUtils.createImportedBookmarksFolder(
aLocalePropertySuffix,
parentGuid
@ -264,6 +293,9 @@ async function GetBookmarksResource(aProfileFolder, aLocalePropertySuffix) {
if (gotErrors) {
throw new Error("The migration included errors.");
}
Services.telemetry
.getKeyedHistogramById("FX_MIGRATION_BOOKMARKS_ROOTS")
.add(aBrowserKey, histogramBookmarkRoots);
})().then(
() => aCallback(true),
() => aCallback(false)

Просмотреть файл

@ -8,6 +8,7 @@ const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
@ -22,6 +23,11 @@ ChromeUtils.defineModuleGetter(
"PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"PlacesUIUtils",
"resource:///modules/PlacesUIUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"ESEDBReader",
@ -389,9 +395,16 @@ EdgeBookmarksMigrator.prototype = {
throw new Error("Edge seems to be running - its database is locked.");
}
let { toplevelBMs, toolbarBMs } = this._fetchBookmarksFromDB();
let histogramBookmarkRoots = 0;
if (toplevelBMs.length) {
histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_MENU;
let parentGuid = PlacesUtils.bookmarks.menuGuid;
if (!MigrationUtils.isStartupMigration) {
if (
!MigrationUtils.isStartupMigration &&
PlacesUtils.getChildCountForFolder(parentGuid) >
PlacesUIUtils.NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
parentGuid = await MigrationUtils.createImportedBookmarksFolder(
"Edge",
parentGuid
@ -400,15 +413,25 @@ EdgeBookmarksMigrator.prototype = {
await MigrationUtils.insertManyBookmarksWrapper(toplevelBMs, parentGuid);
}
if (toolbarBMs.length) {
histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_TOOLBAR;
let parentGuid = PlacesUtils.bookmarks.toolbarGuid;
if (!MigrationUtils.isStartupMigration) {
if (
!MigrationUtils.isStartupMigration &&
PlacesUtils.getChildCountForFolder(parentGuid) >
PlacesUIUtils.NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
parentGuid = await MigrationUtils.createImportedBookmarksFolder(
"Edge",
parentGuid
);
}
await MigrationUtils.insertManyBookmarksWrapper(toolbarBMs, parentGuid);
PlacesUIUtils.maybeToggleBookmarkToolbarVisibilityAfterMigration();
}
Services.telemetry
.getKeyedHistogramById("FX_MIGRATION_BOOKMARKS_ROOTS")
.add("edge", histogramBookmarkRoots);
},
_fetchBookmarksFromDB() {

Просмотреть файл

@ -24,6 +24,11 @@ ChromeUtils.defineModuleGetter(
"PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"PlacesUIUtils",
"resource:///modules/PlacesUIUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"WindowsRegistry",
@ -406,17 +411,22 @@ Bookmarks.prototype = {
return this.__toolbarFolderName;
},
_histogramBookmarkRoots: 0,
migrate: function B_migrate(aCallback) {
return (async () => {
// Import to the bookmarks menu.
this._histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_MENU;
let folderGuid = PlacesUtils.bookmarks.menuGuid;
if (!MigrationUtils.isStartupMigration) {
folderGuid = await MigrationUtils.createImportedBookmarksFolder(
this.importedAppLabel,
folderGuid
);
}
await this._migrateFolder(this._favoritesFolder, folderGuid);
Services.telemetry
.getKeyedHistogramById("FX_MIGRATION_BOOKMARKS_ROOTS")
.add(
this._migrationType == MSMigrationUtils.MIGRATION_TYPE_IE
? "ie"
: "edge",
this._histogramBookmarkRoots
);
})().then(
() => aCallback(true),
e => {
@ -428,12 +438,20 @@ Bookmarks.prototype = {
async _migrateFolder(aSourceFolder, aDestFolderGuid) {
let bookmarks = await this._getBookmarksInFolder(aSourceFolder);
if (bookmarks.length) {
await MigrationUtils.insertManyBookmarksWrapper(
bookmarks,
if (!bookmarks.length) {
return;
}
if (
!MigrationUtils.isStartupMigration &&
PlacesUtils.getChildCountForFolder(aDestFolderGuid) >
PlacesUIUtils.NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
aDestFolderGuid = await MigrationUtils.createImportedBookmarksFolder(
this.importedAppLabel,
aDestFolderGuid
);
}
await MigrationUtils.insertManyBookmarksWrapper(bookmarks, aDestFolderGuid);
},
async _getBookmarksInFolder(aSourceFolder) {
@ -456,14 +474,11 @@ Bookmarks.prototype = {
entry.parent.equals(this._favoritesFolder);
if (isBookmarksFolder && entry.isReadable()) {
// Import to the bookmarks toolbar.
this._histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_TOOLBAR;
let folderGuid = PlacesUtils.bookmarks.toolbarGuid;
if (!MigrationUtils.isStartupMigration) {
folderGuid = await MigrationUtils.createImportedBookmarksFolder(
this.importedAppLabel,
folderGuid
);
}
await this._migrateFolder(entry, folderGuid);
PlacesUIUtils.maybeToggleBookmarkToolbarVisibilityAfterMigration();
} else if (entry.isReadable()) {
let childBookmarks = await this._getBookmarksInFolder(entry);
rv.push({

Просмотреть файл

@ -1306,4 +1306,11 @@ var MigrationUtils = Object.freeze({
getSourceIdForTelemetry(sourceName) {
return this._sourceNameToIdMapping[sourceName] || 0;
},
/* Enum of locations where bookmarks were found in the
source browser that we import from */
SOURCE_BOOKMARK_ROOTS_BOOKMARKS_TOOLBAR: 1,
SOURCE_BOOKMARK_ROOTS_BOOKMARKS_MENU: 2,
SOURCE_BOOKMARK_ROOTS_READING_LIST: 4,
SOURCE_BOOKMARK_ROOTS_UNFILED: 8,
});

Просмотреть файл

@ -8,6 +8,7 @@ const { FileUtils } = ChromeUtils.import(
"resource://gre/modules/FileUtils.jsm"
);
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
@ -25,6 +26,11 @@ ChromeUtils.defineModuleGetter(
"PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"PlacesUIUtils",
"resource:///modules/PlacesUIUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"FormHistory",
@ -35,6 +41,7 @@ XPCOMUtils.defineLazyGlobalGetters(this, ["URL"]);
function Bookmarks(aBookmarksFile) {
this._file = aBookmarksFile;
this._histogramBookmarkRoots = 0;
}
Bookmarks.prototype = {
type: MigrationUtils.resourceTypes.BOOKMARKS,
@ -57,6 +64,15 @@ Bookmarks.prototype = {
? this.READING_LIST_COLLECTION
: this.ROOT_COLLECTION;
await this._migrateCollection(children, collection);
if (
this._histogramBookmarkRoots &
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_TOOLBAR
) {
PlacesUIUtils.maybeToggleBookmarkToolbarVisibilityAfterMigration();
}
Services.telemetry
.getKeyedHistogramById("FX_MIGRATION_BOOKMARKS_ROOTS")
.add("safari", this._histogramBookmarkRoots);
})().then(
() => aCallback(true),
e => {
@ -127,26 +143,40 @@ Bookmarks.prototype = {
// Because the former is only an implementation detail in our UI,
// the unfiled root seems to be the best choice.
folderGuid = PlacesUtils.bookmarks.unfiledGuid;
this._histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_UNFILED;
break;
}
case this.MENU_COLLECTION: {
folderGuid = PlacesUtils.bookmarks.menuGuid;
if (!MigrationUtils.isStartupMigration) {
if (
!MigrationUtils.isStartupMigration &&
PlacesUtils.getChildCountForFolder(folderGuid) >
PlacesUIUtils.NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
folderGuid = await MigrationUtils.createImportedBookmarksFolder(
"Safari",
folderGuid
);
}
this._histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_MENU;
break;
}
case this.TOOLBAR_COLLECTION: {
folderGuid = PlacesUtils.bookmarks.toolbarGuid;
if (!MigrationUtils.isStartupMigration) {
if (
!MigrationUtils.isStartupMigration &&
PlacesUtils.getChildCountForFolder(folderGuid) >
PlacesUIUtils.NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
folderGuid = await MigrationUtils.createImportedBookmarksFolder(
"Safari",
folderGuid
);
}
this._histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_BOOKMARKS_TOOLBAR;
break;
}
case this.READING_LIST_COLLECTION: {
@ -163,6 +193,8 @@ Bookmarks.prototype = {
title: readingListTitle,
})
).guid;
this._histogramBookmarkRoots |=
MigrationUtils.SOURCE_BOOKMARK_ROOTS_READING_LIST;
break;
}
default:

Просмотреть файл

@ -247,6 +247,8 @@ class TestFirefoxRefresh(MarionetteTestCase):
const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
return Services.xulStore.getValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed");
""")
if toolbarVisible == "":
toolbarVisible = "false"
self.assertEqual(toolbarVisible, "false")
def checkHistory(self):

Просмотреть файл

@ -1,5 +1,9 @@
"use strict";
const { CustomizableUI } = ChromeUtils.import(
"resource:///modules/CustomizableUI.jsm"
);
add_task(async function() {
registerFakePath("AppData", do_get_file("AppData/Roaming/"));
@ -20,37 +24,37 @@ add_task(async function() {
"Default user should be the last"
);
// Wait for the imported bookmarks. Check that "From 360 Secure Browser"
// folders are created on the toolbar.
let source = await MigrationUtils.getLocalizedString("source-name-360se");
let label = await MigrationUtils.getLocalizedString(
"imported-bookmarks-source",
{ source }
);
let importedToBookmarksToolbar = false;
let itemsSeen = { bookmarks: 0, folders: 0 };
let expectedParents = [PlacesUtils.toolbarFolderId];
let itemCount = 0;
let gotFolder = false;
let listener = events => {
for (let event of events) {
if (event.title != label) {
itemCount++;
}
if (
event.itemType == PlacesUtils.bookmarks.TYPE_FOLDER &&
event.title == "360 \u76f8\u5173"
) {
gotFolder = true;
}
if (expectedParents.length && event.title == label) {
let index = expectedParents.indexOf(event.parentId);
Assert.ok(index != -1, "Found expected parent");
expectedParents.splice(index, 1);
itemsSeen[
event.itemType == PlacesUtils.bookmarks.TYPE_FOLDER
? "folders"
: "bookmarks"
]++;
if (event.parentId == PlacesUtils.toolbarFolderId) {
importedToBookmarksToolbar = true;
}
}
};
PlacesUtils.observers.addListener(["bookmark-added"], listener);
let observerNotified = false;
Services.obs.addObserver((aSubject, aTopic, aData) => {
let [toolbar, visibility] = JSON.parse(aData);
Assert.equal(
toolbar,
CustomizableUI.AREA_BOOKMARKS,
"Notification should be received for bookmarks toolbar"
);
Assert.equal(
visibility,
"true",
"Notification should say to reveal the bookmarks toolbar"
);
observerNotified = true;
}, "browser-set-toolbar-visibility");
await promiseMigration(migrator, MigrationUtils.resourceTypes.BOOKMARKS, {
id: "default",
@ -58,13 +62,14 @@ add_task(async function() {
PlacesUtils.observers.removeListener(["bookmark-added"], listener);
// Check the bookmarks have been imported to all the expected parents.
Assert.ok(!expectedParents.length, "No more expected parents");
Assert.ok(gotFolder, "Should have seen the folder get imported");
Assert.equal(itemCount, 10, "Should import all 10 items.");
Assert.ok(importedToBookmarksToolbar, "Bookmarks imported in the toolbar");
Assert.equal(itemsSeen.bookmarks, 8, "Should import all bookmarks.");
Assert.equal(itemsSeen.folders, 2, "Should import all folders.");
// Check that the telemetry matches:
Assert.equal(
MigrationUtils._importQuantities.bookmarks,
itemCount,
itemsSeen.bookmarks + itemsSeen.folders,
"Telemetry reporting correct."
);
Assert.ok(observerNotified, "The observer should be notified upon migration");
});

Просмотреть файл

@ -3,6 +3,9 @@
const { AppConstants } = ChromeUtils.import(
"resource://gre/modules/AppConstants.jsm"
);
const { CustomizableUI } = ChromeUtils.import(
"resource:///modules/CustomizableUI.jsm"
);
let rootDir = do_get_file("chromefiles/", true);
@ -116,6 +119,21 @@ async function testBookmarks(migratorKey, subDirs, folderName) {
id: "Default",
name: "Default",
};
let observerNotified = false;
Services.obs.addObserver((aSubject, aTopic, aData) => {
let [toolbar, visibility] = JSON.parse(aData);
Assert.equal(
toolbar,
CustomizableUI.AREA_BOOKMARKS,
"Notification should be received for bookmarks toolbar"
);
Assert.equal(
visibility,
"true",
"Notification should say to reveal the bookmarks toolbar"
);
observerNotified = true;
}, "browser-set-toolbar-visibility");
await promiseMigration(
migrator,
MigrationUtils.resourceTypes.BOOKMARKS,
@ -130,6 +148,7 @@ async function testBookmarks(migratorKey, subDirs, folderName) {
itemsSeen.bookmarks + itemsSeen.folders,
"Telemetry reporting correct."
);
Assert.ok(observerNotified, "The observer should be notified upon migration");
}
add_task(async function test_Chrome() {

Просмотреть файл

@ -594,8 +594,8 @@ add_task(async function() {
Assert.ok(migrateResult, "Migration should succeed");
Assert.equal(
seenBookmarks.length,
7,
"Should have seen 7 items being bookmarked."
5,
"Should have seen 5 items being bookmarked."
);
Assert.equal(
seenBookmarks.filter(bm => bm.title != sourceLabel).length,
@ -608,8 +608,8 @@ add_task(async function() {
);
Assert.equal(
menuParents.length,
1,
"Should have a single folder added to the menu"
3,
"Bookmarks are added to the menu without a folder"
);
let toolbarParents = seenBookmarks.filter(
item => item.parentGuid == PlacesUtils.bookmarks.toolbarGuid
@ -619,8 +619,8 @@ add_task(async function() {
1,
"Should have a single item added to the toolbar"
);
let menuParentGuid = menuParents[0].guid;
let toolbarParentGuid = toolbarParents[0].guid;
let menuParentGuid = PlacesUtils.bookmarks.menuGuid;
let toolbarParentGuid = PlacesUtils.bookmarks.toolbarGuid;
let expectedTitlesInMenu = bookmarkReferenceItems
.filter(item => item.ParentId == kEdgeMenuParent)

Просмотреть файл

@ -1,37 +1,42 @@
"use strict";
const { CustomizableUI } = ChromeUtils.import(
"resource:///modules/CustomizableUI.jsm"
);
add_task(async function() {
let migrator = await MigrationUtils.getMigrator("ie");
// Sanity check for the source.
Assert.ok(await migrator.isSourceAvailable());
// Wait for the imported bookmarks. Check that "From Internet Explorer"
// folders are created in the menu and on the toolbar.
let source = await MigrationUtils.getLocalizedString("source-name-ie");
let label = await MigrationUtils.getLocalizedString(
"imported-bookmarks-source",
{ source }
);
let expectedParents = [
PlacesUtils.bookmarksMenuFolderId,
PlacesUtils.toolbarFolderId,
];
Assert.ok(await migrator.isSourceAvailable(), "Check migrator source");
// Since this test doesn't mock out the favorites, execution is dependent
// on the actual favorites stored on the local machine's IE favorites database.
// As such, we can't assert that bookmarks were migrated to both the bookmarks
// menu and the bookmarks toolbar.
let itemCount = 0;
let listener = events => {
for (let event of events) {
if (event.title != label) {
if (event.itemType == PlacesUtils.bookmarks.TYPE_BOOKMARK) {
itemCount++;
}
if (expectedParents.length && event.title == label) {
let index = expectedParents.indexOf(event.parentId);
Assert.notEqual(index, -1);
expectedParents.splice(index, 1);
}
}
};
PlacesUtils.observers.addListener(["bookmark-added"], listener);
let observerNotified = false;
Services.obs.addObserver((aSubject, aTopic, aData) => {
let [toolbar, visibility] = JSON.parse(aData);
Assert.equal(
toolbar,
CustomizableUI.AREA_BOOKMARKS,
"Notification should be received for bookmarks toolbar"
);
Assert.equal(
visibility,
"true",
"Notification should say to reveal the bookmarks toolbar"
);
observerNotified = true;
}, "browser-set-toolbar-visibility");
await promiseMigration(migrator, MigrationUtils.resourceTypes.BOOKMARKS);
PlacesUtils.observers.removeListener(["bookmark-added"], listener);
@ -42,5 +47,5 @@ add_task(async function() {
);
// Check the bookmarks have been imported to all the expected parents.
Assert.equal(expectedParents.length, 0, "Got all the expected parents");
Assert.ok(observerNotified, "The observer should be notified upon migration");
});

Просмотреть файл

@ -1,5 +1,9 @@
"use strict";
const { CustomizableUI } = ChromeUtils.import(
"resource:///modules/CustomizableUI.jsm"
);
add_task(async function() {
registerFakePath("ULibDir", do_get_file("Library/"));
@ -7,30 +11,24 @@ add_task(async function() {
// Sanity check for the source.
Assert.ok(await migrator.isSourceAvailable());
// Wait for the imported bookmarks. Check that "From Safari"
// folders are created on the toolbar.
let source = await MigrationUtils.getLocalizedString("source-name-safari");
let label = await MigrationUtils.getLocalizedString(
"imported-bookmarks-source",
{ source }
);
// Wait for the imported bookmarks. We don't check that "From Safari"
// folders are created on the toolbar since the profile
// we're importing to has less than 3 bookmarks in the destination
// so a "From Safari" folder isn't created.
let expectedParents = [PlacesUtils.toolbarFolderId];
let itemCount = 0;
let gotFolder = false;
let listener = events => {
for (let event of events) {
if (event.title != label) {
itemCount++;
}
itemCount++;
if (
event.itemType == PlacesUtils.bookmarks.TYPE_FOLDER &&
event.title == "Stuff"
) {
gotFolder = true;
}
if (expectedParents.length && event.title == label) {
if (expectedParents.length) {
let index = expectedParents.indexOf(event.parentId);
Assert.ok(index != -1, "Found expected parent");
expectedParents.splice(index, 1);
@ -38,6 +36,21 @@ add_task(async function() {
}
};
PlacesUtils.observers.addListener(["bookmark-added"], listener);
let observerNotified = false;
Services.obs.addObserver((aSubject, aTopic, aData) => {
let [toolbar, visibility] = JSON.parse(aData);
Assert.equal(
toolbar,
CustomizableUI.AREA_BOOKMARKS,
"Notification should be received for bookmarks toolbar"
);
Assert.equal(
visibility,
"true",
"Notification should say to reveal the bookmarks toolbar"
);
observerNotified = true;
}, "browser-set-toolbar-visibility");
await promiseMigration(migrator, MigrationUtils.resourceTypes.BOOKMARKS);
PlacesUtils.observers.removeListener(["bookmark-added"], listener);
@ -52,4 +65,5 @@ add_task(async function() {
itemCount,
"Telemetry reporting correct."
);
Assert.ok(observerNotified, "The observer should be notified upon migration");
});

Просмотреть файл

@ -18,6 +18,7 @@ XPCOMUtils.defineLazyGlobalGetters(this, ["Element"]);
XPCOMUtils.defineLazyModuleGetters(this, {
AppConstants: "resource://gre/modules/AppConstants.jsm",
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
CustomizableUI: "resource:///modules/CustomizableUI.jsm",
OpenInTabsUtils: "resource:///modules/OpenInTabsUtils.jsm",
PlacesTransactions: "resource://gre/modules/PlacesTransactions.jsm",
PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
@ -1160,6 +1161,58 @@ var PlacesUIUtils = {
win.top.XULBrowserWindow.setOverLink(url);
}
},
/**
* Uncollapses PersonalToolbar if its collapsed status is not
* persisted, and user customized it or changed default bookmarks.
*
* If the user does not have a persisted value for the toolbar's
* "collapsed" attribute, try to determine whether it's customized.
*
* @param {Boolean} aForceVisible Set to true to ignore if the user had
* previously collapsed the toolbar manually.
*/
NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE: 3,
maybeToggleBookmarkToolbarVisibility(aForceVisible = false) {
const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
let xulStore = Services.xulStore;
if (
aForceVisible ||
!xulStore.hasValue(BROWSER_DOCURL, "PersonalToolbar", "collapsed")
) {
// We consider the toolbar customized if it has more than NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
// children, or if it has a persisted currentset value.
let toolbarIsCustomized = xulStore.hasValue(
BROWSER_DOCURL,
"PersonalToolbar",
"currentset"
);
if (
aForceVisible ||
toolbarIsCustomized ||
PlacesUtils.getToolbarFolderCount(PlacesUtils.bookmarks.toolbarGuid) >
this.NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE
) {
Services.obs.notifyObservers(
null,
"browser-set-toolbar-visibility",
JSON.stringify([CustomizableUI.AREA_BOOKMARKS, "true"])
);
}
}
},
maybeToggleBookmarkToolbarVisibilityAfterMigration() {
if (
Services.prefs.getBoolPref(
"browser.migrate.showBookmarksToolbarAfterMigration"
)
) {
this.maybeToggleBookmarkToolbarVisibility(true);
}
},
};
// These are lazy getters to avoid importing PlacesUtils immediately.

Просмотреть файл

@ -2,7 +2,7 @@
* http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test _maybeToggleBookmarkToolbarVisibility() code running for new profiles.
* Test PlacesUIUtils.maybeToggleBookmarkToolbarVisibility() code running for new profiles.
* Ensure that the bookmarks toolbar is hidden in a default configuration.
* If new default bookmarks are added to the toolbar then the threshold of > 3
* in NUM_TOOLBAR_BOOKMARKS_TO_UNHIDE may need to be adjusted there.

Просмотреть файл

@ -1408,6 +1408,13 @@ var PlacesUtils = {
return found;
},
getChildCountForFolder(guid) {
let folder = PlacesUtils.getFolderContents(guid).root;
let childCount = folder.childCount;
folder.containerOpen = false;
return childCount;
},
/**
* Returns an array containing all the uris in the first level of the
* passed in container.

Просмотреть файл

@ -7219,6 +7219,18 @@
"keyed": true,
"description": "Accumulated timer delay (variance between when the timer was expected to fire and when it actually fired) in milliseconds as an indicator for decreased main-thread responsiveness while importing logins / passwords from another browser, keyed by the name of the browser (see gAvailableMigratorKeys in MigrationUtils.jsm). The import is happening on a background thread and should ideally not affect the UI noticeably. The time with the blocking Keychain dialog on macOS can skew this data."
},
"FX_MIGRATION_BOOKMARKS_ROOTS": {
"record_in_processes": ["main"],
"products": ["firefox"],
"bug_numbers": [1656277],
"alert_emails": ["jaws@mozilla.com", "rtestard@mozilla.com"],
"expires_in_version": "91",
"kind": "enumerated",
"n_values": 32,
"releaseChannelCollection": "opt-out",
"keyed": true,
"description": "Where bookmarks were stored in the other browser (1=bookmarks toolbar, 2=bookmarks menu, 4=reading list, 8=unfiled), keyed by the name of the browser. Note that migrating the reading list from classic Edge is supported but its root is not reported here."
},
"FX_MIGRATION_BOOKMARKS_QUANTITY": {
"record_in_processes": ["main"],
"products": ["firefox"],