Bug 1802961 - Convert MigratorPrototype into an ES6 class and move into its own ESM as MigratorBase to be subclassed. r=NeilDeakin

Differential Revision: https://phabricator.services.mozilla.com/D163257
This commit is contained in:
Mike Conley
2022-12-06 14:46:42 +00:00
parent 50a3d421f7
commit 16b3a62829
9 changed files with 1598 additions and 1481 deletions

View File

@@ -5,10 +5,8 @@
import { FileUtils } from "resource://gre/modules/FileUtils.sys.mjs";
const { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm");
import {
MigrationUtils,
MigratorPrototype,
} from "resource:///modules/MigrationUtils.sys.mjs";
import { MigrationUtils } from "resource:///modules/MigrationUtils.sys.mjs";
import { MigratorBase } from "resource:///modules/MigratorBase.sys.mjs";
const lazy = {};
@@ -344,135 +342,134 @@ SearchStrings.prototype = {
},
};
export function SafariProfileMigrator() {}
SafariProfileMigrator.prototype = Object.create(MigratorPrototype);
SafariProfileMigrator.prototype.getResources = function SM_getResources() {
let profileDir = FileUtils.getDir("ULibDir", ["Safari"], false);
if (!profileDir.exists()) {
return null;
/**
* Safari migrator
*/
export class SafariProfileMigrator extends MigratorBase {
get classDescription() {
return "Safari Profile Migrator";
}
let resources = [];
let pushProfileFileResource = function(aFileName, aConstructor) {
let file = profileDir.clone();
file.append(aFileName);
if (file.exists()) {
resources.push(new aConstructor(file));
get contractID() {
return "@mozilla.org/profile/migrator;1?app=browser&type=safari";
}
get classID() {
return Components.ID("{4b609ecf-60b2-4655-9df4-dc149e474da1}");
}
getResources() {
let profileDir = FileUtils.getDir("ULibDir", ["Safari"], false);
if (!profileDir.exists()) {
return null;
}
};
pushProfileFileResource("History.plist", History);
pushProfileFileResource("Bookmarks.plist", Bookmarks);
let resources = [];
let pushProfileFileResource = function(aFileName, aConstructor) {
let file = profileDir.clone();
file.append(aFileName);
if (file.exists()) {
resources.push(new aConstructor(file));
}
};
// The Reading List feature was introduced at the same time in Windows and
// Mac versions of Safari. Not surprisingly, they are stored in the same
// format in both versions. Surpsingly, only on Windows there is a
// separate property list for it. This code is used on mac too, because
// Apple may fix this at some point.
pushProfileFileResource("ReadingList.plist", Bookmarks);
pushProfileFileResource("History.plist", History);
pushProfileFileResource("Bookmarks.plist", Bookmarks);
let prefs = this.mainPreferencesPropertyList;
if (prefs) {
resources.push(new SearchStrings(prefs));
// The Reading List feature was introduced at the same time in Windows and
// Mac versions of Safari. Not surprisingly, they are stored in the same
// format in both versions. Surpsingly, only on Windows there is a
// separate property list for it. This code is used on mac too, because
// Apple may fix this at some point.
pushProfileFileResource("ReadingList.plist", Bookmarks);
let prefs = this.mainPreferencesPropertyList;
if (prefs) {
resources.push(new SearchStrings(prefs));
}
return resources;
}
return resources;
};
SafariProfileMigrator.prototype.getLastUsedDate = function SM_getLastUsedDate() {
let profileDir = FileUtils.getDir("ULibDir", ["Safari"], false);
let datePromises = ["Bookmarks.plist", "History.plist"].map(file => {
let path = OS.Path.join(profileDir.path, file);
return OS.File.stat(path)
.catch(() => null)
.then(info => {
return info ? info.lastModificationDate : 0;
});
});
return Promise.all(datePromises).then(dates => {
return new Date(Math.max.apply(Math, dates));
});
};
SafariProfileMigrator.prototype.hasPermissions = async function SM_hasPermissions() {
if (this._hasPermissions) {
return true;
getLastUsedDate() {
let profileDir = FileUtils.getDir("ULibDir", ["Safari"], false);
let datePromises = ["Bookmarks.plist", "History.plist"].map(file => {
let path = OS.Path.join(profileDir.path, file);
return OS.File.stat(path)
.catch(() => null)
.then(info => {
return info ? info.lastModificationDate : 0;
});
});
return Promise.all(datePromises).then(dates => {
return new Date(Math.max.apply(Math, dates));
});
}
// Check if we have access:
let target = FileUtils.getDir(
"ULibDir",
["Safari", "Bookmarks.plist"],
false
);
try {
// 'stat' is always allowed, but reading is somehow not, if the user hasn't
// allowed it:
await IOUtils.read(target.path, { maxBytes: 1 });
this._hasPermissions = true;
return true;
} catch (ex) {
return false;
}
};
SafariProfileMigrator.prototype.getPermissions = async function SM_getPermissions(
win
) {
// Keep prompting the user until they pick a file that grants us access,
// or they cancel out of the file open panel.
while (!(await this.hasPermissions())) {
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
// The title (second arg) is not displayed on macOS, so leave it blank.
fp.init(win, "", Ci.nsIFilePicker.modeOpen);
// This is a little weird. You'd expect that it matters which file
// the user picks, but it doesn't really, as long as it's in this
// directory. Anyway, let's not confuse the user: the sensible idea
// here is to ask for permissions for Bookmarks.plist, and we'll
// silently accept whatever input as long as we can then read the plist.
fp.appendFilter("plist", "*.plist");
fp.filterIndex = 1;
fp.displayDirectory = FileUtils.getDir("ULibDir", ["Safari"], false);
// Now wait for the filepicker to open and close. If the user picks
// any file in this directory, macOS will grant us read access, so
// we don't need to check or do anything else with the file returned
// by the filepicker.
let result = await new Promise(resolve => fp.open(resolve));
// Bail if the user cancels the dialog:
if (result == Ci.nsIFilePicker.returnCancel) {
async hasPermissions() {
if (this._hasPermissions) {
return true;
}
// Check if we have access:
let target = FileUtils.getDir(
"ULibDir",
["Safari", "Bookmarks.plist"],
false
);
try {
// 'stat' is always allowed, but reading is somehow not, if the user hasn't
// allowed it:
await IOUtils.read(target.path, { maxBytes: 1 });
this._hasPermissions = true;
return true;
} catch (ex) {
return false;
}
}
};
Object.defineProperty(
SafariProfileMigrator.prototype,
"mainPreferencesPropertyList",
{
get: function get_mainPreferencesPropertyList() {
if (this._mainPreferencesPropertyList === undefined) {
let file = FileUtils.getDir("UsrPrfs", [], false);
if (file.exists()) {
file.append("com.apple.Safari.plist");
if (file.exists()) {
this._mainPreferencesPropertyList = new MainPreferencesPropertyList(
file
);
return this._mainPreferencesPropertyList;
}
}
this._mainPreferencesPropertyList = null;
return this._mainPreferencesPropertyList;
async getPermissions(win) {
// Keep prompting the user until they pick a file that grants us access,
// or they cancel out of the file open panel.
while (!(await this.hasPermissions())) {
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
// The title (second arg) is not displayed on macOS, so leave it blank.
fp.init(win, "", Ci.nsIFilePicker.modeOpen);
// This is a little weird. You'd expect that it matters which file
// the user picks, but it doesn't really, as long as it's in this
// directory. Anyway, let's not confuse the user: the sensible idea
// here is to ask for permissions for Bookmarks.plist, and we'll
// silently accept whatever input as long as we can then read the plist.
fp.appendFilter("plist", "*.plist");
fp.filterIndex = 1;
fp.displayDirectory = FileUtils.getDir("ULibDir", ["Safari"], false);
// Now wait for the filepicker to open and close. If the user picks
// any file in this directory, macOS will grant us read access, so
// we don't need to check or do anything else with the file returned
// by the filepicker.
let result = await new Promise(resolve => fp.open(resolve));
// Bail if the user cancels the dialog:
if (result == Ci.nsIFilePicker.returnCancel) {
return false;
}
return this._mainPreferencesPropertyList;
},
}
return true;
}
);
SafariProfileMigrator.prototype.classDescription = "Safari Profile Migrator";
SafariProfileMigrator.prototype.contractID =
"@mozilla.org/profile/migrator;1?app=browser&type=safari";
SafariProfileMigrator.prototype.classID = Components.ID(
"{4b609ecf-60b2-4655-9df4-dc149e474da1}"
);
get mainPreferencesPropertyList() {
if (this._mainPreferencesPropertyList === undefined) {
let file = FileUtils.getDir("UsrPrfs", [], false);
if (file.exists()) {
file.append("com.apple.Safari.plist");
if (file.exists()) {
this._mainPreferencesPropertyList = new MainPreferencesPropertyList(
file
);
return this._mainPreferencesPropertyList;
}
}
this._mainPreferencesPropertyList = null;
return this._mainPreferencesPropertyList;
}
return this._mainPreferencesPropertyList;
}
}