mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Backed out 2 changesets (bug 1821187) for causing failures at browser_file_migration.js. CLOSED TREE
Backed out changeset 8402100dfc12 (bug 1821187) Backed out changeset 2a7196e34b3d (bug 1821187)
This commit is contained in:
parent
903da59f75
commit
54c533e94a
@ -11,7 +11,6 @@ browser.jar:
|
||||
content/branding/about-logo-private.png
|
||||
content/branding/about-logo-private@2x.png
|
||||
content/branding/about-wordmark.svg
|
||||
content/branding/document.ico (../document.ico)
|
||||
content/branding/firefox-wordmark.svg
|
||||
content/branding/icon16.png (../default16.png)
|
||||
content/branding/icon32.png (../default32.png)
|
||||
|
@ -11,7 +11,6 @@ browser.jar:
|
||||
content/branding/about-logo-private.png
|
||||
content/branding/about-logo-private@2x.png
|
||||
content/branding/about-wordmark.svg
|
||||
content/branding/document.ico (../document.ico)
|
||||
content/branding/firefox-wordmark.svg
|
||||
content/branding/icon16.png (../default16.png)
|
||||
content/branding/icon32.png (../default32.png)
|
||||
|
@ -11,7 +11,6 @@ browser.jar:
|
||||
content/branding/about-logo-private.png
|
||||
content/branding/about-logo-private@2x.png
|
||||
content/branding/about-wordmark.svg
|
||||
content/branding/document.ico (../document.ico)
|
||||
content/branding/firefox-wordmark.svg
|
||||
content/branding/icon16.png (../default16.png)
|
||||
content/branding/icon32.png (../default32.png)
|
||||
|
@ -11,7 +11,6 @@ browser.jar:
|
||||
content/branding/about-wordmark.svg
|
||||
content/branding/about-logo-private.png
|
||||
content/branding/about-logo-private@2x.png
|
||||
content/branding/document.ico (../document.ico)
|
||||
content/branding/firefox-wordmark.svg
|
||||
content/branding/icon16.png (../default16.png)
|
||||
content/branding/icon32.png (../default32.png)
|
||||
|
@ -1,230 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
const lazy = {};
|
||||
import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(lazy, {
|
||||
LoginCSVImport: "resource://gre/modules/LoginCSVImport.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(lazy, "gFluentStrings", function() {
|
||||
return new Localization([
|
||||
"branding/brand.ftl",
|
||||
"browser/migrationWizard.ftl",
|
||||
]);
|
||||
});
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
MigrationWizardConstants:
|
||||
"chrome://browser/content/migration/migration-wizard-constants.mjs",
|
||||
});
|
||||
|
||||
/**
|
||||
* Base class for a migration that involves reading a single file off of
|
||||
* the disk that the user picks using a file picker. The file might be
|
||||
* generated by another browser or some other application.
|
||||
*/
|
||||
export class FileMigratorBase {
|
||||
/**
|
||||
* This must be overridden to return a simple string identifier for the
|
||||
* migrator, for example "password-csv". This key is what
|
||||
* is used as an identifier when calling MigrationUtils.getFileMigrator.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
static get key() {
|
||||
throw new Error("FileMigrator.key must be overridden.");
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be overridden to return a Fluent string ID mapping to the display
|
||||
* name for this migrator. These strings should be defined in migrationWizard.ftl.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
static get displayNameL10nID() {
|
||||
throw new Error("FileMigrator.displayNameL10nID must be overridden.");
|
||||
}
|
||||
|
||||
/**
|
||||
* This getter should get overridden to return an icon url to represent the
|
||||
* file to be imported from. By default, this will just use the default Favicon
|
||||
* image.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
static get brandImage() {
|
||||
return "chrome://global/skin/icons/defaultFavicon.svg";
|
||||
}
|
||||
|
||||
/**
|
||||
* This getter should be overridden to return a Fluent string ID for what
|
||||
* the migration wizard header should be while the file migration is
|
||||
* underway.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
get progressHeaderL10nID() {
|
||||
throw new Error("FileMigrator.progressHeaderL10nID must be overridden.");
|
||||
}
|
||||
|
||||
/**
|
||||
* This getter should be overridden to return a Fluent string ID for what
|
||||
* the migration wizard header should be while the file migration is
|
||||
* done.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
get successHeaderL10nID() {
|
||||
throw new Error("FileMigrator.progressHeaderL10nID must be overridden.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} FilePickerConfiguration
|
||||
* @property {string} title
|
||||
* The title that should be assigned to the native file picker window.
|
||||
* @property {FilePickerConfigurationFilter[]} filters
|
||||
* One or more extension filters that should be applied to the native
|
||||
* file picker window to make selection easier.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} FilePickerConfigurationFilter
|
||||
* @property {string} title
|
||||
* The title for the filter. Example: "CSV Files"
|
||||
* @property {string} extensionPattern
|
||||
* A matching pattern for the filter. Example: "*.csv"
|
||||
*/
|
||||
|
||||
/**
|
||||
* A subclass of FileMigratorBase will eventually open a native file picker
|
||||
* for the user to select the file from their file system.
|
||||
*
|
||||
* Subclasses need to override this method in order to configure the
|
||||
* native file picker.
|
||||
*
|
||||
* @returns {Promise<FilePickerConfiguration>}
|
||||
*/
|
||||
async getFilePickerConfig() {
|
||||
throw new Error("FileMigrator.getFilePickerConfig must be overridden.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of one or more resource types that should appear to be
|
||||
* in progress of migrating while the file migration occurs. Notably,
|
||||
* this does not need to match the resource types that are returned by
|
||||
* `FileMigratorBase.migrate`.
|
||||
*
|
||||
* @type {string[]}
|
||||
* An array of resource types from the
|
||||
* MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES set.
|
||||
*/
|
||||
get displayedResourceTypes() {
|
||||
throw new Error("FileMigrator.displayedResourceTypes must be overridden");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to perform the file migration once the user makes a selection
|
||||
* from the native file picker. This will not be called if the user
|
||||
* chooses to cancel the native file picker.
|
||||
*
|
||||
* @param {string} filePath
|
||||
* The path that the user selected from the native file picker.
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async migrate(filePath) {
|
||||
throw new Error("FileMigrator.migrate must be overridden.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A file migrator for importing passwords from CSV or TSV files. CSV
|
||||
* files are more common, so this is what we show as the file type for
|
||||
* the display name, but this FileMigrator accepts both.
|
||||
*/
|
||||
export class PasswordFileMigrator extends FileMigratorBase {
|
||||
static get key() {
|
||||
return "file-password-csv";
|
||||
}
|
||||
|
||||
static get displayNameL10nID() {
|
||||
return "migration-wizard-migrator-display-name-file-password-csv";
|
||||
}
|
||||
|
||||
static get brandImage() {
|
||||
return "chrome://branding/content/document.ico";
|
||||
}
|
||||
|
||||
get displayedResourceTypes() {
|
||||
return [
|
||||
lazy.MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES
|
||||
.PASSWORDS_FROM_FILE,
|
||||
];
|
||||
}
|
||||
|
||||
get progressHeaderL10nID() {
|
||||
return "migration-passwords-from-file-progress-header";
|
||||
}
|
||||
|
||||
get successHeaderL10nID() {
|
||||
return "migration-passwords-from-file-success-header";
|
||||
}
|
||||
|
||||
async getFilePickerConfig() {
|
||||
let [
|
||||
title,
|
||||
csvFilterTitle,
|
||||
tsvFilterTitle,
|
||||
] = await lazy.gFluentStrings.formatValues([
|
||||
{ id: "migration-passwords-from-file-picker-title" },
|
||||
{ id: "migration-passwords-from-file-csv-filter-title" },
|
||||
{ id: "migration-passwords-from-file-tsv-filter-title" },
|
||||
]);
|
||||
|
||||
return {
|
||||
title,
|
||||
filters: [
|
||||
{
|
||||
title: csvFilterTitle,
|
||||
extensionPattern: "*.csv",
|
||||
},
|
||||
{
|
||||
title: tsvFilterTitle,
|
||||
extensionPattern: "*.tsv",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
async migrate(filePath) {
|
||||
let summary = await lazy.LoginCSVImport.importFromCSV(filePath);
|
||||
let newEntries = 0;
|
||||
let updatedEntries = 0;
|
||||
for (let entry of summary) {
|
||||
if (entry.result == "added") {
|
||||
newEntries++;
|
||||
} else if (entry.result == "modified") {
|
||||
updatedEntries++;
|
||||
}
|
||||
}
|
||||
let [newMessage, updatedMessage] = await lazy.gFluentStrings.formatValues([
|
||||
{
|
||||
id: "migration-wizard-progress-success-new-passwords",
|
||||
args: { newEntries },
|
||||
},
|
||||
{
|
||||
id: "migration-wizard-progress-success-updated-passwords",
|
||||
args: { updatedEntries },
|
||||
},
|
||||
]);
|
||||
|
||||
return {
|
||||
[lazy.MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES
|
||||
.PASSWORDS_NEW]: newMessage,
|
||||
[lazy.MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES
|
||||
.PASSWORDS_UPDATED]: updatedMessage,
|
||||
};
|
||||
}
|
||||
}
|
@ -17,7 +17,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
});
|
||||
|
||||
var gMigrators = null;
|
||||
var gFileMigrators = null;
|
||||
var gProfileStartup = null;
|
||||
var gL10n = null;
|
||||
var gPreviousDefaultBrowserKey = "";
|
||||
@ -108,12 +107,6 @@ const MIGRATOR_MODULES = Object.freeze({
|
||||
},
|
||||
});
|
||||
|
||||
const FILE_MIGRATOR_MODULES = Object.freeze({
|
||||
PasswordFileMigrator: {
|
||||
moduleURI: "resource:///modules/FileMigrators.sys.mjs",
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* The singleton MigrationUtils service. This service is the primary mechanism
|
||||
* by which migrations from other browsers to this browser occur. The singleton
|
||||
@ -308,26 +301,6 @@ class MigrationUtils {
|
||||
return gMigrators;
|
||||
}
|
||||
|
||||
get #fileMigrators() {
|
||||
if (!gFileMigrators) {
|
||||
gFileMigrators = new Map();
|
||||
for (let [symbol, { moduleURI }] of Object.entries(
|
||||
FILE_MIGRATOR_MODULES
|
||||
)) {
|
||||
let { [symbol]: migratorClass } = ChromeUtils.importESModule(moduleURI);
|
||||
if (gFileMigrators.has(migratorClass.key)) {
|
||||
console.error(
|
||||
"A pre-existing file migrator exists with key " +
|
||||
`${migratorClass.key}. Not registering.`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
gFileMigrators.set(migratorClass.key, new migratorClass());
|
||||
}
|
||||
}
|
||||
return gFileMigrators;
|
||||
}
|
||||
|
||||
forceExitSpinResolve() {
|
||||
gForceExitSpinResolve = true;
|
||||
}
|
||||
@ -394,15 +367,6 @@ class MigrationUtils {
|
||||
}
|
||||
}
|
||||
|
||||
getFileMigrator(aKey) {
|
||||
let migrator = this.#fileMigrators.get(aKey);
|
||||
if (!migrator) {
|
||||
console.error(`Could not find a file migrator class for key ${aKey}`);
|
||||
return null;
|
||||
}
|
||||
return migrator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a migrator is registered with key aKey. No check is made
|
||||
* to determine if a profile exists that the migrator can migrate from.
|
||||
@ -994,10 +958,6 @@ class MigrationUtils {
|
||||
return [...this.#migrators.keys()];
|
||||
}
|
||||
|
||||
get availableFileMigrators() {
|
||||
return [...this.#fileMigrators.values()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum for the entrypoint that is being used to start migration.
|
||||
* Callers can use the MIGRATION_ENTRYPOINTS getter to use these.
|
||||
|
@ -66,9 +66,7 @@ export class MigrationWizardChild extends JSWindowActorChild {
|
||||
|
||||
let hasPermissions = await this.sendQuery("CheckPermissions", {
|
||||
key: event.detail.key,
|
||||
type: event.detail.type,
|
||||
});
|
||||
|
||||
if (!hasPermissions) {
|
||||
if (event.detail.key == "safari") {
|
||||
this.#sendTelemetryEvent("safari_perms");
|
||||
@ -236,23 +234,12 @@ export class MigrationWizardChild extends JSWindowActorChild {
|
||||
* The message received from the MigrationWizardParent.
|
||||
*/
|
||||
receiveMessage(message) {
|
||||
switch (message.name) {
|
||||
case "UpdateProgress": {
|
||||
this.setComponentState({
|
||||
page: MigrationWizardConstants.PAGES.PROGRESS,
|
||||
progress: message.data.progress,
|
||||
key: message.data.key,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case "UpdateFileImportProgress": {
|
||||
this.setComponentState({
|
||||
page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS,
|
||||
progress: message.data.progress,
|
||||
title: message.data.title,
|
||||
});
|
||||
break;
|
||||
}
|
||||
if (message.name == "UpdateProgress") {
|
||||
this.setComponentState({
|
||||
page: MigrationWizardConstants.PAGES.PROGRESS,
|
||||
progress: message.data.progress,
|
||||
key: message.data.key,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,14 +66,8 @@ export class MigrationWizardParent extends JSWindowActorParent {
|
||||
for (const key of MigrationUtils.availableMigratorKeys) {
|
||||
availableMigrators.push(this.#getMigratorAndProfiles(key));
|
||||
}
|
||||
|
||||
// Wait for all getMigrator calls to resolve in parallel
|
||||
let results = await Promise.all(availableMigrators);
|
||||
|
||||
for (const migrator of MigrationUtils.availableFileMigrators.values()) {
|
||||
results.push(await this.#serializeFileMigrator(migrator));
|
||||
}
|
||||
|
||||
// Each migrator might give us a single MigratorProfileInstance,
|
||||
// or an Array of them, so we flatten them out and filter out
|
||||
// any that ended up going wrong and returning null from the
|
||||
@ -96,33 +90,17 @@ export class MigrationWizardParent extends JSWindowActorParent {
|
||||
}
|
||||
|
||||
case "Migrate": {
|
||||
if (
|
||||
message.data.type ==
|
||||
lazy.MigrationWizardConstants.MIGRATOR_TYPES.BROWSER
|
||||
) {
|
||||
await this.#doBrowserMigration(
|
||||
message.data.key,
|
||||
message.data.resourceTypes,
|
||||
message.data.profile
|
||||
);
|
||||
} else if (
|
||||
message.data.type == lazy.MigrationWizardConstants.MIGRATOR_TYPES.FILE
|
||||
) {
|
||||
let window = this.browsingContext.topChromeWindow;
|
||||
await this.#doFileMigration(window, message.data.key);
|
||||
}
|
||||
await this.#doMigration(
|
||||
message.data.key,
|
||||
message.data.resourceTypes,
|
||||
message.data.profile
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case "CheckPermissions": {
|
||||
if (
|
||||
message.data.type ==
|
||||
lazy.MigrationWizardConstants.MIGRATOR_TYPES.BROWSER
|
||||
) {
|
||||
let migrator = await MigrationUtils.getMigrator(message.data.key);
|
||||
return migrator.hasPermissions();
|
||||
}
|
||||
return true;
|
||||
let migrator = await MigrationUtils.getMigrator(message.data.key);
|
||||
return migrator.hasPermissions();
|
||||
}
|
||||
|
||||
case "RequestSafariPermissions": {
|
||||
@ -159,82 +137,6 @@ export class MigrationWizardParent extends JSWindowActorParent {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FileMigrator associated with the passed in key, and then opens
|
||||
* a native file picker configured for that migrator. Once the user selects
|
||||
* a file from the native file picker, this is then passed to the
|
||||
* FileMigrator.migrate method.
|
||||
*
|
||||
* As the migration occurs, this will send UpdateProgress messages to the
|
||||
* MigrationWizardChild to show the beginning and then the ending state of
|
||||
* the migration.
|
||||
*
|
||||
* @param {DOMWindow} window
|
||||
* The window that the native file picker should be associated with. This
|
||||
* cannot be null. See nsIFilePicker.init for more details.
|
||||
* @param {string} key
|
||||
* The unique identification key for a file migrator.
|
||||
* @returns {Promise<undefined>}
|
||||
* Resolves once the file migrator's migrate method has resolved.
|
||||
*/
|
||||
async #doFileMigration(window, key) {
|
||||
let fileMigrator = MigrationUtils.getFileMigrator(key);
|
||||
let filePickerConfig = await fileMigrator.getFilePickerConfig();
|
||||
|
||||
let { result, path } = await new Promise(resolve => {
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.init(window, filePickerConfig.title, Ci.nsIFilePicker.modeOpen);
|
||||
|
||||
for (let filter of filePickerConfig.filters) {
|
||||
fp.appendFilter(filter.title, filter.extensionPattern);
|
||||
}
|
||||
fp.appendFilters(Ci.nsIFilePicker.filterAll);
|
||||
fp.open(async fileOpenResult => {
|
||||
resolve({ result: fileOpenResult, path: fp.file.path });
|
||||
});
|
||||
});
|
||||
|
||||
if (result == Ci.nsIFilePicker.returnCancel) {
|
||||
// If the user cancels out of the file picker, the migration wizard should
|
||||
// still be in the state that lets the user re-open the file picker if
|
||||
// they closed it by accident, so we don't have to do anything else here.
|
||||
return;
|
||||
}
|
||||
|
||||
let progress = {};
|
||||
for (let resourceType of fileMigrator.displayedResourceTypes) {
|
||||
progress[resourceType] = {
|
||||
inProgress: true,
|
||||
message: "",
|
||||
};
|
||||
}
|
||||
|
||||
let [
|
||||
progressHeaderString,
|
||||
successHeaderString,
|
||||
] = await lazy.gFluentStrings.formatValues([
|
||||
fileMigrator.progressHeaderL10nID,
|
||||
fileMigrator.successHeaderL10nID,
|
||||
]);
|
||||
|
||||
this.sendAsyncMessage("UpdateFileImportProgress", {
|
||||
title: progressHeaderString,
|
||||
progress,
|
||||
});
|
||||
let migrationResult = await fileMigrator.migrate(path);
|
||||
let successProgress = {};
|
||||
for (let resourceType in migrationResult) {
|
||||
successProgress[resourceType] = {
|
||||
inProgress: false,
|
||||
message: migrationResult[resourceType],
|
||||
};
|
||||
}
|
||||
this.sendAsyncMessage("UpdateFileImportProgress", {
|
||||
title: successHeaderString,
|
||||
progress: successProgress,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls into MigrationUtils to perform a migration given the parameters
|
||||
* sent via the wizard.
|
||||
@ -255,7 +157,7 @@ export class MigrationWizardParent extends JSWindowActorParent {
|
||||
* @returns {Promise<undefined>}
|
||||
* Resolves once the Migration:Ended observer notification has fired.
|
||||
*/
|
||||
async #doBrowserMigration(migratorKey, resourceTypeNames, profileObj) {
|
||||
async #doMigration(migratorKey, resourceTypeNames, profileObj) {
|
||||
let migrator = await MigrationUtils.getMigrator(migratorKey);
|
||||
let availableResourceTypes = await migrator.getMigrateData(profileObj);
|
||||
let resourceTypesToMigrate = 0;
|
||||
@ -424,7 +326,6 @@ export class MigrationWizardParent extends JSWindowActorParent {
|
||||
}
|
||||
|
||||
return {
|
||||
type: lazy.MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: migrator.constructor.key,
|
||||
displayName,
|
||||
brandImage: migrator.constructor.brandImage,
|
||||
@ -489,25 +390,4 @@ export class MigrationWizardParent extends JSWindowActorParent {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Promise that resolves to a serializable representation of a
|
||||
* FileMigrator for sending down to the MigrationWizard.
|
||||
*
|
||||
* @param {FileMigrator} fileMigrator
|
||||
* The FileMigrator to serialize.
|
||||
* @returns {Promise<object>}
|
||||
* The serializable representation of the FileMigrator.
|
||||
*/
|
||||
async #serializeFileMigrator(fileMigrator) {
|
||||
return {
|
||||
type: lazy.MigrationWizardConstants.MIGRATOR_TYPES.FILE,
|
||||
key: fileMigrator.constructor.key,
|
||||
displayName: await lazy.gFluentStrings.formatValue(
|
||||
fileMigrator.constructor.displayNameL10nID
|
||||
),
|
||||
brandImage: fileMigrator.constructor.brandImage,
|
||||
resourceTypes: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,6 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
export const MigrationWizardConstants = Object.freeze({
|
||||
MIGRATOR_TYPES: Object.freeze({
|
||||
BROWSER: "browser",
|
||||
FILE: "file",
|
||||
}),
|
||||
|
||||
/**
|
||||
* A mapping of a page identification string to the IDs used by the
|
||||
* various wizard pages. These are used by MigrationWizard.setState
|
||||
@ -19,7 +14,6 @@ export const MigrationWizardConstants = Object.freeze({
|
||||
LOADING: "loading",
|
||||
SELECTION: "selection",
|
||||
PROGRESS: "progress",
|
||||
FILE_IMPORT_PROGRESS: "file-import-progress",
|
||||
SAFARI_PERMISSION: "safari-permission",
|
||||
SAFARI_PASSWORD_PERMISSION: "safari-password-permission",
|
||||
NO_BROWSERS_FOUND: "no-browsers-found",
|
||||
@ -37,6 +31,9 @@ export const MigrationWizardConstants = Object.freeze({
|
||||
// The DISPLAYED_RESOURCE_TYPES should have their keys match those
|
||||
// in MigrationUtils.resourceTypes.
|
||||
|
||||
// COOKIE resource migration is going to be removed, so we don't include
|
||||
// it here.
|
||||
|
||||
// This is a little silly, but JavaScript doesn't have a notion of
|
||||
// enums. The advantage of this set-up is that these constants values
|
||||
// can be used to access the MigrationUtils.resourceTypes constants,
|
||||
@ -50,17 +47,6 @@ export const MigrationWizardConstants = Object.freeze({
|
||||
// We don't yet show OTHERDATA or SESSION resources.
|
||||
}),
|
||||
|
||||
DISPLAYED_FILE_RESOURCE_TYPES: Object.freeze({
|
||||
// When migrating passwords from a file, we first show the progress
|
||||
// for a single PASSWORDS_FROM_FILE resource type, and then upon
|
||||
// completion, show two different resource types - one for new
|
||||
// passwords imported from the file, and one for existing passwords
|
||||
// that were updated from the file.
|
||||
PASSWORDS_FROM_FILE: "PASSWORDS_FROM_FILE",
|
||||
PASSWORDS_NEW: "PASSWORDS_NEW",
|
||||
PASSWORDS_UPDATED: "PASSWORDS_UPDATED",
|
||||
}),
|
||||
|
||||
/**
|
||||
* The set of keys that maps to migrators that use the term "favorites"
|
||||
* in the place of "bookmarks". This tends to be browsers from Microsoft.
|
||||
|
@ -21,7 +21,6 @@ export class MigrationWizard extends HTMLElement {
|
||||
#resourceTypeList = null;
|
||||
#shadowRoot = null;
|
||||
#importButton = null;
|
||||
#importFromFileButton = null;
|
||||
#safariPermissionButton = null;
|
||||
#selectAllCheckbox = null;
|
||||
#resourceSummary = null;
|
||||
@ -87,7 +86,6 @@ export class MigrationWizard extends HTMLElement {
|
||||
|
||||
<moz-button-group class="buttons">
|
||||
<button class="cancel-close" data-l10n-id="migration-cancel-button-label"></button>
|
||||
<button id="import-from-file" class="primary" data-l10n-id="migration-import-from-file-button-label"></button>
|
||||
<button id="import" class="primary" data-l10n-id="migration-import-button-label"></button>
|
||||
</moz-button-group>
|
||||
</div>
|
||||
@ -121,34 +119,7 @@ export class MigrationWizard extends HTMLElement {
|
||||
</div>
|
||||
<moz-button-group class="buttons">
|
||||
<button class="cancel-close" data-l10n-id="migration-cancel-button-label" disabled></button>
|
||||
<button class="primary done-button" data-l10n-id="migration-done-button-label"></button>
|
||||
</moz-button-group>
|
||||
</div>
|
||||
|
||||
<div name="page-file-import-progress">
|
||||
<h1 id="file-import-progress-header"></h1>
|
||||
<div class="resource-progress">
|
||||
<div data-resource-type="PASSWORDS_FROM_FILE" class="resource-progress-group">
|
||||
<span class="progress-icon-parent"><span class="progress-icon" role="img"></span></span>
|
||||
<span data-l10n-id="migration-passwords-from-file"></span>
|
||||
<span class="success-text deemphasized-text"> </span>
|
||||
</div>
|
||||
|
||||
<div data-resource-type="PASSWORDS_NEW" class="resource-progress-group">
|
||||
<span class="progress-icon-parent"><span class="progress-icon" role="img"></span></span>
|
||||
<span data-l10n-id="migration-passwords-new"></span>
|
||||
<span class="success-text deemphasized-text"> </span>
|
||||
</div>
|
||||
|
||||
<div data-resource-type="PASSWORDS_UPDATED" class="resource-progress-group">
|
||||
<span class="progress-icon-parent"><span class="progress-icon" role="img"></span></span>
|
||||
<span data-l10n-id="migration-passwords-updated"></span>
|
||||
<span class="success-text deemphasized-text"> </span>
|
||||
</div>
|
||||
</div>
|
||||
<moz-button-group class="buttons">
|
||||
<button class="cancel-close" data-l10n-id="migration-cancel-button-label" disabled></button>
|
||||
<button class="primary done-button" data-l10n-id="migration-done-button-label"></button>
|
||||
<button class="primary" id="done-button" data-l10n-id="migration-done-button-label"></button>
|
||||
</moz-button-group>
|
||||
</div>
|
||||
|
||||
@ -242,15 +213,11 @@ export class MigrationWizard extends HTMLElement {
|
||||
button.addEventListener("click", this);
|
||||
}
|
||||
|
||||
let doneButtons = shadow.querySelectorAll(".done-button");
|
||||
for (let button of doneButtons) {
|
||||
button.addEventListener("click", this);
|
||||
}
|
||||
let doneCloseButtons = shadow.querySelector("#done-button");
|
||||
doneCloseButtons.addEventListener("click", this);
|
||||
|
||||
this.#importButton = shadow.querySelector("#import");
|
||||
this.#importButton.addEventListener("click", this);
|
||||
this.#importFromFileButton = shadow.querySelector("#import-from-file");
|
||||
this.#importFromFileButton.addEventListener("click", this);
|
||||
|
||||
this.#browserProfileSelector.addEventListener("click", this);
|
||||
this.#resourceTypeList = shadow.querySelector("#resource-type-list");
|
||||
@ -309,10 +276,6 @@ export class MigrationWizard extends HTMLElement {
|
||||
this.#onShowingProgress(state);
|
||||
break;
|
||||
}
|
||||
case MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS: {
|
||||
this.#onShowingFileImportProgress(state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.#deck.toggleAttribute(
|
||||
@ -352,7 +315,7 @@ export class MigrationWizard extends HTMLElement {
|
||||
* should update the list of resource types to match what's supported
|
||||
* by the selected migrator and profile.
|
||||
*
|
||||
* @param {Element} panelItem the selected <panel-item>
|
||||
* @param {Element} panelItem the selected <oabel-item>
|
||||
*/
|
||||
#onBrowserProfileSelectionChanged(panelItem) {
|
||||
this.#browserProfileSelector.selectedPanelItem = panelItem;
|
||||
@ -373,7 +336,6 @@ export class MigrationWizard extends HTMLElement {
|
||||
|
||||
let key = panelItem.getAttribute("key");
|
||||
let resourceTypes = panelItem.resourceTypes;
|
||||
|
||||
for (let child of this.#resourceTypeList.children) {
|
||||
child.hidden = true;
|
||||
child.control.checked = false;
|
||||
@ -407,19 +369,13 @@ export class MigrationWizard extends HTMLElement {
|
||||
}
|
||||
let selectAll = this.#shadowRoot.querySelector("#select-all").control;
|
||||
selectAll.checked = true;
|
||||
|
||||
this.#displaySelectedResources();
|
||||
this.#browserProfileSelector.selectedPanelItem = panelItem;
|
||||
|
||||
let selectionPage = this.#shadowRoot.querySelector(
|
||||
"div[name='page-selection']"
|
||||
);
|
||||
selectionPage.setAttribute("migrator-type", panelItem.getAttribute("type"));
|
||||
selectionPage.toggleAttribute(
|
||||
"no-resources",
|
||||
panelItem.getAttribute("type") ==
|
||||
MigrationWizardConstants.MIGRATOR_TYPES.BROWSER && !resourceTypes.length
|
||||
);
|
||||
selectionPage.toggleAttribute("no-resources", !resourceTypes.length);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -448,7 +404,6 @@ export class MigrationWizard extends HTMLElement {
|
||||
for (let migrator of state.migrators) {
|
||||
let opt = document.createElement("panel-item");
|
||||
opt.setAttribute("key", migrator.key);
|
||||
opt.setAttribute("type", migrator.type);
|
||||
opt.profile = migrator.profile;
|
||||
opt.displayName = migrator.displayName;
|
||||
opt.resourceTypes = migrator.resourceTypes;
|
||||
@ -532,10 +487,7 @@ export class MigrationWizard extends HTMLElement {
|
||||
*/
|
||||
#onShowingProgress(state) {
|
||||
// Any resource progress group not included in state.progress is hidden.
|
||||
let progressPage = this.#shadowRoot.querySelector(
|
||||
"div[name='page-progress']"
|
||||
);
|
||||
let resourceGroups = progressPage.querySelectorAll(
|
||||
let resourceGroups = this.#shadowRoot.querySelectorAll(
|
||||
".resource-progress-group"
|
||||
);
|
||||
let totalProgressGroups = Object.keys(state.progress).length;
|
||||
@ -594,83 +546,10 @@ export class MigrationWizard extends HTMLElement {
|
||||
let header = this.#shadowRoot.getElementById("progress-header");
|
||||
document.l10n.setAttributes(header, headerL10nID);
|
||||
|
||||
let doneButton = progressPage.querySelector(".done-button");
|
||||
let cancelButton = progressPage.querySelector(".cancel-close");
|
||||
doneButton.hidden = !migrationDone;
|
||||
cancelButton.hidden = migrationDone;
|
||||
|
||||
if (migrationDone) {
|
||||
// Since this might be called before the named-deck actually switches to
|
||||
// show the progress page, we cannot focus this button immediately.
|
||||
// Instead, we use a rAF to queue this up for focusing before the
|
||||
// next paint.
|
||||
requestAnimationFrame(() => {
|
||||
doneButton.focus({ focusVisible: false });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when showing the progress / success page of the wizard for
|
||||
* files.
|
||||
*
|
||||
* @param {object} state
|
||||
* The state object passed into setState. The following properties are
|
||||
* used:
|
||||
* @param {string} state.title
|
||||
* The string to display in the header.
|
||||
* @param {Object<string, ProgressState>} state.progress
|
||||
* An object whose keys match one of DISPLAYED_FILE_RESOURCE_TYPES.
|
||||
*
|
||||
* Any resource type not included in state.progress will be hidden.
|
||||
*/
|
||||
#onShowingFileImportProgress(state) {
|
||||
// Any resource progress group not included in state.progress is hidden.
|
||||
let progressPage = this.#shadowRoot.querySelector(
|
||||
"div[name='page-file-import-progress']"
|
||||
"div[name='page-progress']"
|
||||
);
|
||||
let resourceGroups = progressPage.querySelectorAll(
|
||||
".resource-progress-group"
|
||||
);
|
||||
let totalProgressGroups = Object.keys(state.progress).length;
|
||||
let remainingProgressGroups = totalProgressGroups;
|
||||
|
||||
for (let group of resourceGroups) {
|
||||
let resourceType = group.dataset.resourceType;
|
||||
if (!state.progress.hasOwnProperty(resourceType)) {
|
||||
group.hidden = true;
|
||||
continue;
|
||||
}
|
||||
group.hidden = false;
|
||||
|
||||
let progressIcon = group.querySelector(".progress-icon");
|
||||
let successText = group.querySelector(".success-text");
|
||||
|
||||
if (state.progress[resourceType].inProgress) {
|
||||
document.l10n.setAttributes(
|
||||
progressIcon,
|
||||
"migration-wizard-progress-icon-in-progress"
|
||||
);
|
||||
progressIcon.classList.remove("completed");
|
||||
// With no status text, we re-insert the so that the status
|
||||
// text area does not fully collapse.
|
||||
successText.appendChild(document.createTextNode("\u00A0"));
|
||||
} else {
|
||||
document.l10n.setAttributes(
|
||||
progressIcon,
|
||||
"migration-wizard-progress-icon-completed"
|
||||
);
|
||||
progressIcon.classList.add("completed");
|
||||
successText.textContent = state.progress[resourceType].message;
|
||||
remainingProgressGroups--;
|
||||
}
|
||||
}
|
||||
|
||||
let migrationDone = remainingProgressGroups == 0;
|
||||
let header = this.#shadowRoot.getElementById("file-import-progress-header");
|
||||
header.textContent = state.title;
|
||||
|
||||
let doneButton = progressPage.querySelector(".primary");
|
||||
let doneButton = progressPage.querySelector("#done-button");
|
||||
let cancelButton = progressPage.querySelector(".cancel-close");
|
||||
doneButton.hidden = !migrationDone;
|
||||
cancelButton.hidden = migrationDone;
|
||||
@ -750,7 +629,6 @@ export class MigrationWizard extends HTMLElement {
|
||||
#gatherMigrationEventDetails() {
|
||||
let panelItem = this.#browserProfileSelector.selectedPanelItem;
|
||||
let key = panelItem.getAttribute("key");
|
||||
let type = panelItem.getAttribute("type");
|
||||
let profile = panelItem.profile;
|
||||
let hasPermissions = panelItem.hasPermissions;
|
||||
|
||||
@ -766,7 +644,6 @@ export class MigrationWizard extends HTMLElement {
|
||||
|
||||
return {
|
||||
key,
|
||||
type,
|
||||
profile,
|
||||
resourceTypes,
|
||||
hasPermissions,
|
||||
@ -890,14 +767,11 @@ export class MigrationWizard extends HTMLElement {
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "click": {
|
||||
if (
|
||||
event.target == this.#importButton ||
|
||||
event.target == this.#importFromFileButton
|
||||
) {
|
||||
if (event.target == this.#importButton) {
|
||||
this.#doImport();
|
||||
} else if (
|
||||
event.target.classList.contains("cancel-close") ||
|
||||
event.target.classList.contains("done-button")
|
||||
event.target.id == "done-button"
|
||||
) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("MigrationWizard:Close", { bubbles: true })
|
||||
@ -909,15 +783,6 @@ export class MigrationWizard extends HTMLElement {
|
||||
event.target != this.#browserProfileSelectorList
|
||||
) {
|
||||
this.#onBrowserProfileSelectionChanged(event.target);
|
||||
// If the user selected a file migration type from the selector, we'll
|
||||
// help the user out by immediately starting the file migration flow,
|
||||
// rather than waiting for them to click the "Select File".
|
||||
if (
|
||||
event.target.getAttribute("type") ==
|
||||
MigrationWizardConstants.MIGRATOR_TYPES.FILE
|
||||
) {
|
||||
this.#doImport();
|
||||
}
|
||||
} else if (event.target == this.#safariPermissionButton) {
|
||||
this.#requestSafariPermissions();
|
||||
} else if (event.currentTarget == this.#resourceSummary) {
|
||||
|
@ -2,11 +2,6 @@
|
||||
Migrators Reference
|
||||
===================
|
||||
|
||||
There are currently two types of migrators: browser migrators, and file migrators. Browser migrators will migrate various resources from another browser. A file migrator allows the user to migrate data through an intermediary file (like passwords from a .CSV file).
|
||||
|
||||
Browser migrators
|
||||
=================
|
||||
|
||||
MigratorBase class
|
||||
------------------
|
||||
.. js:autoclass:: MigratorBase
|
||||
@ -91,22 +86,3 @@ IEProfileMigrator class
|
||||
-----------------------
|
||||
.. js:autoclass:: IEProfileMigrator
|
||||
:members:
|
||||
|
||||
File migrators
|
||||
==============
|
||||
|
||||
.. js:autofunction:: FilePickerConfigurationFilter
|
||||
:short-name:
|
||||
|
||||
.. js:autofunction:: FilePickerConfiguration
|
||||
:short-name:
|
||||
|
||||
FileMigratorBase class
|
||||
----------------------
|
||||
.. js:autoclass:: FileMigratorBase
|
||||
:members:
|
||||
|
||||
PasswordFileMigrator class
|
||||
--------------------------
|
||||
.. js:autoclass:: PasswordFileMigrator
|
||||
:members:
|
||||
|
@ -25,7 +25,6 @@ XPIDL_MODULE = "migration"
|
||||
EXTRA_JS_MODULES += [
|
||||
"ChromeMigrationUtils.sys.mjs",
|
||||
"ChromeProfileMigrator.sys.mjs",
|
||||
"FileMigrators.sys.mjs",
|
||||
"FirefoxProfileMigrator.sys.mjs",
|
||||
"InternalTestingProfileMigrator.sys.mjs",
|
||||
"MigrationUtils.sys.mjs",
|
||||
|
@ -11,7 +11,6 @@ prefs =
|
||||
[browser_disabled_migrator.js]
|
||||
[browser_do_migration.js]
|
||||
[browser_entrypoint_telemetry.js]
|
||||
[browser_file_migration.js]
|
||||
[browser_ie_edge_bookmarks_success_strings.js]
|
||||
[browser_safari_permissions.js]
|
||||
run-if =
|
||||
|
@ -142,9 +142,7 @@ add_task(async function test_successful_migrations() {
|
||||
await wizardDone;
|
||||
|
||||
let dialog = prefsWin.document.querySelector("#migrationWizardDialog");
|
||||
let doneButton = shadow.querySelector(
|
||||
"div[name='page-progress'] .done-button"
|
||||
);
|
||||
let doneButton = shadow.querySelector("#done-button");
|
||||
|
||||
await new Promise(resolve => prefsWin.requestAnimationFrame(resolve));
|
||||
Assert.equal(
|
||||
@ -192,9 +190,7 @@ add_task(async function test_successful_migrations() {
|
||||
await wizardDone;
|
||||
|
||||
let dialog = prefsWin.document.querySelector("#migrationWizardDialog");
|
||||
let doneButton = shadow.querySelector(
|
||||
"div[name='page-progress'] .done-button"
|
||||
);
|
||||
let doneButton = shadow.querySelector("#done-button");
|
||||
|
||||
await new Promise(resolve => prefsWin.requestAnimationFrame(resolve));
|
||||
Assert.equal(
|
||||
@ -280,9 +276,7 @@ add_task(async function test_invalid_resource_type() {
|
||||
|
||||
let dialog = prefsWin.document.querySelector("#migrationWizardDialog");
|
||||
let shadow = wizard.openOrClosedShadowRoot;
|
||||
let doneButton = shadow.querySelector(
|
||||
"div[name='page-progress'] .done-button"
|
||||
);
|
||||
let doneButton = shadow.querySelector("#done-button");
|
||||
|
||||
await new Promise(resolve => prefsWin.requestAnimationFrame(resolve));
|
||||
Assert.equal(
|
||||
|
@ -1,178 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { FileMigratorBase } = ChromeUtils.importESModule(
|
||||
"resource:///modules/FileMigrators.sys.mjs"
|
||||
);
|
||||
|
||||
const DUMMY_FILEMIGRATOR_KEY = "dummy-file-migrator";
|
||||
const DUMMY_FILEPICKER_TITLE = "Some dummy file picker title";
|
||||
const DUMMY_FILTER_TITLE = "Some file type";
|
||||
const DUMMY_EXTENSION_PATTERN = "*.test";
|
||||
const TEST_FILE_PATH = "/some/dummy/path/file.test";
|
||||
|
||||
/**
|
||||
* A subclass of FileMigratorBase that doesn't do anything, but
|
||||
* is useful for testing.
|
||||
*
|
||||
* Notably, the `migrate` method is not overridden here. Tests that
|
||||
* use this class should use Sinon to stub out the migrate method.
|
||||
*/
|
||||
class DummyFileMigrator extends FileMigratorBase {
|
||||
static get key() {
|
||||
return DUMMY_FILEMIGRATOR_KEY;
|
||||
}
|
||||
|
||||
static get displayNameL10nID() {
|
||||
return "migration-wizard-migrator-display-name-file-password-csv";
|
||||
}
|
||||
|
||||
static get brandImage() {
|
||||
return "chrome://branding/content/document.ico";
|
||||
}
|
||||
|
||||
get progressHeaderL10nID() {
|
||||
return "migration-passwords-from-file-progress-header";
|
||||
}
|
||||
|
||||
get successHeaderL10nID() {
|
||||
return "migration-passwords-from-file-success-header";
|
||||
}
|
||||
|
||||
async getFilePickerConfig() {
|
||||
return Promise.resolve({
|
||||
title: DUMMY_FILEPICKER_TITLE,
|
||||
filters: [
|
||||
{
|
||||
title: DUMMY_FILTER_TITLE,
|
||||
extensionPattern: DUMMY_EXTENSION_PATTERN,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
get displayedResourceTypes() {
|
||||
return [MigrationWizardConstants.DISPLAYED_RESOURCE_TYPES.PASSWORDS];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the flow of selecting a file migrator (in this case,
|
||||
* the DummyFileMigrator), getting the file picker opened for it,
|
||||
* and then passing the path of the selected file to the migrator.
|
||||
*/
|
||||
add_task(async function test_file_migration() {
|
||||
let migrator = new DummyFileMigrator();
|
||||
let sandbox = sinon.createSandbox();
|
||||
registerCleanupFunction(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
// First, use Sinon to insert our DummyFileMigrator as the only available
|
||||
// file migrator.
|
||||
sandbox.stub(MigrationUtils, "getFileMigrator").callsFake(() => {
|
||||
return migrator;
|
||||
});
|
||||
sandbox.stub(MigrationUtils, "availableFileMigrators").get(() => {
|
||||
return [migrator];
|
||||
});
|
||||
|
||||
// This is the expected success state that our DummyFileMigrator will
|
||||
// return as the final progress update to the migration wizard.
|
||||
const SUCCESS_STATE = {
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]:
|
||||
"2 added",
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED]:
|
||||
"1 updated",
|
||||
};
|
||||
|
||||
let migrateStub = sandbox.stub(migrator, "migrate").callsFake(filePath => {
|
||||
Assert.equal(filePath, TEST_FILE_PATH);
|
||||
return SUCCESS_STATE;
|
||||
});
|
||||
|
||||
// We use MockFilePicker to simulate a native file picker, and prepare it
|
||||
// to return a dummy file pointed at TEST_FILE_PATH. The file at
|
||||
// TEST_FILE_PATH is not required (nor expected) to exist.
|
||||
const { MockFilePicker } = SpecialPowers;
|
||||
MockFilePicker.init(window);
|
||||
registerCleanupFunction(() => {
|
||||
MockFilePicker.cleanup();
|
||||
});
|
||||
|
||||
let dummyFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
dummyFile.initWithPath(TEST_FILE_PATH);
|
||||
let filePickerShownPromise = new Promise(resolve => {
|
||||
MockFilePicker.showCallback = () => {
|
||||
Assert.ok(true, "Filepicker shown.");
|
||||
MockFilePicker.setFiles([dummyFile]);
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
MockFilePicker.returnValue = MockFilePicker.returnOK;
|
||||
|
||||
await withMigrationWizardDialog(async prefsWin => {
|
||||
let dialogBody = prefsWin.document.body;
|
||||
let wizard = dialogBody.querySelector("migration-wizard");
|
||||
let shadow = wizard.openOrClosedShadowRoot;
|
||||
|
||||
let wizardDone = BrowserTestUtils.waitForEvent(
|
||||
wizard,
|
||||
"MigrationWizard:DoneMigration"
|
||||
);
|
||||
|
||||
// Now select our DummyFileMigrator from the list.
|
||||
let selector = shadow.querySelector("#browser-profile-selector");
|
||||
selector.click();
|
||||
|
||||
await new Promise(resolve => {
|
||||
wizard
|
||||
.querySelector("panel-list")
|
||||
.addEventListener("shown", resolve, { once: true });
|
||||
});
|
||||
|
||||
let panelItem = wizard.querySelector(
|
||||
`panel-item[key="${DUMMY_FILEMIGRATOR_KEY}"]`
|
||||
);
|
||||
panelItem.click();
|
||||
|
||||
// Selecting a file migrator from the selector should automatically
|
||||
// open the file picker, so we await it here. Once the file is
|
||||
// selected, migration should begin immediately.
|
||||
|
||||
await filePickerShownPromise;
|
||||
await wizardDone;
|
||||
Assert.ok(migrateStub.called, "Migrate on DummyFileMigrator was called.");
|
||||
|
||||
// At this point, with migration having completed, we should be showing
|
||||
// the PROGRESS page with the SUCCESS_STATE represented.
|
||||
let deck = shadow.querySelector("#wizard-deck");
|
||||
Assert.equal(
|
||||
deck.selectedViewName,
|
||||
`page-${MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS}`
|
||||
);
|
||||
|
||||
// We expect only the displayed resource types in SUCCESS_STATE are
|
||||
// displayed now.
|
||||
let progressGroups = shadow.querySelectorAll(
|
||||
"div[name='page-page-file-import-progress'] .resource-progress-group"
|
||||
);
|
||||
for (let progressGroup of progressGroups) {
|
||||
let expectedSuccessText =
|
||||
SUCCESS_STATE[progressGroup.dataset.resourceType];
|
||||
if (expectedSuccessText) {
|
||||
let successText = progressGroup.querySelector(".success-text")
|
||||
.textContent;
|
||||
Assert.equal(successText, expectedSuccessText);
|
||||
} else {
|
||||
Assert.ok(
|
||||
BrowserTestUtils.is_hidden(progressGroup),
|
||||
`Resource progress group for ${progressGroup.dataset.resourceType}` +
|
||||
` should be hidden.`
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
@ -76,9 +76,7 @@ add_task(async function test_ie_edge_bookmarks_success_strings() {
|
||||
);
|
||||
}
|
||||
|
||||
let doneButton = shadow.querySelector(
|
||||
"div[name='page-progress'] .done-button"
|
||||
);
|
||||
let doneButton = shadow.querySelector("#done-button");
|
||||
let dialogClosed = BrowserTestUtils.waitForEvent(dialog, "close");
|
||||
doneButton.click();
|
||||
await dialogClosed;
|
||||
|
@ -116,9 +116,7 @@ add_task(async function test_safari_permissions() {
|
||||
Assert.ok(true, "Completed migration");
|
||||
|
||||
let dialog = prefsWin.document.querySelector("#migrationWizardDialog");
|
||||
let doneButton = shadow.querySelector(
|
||||
"div[name='page-progress'] .done-button"
|
||||
);
|
||||
let doneButton = shadow.querySelector("#done-button");
|
||||
let dialogClosed = BrowserTestUtils.waitForEvent(dialog, "close");
|
||||
|
||||
doneButton.click();
|
||||
|
@ -27,14 +27,12 @@
|
||||
const MIGRATOR_PROFILE_INSTANCES = [
|
||||
{
|
||||
key: "some-browser-0",
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
displayName: "Some Browser 0",
|
||||
resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"],
|
||||
profile: { id: "person-2", name: "Person 2" },
|
||||
},
|
||||
{
|
||||
key: "some-browser-1",
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
displayName: "Some Browser 1",
|
||||
resourceTypes: ["HISTORY", "BOOKMARKS"],
|
||||
profile: null,
|
||||
@ -215,7 +213,6 @@
|
||||
page: MigrationWizardConstants.PAGES.SELECTION,
|
||||
migrators: [{
|
||||
key: "some-browser-0",
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
displayName: "Some Browser 0 with no resources",
|
||||
resourceTypes: [],
|
||||
profile: { id: "person-1", name: "Person 1" },
|
||||
@ -379,13 +376,11 @@
|
||||
page: MigrationWizardConstants.PAGES.SELECTION,
|
||||
migrators: [{
|
||||
key: "some-browser-0",
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
displayName: "Some Browser 0 with a single resource",
|
||||
resourceTypes: ["HISTORY"],
|
||||
profile: { id: "person-1", name: "Person 1" },
|
||||
}, {
|
||||
key: "some-browser-1",
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
displayName: "Some Browser 1 with a two resources",
|
||||
resourceTypes: ["HISTORY", "BOOKMARKS"],
|
||||
profile: { id: "person-2", name: "Person 2" },
|
||||
@ -532,7 +527,7 @@
|
||||
);
|
||||
|
||||
let progressPage = gShadowRoot.querySelector("div[name='page-progress']");
|
||||
let doneButton = progressPage.querySelector(".done-button");
|
||||
let doneButton = progressPage.querySelector("#done-button");
|
||||
ok(isHidden(doneButton), "Done button should be hidden");
|
||||
let cancelButton = progressPage.querySelector(".cancel-close");
|
||||
ok(!isHidden(cancelButton), "Cancel button should be visible");
|
||||
@ -632,146 +627,7 @@
|
||||
);
|
||||
|
||||
let progressPage = gShadowRoot.querySelector("div[name='page-progress']");
|
||||
let doneButton = progressPage.querySelector(".done-button");
|
||||
ok(!isHidden(doneButton), "Done button should be visible and enabled");
|
||||
let cancelButton = progressPage.querySelector(".cancel-close");
|
||||
ok(isHidden(cancelButton), "Cancel button should be hidden");
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that the wizard can show partial progress during file migration.
|
||||
*/
|
||||
add_task(async function test_partial_file_progress() {
|
||||
const PASSWORDS_SUCCESS_STRING = "Some passwords success string";
|
||||
const TITLE = "Partial progress";
|
||||
|
||||
gWiz.setState({
|
||||
page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS,
|
||||
title: "Partial progress",
|
||||
progress: {
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_FROM_FILE]: {
|
||||
inProgress: false,
|
||||
message: PASSWORDS_SUCCESS_STRING,
|
||||
},
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: {
|
||||
inProgress: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
is(
|
||||
gDeck.selectedViewName,
|
||||
"page-file-import-progress",
|
||||
"Should have the file progress page selected"
|
||||
);
|
||||
|
||||
let header = gShadowRoot.querySelector("#file-import-progress-header");
|
||||
is(header.textContent, TITLE, "Title is set correctly.");
|
||||
|
||||
let passwordsFromFileGroup = getResourceGroup(
|
||||
MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_FROM_FILE
|
||||
);
|
||||
ok(!isHidden(passwordsFromFileGroup), "Passwords from file group should be visible");
|
||||
let progressIcon = passwordsFromFileGroup.querySelector(".progress-icon");
|
||||
ok(
|
||||
progressIcon.classList.contains("completed"),
|
||||
"Progress should be completed"
|
||||
);
|
||||
is(
|
||||
passwordsFromFileGroup.querySelector(".success-text").textContent,
|
||||
PASSWORDS_SUCCESS_STRING
|
||||
);
|
||||
|
||||
let passwordsUpdatedGroup = getResourceGroup(
|
||||
MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED
|
||||
);
|
||||
ok(isHidden(passwordsUpdatedGroup), "Passwords updated group should be hidden");
|
||||
|
||||
let passwordsNewGroup = getResourceGroup(
|
||||
MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW
|
||||
);
|
||||
ok(!isHidden(passwordsNewGroup), "Passwords new group should be visible");
|
||||
progressIcon = passwordsNewGroup.querySelector(".progress-icon");
|
||||
ok(
|
||||
!progressIcon.classList.contains("completed"),
|
||||
"Progress should be still be underway"
|
||||
);
|
||||
is(passwordsNewGroup.querySelector(".success-text").textContent.trim(), "");
|
||||
|
||||
let progressPage = gShadowRoot.querySelector("div[name='page-file-import-progress']");
|
||||
let doneButton = progressPage.querySelector(".done-button");
|
||||
ok(isHidden(doneButton), "Done button should be hidden");
|
||||
let cancelButton = progressPage.querySelector(".cancel-close");
|
||||
ok(!isHidden(cancelButton), "Cancel button should be visible");
|
||||
ok(cancelButton.disabled, "Cancel button should be disabled");
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that the wizard can show completed migration progress.
|
||||
*/
|
||||
add_task(async function test_completed_file_progress() {
|
||||
const PASSWORDS_NEW_SUCCESS_STRING = "2 added";
|
||||
const PASSWORDS_UPDATED_SUCCESS_STRING = "5 updated";
|
||||
const TITLE = "Done doing file import";
|
||||
|
||||
gWiz.setState({
|
||||
page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS,
|
||||
title: TITLE,
|
||||
progress: {
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: {
|
||||
inProgress: false,
|
||||
message: PASSWORDS_NEW_SUCCESS_STRING,
|
||||
},
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED]: {
|
||||
inProgress: false,
|
||||
message: PASSWORDS_UPDATED_SUCCESS_STRING,
|
||||
},
|
||||
},
|
||||
});
|
||||
is(
|
||||
gDeck.selectedViewName,
|
||||
"page-file-import-progress",
|
||||
"Should have the file progress page selected"
|
||||
);
|
||||
|
||||
let header = gShadowRoot.querySelector("#file-import-progress-header");
|
||||
is(header.textContent, TITLE, "Title is set correctly.");
|
||||
|
||||
let passwordsNewGroup = getResourceGroup(
|
||||
MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW
|
||||
);
|
||||
ok(!isHidden(passwordsNewGroup), "Passwords new group should be visible");
|
||||
let progressIcon = passwordsNewGroup.querySelector(".progress-icon");
|
||||
ok(
|
||||
progressIcon.classList.contains("completed"),
|
||||
"Progress should be completed"
|
||||
);
|
||||
is(
|
||||
passwordsNewGroup.querySelector(".success-text").textContent,
|
||||
PASSWORDS_NEW_SUCCESS_STRING
|
||||
);
|
||||
|
||||
let passwordsUpdatedGroup = getResourceGroup(
|
||||
MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED
|
||||
);
|
||||
ok(!isHidden(passwordsUpdatedGroup), "Passwords updated group should be visible");
|
||||
progressIcon = passwordsUpdatedGroup.querySelector(".progress-icon");
|
||||
ok(
|
||||
progressIcon.classList.contains("completed"),
|
||||
"Progress should be completed"
|
||||
);
|
||||
is(
|
||||
passwordsUpdatedGroup.querySelector(".success-text").textContent,
|
||||
PASSWORDS_UPDATED_SUCCESS_STRING
|
||||
);
|
||||
|
||||
let passwordsFromFileGroup = getResourceGroup(
|
||||
MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_FROM_FILE
|
||||
);
|
||||
ok(isHidden(passwordsFromFileGroup), "Passwords from file group should be hidden");
|
||||
|
||||
let progressPage = gShadowRoot.querySelector("div[name='page-file-import-progress']");
|
||||
let doneButton = progressPage.querySelector(".done-button");
|
||||
let doneButton = progressPage.querySelector("#done-button");
|
||||
ok(!isHidden(doneButton), "Done button should be visible and enabled");
|
||||
let cancelButton = progressPage.querySelector(".cancel-close");
|
||||
ok(isHidden(cancelButton), "Cancel button should be hidden");
|
||||
|
@ -1,80 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { PasswordFileMigrator } = ChromeUtils.importESModule(
|
||||
"resource:///modules/FileMigrators.sys.mjs"
|
||||
);
|
||||
const { LoginCSVImport } = ChromeUtils.import(
|
||||
"resource://gre/modules/LoginCSVImport.jsm"
|
||||
);
|
||||
const { sinon } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/Sinon.sys.mjs"
|
||||
);
|
||||
const { MigrationWizardConstants } = ChromeUtils.importESModule(
|
||||
"chrome://browser/content/migration/migration-wizard-constants.mjs"
|
||||
);
|
||||
|
||||
/**
|
||||
* Tests that the PasswordFileMigrator properly subclasses FileMigratorBase
|
||||
* and delegates to the LoginCSVImport module.
|
||||
*/
|
||||
add_task(async function test_PasswordFileMigrator() {
|
||||
let migrator = new PasswordFileMigrator();
|
||||
Assert.ok(
|
||||
migrator.constructor.key,
|
||||
"PasswordFileMigrator implements static getter 'key'"
|
||||
);
|
||||
Assert.ok(
|
||||
migrator.constructor.displayNameL10nID,
|
||||
"PasswordFileMigrator implements static getter 'displayNameL10nID'"
|
||||
);
|
||||
Assert.ok(
|
||||
await migrator.getFilePickerConfig(),
|
||||
"PasswordFileMigrator returns something for getFilePickerConfig()"
|
||||
);
|
||||
Assert.ok(
|
||||
migrator.displayedResourceTypes,
|
||||
"PasswordFileMigrator returns something for displayedResourceTypes"
|
||||
);
|
||||
|
||||
let sandbox = sinon.createSandbox();
|
||||
registerCleanupFunction(() => {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
const IMPORT_SUMMARY = [
|
||||
{
|
||||
result: "added",
|
||||
},
|
||||
{
|
||||
result: "added",
|
||||
},
|
||||
{
|
||||
result: "modified",
|
||||
},
|
||||
];
|
||||
const EXPECTED_SUCCESS_STATE = {
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]:
|
||||
"2 added",
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_UPDATED]:
|
||||
"1 updated",
|
||||
};
|
||||
const FAKE_PATH = "some/fake/path.csv";
|
||||
|
||||
let importFromCSVStub = sandbox
|
||||
.stub(LoginCSVImport, "importFromCSV")
|
||||
.callsFake(somePath => {
|
||||
Assert.equal(somePath, FAKE_PATH, "Got expected path");
|
||||
return Promise.resolve(IMPORT_SUMMARY);
|
||||
});
|
||||
let result = await migrator.migrate(FAKE_PATH);
|
||||
|
||||
Assert.ok(importFromCSVStub.called, "The stub should have been called.");
|
||||
Assert.deepEqual(
|
||||
result,
|
||||
EXPECTED_SUCCESS_STATE,
|
||||
"Got back the expected success state."
|
||||
);
|
||||
});
|
@ -32,7 +32,6 @@ support-files =
|
||||
skip-if = os != "win"
|
||||
[test_Edge_registry_migration.js]
|
||||
skip-if = os != "win"
|
||||
[test_PasswordFileMigrator.js]
|
||||
[test_fx_telemetry.js]
|
||||
[test_IE_bookmarks.js]
|
||||
skip-if = !(os == "win" && bits == 64) # bug 1392396
|
||||
|
@ -19,9 +19,8 @@ export default {
|
||||
component: "migration-wizard",
|
||||
};
|
||||
|
||||
const FAKE_MIGRATOR_LIST = [
|
||||
const FAKE_BROWSER_LIST = [
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "chrome",
|
||||
displayName: "Chrome",
|
||||
resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"],
|
||||
@ -29,7 +28,6 @@ const FAKE_MIGRATOR_LIST = [
|
||||
brandImage: "chrome://browser/content/migration/brands/chrome.png",
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "chrome",
|
||||
displayName: "Chrome",
|
||||
resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"],
|
||||
@ -37,7 +35,6 @@ const FAKE_MIGRATOR_LIST = [
|
||||
brandImage: "chrome://browser/content/migration/brands/chrome.png",
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "ie",
|
||||
displayName: "Microsoft Internet Explorer",
|
||||
resourceTypes: ["HISTORY", "BOOKMARKS"],
|
||||
@ -45,14 +42,12 @@ const FAKE_MIGRATOR_LIST = [
|
||||
brandImage: "chrome://browser/content/migration/brands/ie.png",
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "edge",
|
||||
displayName: "Microsoft Edge Legacy",
|
||||
resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"],
|
||||
profile: null,
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "chromium-edge",
|
||||
displayName: "Microsoft Edge",
|
||||
resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"],
|
||||
@ -60,7 +55,6 @@ const FAKE_MIGRATOR_LIST = [
|
||||
brandImage: "chrome://browser/content/migration/brands/edge.png",
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "brave",
|
||||
displayName: "Brave",
|
||||
resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"],
|
||||
@ -68,14 +62,12 @@ const FAKE_MIGRATOR_LIST = [
|
||||
brandImage: "chrome://browser/content/migration/brands/brave.png",
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "internal-testing",
|
||||
displayName: "Internal Testing Migrator",
|
||||
resourceTypes: ["HISTORY", "PASSWORDS", "BOOKMARKS"],
|
||||
profile: null,
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "safari",
|
||||
displayName: "Safari",
|
||||
resourceTypes: ["HISTORY", "PASSWORDS", "BOOKMARKS"],
|
||||
@ -83,7 +75,6 @@ const FAKE_MIGRATOR_LIST = [
|
||||
brandImage: "chrome://browser/content/migration/brands/safari.png",
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "opera",
|
||||
displayName: "Opera",
|
||||
resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"],
|
||||
@ -91,7 +82,6 @@ const FAKE_MIGRATOR_LIST = [
|
||||
brandImage: "chrome://browser/content/migration/brands/opera.png",
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "opera-gx",
|
||||
displayName: "Opera GX",
|
||||
resourceTypes: ["HISTORY", "FORMDATA", "PASSWORDS", "BOOKMARKS"],
|
||||
@ -99,7 +89,6 @@ const FAKE_MIGRATOR_LIST = [
|
||||
brandImage: "chrome://browser/content/migration/brands/operagx.png",
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "vivaldi",
|
||||
displayName: "Vivaldi",
|
||||
resourceTypes: ["HISTORY"],
|
||||
@ -107,26 +96,11 @@ const FAKE_MIGRATOR_LIST = [
|
||||
brandImage: "chrome://browser/content/migration/brands/vivaldi.png",
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.BROWSER,
|
||||
key: "no-resources-browser",
|
||||
displayName: "Browser with no resources",
|
||||
resourceTypes: [],
|
||||
profile: { id: "Default", name: "Default" },
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.FILE,
|
||||
key: "file-password-csv",
|
||||
displayName: "Passwords from CSV file",
|
||||
brandImage: "chrome://branding/content/document.ico",
|
||||
resourceTypes: [],
|
||||
},
|
||||
{
|
||||
type: MigrationWizardConstants.MIGRATOR_TYPES.FILE,
|
||||
key: "file-bookmarks",
|
||||
displayName: "Bookmarks from file",
|
||||
brandImage: "chrome://branding/content/document.ico",
|
||||
resourceTypes: [],
|
||||
},
|
||||
];
|
||||
|
||||
const Template = ({ state, dialogMode }) => html`
|
||||
@ -158,7 +132,7 @@ MainSelectorVariant1.args = {
|
||||
dialogMode: true,
|
||||
state: {
|
||||
page: MigrationWizardConstants.PAGES.SELECTION,
|
||||
migrators: FAKE_MIGRATOR_LIST,
|
||||
migrators: FAKE_BROWSER_LIST,
|
||||
showImportAll: false,
|
||||
},
|
||||
};
|
||||
@ -168,7 +142,7 @@ MainSelectorVariant2.args = {
|
||||
dialogMode: true,
|
||||
state: {
|
||||
page: MigrationWizardConstants.PAGES.SELECTION,
|
||||
migrators: FAKE_MIGRATOR_LIST,
|
||||
migrators: FAKE_BROWSER_LIST,
|
||||
showImportAll: true,
|
||||
},
|
||||
};
|
||||
@ -248,41 +222,6 @@ Success.args = {
|
||||
},
|
||||
};
|
||||
|
||||
export const FileImportProgress = Template.bind({});
|
||||
FileImportProgress.args = {
|
||||
dialogMode: true,
|
||||
state: {
|
||||
page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS,
|
||||
title: "Importing Passwords",
|
||||
progress: {
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES
|
||||
.PASSWORDS_FROM_FILE]: {
|
||||
inProgress: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const FileImportSuccess = Template.bind({});
|
||||
FileImportSuccess.args = {
|
||||
dialogMode: true,
|
||||
state: {
|
||||
page: MigrationWizardConstants.PAGES.FILE_IMPORT_PROGRESS,
|
||||
title: "Passwords Imported Successfully",
|
||||
progress: {
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES.PASSWORDS_NEW]: {
|
||||
inProgress: false,
|
||||
message: "2 added",
|
||||
},
|
||||
[MigrationWizardConstants.DISPLAYED_FILE_RESOURCE_TYPES
|
||||
.PASSWORDS_UPDATED]: {
|
||||
inProgress: false,
|
||||
message: "14 updated",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const SafariPermissions = Template.bind({});
|
||||
SafariPermissions.args = {
|
||||
dialogMode: true,
|
||||
|
@ -37,7 +37,6 @@ migration-wizard-migrator-display-name-chromium-edge = Microsoft Edge
|
||||
migration-wizard-migrator-display-name-chromium-edge-beta = Microsoft Edge Beta
|
||||
migration-wizard-migrator-display-name-edge-legacy = Microsoft Edge Legacy
|
||||
migration-wizard-migrator-display-name-firefox = Firefox
|
||||
migration-wizard-migrator-display-name-file-password-csv = Passwords from CSV file
|
||||
migration-wizard-migrator-display-name-ie = Microsoft Internet Explorer
|
||||
migration-wizard-migrator-display-name-opera = Opera
|
||||
migration-wizard-migrator-display-name-opera-gx = Opera GX
|
||||
@ -62,53 +61,7 @@ migration-favorites-option-label = Favorites
|
||||
migration-logins-and-passwords-option-label = Saved logins and passwords
|
||||
migration-history-option-label = Browsing history
|
||||
migration-form-autofill-option-label = Form autofill data
|
||||
|
||||
migration-passwords-from-file-progress-header = Import Passwords File
|
||||
migration-passwords-from-file-success-header = Passwords Imported Successfully
|
||||
migration-passwords-from-file = Checking file for passwords
|
||||
migration-passwords-new = New passwords
|
||||
migration-passwords-updated = Existing passwords
|
||||
|
||||
migration-passwords-from-file-picker-title = Import Passwords File
|
||||
# A description for the .csv file format that may be shown as the file type
|
||||
# filter by the operating system.
|
||||
migration-passwords-from-file-csv-filter-title =
|
||||
{ PLATFORM() ->
|
||||
[macos] CSV Document
|
||||
*[other] CSV File
|
||||
}
|
||||
# A description for the .tsv file format that may be shown as the file type
|
||||
# filter by the operating system. TSV is short for 'tab separated values'.
|
||||
migration-passwords-from-file-tsv-filter-title =
|
||||
{ PLATFORM() ->
|
||||
[macos] TSV Document
|
||||
*[other] TSV File
|
||||
}
|
||||
|
||||
# Shown in the migration wizard after importing passwords from a file
|
||||
# has completed, if new passwords were added.
|
||||
#
|
||||
# Variables:
|
||||
# $newEntries (Number): the number of new successfully imported passwords
|
||||
migration-wizard-progress-success-new-passwords =
|
||||
{ $newEntries ->
|
||||
[one] { $newEntries } added
|
||||
*[other] { $newEntries } added
|
||||
}
|
||||
|
||||
# Shown in the migration wizard after importing passwords from a file
|
||||
# has completed, if existing passwords were updated.
|
||||
#
|
||||
# Variables:
|
||||
# $updatedEntries (Number): the number of updated passwords
|
||||
migration-wizard-progress-success-updated-passwords =
|
||||
{ $updatedEntries ->
|
||||
[one] { $updatedEntries } updated
|
||||
*[other] { $updatedEntries } updated
|
||||
}
|
||||
|
||||
migration-import-button-label = Import
|
||||
migration-import-from-file-button-label = Select File
|
||||
migration-cancel-button-label = Cancel
|
||||
migration-done-button-label = Done
|
||||
|
||||
|
@ -142,10 +142,6 @@ div[name="page-selection"][show-import-all] #select-all {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
div[name="page-selection"][migrator-type="browser"] > .buttons > #import-from-file,
|
||||
div[name="page-selection"][migrator-type="file"] > .buttons > #import,
|
||||
div[name="page-selection"][migrator-type="file"] > .resource-selection-details,
|
||||
div[name="page-selection"][migrator-type="file"] > .resource-selection-preamble,
|
||||
div[name="page-selection"][show-import-all] .resource-selection-preamble {
|
||||
display: none;
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
# coding=utf8
|
||||
|
||||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
from __future__ import absolute_import
|
||||
import fluent.syntax.ast as FTL
|
||||
from fluent.migrate import COPY_PATTERN
|
||||
from fluent.migrate.helpers import transforms_from
|
||||
|
||||
|
||||
def migrate(ctx):
|
||||
"""Bug 1821187 - Copy password file import strings to migrationWizard.ftl, part {index}."""
|
||||
|
||||
ctx.add_transforms(
|
||||
"browser/browser/migrationWizard.ftl",
|
||||
"browser/browser/migrationWizard.ftl",
|
||||
transforms_from(
|
||||
"""
|
||||
migration-passwords-from-file-csv-filter-title =
|
||||
{COPY_PATTERN(from_path, "about-logins-import-file-picker-csv-filter-title")}
|
||||
migration-passwords-from-file-tsv-filter-title =
|
||||
{COPY_PATTERN(from_path, "about-logins-import-file-picker-tsv-filter-title")}
|
||||
""",
|
||||
from_path="browser/browser/aboutLogins.ftl",
|
||||
),
|
||||
)
|
Loading…
Reference in New Issue
Block a user