IEProfileMigrator.sys.mjs (3948B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { MigrationUtils } from "resource:///modules/MigrationUtils.sys.mjs"; 6 import { MigratorBase } from "resource:///modules/MigratorBase.sys.mjs"; 7 import { MSMigrationUtils } from "resource:///modules/MSMigrationUtils.sys.mjs"; 8 9 import { PlacesUtils } from "resource://gre/modules/PlacesUtils.sys.mjs"; 10 11 // Resources 12 13 // eslint-disable-next-line no-shadow 14 function History() {} 15 16 History.prototype = { 17 type: MigrationUtils.resourceTypes.HISTORY, 18 19 get exists() { 20 return true; 21 }, 22 23 migrate: function H_migrate(aCallback) { 24 let pageInfos = []; 25 let typedURLs = MSMigrationUtils.getTypedURLs( 26 "Software\\Microsoft\\Internet Explorer" 27 ); 28 let now = new Date(); 29 let maxDate = new Date( 30 Date.now() - MigrationUtils.HISTORY_MAX_AGE_IN_MILLISECONDS 31 ); 32 33 for (let entry of Cc[ 34 "@mozilla.org/profile/migrator/iehistoryenumerator;1" 35 ].createInstance(Ci.nsISimpleEnumerator)) { 36 let url = entry.get("uri").QueryInterface(Ci.nsIURI); 37 // MSIE stores some types of URLs in its history that we don't handle, 38 // like HTMLHelp and others. Since we don't properly map handling for 39 // all of them we just avoid importing them. 40 if (!["http", "https", "ftp", "file"].includes(url.scheme)) { 41 continue; 42 } 43 44 let title = entry.get("title"); 45 // Embed visits have no title and don't need to be imported. 46 if (!title.length) { 47 continue; 48 } 49 50 // The typed urls are already fixed-up, so we can use them for comparison. 51 let transition = typedURLs.has(url.spec) 52 ? PlacesUtils.history.TRANSITIONS.LINK 53 : PlacesUtils.history.TRANSITIONS.TYPED; 54 55 let time = entry.get("time"); 56 57 let visitDate = time ? PlacesUtils.toDate(time) : null; 58 if (visitDate && visitDate < maxDate) { 59 continue; 60 } 61 62 pageInfos.push({ 63 url, 64 title, 65 visits: [ 66 { 67 transition, 68 // use the current date if we have no visits for this entry. 69 date: visitDate ?? now, 70 }, 71 ], 72 }); 73 } 74 75 // Check whether there is any history to import. 76 if (!pageInfos.length) { 77 aCallback(true); 78 return; 79 } 80 81 MigrationUtils.insertVisitsWrapper(pageInfos).then( 82 () => aCallback(true), 83 () => aCallback(false) 84 ); 85 }, 86 }; 87 88 /** 89 * Internet Explorer profile migrator 90 */ 91 export class IEProfileMigrator extends MigratorBase { 92 static get key() { 93 return "ie"; 94 } 95 96 static get displayNameL10nID() { 97 return "migration-wizard-migrator-display-name-ie"; 98 } 99 100 static get brandImage() { 101 return "chrome://browser/content/migration/brands/ie.png"; 102 } 103 104 getResources() { 105 let resources = [MSMigrationUtils.getBookmarksMigrator(), new History()]; 106 let windowsVaultFormPasswordsMigrator = 107 MSMigrationUtils.getWindowsVaultFormPasswordsMigrator(); 108 windowsVaultFormPasswordsMigrator.name = "IEVaultFormPasswords"; 109 resources.push(windowsVaultFormPasswordsMigrator); 110 return resources.filter(r => r.exists); 111 } 112 113 async getLastUsedDate() { 114 const datePromises = ["Favs", "CookD"].map(dirId => { 115 const { path } = Services.dirsvc.get(dirId, Ci.nsIFile); 116 return IOUtils.stat(path) 117 .then(info => info.lastModified) 118 .catch(() => 0); 119 }); 120 121 const dates = await Promise.all(datePromises); 122 123 try { 124 const typedURLs = MSMigrationUtils.getTypedURLs( 125 "Software\\Microsoft\\Internet Explorer" 126 ); 127 // typedURLs.values() returns an array of PRTimes, which are in 128 // microseconds - convert to milliseconds 129 dates.push(Math.max(0, ...typedURLs.values()) / 1000); 130 } catch (ex) {} 131 132 return new Date(Math.max(...dates)); 133 } 134 }