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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user