summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--application/palemoon/base/content/browser.js70
-rw-r--r--application/palemoon/components/build/moz.build1
-rw-r--r--application/palemoon/components/build/nsBrowserCompsCID.h8
-rw-r--r--application/palemoon/components/build/nsModule.cpp20
-rw-r--r--application/palemoon/components/migration/BrowserProfileMigrators.manifest14
-rw-r--r--application/palemoon/components/migration/ChromeProfileMigrator.js463
-rw-r--r--application/palemoon/components/migration/FirefoxProfileMigrator.js117
-rw-r--r--application/palemoon/components/migration/IEProfileMigrator.js521
-rw-r--r--application/palemoon/components/migration/MigrationUtils.jsm657
-rw-r--r--application/palemoon/components/migration/ProfileMigrator.js21
-rw-r--r--application/palemoon/components/migration/SafariProfileMigrator.js416
-rw-r--r--application/palemoon/components/migration/content/migration.js474
-rw-r--r--application/palemoon/components/migration/content/migration.xul96
-rw-r--r--application/palemoon/components/migration/jar.mn7
-rw-r--r--application/palemoon/components/migration/moz.build53
-rw-r--r--application/palemoon/components/migration/nsIBrowserProfileMigrator.idl63
-rw-r--r--application/palemoon/components/migration/nsIEHistoryEnumerator.cpp119
-rw-r--r--application/palemoon/components/migration/nsIEHistoryEnumerator.h37
-rw-r--r--application/palemoon/components/migration/nsWindowsMigrationUtils.h36
-rw-r--r--application/palemoon/components/moz.build1
-rw-r--r--application/palemoon/components/nsBrowserGlue.js3
-rw-r--r--application/palemoon/components/places/content/places.js9
-rw-r--r--application/palemoon/components/places/content/places.xul7
-rw-r--r--application/palemoon/locales/en-US/chrome/browser/migration/migration.dtd36
-rw-r--r--application/palemoon/locales/en-US/chrome/browser/migration/migration.properties51
-rw-r--r--application/palemoon/locales/en-US/chrome/browser/places/places.dtd2
-rw-r--r--application/palemoon/locales/jar.mn2
-rw-r--r--browser/base/content/browser-places.js33
-rw-r--r--browser/components/places/content/editBookmarkOverlay.js72
-rw-r--r--build/valgrind/x86_64-redhat-linux-gnu.sup1
-rw-r--r--modules/libpref/init/all.js2
-rw-r--r--toolkit/components/alerts/resources/content/alert.css1
-rw-r--r--toolkit/components/alerts/resources/content/alert.js10
-rw-r--r--toolkit/components/passwordmgr/content/passwordManager.js2
-rw-r--r--toolkit/components/passwordmgr/content/passwordManager.xul2
-rw-r--r--toolkit/components/passwordmgr/jar.mn2
-rw-r--r--toolkit/locales/en-US/chrome/places/places.properties1
-rw-r--r--toolkit/themes/windows/mozapps/jar.mn1
-rw-r--r--widget/gtk/WidgetStyleCache.cpp159
-rw-r--r--widget/gtk/gtk3drawing.cpp285
-rw-r--r--widget/gtk/gtkdrawing.h18
-rw-r--r--widget/gtk/nsLookAndFeel.cpp201
-rw-r--r--widget/gtk/nsLookAndFeel.h3
-rw-r--r--widget/gtk/nsWindow.cpp16
44 files changed, 516 insertions, 3597 deletions
diff --git a/application/palemoon/base/content/browser.js b/application/palemoon/base/content/browser.js
index 8cc091e85..8b3fa0b4f 100644
--- a/application/palemoon/base/content/browser.js
+++ b/application/palemoon/base/content/browser.js
@@ -2017,49 +2017,43 @@ function readFromClipboard()
return url;
}
-function BrowserViewSourceOfDocument(aDocument)
+function BrowserViewSourceOfDocument(aArgsOrDocument)
{
- var pageCookie;
- var webNav;
-
- // Get the document charset
- var docCharset = "charset=" + aDocument.characterSet;
-
- // Get the nsIWebNavigation associated with the document
- try {
- var win;
- var ifRequestor;
-
- // Get the DOMWindow for the requested document. If the DOMWindow
- // cannot be found, then just use the content window...
- //
- // XXX: This is a bit of a hack...
- win = aDocument.defaultView;
- if (win == window) {
- win = content;
- }
- ifRequestor = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
-
- webNav = ifRequestor.getInterface(nsIWebNavigation);
- } catch(err) {
- // If nsIWebNavigation cannot be found, just get the one for the whole
- // window...
- webNav = gBrowser.webNavigation;
+ let args;
+
+ if (aArgsOrDocument instanceof Document) {
+ let doc = aArgsOrDocument;
+
+ let requestor = doc.defaultView
+ .QueryInterface(Ci.nsIInterfaceRequestor);
+ let browser = requestor.getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell)
+ .chromeEventHandler;
+ let outerWindowID = requestor.getInterface(Ci.nsIDOMWindowUtils)
+ .outerWindowID;
+ let URL = browser.currentURI.spec;
+ args = { browser, outerWindowID, URL };
+ } else {
+ args = aArgsOrDocument;
}
- //
- // Get the 'PageDescriptor' for the current document. This allows the
- // view-source to access the cached copy of the content rather than
- // refetching it from the network...
- //
- try{
- var PageLoader = webNav.QueryInterface(Components.interfaces.nsIWebPageDescriptor);
- pageCookie = PageLoader.currentDescriptor;
- } catch(err) {
- // If no page descriptor is available, just use the view-source URL...
+ let viewInternal = () => {
+ top.gViewSourceUtils.viewSource(args);
}
- top.gViewSourceUtils.viewSource(webNav.currentURI.spec, pageCookie, aDocument);
+ // Check if external view source is enabled. If so, try it. If it fails,
+ // fallback to internal view source.
+ if (Services.prefs.getBoolPref("view_source.editor.external")) {
+ top.gViewSourceUtils
+ .openInExternalEditor(args, null, null, null, result => {
+ if (!result) {
+ viewInternal();
+ }
+ });
+ } else {
+ // Display using internal view source
+ viewInternal();
+ }
}
// doc - document to use for source, or null for this window's document
diff --git a/application/palemoon/components/build/moz.build b/application/palemoon/components/build/moz.build
index 5bc4858d7..c85723e16 100644
--- a/application/palemoon/components/build/moz.build
+++ b/application/palemoon/components/build/moz.build
@@ -18,7 +18,6 @@ LOCAL_INCLUDES += [
'../about',
'../dirprovider',
'../feeds',
- '../migration',
'../shell',
]
diff --git a/application/palemoon/components/build/nsBrowserCompsCID.h b/application/palemoon/components/build/nsBrowserCompsCID.h
index e325e43d4..23670ae80 100644
--- a/application/palemoon/components/build/nsBrowserCompsCID.h
+++ b/application/palemoon/components/build/nsBrowserCompsCID.h
@@ -4,14 +4,6 @@
/////////////////////////////////////////////////////////////////////////////
-#ifdef XP_WIN
-#define NS_WINIEHISTORYENUMERATOR_CID \
-{ 0x93480624, 0x806e, 0x4756, { 0xb7, 0xcb, 0x0f, 0xb7, 0xdd, 0x74, 0x6a, 0x8f } }
-
-#define NS_IEHISTORYENUMERATOR_CONTRACTID \
- "@mozilla.org/profile/migrator/iehistoryenumerator;1"
-#endif
-
#define NS_SHELLSERVICE_CID \
{ 0x63c7b9f4, 0xcc8, 0x43f8, { 0xb6, 0x66, 0xa, 0x66, 0x16, 0x55, 0xcb, 0x73 } }
diff --git a/application/palemoon/components/build/nsModule.cpp b/application/palemoon/components/build/nsModule.cpp
index fad87d831..304280ca9 100644
--- a/application/palemoon/components/build/nsModule.cpp
+++ b/application/palemoon/components/build/nsModule.cpp
@@ -16,10 +16,6 @@
#include "nsGNOMEShellService.h"
#endif
-#if defined(XP_WIN)
-#include "nsIEHistoryEnumerator.h"
-#endif
-
#include "rdf.h"
#include "nsFeedSniffer.h"
#include "AboutRedirector.h"
@@ -40,10 +36,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
#endif
-#if defined(XP_WIN)
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEHistoryEnumerator)
-#endif
-
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
NS_DEFINE_NAMED_CID(NS_BROWSERDIRECTORYPROVIDER_CID);
@@ -54,9 +46,7 @@ NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
#endif
NS_DEFINE_NAMED_CID(NS_FEEDSNIFFER_CID);
NS_DEFINE_NAMED_CID(NS_BROWSER_ABOUT_REDIRECTOR_CID);
-#if defined(XP_WIN)
-NS_DEFINE_NAMED_CID(NS_WINIEHISTORYENUMERATOR_CID);
-#elif defined(XP_MACOSX)
+#ifdef XP_MACOSX
NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
#endif
@@ -69,9 +59,7 @@ static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
#endif
{ &kNS_FEEDSNIFFER_CID, false, nullptr, nsFeedSnifferConstructor },
{ &kNS_BROWSER_ABOUT_REDIRECTOR_CID, false, nullptr, AboutRedirector::Create },
-#if defined(XP_WIN)
- { &kNS_WINIEHISTORYENUMERATOR_CID, false, nullptr, nsIEHistoryEnumeratorConstructor },
-#elif defined(XP_MACOSX)
+#ifdef XP_MACOSX
{ &kNS_SHELLSERVICE_CID, false, nullptr, nsMacShellServiceConstructor },
#endif
{ nullptr }
@@ -101,9 +89,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "downloads", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
-#if defined(XP_WIN)
- { NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID },
-#elif defined(XP_MACOSX)
+#ifdef XP_MACOSX
{ NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
#endif
{ nullptr }
diff --git a/application/palemoon/components/migration/BrowserProfileMigrators.manifest b/application/palemoon/components/migration/BrowserProfileMigrators.manifest
deleted file mode 100644
index d7fec75e3..000000000
--- a/application/palemoon/components/migration/BrowserProfileMigrators.manifest
+++ /dev/null
@@ -1,14 +0,0 @@
-component {6F8BB968-C14F-4D6F-9733-6C6737B35DCE} ProfileMigrator.js
-contract @mozilla.org/toolkit/profile-migrator;1 {6F8BB968-C14F-4D6F-9733-6C6737B35DCE}
-component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js
-contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26}
-component {91185366-ba97-4438-acba-48deaca63386} FirefoxProfileMigrator.js
-contract @mozilla.org/profile/migrator;1?app=browser&type=firefox {91185366-ba97-4438-acba-48deaca63386}
-#ifdef HAS_IE_MIGRATOR
-component {3d2532e3-4932-4774-b7ba-968f5899d3a4} IEProfileMigrator.js
-contract @mozilla.org/profile/migrator;1?app=browser&type=ie {3d2532e3-4932-4774-b7ba-968f5899d3a4}
-#endif
-#ifdef HAS_SAFARI_MIGRATOR
-component {4b609ecf-60b2-4655-9df4-dc149e474da1} SafariProfileMigrator.js
-contract @mozilla.org/profile/migrator;1?app=browser&type=safari {4b609ecf-60b2-4655-9df4-dc149e474da1}
-#endif
diff --git a/application/palemoon/components/migration/ChromeProfileMigrator.js b/application/palemoon/components/migration/ChromeProfileMigrator.js
deleted file mode 100644
index 61955fbb4..000000000
--- a/application/palemoon/components/migration/ChromeProfileMigrator.js
+++ /dev/null
@@ -1,463 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 sts=2 et */
-/* 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/. */
-
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
-const FILE_INPUT_STREAM_CID = "@mozilla.org/network/file-input-stream;1";
-
-const S100NS_FROM1601TO1970 = 0x19DB1DED53E8000;
-const S100NS_PER_MS = 10;
-
-const AUTH_TYPE = {
- SCHEME_HTML: 0,
- SCHEME_BASIC: 1,
- SCHEME_DIGEST: 2
-};
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource:///modules/MigrationUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "OSCrypto",
- "resource://gre/modules/OSCrypto.jsm");
-
-/**
- * Convert Chrome time format to Date object
- *
- * @param aTime
- * Chrome time
- * @return converted Date object
- * @note Google Chrome uses FILETIME / 10 as time.
- * FILETIME is based on same structure of Windows.
- */
-function chromeTimeToDate(aTime)
-{
- return new Date((aTime * S100NS_PER_MS - S100NS_FROM1601TO1970 ) / 10000);
-}
-
-/**
- * Insert bookmark items into specific folder.
- *
- * @param aFolderId
- * id of folder where items will be inserted
- * @param aItems
- * bookmark items to be inserted
- */
-function insertBookmarkItems(aFolderId, aItems)
-{
- for (let i = 0; i < aItems.length; i++) {
- let item = aItems[i];
-
- try {
- if (item.type == "url") {
- PlacesUtils.bookmarks.insertBookmark(aFolderId,
- NetUtil.newURI(item.url),
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- item.name);
- } else if (item.type == "folder") {
- let newFolderId =
- PlacesUtils.bookmarks.createFolder(aFolderId,
- item.name,
- PlacesUtils.bookmarks.DEFAULT_INDEX);
-
- insertBookmarkItems(newFolderId, item.children);
- }
- } catch (e) {
- Cu.reportError(e);
- }
- }
-}
-
-
-function ChromeProfileMigrator() {
- let chromeUserDataFolder = FileUtils.getDir(
-#ifdef XP_WIN
- "LocalAppData", ["Google", "Chrome", "User Data"]
-#elifdef XP_MACOSX
- "ULibDir", ["Application Support", "Google", "Chrome"]
-#else
- "Home", [".config", "google-chrome"]
-#endif
- , false);
- this._chromeUserDataFolder = chromeUserDataFolder.exists() ?
- chromeUserDataFolder : null;
-}
-
-ChromeProfileMigrator.prototype = Object.create(MigratorPrototype);
-
-ChromeProfileMigrator.prototype.getResources =
- function Chrome_getResources(aProfile) {
- if (this._chromeUserDataFolder) {
- let profileFolder = this._chromeUserDataFolder.clone();
- profileFolder.append(aProfile.id);
- if (profileFolder.exists()) {
- let possibleResources = [GetBookmarksResource(profileFolder),
- GetHistoryResource(profileFolder),
- GetCookiesResource(profileFolder),
-#ifdef XP_WIN
- GetWindowsPasswordsResource(profileFolder)
-#endif
- ];
- return [r for each (r in possibleResources) if (r != null)];
- }
- }
- return [];
- };
-
-Object.defineProperty(ChromeProfileMigrator.prototype, "sourceProfiles", {
- get: function Chrome_sourceProfiles() {
- if ("__sourceProfiles" in this)
- return this.__sourceProfiles;
-
- if (!this._chromeUserDataFolder)
- return [];
-
- let profiles = [];
- try {
- // Local State is a JSON file that contains profile info.
- let localState = this._chromeUserDataFolder.clone();
- localState.append("Local State");
- if (!localState.exists())
- throw new Error("Chrome's 'Local State' file does not exist.");
- if (!localState.isReadable())
- throw new Error("Chrome's 'Local State' file could not be read.");
-
- let fstream = Cc[FILE_INPUT_STREAM_CID].createInstance(Ci.nsIFileInputStream);
- fstream.init(localState, -1, 0, 0);
- let inputStream = NetUtil.readInputStreamToString(fstream, fstream.available(),
- { charset: "UTF-8" });
- let info_cache = JSON.parse(inputStream).profile.info_cache;
- for (let profileFolderName in info_cache) {
- let profileFolder = this._chromeUserDataFolder.clone();
- profileFolder.append(profileFolderName);
- profiles.push({
- id: profileFolderName,
- name: info_cache[profileFolderName].name || profileFolderName,
- });
- }
- } catch (e) {
- Cu.reportError("Error detecting Chrome profiles: " + e);
- // If we weren't able to detect any profiles above, fallback to the Default profile.
- let defaultProfileFolder = this._chromeUserDataFolder.clone();
- defaultProfileFolder.append("Default");
- if (defaultProfileFolder.exists()) {
- profiles = [{
- id: "Default",
- name: "Default",
- }];
- }
- }
-
- // Only list profiles from which any data can be imported
- return this.__sourceProfiles = profiles.filter(function(profile) {
- let resources = this.getResources(profile);
- return resources && resources.length > 0;
- }, this);
- }
-});
-
-Object.defineProperty(ChromeProfileMigrator.prototype, "sourceHomePageURL", {
- get: function Chrome_sourceHomePageURL() {
- let prefsFile = this._chromeUserDataFolder.clone();
- prefsFile.append("Preferences");
- if (prefsFile.exists()) {
- // XXX reading and parsing JSON is synchronous.
- let fstream = Cc[FILE_INPUT_STREAM_CID].
- createInstance(Ci.nsIFileInputStream);
- fstream.init(file, -1, 0, 0);
- try {
- return JSON.parse(
- NetUtil.readInputStreamToString(fstream, fstream.available(),
- { charset: "UTF-8" })
- ).homepage;
- }
- catch(e) {
- Cu.reportError("Error parsing Chrome's preferences file: " + e);
- }
- }
- return "";
- }
-});
-
-function GetBookmarksResource(aProfileFolder) {
- let bookmarksFile = aProfileFolder.clone();
- bookmarksFile.append("Bookmarks");
- if (!bookmarksFile.exists())
- return null;
-
- return {
- type: MigrationUtils.resourceTypes.BOOKMARKS,
-
- migrate: function(aCallback) {
- NetUtil.asyncFetch(bookmarksFile, MigrationUtils.wrapMigrateFunction(
- function(aInputStream, aResultCode) {
- if (!Components.isSuccessCode(aResultCode))
- throw new Error("Could not read Bookmarks file");
-
- // Parse Chrome bookmark file that is JSON format
- let bookmarkJSON = NetUtil.readInputStreamToString(
- aInputStream, aInputStream.available(), { charset : "UTF-8" });
- let roots = JSON.parse(bookmarkJSON).roots;
- PlacesUtils.bookmarks.runInBatchMode({
- runBatched: function() {
- // Importing bookmark bar items
- if (roots.bookmark_bar.children &&
- roots.bookmark_bar.children.length > 0) {
- // Toolbar
- let parentId = PlacesUtils.toolbarFolderId;
- if (!MigrationUtils.isStartupMigration) {
- parentId = MigrationUtils.createImportedBookmarksFolder(
- "Chrome", parentId);
- }
- insertBookmarkItems(parentId, roots.bookmark_bar.children);
- }
-
- // Importing bookmark menu items
- if (roots.other.children &&
- roots.other.children.length > 0) {
- // Bookmark menu
- let parentId = PlacesUtils.bookmarksMenuFolderId;
- if (!MigrationUtils.isStartupMigration) {
- parentId = MigrationUtils.createImportedBookmarksFolder(
- "Chrome", parentId);
- }
- insertBookmarkItems(parentId, roots.other.children);
- }
- }
- }, null);
- }, aCallback));
- }
- };
-}
-
-function GetHistoryResource(aProfileFolder) {
- let historyFile = aProfileFolder.clone();
- historyFile.append("History");
- if (!historyFile.exists())
- return null;
-
- return {
- type: MigrationUtils.resourceTypes.HISTORY,
-
- migrate: function(aCallback) {
- let dbConn = Services.storage.openUnsharedDatabase(historyFile);
- let stmt = dbConn.createAsyncStatement(
- "SELECT url, title, last_visit_time, typed_count FROM urls WHERE hidden = 0");
-
- stmt.executeAsync({
- handleResult : function(aResults) {
- let places = [];
- for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
- try {
- // if having typed_count, we changes transition type to typed.
- let transType = PlacesUtils.history.TRANSITION_LINK;
- if (row.getResultByName("typed_count") > 0)
- transType = PlacesUtils.history.TRANSITION_TYPED;
-
- places.push({
- uri: NetUtil.newURI(row.getResultByName("url")),
- title: row.getResultByName("title"),
- visits: [{
- transitionType: transType,
- visitDate: chromeTimeToDate(
- row.getResultByName(
- "last_visit_time")) * 1000,
- }],
- });
- } catch (e) {
- Cu.reportError(e);
- }
- }
-
- try {
- PlacesUtils.asyncHistory.updatePlaces(places);
- } catch (e) {
- Cu.reportError(e);
- }
- },
-
- handleError : function(aError) {
- Cu.reportError("Async statement execution returned with '" +
- aError.result + "', '" + aError.message + "'");
- },
-
- handleCompletion : function(aReason) {
- dbConn.asyncClose();
- aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED);
- }
- });
- stmt.finalize();
- }
- };
-}
-
-function GetCookiesResource(aProfileFolder) {
- let cookiesFile = aProfileFolder.clone();
- cookiesFile.append("Cookies");
- if (!cookiesFile.exists())
- return null;
-
- return {
- type: MigrationUtils.resourceTypes.COOKIES,
-
- migrate: function(aCallback) {
- let dbConn = Services.storage.openUnsharedDatabase(cookiesFile);
- let stmt = dbConn.createAsyncStatement(
- "SELECT host_key, path, name, value, secure, httponly, expires_utc FROM cookies");
-
- stmt.executeAsync({
- handleResult : function(aResults) {
- for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
- let host_key = row.getResultByName("host_key");
- if (host_key.match(/^\./)) {
- // 1st character of host_key may be ".", so we have to remove it
- host_key = host_key.substr(1);
- }
-
- try {
- let expiresUtc =
- chromeTimeToDate(row.getResultByName("expires_utc")) / 1000;
- Services.cookies.add(host_key,
- row.getResultByName("path"),
- row.getResultByName("name"),
- row.getResultByName("value"),
- row.getResultByName("secure"),
- row.getResultByName("httponly"),
- false,
- parseInt(expiresUtc));
- } catch (e) {
- Cu.reportError(e);
- }
- }
- },
-
- handleError : function(aError) {
- Cu.reportError("Async statement execution returned with '" +
- aError.result + "', '" + aError.message + "'");
- },
-
- handleCompletion : function(aReason) {
- dbConn.asyncClose();
- aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED);
- },
- });
- stmt.finalize();
- }
- }
-}
-
-function GetWindowsPasswordsResource(aProfileFolder) {
- let loginFile = aProfileFolder.clone();
- loginFile.append("Login Data");
- if (!loginFile.exists())
- return null;
-
- return {
- type: MigrationUtils.resourceTypes.PASSWORDS,
-
- migrate(aCallback) {
- let dbConn = Services.storage.openUnsharedDatabase(loginFile);
- let stmt = dbConn.createAsyncStatement(`
- SELECT origin_url, action_url, username_element, username_value,
- password_element, password_value, signon_realm, scheme, date_created,
- times_used FROM logins WHERE blacklisted_by_user = 0`);
- let crypto = new OSCrypto();
- let utf8Converter = Cc["@mozilla.org/intl/utf8converterservice;1"].getService(Ci.nsIUTF8ConverterService);
-
- stmt.executeAsync({
- _rowToLoginInfo(row) {
- let loginInfo = {
- username: utf8Converter.convertURISpecToUTF8(row.getResultByName("username_value"), "UTF-8"),
- password: utf8Converter.convertURISpecToUTF8(
- crypto.decryptData(crypto.arrayToString(row.getResultByName("password_value")), null),
- "UTF-8"),
- hostName: NetUtil.newURI(row.getResultByName("origin_url")).prePath,
- submitURL: null,
- httpRealm: null,
- usernameElement: row.getResultByName("username_element"),
- passwordElement: row.getResultByName("password_element"),
- timeCreated: chromeTimeToDate(row.getResultByName("date_created") + 0).getTime(),
- timesUsed: row.getResultByName("times_used") + 0,
- };
-
- switch (row.getResultByName("scheme")) {
- case AUTH_TYPE.SCHEME_HTML:
- loginInfo.submitURL = NetUtil.newURI(row.getResultByName("action_url")).prePath;
- break;
- case AUTH_TYPE.SCHEME_BASIC:
- case AUTH_TYPE.SCHEME_DIGEST:
- // signon_realm format is URIrealm, so we need remove URI
- loginInfo.httpRealm = row.getResultByName("signon_realm")
- .substring(loginInfo.hostName.length + 1);
- break;
- default:
- throw new Error("Login data scheme type not supported: " +
- row.getResultByName("scheme"));
- }
-
- return loginInfo;
- },
-
- handleResult(aResults) {
- for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
- try {
- let loginInfo = this._rowToLoginInfo(row);
- let login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo);
-
- login.init(loginInfo.hostName, loginInfo.submitURL, loginInfo.httpRealm,
- loginInfo.username, loginInfo.password, loginInfo.usernameElement,
- loginInfo.passwordElement);
- login.QueryInterface(Ci.nsILoginMetaInfo);
- login.timeCreated = loginInfo.timeCreated;
- login.timeLastUsed = loginInfo.timeCreated;
- login.timePasswordChanged = loginInfo.timeCreated;
- login.timesUsed = loginInfo.timesUsed;
-
- // Add the login only if there's not an existing entry
- let logins = Services.logins.findLogins({}, login.hostname,
- login.formSubmitURL,
- login.httpRealm);
-
- // Bug 1187190: Password changes should be propagated depending on timestamps.
- if (!logins.some(l => login.matches(l, true))) {
- Services.logins.addLogin(login);
- }
- } catch (e) {
- Cu.reportError(e);
- }
- }
- },
-
- handleError(aError) {
- Cu.reportError("Async statement execution returned with '" +
- aError.result + "', '" + aError.message + "'");
- },
-
- handleCompletion(aReason) {
- dbConn.asyncClose();
- aCallback(aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED);
- crypto.finalize();
- },
- });
- stmt.finalize();
- }
- };
-}
-
-ChromeProfileMigrator.prototype.classDescription = "Chrome Profile Migrator";
-ChromeProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=chrome";
-ChromeProfileMigrator.prototype.classID = Components.ID("{4cec1de4-1671-4fc3-a53e-6c539dc77a26}");
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeProfileMigrator]);
diff --git a/application/palemoon/components/migration/FirefoxProfileMigrator.js b/application/palemoon/components/migration/FirefoxProfileMigrator.js
deleted file mode 100644
index ab4ae55fb..000000000
--- a/application/palemoon/components/migration/FirefoxProfileMigrator.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * vim: sw=2 ts=2 sts=2 et */
- /* 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/. */
-
-"use strict";
-
-/*
- * Migrates from a Pale Moon profile in a lossy manner in order to clean up a
- * user's profile. Data is only migrated where the benefits outweigh the
- * potential problems caused by importing undesired/invalid configurations
- * from the source profile.
- */
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource:///modules/MigrationUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesBackups",
- "resource://gre/modules/PlacesBackups.jsm");
-
-function FirefoxProfileMigrator() { }
-
-FirefoxProfileMigrator.prototype = Object.create(MigratorPrototype);
-
-FirefoxProfileMigrator.prototype._getAllProfiles = function () {
- let allProfiles = new Map();
- let profiles =
- Components.classes["@mozilla.org/toolkit/profile-service;1"]
- .getService(Components.interfaces.nsIToolkitProfileService)
- .profiles;
- while (profiles.hasMoreElements()) {
- let profile = profiles.getNext().QueryInterface(Components.interfaces.nsIToolkitProfile);
- let rootDir = profile.rootDir;
-
- if (rootDir.exists() && rootDir.isReadable() &&
- !rootDir.equals(MigrationUtils.profileStartup.directory)) {
- allProfiles.set(profile.name, rootDir);
- }
- }
- return allProfiles;
-};
-
-function sorter(a, b) {
- return a.id.toLocaleLowerCase().localeCompare(b.id.toLocaleLowerCase());
-}
-
-Object.defineProperty(FirefoxProfileMigrator.prototype, "sourceProfiles", {
- get: function() {
- return [{id: x, name: x} for (x of this._getAllProfiles().keys())].sort(sorter);
- }
-});
-
-FirefoxProfileMigrator.prototype.getResources = function(aProfile) {
- let sourceProfileDir = aProfile ? this._getAllProfiles().get(aProfile.id) :
- Components.classes["@mozilla.org/toolkit/profile-service;1"]
- .getService(Components.interfaces.nsIToolkitProfileService)
- .selectedProfile.rootDir;
- if (!sourceProfileDir || !sourceProfileDir.exists() ||
- !sourceProfileDir.isReadable())
- return null;
-
- // Being a startup-only migrator, we can rely on
- // MigrationUtils.profileStartup being set.
- let currentProfileDir = MigrationUtils.profileStartup.directory;
-
- // Surely data cannot be imported from the current profile.
- if (sourceProfileDir.equals(currentProfileDir))
- return null;
-
- let getFileResource = function(aMigrationType, aFileNames) {
- let files = [];
- for (let fileName of aFileNames) {
- let file = sourceProfileDir.clone();
- file.append(fileName);
-
- if (file.exists()) {
- files.push(file);
- }
- }
- if (!files.length) {
- return null;
- }
- return {
- type: aMigrationType,
- migrate: function(aCallback) {
- for (let file of files) {
- file.copyTo(currentProfileDir, "");
- }
- aCallback(true);
- }
- };
- };
-
- let types = MigrationUtils.resourceTypes;
- let places = getFileResource(types.HISTORY, ["places.sqlite", "places.sqlite-wal"]);
- let cookies = getFileResource(types.COOKIES, ["cookies.sqlite", "cookies.sqlite-wal"]);
- let passwords = getFileResource(types.PASSWORDS,
- ["signons.sqlite", "logins.json", "key3.db"]);
- let formData = getFileResource(types.FORMDATA, ["formhistory.sqlite"]);
- let bookmarksBackups = getFileResource(types.OTHERDATA,
- [PlacesBackups.profileRelativeFolderPath]);
- let dictionary = getFileResource(types.OTHERDATA, ["persdict.dat"]);
-
- return [r for each (r in [places, cookies, passwords, formData,
- dictionary, bookmarksBackups]) if (r)];
-}
-
-Object.defineProperty(FirefoxProfileMigrator.prototype, "startupOnlyMigrator", {
- get: function() true
-});
-
-
-FirefoxProfileMigrator.prototype.classDescription = "Firefox Profile Migrator";
-FirefoxProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=firefox";
-FirefoxProfileMigrator.prototype.classID = Components.ID("{91185366-ba97-4438-acba-48deaca63386}");
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FirefoxProfileMigrator]);
diff --git a/application/palemoon/components/migration/IEProfileMigrator.js b/application/palemoon/components/migration/IEProfileMigrator.js
deleted file mode 100644
index a46deae68..000000000
--- a/application/palemoon/components/migration/IEProfileMigrator.js
+++ /dev/null
@@ -1,521 +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/. */
-
-"use strict";
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-const Cr = Components.results;
-
-const kMainKey = "Software\\Microsoft\\Internet Explorer\\Main";
-const kRegMultiSz = 7;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-Cu.import("resource:///modules/MigrationUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ctypes",
- "resource://gre/modules/ctypes.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "WindowsRegistry",
- "resource://gre/modules/WindowsRegistry.jsm");
-
-Cu.importGlobalProperties(["File"]);
-
-////////////////////////////////////////////////////////////////////////////////
-//// Helpers.
-
-let CtypesHelpers = {
- _structs: {},
- _functions: {},
- _libs: {},
-
- /**
- * Must be invoked once before first use of any of the provided helpers.
- */
- initialize: function CH_initialize() {
- const WORD = ctypes.uint16_t;
- const DWORD = ctypes.uint32_t;
- const BOOL = ctypes.int;
-
- this._structs.SYSTEMTIME = new ctypes.StructType('SYSTEMTIME', [
- {wYear: WORD},
- {wMonth: WORD},
- {wDayOfWeek: WORD},
- {wDay: WORD},
- {wHour: WORD},
- {wMinute: WORD},
- {wSecond: WORD},
- {wMilliseconds: WORD}
- ]);
-
- this._structs.FILETIME = new ctypes.StructType('FILETIME', [
- {dwLowDateTime: DWORD},
- {dwHighDateTime: DWORD}
- ]);
-
- try {
- this._libs.kernel32 = ctypes.open("Kernel32");
- this._functions.FileTimeToSystemTime =
- this._libs.kernel32.declare("FileTimeToSystemTime",
- ctypes.default_abi,
- BOOL,
- this._structs.FILETIME.ptr,
- this._structs.SYSTEMTIME.ptr);
- } catch (ex) {
- this.finalize();
- }
- },
-
- /**
- * Must be invoked once after last use of any of the provided helpers.
- */
- finalize: function CH_finalize() {
- this._structs = {};
- this._functions = {};
- for each (let lib in this._libs) {
- try {
- lib.close();
- } catch (ex) {}
- }
- this._libs = {};
- },
-
- /**
- * Converts a FILETIME struct (2 DWORDS), to a SYSTEMTIME struct.
- *
- * @param aTimeHi
- * Least significant DWORD.
- * @param aTimeLo
- * Most significant DWORD.
- * @return a Date object representing the converted datetime.
- */
- fileTimeToDate: function CH_fileTimeToDate(aTimeHi, aTimeLo) {
- let fileTime = this._structs.FILETIME();
- fileTime.dwLowDateTime = aTimeLo;
- fileTime.dwHighDateTime = aTimeHi;
- let systemTime = this._structs.SYSTEMTIME();
- let result = this._functions.FileTimeToSystemTime(fileTime.address(),
- systemTime.address());
- if (result == 0)
- throw new Error(ctypes.winLastError);
-
- return new Date(systemTime.wYear,
- systemTime.wMonth - 1,
- systemTime.wDay,
- systemTime.wHour,
- systemTime.wMinute,
- systemTime.wSecond,
- systemTime.wMilliseconds);
- }
-};
-
-/**
- * Checks whether an host is an IP (v4 or v6) address.
- *
- * @param aHost
- * The host to check.
- * @return whether aHost is an IP address.
- */
-function hostIsIPAddress(aHost) {
- try {
- Services.eTLD.getBaseDomainFromHost(aHost);
- } catch (e if e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS) {
- return true;
- } catch (e) {}
- return false;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//// Resources
-
-function Bookmarks() {
-}
-
-Bookmarks.prototype = {
- type: MigrationUtils.resourceTypes.BOOKMARKS,
-
- get exists() !!this._favoritesFolder,
-
- __favoritesFolder: null,
- get _favoritesFolder() {
- if (!this.__favoritesFolder) {
- let favoritesFolder = Services.dirsvc.get("Favs", Ci.nsIFile);
- if (favoritesFolder.exists() && favoritesFolder.isReadable())
- this.__favoritesFolder = favoritesFolder;
- }
- return this.__favoritesFolder;
- },
-
- __toolbarFolderName: null,
- get _toolbarFolderName() {
- if (!this.__toolbarFolderName) {
- // Retrieve the name of IE's favorites subfolder that holds the bookmarks
- // in the toolbar. This was previously stored in the registry and changed
- // in IE7 to always be called "Links".
- let folderName = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
- "Software\\Microsoft\\Internet Explorer\\Toolbar",
- "LinksFolderName");
- this.__toolbarFolderName = folderName || "Links";
- }
- return this.__toolbarFolderName;
- },
-
- migrate: function B_migrate(aCallback) {
- PlacesUtils.bookmarks.runInBatchMode({
- runBatched: (function migrateBatched() {
- // Import to the bookmarks menu.
- let destFolderId = PlacesUtils.bookmarksMenuFolderId;
- if (!MigrationUtils.isStartupMigration) {
- destFolderId =
- MigrationUtils.createImportedBookmarksFolder("IE", destFolderId);
- }
-
- this._migrateFolder(this._favoritesFolder, destFolderId);
-
- aCallback(true);
- }).bind(this)
- }, null);
- },
-
- _migrateFolder: function B__migrateFolder(aSourceFolder, aDestFolderId) {
- // TODO (bug 741993): the favorites order is stored in the Registry, at
- // HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\MenuOrder\Favorites
- // Until we support it, bookmarks are imported in alphabetical order.
- let entries = aSourceFolder.directoryEntries;
- while (entries.hasMoreElements()) {
- let entry = entries.getNext().QueryInterface(Ci.nsIFile);
-
- // Make sure that entry.path == entry.target to not follow .lnk folder
- // shortcuts which could lead to infinite cycles.
- if (entry.isDirectory() && entry.path == entry.target) {
- let destFolderId;
- if (entry.leafName == this._toolbarFolderName &&
- entry.parent.equals(this._favoritesFolder)) {
- // Import to the bookmarks toolbar.
- destFolderId = PlacesUtils.toolbarFolderId;
- if (!MigrationUtils.isStartupMigration) {
- destFolderId =
- MigrationUtils.createImportedBookmarksFolder("IE", destFolderId);
- }
- }
- else {
- // Import to a new folder.
- destFolderId =
- PlacesUtils.bookmarks.createFolder(aDestFolderId, entry.leafName,
- PlacesUtils.bookmarks.DEFAULT_INDEX);
- }
-
- if (entry.isReadable()) {
- // Recursively import the folder.
- this._migrateFolder(entry, destFolderId);
- }
- }
- else {
- // Strip the .url extension, to both check this is a valid link file,
- // and get the associated title.
- let matches = entry.leafName.match(/(.+)\.url$/i);
- if (matches) {
- let fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"].
- getService(Ci.nsIFileProtocolHandler);
- let uri = fileHandler.readURLFile(entry);
- let title = matches[1];
-
- PlacesUtils.bookmarks.insertBookmark(aDestFolderId,
- uri,
- PlacesUtils.bookmarks.DEFAULT_INDEX,
- title);
- }
- }
- }
- }
-};
-
-function History() {
-}
-
-History.prototype = {
- type: MigrationUtils.resourceTypes.HISTORY,
-
- get exists() true,
-
- __typedURLs: null,
- get _typedURLs() {
- if (!this.__typedURLs) {
- // The list of typed URLs is a sort of annotation stored in the registry.
- // Currently, IE stores 25 entries and this value is not configurable,
- // but we just keep reading up to the first non-existing entry to support
- // possible future bumps of this limit.
- this.__typedURLs = {};
- let registry = Cc["@mozilla.org/windows-registry-key;1"].
- createInstance(Ci.nsIWindowsRegKey);
- try {
- registry.open(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
- "Software\\Microsoft\\Internet Explorer\\TypedURLs",
- Ci.nsIWindowsRegKey.ACCESS_READ);
- for (let entry = 1; registry.hasValue("url" + entry); entry++) {
- let url = registry.readStringValue("url" + entry);
- this.__typedURLs[url] = true;
- }
- } catch (ex) {
- } finally {
- registry.close();
- }
- }
- return this.__typedURLs;
- },
-
- migrate: function H_migrate(aCallback) {
- let places = [];
- let historyEnumerator = Cc["@mozilla.org/profile/migrator/iehistoryenumerator;1"].
- createInstance(Ci.nsISimpleEnumerator);
- while (historyEnumerator.hasMoreElements()) {
- let entry = historyEnumerator.getNext().QueryInterface(Ci.nsIPropertyBag2);
- let uri = entry.get("uri").QueryInterface(Ci.nsIURI);
- // MSIE stores some types of URLs in its history that we don't handle,
- // like HTMLHelp and others. Since we don't properly map handling for
- // all of them we just avoid importing them.
- if (["http", "https", "ftp", "file"].indexOf(uri.scheme) == -1) {
- continue;
- }
-
- let title = entry.get("title");
- // Embed visits have no title and don't need to be imported.
- if (title.length == 0) {
- continue;
- }
-
- // The typed urls are already fixed-up, so we can use them for comparison.
- let transitionType = this._typedURLs[uri.spec] ?
- Ci.nsINavHistoryService.TRANSITION_TYPED :
- Ci.nsINavHistoryService.TRANSITION_LINK;
- let lastVisitTime = entry.get("time");
-
- places.push(
- { uri: uri,
- title: title,
- visits: [{ transitionType: transitionType,
- visitDate: lastVisitTime }]
- }
- );
- }
-
- // Check whether there is any history to import.
- if (places.length == 0) {
- aCallback(true);
- return;
- }
-
- PlacesUtils.asyncHistory.updatePlaces(places, {
- _success: false,
- handleResult: function() {
- // Importing any entry is considered a successful import.
- this._success = true;
- },
- handleError: function() {},
- handleCompletion: function() {
- aCallback(this._success);
- }
- });
- }
-};
-
-function Cookies() {
-}
-
-Cookies.prototype = {
- type: MigrationUtils.resourceTypes.COOKIES,
-
- get exists() !!this._cookiesFolder,
-
- __cookiesFolder: null,
- get _cookiesFolder() {
- // Cookies are stored in txt files, in a Cookies folder whose path varies
- // across the different OS versions. CookD takes care of most of these
- // cases, though, in Windows Vista/7, UAC makes a difference.
- // If UAC is enabled, the most common destination is CookD/Low. Though,
- // if the user runs the application in administrator mode or disables UAC,
- // cookies are stored in the original CookD destination. Cause running the
- // browser in administrator mode is unsafe and discouraged, we just care
- // about the UAC state.
- if (!this.__cookiesFolder) {
- let cookiesFolder = Services.dirsvc.get("CookD", Ci.nsIFile);
- if (cookiesFolder.exists() && cookiesFolder.isReadable()) {
- // Check if UAC is enabled.
- if (Services.appinfo.QueryInterface(Ci.nsIWinAppHelper).userCanElevate) {
- cookiesFolder.append("Low");
- }
- this.__cookiesFolder = cookiesFolder;
- }
- }
- return this.__cookiesFolder;
- },
-
- migrate: function C_migrate(aCallback) {
- CtypesHelpers.initialize();
-
- let cookiesGenerator = (function genCookie() {
- let success = false;
- let entries = this._cookiesFolder.directoryEntries;
- while (entries.hasMoreElements()) {
- let entry = entries.getNext().QueryInterface(Ci.nsIFile);
- // Skip eventual bogus entries.
- if (!entry.isFile() || !/\.txt$/.test(entry.leafName))
- continue;
-
- this._readCookieFile(entry, function(aSuccess) {
- // Importing even a single cookie file is considered a success.
- if (aSuccess)
- success = true;
- try {
- cookiesGenerator.next();
- } catch (ex) {}
- });
-
- yield;
- }
-
- CtypesHelpers.finalize();
-
- aCallback(success);
- }).apply(this);
- cookiesGenerator.next();
- },
-
- _readCookieFile: function C__readCookieFile(aFile, aCallback) {
- let fileReader = Cc["@mozilla.org/files/filereader;1"].
- createInstance(Ci.nsIDOMFileReader);
- fileReader.addEventListener("loadend", (function onLoadEnd() {
- fileReader.removeEventListener("loadend", onLoadEnd, false);
-
- if (fileReader.readyState != fileReader.DONE) {
- Cu.reportError("Could not read cookie contents: " + fileReader.error);
- aCallback(false);
- return;
- }
-
- let success = true;
- try {
- this._parseCookieBuffer(fileReader.result);
- } catch (ex) {
- Components.utils.reportError("Unable to migrate cookie: " + ex);
- success = false;
- } finally {
- aCallback(success);
- }
- }).bind(this), false);
- fileReader.readAsText(new File(aFile));
- },
-
- /**
- * Parses a cookie file buffer and returns an array of the contained cookies.
- *
- * The cookie file format is a newline-separated-values with a "*" used as
- * delimeter between multiple records.
- * Each cookie has the following fields:
- * - name
- * - value
- * - host/path
- * - flags
- * - Expiration time most significant integer
- * - Expiration time least significant integer
- * - Creation time most significant integer
- * - Creation time least significant integer
- * - Record delimiter "*"
- *
- * @note All the times are in FILETIME format.
- */
- _parseCookieBuffer: function C__parseCookieBuffer(aTextBuffer) {
- // Note the last record is an empty string.
- let records = [r for each (r in aTextBuffer.split("*\n")) if (r)];
- for (let record of records) {
- let [name, value, hostpath, flags,
- expireTimeLo, expireTimeHi] = record.split("\n");
-
- // IE stores deleted cookies with a zero-length value, skip them.
- if (value.length == 0)
- continue;
-
- let hostLen = hostpath.indexOf("/");
- let host = hostpath.substr(0, hostLen);
- let path = hostpath.substr(hostLen);
-
- // For a non-null domain, assume it's what Mozilla considers
- // a domain cookie. See bug 222343.
- if (host.length > 0) {
- // Fist delete any possible extant matching host cookie.
- Services.cookies.remove(host, name, path, false);
- // Now make it a domain cookie.
- if (host[0] != "." && !hostIsIPAddress(host))
- host = "." + host;
- }
-
- let expireTime = CtypesHelpers.fileTimeToDate(Number(expireTimeHi),
- Number(expireTimeLo));
- Services.cookies.add(host,
- path,
- name,
- value,
- Number(flags) & 0x1, // secure
- false, // httpOnly
- false, // session
- expireTime);
- }
- }
-};
-
-
-////////////////////////////////////////////////////////////////////////////////
-//// Migrator
-
-function IEProfileMigrator()
-{
-}
-
-IEProfileMigrator.prototype = Object.create(MigratorPrototype);
-
-IEProfileMigrator.prototype.getResources = function IE_getResources() {
- let resources = [
- new Bookmarks()
- , new History()
- , new Cookies()
- ];
- return [r for each (r in resources) if (r.exists)];
-};
-
-Object.defineProperty(IEProfileMigrator.prototype, "sourceHomePageURL", {
- get: function IE_get_sourceHomePageURL() {
- let defaultStartPage = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_LOCAL_MACHINE,
- kMainKey, "Default_Page_URL");
- let startPage = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
- kMainKey, "Start Page");
- // If the user didn't customize the Start Page, he is still on the default
- // page, that may be considered the equivalent of our about:home. There's
- // no reason to retain it, since it is heavily targeted to IE.
- let homepage = startPage != defaultStartPage ? startPage : "";
-
- // IE7+ supports secondary home pages located in a REG_MULTI_SZ key. These
- // are in addition to the Start Page, and no empty entries are possible,
- // thus a Start Page is always defined if any of these exists, though it
- // may be the default one.
- let secondaryPages = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER,
- kMainKey, "Secondary Start Pages");
- if (secondaryPages) {
- if (homepage)
- secondaryPages.unshift(homepage);
- homepage = secondaryPages.join("|");
- }
-
- return homepage;
- }
-});
-
-IEProfileMigrator.prototype.classDescription = "IE Profile Migrator";
-IEProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=ie";
-IEProfileMigrator.prototype.classID = Components.ID("{3d2532e3-4932-4774-b7ba-968f5899d3a4}");
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([IEProfileMigrator]);
diff --git a/application/palemoon/components/migration/MigrationUtils.jsm b/application/palemoon/components/migration/MigrationUtils.jsm
deleted file mode 100644
index 882c7cf32..000000000
--- a/application/palemoon/components/migration/MigrationUtils.jsm
+++ /dev/null
@@ -1,657 +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/. */
-
-"use strict";
-
-this.EXPORTED_SYMBOLS = ["MigrationUtils", "MigratorPrototype"];
-
-const Cu = Components.utils;
-const Ci = Components.interfaces;
-const Cc = Components.classes;
-
-const TOPIC_WILL_IMPORT_BOOKMARKS = "initial-migration-will-import-default-bookmarks";
-const TOPIC_DID_IMPORT_BOOKMARKS = "initial-migration-did-import-default-bookmarks";
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Dict",
- "resource://gre/modules/Dict.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
- "resource://gre/modules/NetUtil.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "BookmarkHTMLUtils",
- "resource://gre/modules/BookmarkHTMLUtils.jsm");
-
-let gMigrators = null;
-let gProfileStartup = null;
-let gMigrationBundle = null;
-
-function getMigrationBundle() {
- if (!gMigrationBundle) {
- gMigrationBundle = Services.strings.createBundle(
- "chrome://browser/locale/migration/migration.properties");
- }
- return gMigrationBundle;
-}
-
-/**
- * Figure out what is the default browser, and if there is a migrator
- * for it, return that migrator's internal name.
- * For the time being, the "internal name" of a migraotr is its contract-id
- * trailer (e.g. ie for @mozilla.org/profile/migrator;1?app=browser&type=ie),
- * but it will soon be exposed properly.
- */
-function getMigratorKeyForDefaultBrowser() {
- const APP_DESC_TO_KEY = {
- "Internet Explorer": "ie",
- "Safari": "safari",
- "Pale Moon web browser": "firefox",
- "Google Chrome": "chrome", // Windows, Linux
- "Chrome": "chrome", // OS X
- };
-
- let browserDesc = "";
- try {
- let browserDesc =
- Cc["@mozilla.org/uriloader/external-protocol-service;1"].
- getService(Ci.nsIExternalProtocolService).
- getApplicationDescription("http");
- return APP_DESC_TO_KEY[browserDesc] || "";
- }
- catch(ex) {
- Cu.reportError("Could not detect default browser: " + ex);
- }
- return "";
-}
-
-/**
- * Shared prototype for migrators, implementing nsIBrowserProfileMigrator.
- *
- * To implement a migrator:
- * 1. Import this module.
- * 2. Create the prototype for the migrator, extending MigratorPrototype.
- * Namely: MosaicMigrator.prototype = Object.create(MigratorPrototype);
- * 3. Set classDescription, contractID and classID for your migrator, and set
- * NSGetFactory appropriately.
- * 4. If the migrator supports multiple profiles, override the sourceProfiles
- * Here we default for single-profile migrator.
- * 5. Implement getResources(aProfile) (see below).
- * 6. If the migrator supports reading the home page of the source browser,
- * override |sourceHomePageURL| getter.
- * 7. For startup-only migrators, override |startupOnlyMigrator|.
- */
-this.MigratorPrototype = {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIBrowserProfileMigrator]),
-
- /**
- * OVERRIDE IF AND ONLY IF the source supports multiple profiles.
- *
- * Returns array of profile objects from which data may be imported. The object
- * should have the following keys:
- * id - a unique string identifier for the profile
- * name - a pretty name to display to the user in the UI
- *
- * Only profiles from which data can be imported should be listed. Otherwise
- * the behavior of the migration wizard isn't well-defined.
- *
- * For a single-profile source (e.g. safari, ie), this returns null,
- * and not an empty array. That is the default implementation.
- */
- get sourceProfiles() null,
-
- /**
- * MUST BE OVERRIDDEN.
- *
- * Returns an array of "migration resources" objects for the given profile,
- * or for the "default" profile, if the migrator does not support multiple
- * profiles.
- *
- * Each migration resource should provide:
- * - a |type| getter, retunring any of the migration types (see
- * nsIBrowserProfileMigrator).
- *
- * - a |migrate| method, taking a single argument, aCallback(bool success),
- * for migrating the data for this resource. It may do its job
- * synchronously or asynchronously. Either way, it must call
- * aCallback(bool aSuccess) when it's done. In the case of an exception
- * thrown from |migrate|, it's taken as if aCallback(false) is called.
- *
- * Note: In the case of a simple asynchronous implementation, you may find
- * MigrationUtils.wrapMigrateFunction handy for handling aCallback easily.
- *
- * For each migration type listed in nsIBrowserProfileMigrator, multiple
- * migration resources may be provided. This practice is useful when the
- * data for a certain migration type is independently stored in few
- * locations. For example, the mac version of Safari stores its "reading list"
- * bookmarks in a separate property list.
- *
- * Note that the importation of a particular migration type is reported as
- * successful if _any_ of its resources succeeded to import (that is, called,
- * |aCallback(true)|). However, completion-status for a particular migration
- * type is reported to the UI only once all of its migrators have called
- * aCallback.
- *
- * @note The returned array should only include resources from which data
- * can be imported. So, for example, before adding a resource for the
- * BOOKMARKS migration type, you should check if you should check that the
- * bookmarks file exists.
- *
- * @param aProfile
- * The profile from which data may be imported, or an empty string
- * in the case of a single-profile migrator.
- * In the case of multiple-profiles migrator, it is guaranteed that
- * aProfile is a value returned by the sourceProfiles getter (see
- * above).
- */
- getResources: function MP_getResources(aProfile) {
- throw new Error("getResources must be overridden");
- },
-
- /**
- * OVERRIDE IF AND ONLY IF the migrator is a startup-only migrator (For now,
- * that is just the Firefox migrator, see bug 737381). Default: false.
- *
- * Startup-only migrators are different in two ways:
- * - they may only be used during startup.
- * - the user-profile is half baked during migration. The folder exists,
- * but it's only accessible through MigrationUtils.profileStartup.
- * The migrator can call MigrationUtils.profileStartup.doStartup
- * at any point in order to initialize the profile.
- */
- get startupOnlyMigrator() false,
-
- /**
- * OVERRIDE IF AND ONLY IF your migrator supports importing the homepage.
- * @see nsIBrowserProfileMigrator
- */
- get sourceHomePageURL() "",
-
- /**
- * DO NOT OVERRIDE - After deCOMing migration, the UI will just call
- * getResources.
- *
- * @see nsIBrowserProfileMigrator
- */
- getMigrateData: function MP_getMigrateData(aProfile) {
- // Tycho: let types = [r.type for each (r in this._getMaybeCachedResources(aProfile))];
- let types = [];
-
- for each (r in this._getMaybeCachedResources(aProfile)) {
- types.push(r.type);
- }
-
- return types.reduce(function(a, b) a |= b, 0);
- },
-
- /**
- * DO NOT OVERRIDE - After deCOMing migration, the UI will just call
- * migrate for each resource.
- *
- * @see nsIBrowserProfileMigrator
- */
- migrate: function MP_migrate(aItems, aStartup, aProfile) {
- let resources = this._getMaybeCachedResources(aProfile);
- if (resources.length == 0)
- throw new Error("migrate called for a non-existent source");
-
- if (aItems != Ci.nsIBrowserProfileMigrator.ALL)
- // Tycho: resources = [r for each (r in resources) if (aItems & r.type)];
- resources = [];
-
- for each (r in resources) {
- if (aItems & r.type) {
- resources.push(r);
- }
- }
-
- // Called either directly or through the bookmarks import callback.
- function doMigrate() {
- // TODO: use Map (for the items) and Set (for the resources)
- // once they are iterable.
- let resourcesGroupedByItems = new Dict();
- resources.forEach(function(resource) {
- if (resourcesGroupedByItems.has(resource.type))
- resourcesGroupedByItems.get(resource.type).push(resource);
- else
- resourcesGroupedByItems.set(resource.type, [resource]);
- });
-
- if (resourcesGroupedByItems.count == 0)
- throw new Error("No items to import");
-
- let notify = function(aMsg, aItemType) {
- Services.obs.notifyObservers(null, aMsg, aItemType);
- }
-
- notify("Migration:Started");
- resourcesGroupedByItems.listkeys().forEach(function(migrationType) {
- let migrationTypeA = migrationType;
- let itemResources = resourcesGroupedByItems.get(migrationType);
- notify("Migration:ItemBeforeMigrate", migrationType);
-
- let itemSuccess = false;
- itemResources.forEach(function(resource) {
- let resourceDone = function(aSuccess) {
- let resourceIndex = itemResources.indexOf(resource);
- if (resourceIndex != -1) {
- itemResources.splice(resourceIndex, 1);
- itemSuccess |= aSuccess;
- if (itemResources.length == 0) {
- resourcesGroupedByItems.del(migrationType);
- notify(itemSuccess ?
- "Migration:ItemAfterMigrate" : "Migration:ItemError",
- migrationType);
- if (resourcesGroupedByItems.count == 0)
- notify("Migration:Ended");
- }
- }
- };
-
- Services.tm.mainThread.dispatch(function() {
- // If migrate throws, an error occurred, and the callback
- // (itemMayBeDone) might haven't been called.
- try {
- resource.migrate(resourceDone);
- }
- catch(ex) {
- Cu.reportError(ex);
- resourceDone(false);
- }
- }, Ci.nsIThread.DISPATCH_NORMAL);
- });
- });
- }
-
- if (MigrationUtils.isStartupMigration && !this.startupOnlyMigrator) {
- MigrationUtils.profileStartup.doStartup();
-
- // If we're about to migrate bookmarks, first import the default bookmarks.
- // Note We do not need to do so for the Firefox migrator
- // (=startupOnlyMigrator), as it just copies over the places database
- // from another profile.
- const BOOKMARKS = MigrationUtils.resourceTypes.BOOKMARKS;
- let migratingBookmarks = resources.some(function(r) r.type == BOOKMARKS);
- if (migratingBookmarks) {
- let browserGlue = Cc["@mozilla.org/browser/browserglue;1"].
- getService(Ci.nsIObserver);
- browserGlue.observe(null, TOPIC_WILL_IMPORT_BOOKMARKS, "");
-
- // Note doMigrate doesn't care about the success of the import.
- let onImportComplete = function() {
- browserGlue.observe(null, TOPIC_DID_IMPORT_BOOKMARKS, "");
- doMigrate();
- };
- BookmarkHTMLUtils.importFromURL(
- "resource:///defaults/profile/bookmarks.html", true).then(
- onImportComplete, onImportComplete);
- return;
- }
- }
- doMigrate();
- },
-
- /**
- * DO NOT OVERRIDE - After deCOMing migration, this code
- * won't be part of the migrator itself.
- *
- * @see nsIBrowserProfileMigrator
- */
- get sourceExists() {
- if (this.startupOnlyMigrator && !MigrationUtils.isStartupMigration)
- return false;
-
- // For a single-profile source, check if any data is available.
- // For multiple-profiles source, make sure that at least one
- // profile is available.
- let exists = false;
- try {
- let profiles = this.sourceProfiles;
- if (!profiles) {
- let resources = this._getMaybeCachedResources("");
- if (resources && resources.length > 0)
- exists = true;
- }
- else {
- exists = profiles.length > 0;
- }
- }
- catch(ex) {
- Cu.reportError(ex);
- }
- return exists;
- },
-
- /*** PRIVATE STUFF - DO NOT OVERRIDE ***/
- _getMaybeCachedResources: function PMB__getMaybeCachedResources(aProfile) {
- let profileKey = aProfile ? aProfile.id : "";
- if (this._resourcesByProfile) {
- if (profileKey in this._resourcesByProfile)
- return this._resourcesByProfile[profileKey];
- }
- else {
- this._resourcesByProfile = { };
- }
- return this._resourcesByProfile[profileKey] = this.getResources(aProfile);
- }
-};
-
-this.MigrationUtils = Object.freeze({
- resourceTypes: {
- SETTINGS: Ci.nsIBrowserProfileMigrator.SETTINGS,
- COOKIES: Ci.nsIBrowserProfileMigrator.COOKIES,
- HISTORY: Ci.nsIBrowserProfileMigrator.HISTORY,
- FORMDATA: Ci.nsIBrowserProfileMigrator.FORMDATA,
- PASSWORDS: Ci.nsIBrowserProfileMigrator.PASSWORDS,
- BOOKMARKS: Ci.nsIBrowserProfileMigrator.BOOKMARKS,
- OTHERDATA: Ci.nsIBrowserProfileMigrator.OTHERDATA
- },
-
- /**
- * Helper for implementing simple asynchronous cases of migration resources'
- * |migrate(aCallback)| (see MigratorPrototype). If your |migrate| method
- * just waits for some file to be read, for example, and then migrates
- * everything right away, you can wrap the async-function with this helper
- * and not worry about notifying the callback.
- *
- * For example, instead of writing:
- * setTimeout(function() {
- * try {
- * ....
- * aCallback(true);
- * }
- * catch() {
- * aCallback(false);
- * }
- * }, 0);
- *
- * You may write:
- * setTimeout(MigrationUtils.wrapMigrateFunction(function() {
- * if (importingFromMosaic)
- * throw Cr.NS_ERROR_UNEXPECTED;
- * }, aCallback), 0);
- *
- * ... and aCallback will be called with aSuccess=false when importing
- * from Mosaic, or with aSuccess=true otherwise.
- *
- * @param aFunction
- * the function that will be called sometime later. If aFunction
- * throws when it's called, aCallback(false) is called, otherwise
- * aCallback(true) is called.
- * @param aCallback
- * the callback function passed to |migrate|.
- * @return the wrapped function.
- */
- wrapMigrateFunction: function MU_wrapMigrateFunction(aFunction, aCallback) {
- return function() {
- let success = false;
- try {
- aFunction.apply(null, arguments);
- success = true;
- }
- catch(ex) {
- Cu.reportError(ex);
- }
- // Do not change this to call aCallback directly in try try & catch
- // blocks, because if aCallback throws, we may end up calling aCallback
- // twice.
- aCallback(success);
- }
- },
-
- /**
- * Gets a string from the migration bundle. Shorthand for
- * nsIStringBundle.GetStringFromName, if aReplacements isn't passed, or for
- * nsIStringBundle.formatStringFromName if it is.
- *
- * This method also takes care of "bumped" keys (See bug 737381 comment 8 for
- * details).
- *
- * @param aKey
- * The key of the string to retrieve.
- * @param aReplacemts
- * [optioanl] Array of replacements to run on the retrieved string.
- * @return the retrieved string.
- *
- * @see nsIStringBundle
- */
- getLocalizedString: function MU_getLocalizedString(aKey, aReplacements) {
- const OVERRIDES = {
- "4_firefox": "4_firefox_history_and_bookmarks",
- "64_firefox": "64_firefox_other"
- };
- aKey = OVERRIDES[aKey] || aKey;
-
- if (aReplacements === undefined)
- return getMigrationBundle().GetStringFromName(aKey);
- return getMigrationBundle().formatStringFromName(
- aKey, aReplacements, aReplacements.length);
- },
-
- /**
- * Helper for creating a folder for imported bookmarks from a particular
- * migration source. The folder is created at the end of the given folder.
- *
- * @param aSourceNameStr
- * the source name (first letter capitalized). This is used
- * for reading the localized source name from the migration
- * bundle (e.g. if aSourceNameStr is Mosaic, this will try to read
- * sourceNameMosaic from the migration bundle).
- * @param aParentId
- * the item-id of the folder in which the new folder should be
- * created.
- * @return the item-id of the new folder.
- */
- createImportedBookmarksFolder:
- function MU_createImportedBookmarksFolder(aSourceNameStr, aParentId) {
- let source = this.getLocalizedString("sourceName" + aSourceNameStr);
- let label = this.getLocalizedString("importedBookmarksFolder", [source]);
- return PlacesUtils.bookmarks.createFolder(
- aParentId, label, PlacesUtils.bookmarks.DEFAULT_INDEX);
- },
-
- get _migrators() gMigrators ? gMigrators : gMigrators = new Dict(),
-
- /*
- * Returns the migrator for the given source, if any data is available
- * for this source, or null otherwise.
- *
- * @param aKey internal name of the migration source.
- * Supported values: ie (windows),
- * safari (mac/windows),
- * chrome (mac/windows/linux),
- * firefox.
- *
- * If null is returned, either no data can be imported
- * for the given migrator, or aMigratorKey is invalid (e.g. ie on mac,
- * or mosaic everywhere). This method should be used rather than direct
- * getService for future compatibility (see bug 718280).
- *
- * @return profile migrator implementing nsIBrowserProfileMigrator, if it can
- * import any data, null otherwise.
- */
- getMigrator: function MU_getMigrator(aKey) {
- let migrator = null;
- if (this._migrators.has(aKey)) {
- migrator = this._migrators.get(aKey);
- }
- else {
- try {
- migrator = Cc["@mozilla.org/profile/migrator;1?app=browser&type=" +
- aKey].createInstance(Ci.nsIBrowserProfileMigrator);
- }
- catch(ex) { }
- this._migrators.set(aKey, migrator);
- }
-
- return migrator && migrator.sourceExists ? migrator : null;
- },
-
- // Iterates the available migrators, in the most suitable
- // order for the running platform.
- get migrators() {
- let migratorKeysOrdered = [
-#ifdef XP_WIN
- "firefox", "ie", "chrome", "safari"
-#elifdef XP_MACOSX
- "firefox", "safari", "chrome"
-#elifdef XP_UNIX
- "firefox", "chrome"
-#endif
- ];
-
- // If a supported default browser is found check it first
- // so that the wizard defaults to import from that browser.
- let defaultBrowserKey = getMigratorKeyForDefaultBrowser();
- if (defaultBrowserKey)
- migratorKeysOrdered.sort(function (a, b) b == defaultBrowserKey ? 1 : 0);
-
- for (let migratorKey of migratorKeysOrdered) {
- let migrator = this.getMigrator(migratorKey);
- if (migrator)
- yield migrator;
- }
- },
-
- // Whether or not we're in the process of startup migration
- get isStartupMigration() gProfileStartup != null,
-
- /**
- * In the case of startup migration, this is set to the nsIProfileStartup
- * instance passed to ProfileMigrator's migrate.
- *
- * @see showMigrationWizard
- */
- get profileStartup() gProfileStartup,
-
- /**
- * Show the migration wizard. On mac, this may just focus the wizard if it's
- * already running, in which case aOpener and aParams are ignored.
- *
- * @param [optional] aOpener
- * the window that asks to open the wizard.
- * @param [optional] aParams
- * arguments for the migration wizard, in the form of an nsIArray.
- * This is passed as-is for the params argument of
- * nsIWindowWatcher.openWindow.
- */
- showMigrationWizard:
- function MU_showMigrationWizard(aOpener, aParams) {
- let features = "chrome,dialog,modal,centerscreen,titlebar,resizable=no";
-#ifdef XP_MACOSX
- if (!this.isStartupMigration) {
- let win = Services.wm.getMostRecentWindow("Browser:MigrationWizard");
- if (win) {
- win.focus();
- return;
- }
- // On mac, the migration wiazrd should only be modal in the case of
- // startup-migration.
- features = "centerscreen,chrome,resizable=no";
- }
-#endif
-
- Services.ww.openWindow(aOpener,
- "chrome://browser/content/migration/migration.xul",
- "_blank",
- features,
- aParams);
- },
-
- /**
- * Show the migration wizard for startup-migration. This should only be
- * called by ProfileMigrator (see ProfileMigrator.js), which implements
- * nsIProfileMigrator.
- *
- * @param aProfileStartup
- * the nsIProfileStartup instance provided to ProfileMigrator.migrate.
- * @param [optional] aMigratorKey
- * If set, the migration wizard will import from the corresponding
- * migrator, bypassing the source-selection page. Otherwise, the
- * source-selection page will be displayed, either with the default
- * browser selected, if it could be detected and if there is a
- * migrator for it, or with the first option selected as a fallback
- * (The first option is hardcoded to be the most common browser for
- * the OS we run on. See migration.xul).
- * @param [optional] aProfileToMigrate
- * If set, the migration wizard will import from the profile indicated.
- *
- * @throws if aMigratorKey is invalid or if it points to a non-existent
- * source.
- */
- startupMigration:
- function MU_startupMigrator(aProfileStartup, aMigratorKey, aProfileToMigrate) {
- if (!aProfileStartup) {
- throw new Error("a profile-startup instance is required for startup-migration");
- }
- gProfileStartup = aProfileStartup;
-
- let skipSourcePage = false, migrator = null, migratorKey = "";
- if (aMigratorKey) {
- migrator = this.getMigrator(aMigratorKey);
- if (!migrator) {
- // aMigratorKey must point to a valid source, so, if it doesn't
- // cleanup and throw.
- this.finishMigration();
- throw new Error("startMigration was asked to open auto-migrate from " +
- "a non-existent source: " + aMigratorKey);
- }
- migratorKey = aMigratorKey;
- skipSourcePage = true;
- }
- else {
- let defaultBrowserKey = getMigratorKeyForDefaultBrowser();
- if (defaultBrowserKey) {
- migrator = this.getMigrator(defaultBrowserKey);
- if (migrator)
- migratorKey = defaultBrowserKey;
- }
- }
-
- if (!migrator) {
- // If there's no migrator set so far, ensure that there is at least one
- // migrator available before opening the wizard.
- try {
- this.migrators.next();
- }
- catch(ex) {
- this.finishMigration();
- if (!(ex instanceof StopIteration))
- throw ex;
- return;
- }
- }
-
- let params = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
- let keyCSTR = Cc["@mozilla.org/supports-cstring;1"].
- createInstance(Ci.nsISupportsCString);
- keyCSTR.data = migratorKey;
- let skipImportSourcePageBool = Cc["@mozilla.org/supports-PRBool;1"].
- createInstance(Ci.nsISupportsPRBool);
- skipImportSourcePageBool.data = skipSourcePage;
- let profileToMigrate = null;
- if (aProfileToMigrate) {
- profileToMigrate = Cc["@mozilla.org/supports-string;1"].
- createInstance(Ci.nsISupportsString);
- profileToMigrate.data = aProfileToMigrate;
- }
- params.appendElement(keyCSTR, false);
- params.appendElement(migrator, false);
- params.appendElement(aProfileStartup, false);
- params.appendElement(skipImportSourcePageBool, false);
- params.appendElement(profileToMigrate, false);
-
- this.showMigrationWizard(null, params);
- },
-
- /**
- * Cleans up references to migrators and nsIProfileInstance instances.
- */
- finishMigration: function MU_finishMigration() {
- gMigrators = null;
- gProfileStartup = null;
- gMigrationBundle = null;
- }
-});
diff --git a/application/palemoon/components/migration/ProfileMigrator.js b/application/palemoon/components/migration/ProfileMigrator.js
deleted file mode 100644
index f67823bae..000000000
--- a/application/palemoon/components/migration/ProfileMigrator.js
+++ /dev/null
@@ -1,21 +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/. */
-
-"use strict";
-
-Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource:///modules/MigrationUtils.jsm");
-
-function ProfileMigrator() {
-}
-
-ProfileMigrator.prototype = {
- migrate: MigrationUtils.startupMigration.bind(MigrationUtils),
- QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIProfileMigrator]),
- classDescription: "Profile Migrator",
- contractID: "@mozilla.org/toolkit/profile-migrator;1",
- classID: Components.ID("6F8BB968-C14F-4D6F-9733-6C6737B35DCE")
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ProfileMigrator]);
diff --git a/application/palemoon/components/migration/SafariProfileMigrator.js b/application/palemoon/components/migration/SafariProfileMigrator.js
deleted file mode 100644
index e3f73c2c8..000000000
--- a/application/palemoon/components/migration/SafariProfileMigrator.js
+++ /dev/null
@@ -1,416 +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/. */
-
-"use strict";
-
-var Cc = Components.classes;
-var Ci = Components.interfaces;
-var Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/FileUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource:///modules/MigrationUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PropertyListUtils",
- "resource://gre/modules/PropertyListUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
- "resource://gre/modules/NetUtil.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "FormHistory",
- "resource://gre/modules/FormHistory.jsm");
-
-function Bookmarks(aBookmarksFile) {
- this._file = aBookmarksFile;
-}
-Bookmarks.prototype = {
- type: MigrationUtils.resourceTypes.BOOKMARKS,
-
- migrate: function B_migrate(aCallback) {
- PropertyListUtils.read(this._file,
- MigrationUtils.wrapMigrateFunction(function migrateBookmarks(aDict) {
- if (!aDict)
- throw new Error("Could not read Bookmarks.plist");
-
- let children = aDict.get("Children");;
- if (!children)
- throw new Error("Invalid Bookmarks.plist format");
-
- PlacesUtils.bookmarks.runInBatchMode({
- runBatched: function() {
- let collection = aDict.get("Title") == "com.apple.ReadingList" ?
- this.READING_LIST_COLLECTION : this.ROOT_COLLECTION;
- this._migrateCollection(children, collection);
- }.bind(this)
- }, null);
- }.bind(this), aCallback));
- },
-
- // Bookmarks collections in Safari. Constants for migrateCollection.
- ROOT_COLLECTION: 0,
- MENU_COLLECTION: 1,
- TOOLBAR_COLLECTION: 2,
- READING_LIST_COLLECTION: 3,
-
- /**
- * Recursively migrate a Safari collection of bookmarks.
- *
- * @param aEntries
- * the collection's children
- * @param aCollection
- * one of the values above.
- */
- _migrateCollection: function B__migrateCollection(aEntries, aCollection) {
- // A collection of bookmarks in Safari resembles places roots. In the
- // property list files (Bookmarks.plist, ReadingList.plist) they are
- // stored as regular bookmarks folders, and thus can only be distinguished
- // from by their names and places in the hierarchy.
-
- let entriesFiltered = [];
- if (aCollection == this.ROOT_COLLECTION) {
- for (let entry of aEntries) {
- let type = entry.get("WebBookmarkType");
- if (type == "WebBookmarkTypeList" && entry.has("Children")) {
- let title = entry.get("Title");
- let children = entry.get("Children");
- if (title == "BookmarksBar")
- this._migrateCollection(children, this.TOOLBAR_COLLECTION);
- else if (title == "BookmarksMenu")
- this._migrateCollection(children, this.MENU_COLLECTION);
- else if (title == "com.apple.ReadingList")
- this._migrateCollection(children, this.READING_LIST_COLLECTION);
- else if (entry.get("ShouldOmitFromUI") !== true)
- entriesFiltered.push(entry);
- }
- else if (type == "WebBookmarkTypeLeaf") {
- entriesFiltered.push(entry);
- }
- }
- }
- else {
- entriesFiltered = aEntries;
- }
-
- if (entriesFiltered.length == 0)
- return;
-
- let folder = -1;
- switch (aCollection) {
- case this.ROOT_COLLECTION: {
- // In Safari, it is possible (though quite cumbersome) to move
- // bookmarks to the bookmarks root, which is the parent folder of
- // all bookmarks "collections". That is somewhat in parallel with
- // both the places root and the unfiled-bookmarks root.
- // Because the former is only an implementation detail in our UI,
- // the unfiled root seems to be the best choice.
- folder = PlacesUtils.unfiledBookmarksFolderId;
- break;
- }
- case this.MENU_COLLECTION: {
- folder = PlacesUtils.bookmarksMenuFolderId;
- if (!MigrationUtils.isStartupMigration) {
- folder = MigrationUtils.createImportedBookmarksFolder("Safari",
- folder);
- }
- break;
- }
- case this.TOOLBAR_COLLECTION: {
- folder = PlacesUtils.toolbarFolderId;
- if (!MigrationUtils.isStartupMigration) {
- folder = MigrationUtils.createImportedBookmarksFolder("Safari",
- folder);
- }
- break;
- }
- case this.READING_LIST_COLLECTION: {
- // Reading list items are imported as regular bookmarks.
- // They are imported under their own folder, created either under the
- // bookmarks menu (in the case of startup migration).
- folder = PlacesUtils.bookmarks.createFolder(
- PlacesUtils.bookmarksMenuFolderId,
- MigrationUtils.getLocalizedString("importedSafariReadingList"),
- PlacesUtils.bookmarks.DEFAULT_INDEX);
- break;
- }
- default:
- throw new Error("Unexpected value for aCollection!");
- }
-
- this._migrateEntries(entriesFiltered, folder);
- },
-
- // migrate the given array of safari bookmarks to the given places
- // folder.
- _migrateEntries: function B__migrateEntries(aEntries, aFolderId) {
- for (let entry of aEntries) {
- let type = entry.get("WebBookmarkType");
- if (type == "WebBookmarkTypeList" && entry.has("Children")) {
- let title = entry.get("Title");
- let folderId = PlacesUtils.bookmarks.createFolder(
- aFolderId, title, PlacesUtils.bookmarks.DEFAULT_INDEX);
-
- // Empty folders may not have a children array.
- if (entry.has("Children"))
- this._migrateEntries(entry.get("Children"), folderId, false);
- }
- else if (type == "WebBookmarkTypeLeaf" && entry.has("URLString")) {
- let title, uri;
- if (entry.has("URIDictionary"))
- title = entry.get("URIDictionary").get("title");
-
- try {
- uri = NetUtil.newURI(entry.get("URLString"));
- }
- catch(ex) {
- Cu.reportError("Invalid uri set for Safari bookmark: " + entry.get("URLString"));
- }
- if (uri) {
- PlacesUtils.bookmarks.insertBookmark(aFolderId, uri,
- PlacesUtils.bookmarks.DEFAULT_INDEX, title);
- }
- }
- }
- }
-};
-
-function History(aHistoryFile) {
- this._file = aHistoryFile;
-}
-History.prototype = {
- type: MigrationUtils.resourceTypes.HISTORY,
-
- // Helper method for converting the visit date property to a PRTime value.
- // The visit date is stored as a string, so it's not read as a Date
- // object by PropertyListUtils.
- _parseCocoaDate: function H___parseCocoaDate(aCocoaDateStr) {
- let asDouble = parseFloat(aCocoaDateStr);
- if (!isNaN(asDouble)) {
- // reference date of NSDate.
- let date = new Date("1 January 2001, GMT");
- date.setMilliseconds(asDouble * 1000);
- return date * 1000;
- }
- return 0;
- },
-
- migrate: function H_migrate(aCallback) {
- PropertyListUtils.read(this._file, function migrateHistory(aDict) {
- try {
- if (!aDict)
- throw new Error("Could not read history property list");
- if (!aDict.has("WebHistoryDates"))
- throw new Error("Unexpected history-property list format");
-
- // Safari's History file contains only top-level urls. It does not
- // distinguish between typed urls and linked urls.
- let transType = PlacesUtils.history.TRANSITION_LINK;
-
- let places = [];
- let entries = aDict.get("WebHistoryDates");
- for (let entry of entries) {
- if (entry.has("lastVisitedDate")) {
- let visitDate = this._parseCocoaDate(entry.get("lastVisitedDate"));
- places.push({ uri: NetUtil.newURI(entry.get("")),
- title: entry.get("title"),
- visits: [{ transitionType: transType,
- visitDate: visitDate }] });
- }
- }
- if (places.length > 0) {
- PlacesUtils.asyncHistory.updatePlaces(places, {
- _success: false,
- handleResult: function() {
- // Importing any entry is considered a successful import.
- this._success = true;
- },
- handleError: function() {},
- handleCompletion: function() {
- aCallback(this._success);
- }
- });
- }
- else {
- aCallback(false);
- }
- }
- catch(ex) {
- Cu.reportError(ex);
- aCallback(false);
- }
- }.bind(this));
- }
-};
-
-/**
- * Safari's preferences property list is independently used for three purposes:
- * (a) importation of preferences
- * (b) importation of search strings
- * (c) retrieving the home page.
- *
- * So, rather than reading it three times, it's cached and managed here.
- */
-function MainPreferencesPropertyList(aPreferencesFile) {
- this._file = aPreferencesFile;
- this._callbacks = [];
-}
-MainPreferencesPropertyList.prototype = {
- /**
- * @see PropertyListUtils.read
- */
- read: function MPPL_read(aCallback) {
- if ("_dict" in this) {
- aCallback(this._dict);
- return;
- }
-
- let alreadyReading = this._callbacks.length > 0;
- this._callbacks.push(aCallback);
- if (!alreadyReading) {
- PropertyListUtils.read(this._file, function readPrefs(aDict) {
- this._dict = aDict;
- for (let callback of this._callbacks) {
- try {
- callback(aDict);
- }
- catch(ex) {
- Cu.reportError(ex);
- }
- }
- this._callbacks.splice(0);
- }.bind(this));
- }
- },
-
- // Workaround for nsIBrowserProfileMigrator.sourceHomePageURL until
- // it's replaced with an async method.
- _readSync: function MPPL__readSync() {
- if ("_dict" in this)
- return this._dict;
-
- let inputStream = Cc["@mozilla.org/network/file-input-stream;1"].
- createInstance(Ci.nsIFileInputStream);
- inputStream.init(this._file, -1, -1, 0);
- let binaryStream = Cc["@mozilla.org/binaryinputstream;1"].
- createInstance(Ci.nsIBinaryInputStream);
- binaryStream.setInputStream(inputStream);
- let bytes = binaryStream.readByteArray(inputStream.available());
- this._dict = PropertyListUtils._readFromArrayBufferSync(
- Uint8Array(bytes).buffer);
- return this._dict;
- }
-};
-
-function SearchStrings(aMainPreferencesPropertyListInstance) {
- this._mainPreferencesPropertyList = aMainPreferencesPropertyListInstance;
-}
-SearchStrings.prototype = {
- type: MigrationUtils.resourceTypes.OTHERDATA,
-
- migrate: function SS_migrate(aCallback) {
- this._mainPreferencesPropertyList.read(MigrationUtils.wrapMigrateFunction(
- function migrateSearchStrings(aDict) {
- if (!aDict)
- throw new Error("Could not get preferences dictionary");
-
- if (aDict.has("RecentSearchStrings")) {
- let recentSearchStrings = aDict.get("RecentSearchStrings");
- if (recentSearchStrings && recentSearchStrings.length > 0) {
- let changes = [{op: "add",
- fieldname: "searchbar-history",
- value: searchString}
- for (searchString of recentSearchStrings)];
- FormHistory.update(changes);
- }
- }
- }.bind(this), aCallback));
- }
-};
-
-function SafariProfileMigrator() {
-}
-
-SafariProfileMigrator.prototype = Object.create(MigratorPrototype);
-
-SafariProfileMigrator.prototype.getResources = function SM_getResources() {
- let profileDir =
-#ifdef XP_MACOSX
- FileUtils.getDir("ULibDir", ["Safari"], false);
-#else
- FileUtils.getDir("AppData", ["Apple Computer", "Safari"], false);
-#endif
- if (!profileDir.exists())
- return null;
-
- let resources = [];
- let pushProfileFileResource = function(aFileName, aConstructor) {
- let file = profileDir.clone();
- file.append(aFileName);
- if (file.exists())
- resources.push(new aConstructor(file));
- };
-
- pushProfileFileResource("History.plist", History);
- pushProfileFileResource("Bookmarks.plist", Bookmarks);
-
- // 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 isn't #ifdefed out on mac, because
- // Apple may fix this at some point.
- pushProfileFileResource("ReadingList.plist", Bookmarks);
-
- let prefsDir =
-#ifdef XP_MACOSX
- FileUtils.getDir("UsrPrfs", [], false);
-#else
- FileUtils.getDir("AppData", ["Apple Computer", "Preferences"], false);
-#endif
-
- let prefs = this.mainPreferencesPropertyList;
- if (prefs) {
- resources.push(new SearchStrings(prefs));
- }
-
- return resources;
-};
-
-Object.defineProperty(SafariProfileMigrator.prototype, "mainPreferencesPropertyList", {
- get: function get_mainPreferencesPropertyList() {
- if (this._mainPreferencesPropertyList === undefined) {
- let file =
-#ifdef XP_MACOSX
- FileUtils.getDir("UsrPrfs", [], false);
-#else
- FileUtils.getDir("AppData", ["Apple Computer", "Preferences"], false);
-#endif
- if (file.exists()) {
- file.append("com.apple.Safari.plist");
- if (file.exists()) {
- return this._mainPreferencesPropertyList =
- new MainPreferencesPropertyList(file);
- }
- }
- return this._mainPreferencesPropertyList = null;
- }
- return this._mainPreferencesPropertyList;
- }
-});
-
-Object.defineProperty(SafariProfileMigrator.prototype, "sourceHomePageURL", {
- get: function get_sourceHomePageURL() {
- if (this.mainPreferencesPropertyList) {
- let dict = this.mainPreferencesPropertyList._readSync();
- if (dict.has("HomePage"))
- return dict.get("HomePage");
- }
- return "";
- }
-});
-
-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}");
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SafariProfileMigrator]);
diff --git a/application/palemoon/components/migration/content/migration.js b/application/palemoon/components/migration/content/migration.js
deleted file mode 100644
index 512197b8b..000000000
--- a/application/palemoon/components/migration/content/migration.js
+++ /dev/null
@@ -1,474 +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 Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cu = Components.utils;
-
-const kIMig = Ci.nsIBrowserProfileMigrator;
-const kIPStartup = Ci.nsIProfileStartup;
-
-Cu.import("resource:///modules/MigrationUtils.jsm");
-
-var MigrationWizard = {
- _source: "", // Source Profile Migrator ContractID suffix
- _itemsFlags: kIMig.ALL, // Selected Import Data Sources (16-bit bitfield)
- _selectedProfile: null, // Selected Profile name to import from
- _wiz: null,
- _migrator: null,
- _autoMigrate: null,
-
- init: function ()
- {
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- os.addObserver(this, "Migration:Started", false);
- os.addObserver(this, "Migration:ItemBeforeMigrate", false);
- os.addObserver(this, "Migration:ItemAfterMigrate", false);
- os.addObserver(this, "Migration:ItemError", false);
- os.addObserver(this, "Migration:Ended", false);
-
- this._wiz = document.documentElement;
-
- if ("arguments" in window && window.arguments.length > 1) {
- this._source = window.arguments[0];
- this._migrator = window.arguments[1] instanceof kIMig ?
- window.arguments[1] : null;
- this._autoMigrate = window.arguments[2].QueryInterface(kIPStartup);
- this._skipImportSourcePage = window.arguments[3];
- if (this._migrator && window.arguments[4]) {
- let sourceProfiles = this._migrator.sourceProfiles;
- this._selectedProfile = sourceProfiles.find(profile => profile.id == window.arguments[4]);
- }
-
- if (this._autoMigrate) {
- // Show the "nothing" option in the automigrate case to provide an
- // easily identifiable way to avoid migration and create a new profile.
- var nothing = document.getElementById("nothing");
- nothing.hidden = false;
- }
- }
-
- this.onImportSourcePageShow();
- },
-
- uninit: function ()
- {
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- os.removeObserver(this, "Migration:Started");
- os.removeObserver(this, "Migration:ItemBeforeMigrate");
- os.removeObserver(this, "Migration:ItemAfterMigrate");
- os.removeObserver(this, "Migration:ItemError");
- os.removeObserver(this, "Migration:Ended");
- MigrationUtils.finishMigration();
- },
-
- // 1 - Import Source
- onImportSourcePageShow: function ()
- {
- this._wiz.canRewind = false;
-
- var selectedMigrator = null;
-
- // Figure out what source apps are are available to import from:
- var group = document.getElementById("importSourceGroup");
- for (var i = 0; i < group.childNodes.length; ++i) {
- var migratorKey = group.childNodes[i].id;
- if (migratorKey != "nothing") {
- var migrator = MigrationUtils.getMigrator(migratorKey);
- if (migrator) {
- // Save this as the first selectable item, if we don't already have
- // one, or if it is the migrator that was passed to us.
- if (!selectedMigrator || this._source == migratorKey)
- selectedMigrator = group.childNodes[i];
- } else {
- // Hide this option
- group.childNodes[i].hidden = true;
- }
- }
- }
-
- if (selectedMigrator)
- group.selectedItem = selectedMigrator;
- else {
- // We didn't find a migrator, notify the user
- document.getElementById("noSources").hidden = false;
-
- this._wiz.canAdvance = false;
-
- document.getElementById("importBookmarks").hidden = true;
- document.getElementById("importAll").hidden = true;
- }
-
- // Advance to the next page if the caller told us to.
- if (this._migrator && this._skipImportSourcePage) {
- this._wiz.advance();
- this._wiz.canRewind = false;
- }
- },
-
- onImportSourcePageAdvanced: function ()
- {
- var newSource = document.getElementById("importSourceGroup").selectedItem.id;
-
- if (newSource == "nothing") {
- document.documentElement.cancel();
- return false;
- }
-
- if (!this._migrator || (newSource != this._source)) {
- // Create the migrator for the selected source.
- this._migrator = MigrationUtils.getMigrator(newSource);
-
- this._itemsFlags = kIMig.ALL;
- this._selectedProfile = null;
- }
- this._source = newSource;
-
- // check for more than one source profile
- var sourceProfiles = this._migrator.sourceProfiles;
- if (this._skipImportSourcePage) {
- this._wiz.currentPage.next = "homePageImport";
- }
- else if (sourceProfiles && sourceProfiles.length > 1) {
- this._wiz.currentPage.next = "selectProfile";
- }
- else {
- if (this._autoMigrate)
- this._wiz.currentPage.next = "homePageImport";
- else
- this._wiz.currentPage.next = "importItems";
-
- if (sourceProfiles && sourceProfiles.length == 1)
- this._selectedProfile = sourceProfiles[0];
- else
- this._selectedProfile = null;
- }
- },
-
- // 2 - [Profile Selection]
- onSelectProfilePageShow: function ()
- {
- // Disabling this for now, since we ask about import sources in automigration
- // too and don't want to disable the back button
- // if (this._autoMigrate)
- // document.documentElement.getButton("back").disabled = true;
-
- var profiles = document.getElementById("profiles");
- while (profiles.hasChildNodes())
- profiles.removeChild(profiles.firstChild);
-
- // Note that this block is still reached even if the user chose 'From File'
- // and we canceled the dialog. When that happens, _migrator will be null.
- if (this._migrator) {
- var sourceProfiles = this._migrator.sourceProfiles;
-
- for (let profile of sourceProfiles) {
- var item = document.createElement("radio");
- item.id = profile.id;
- item.setAttribute("label", profile.name);
- profiles.appendChild(item);
- }
- }
-
- profiles.selectedItem = this._selectedProfile ? document.getElementById(this._selectedProfile.id) : profiles.firstChild;
- },
-
- onSelectProfilePageRewound: function ()
- {
- var profiles = document.getElementById("profiles");
- this._selectedProfile = this._migrator.sourceProfiles.find(
- profile => profile.id == profiles.selectedItem.id
- ) || null;
- },
-
- onSelectProfilePageAdvanced: function ()
- {
- var profiles = document.getElementById("profiles");
- this._selectedProfile = this._migrator.sourceProfiles.find(
- profile => profile.id == profiles.selectedItem.id
- ) || null;
-
- // If we're automigrating or just doing bookmarks don't show the item selection page
- if (this._autoMigrate)
- this._wiz.currentPage.next = "homePageImport";
- },
-
- // 3 - ImportItems
- onImportItemsPageShow: function ()
- {
- var dataSources = document.getElementById("dataSources");
- while (dataSources.hasChildNodes())
- dataSources.removeChild(dataSources.firstChild);
-
- var items = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate);
- for (var i = 0; i < 16; ++i) {
- var itemID = (items >> i) & 0x1 ? Math.pow(2, i) : 0;
- if (itemID > 0) {
- var checkbox = document.createElement("checkbox");
- checkbox.id = itemID;
- checkbox.setAttribute("label",
- MigrationUtils.getLocalizedString(itemID + "_" + this._source));
- dataSources.appendChild(checkbox);
- if (!this._itemsFlags || this._itemsFlags & itemID)
- checkbox.checked = true;
- }
- }
- },
-
- onImportItemsPageRewound: function ()
- {
- this._wiz.canAdvance = true;
- this.onImportItemsPageAdvanced();
- },
-
- onImportItemsPageAdvanced: function ()
- {
- var dataSources = document.getElementById("dataSources");
- this._itemsFlags = 0;
- for (var i = 0; i < dataSources.childNodes.length; ++i) {
- var checkbox = dataSources.childNodes[i];
- if (checkbox.localName == "checkbox" && checkbox.checked)
- this._itemsFlags |= parseInt(checkbox.id);
- }
- },
-
- onImportItemCommand: function (aEvent)
- {
- var items = document.getElementById("dataSources");
- var checkboxes = items.getElementsByTagName("checkbox");
-
- var oneChecked = false;
- for (var i = 0; i < checkboxes.length; ++i) {
- if (checkboxes[i].checked) {
- oneChecked = true;
- break;
- }
- }
-
- this._wiz.canAdvance = oneChecked;
- },
-
- // 4 - Home Page Selection
- onHomePageMigrationPageShow: function ()
- {
- // only want this on the first run
- if (!this._autoMigrate) {
- this._wiz.advance();
- return;
- }
-
- var brandBundle = document.getElementById("brandBundle");
- // These strings don't exist when not using official branding. If that's
- // the case, just skip this page.
- try {
- var pageTitle = brandBundle.getString("homePageMigrationPageTitle");
- var pageDesc = brandBundle.getString("homePageMigrationDescription");
- var mainStr = brandBundle.getString("homePageSingleStartMain");
- }
- catch (e) {
- this._wiz.advance();
- return;
- }
-
- document.getElementById("homePageImport").setAttribute("label", pageTitle);
- document.getElementById("homePageImportDesc").setAttribute("value", pageDesc);
-
- this._wiz._adjustWizardHeader();
-
- var singleStart = document.getElementById("homePageSingleStart");
- singleStart.setAttribute("label", mainStr);
- singleStart.setAttribute("value", "DEFAULT");
-
- var source = null;
- switch (this._source) {
- case "ie":
- source = "sourceNameIE";
- break;
- case "safari":
- source = "sourceNameSafari";
- break;
- case "chrome":
- source = "sourceNameChrome";
- break;
- case "firefox":
- source = "sourceNameFirefox";
- break;
- }
-
- // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places
- this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate);
-
- var oldHomePageURL = this._migrator.sourceHomePageURL;
-
- if (oldHomePageURL && source) {
- var appName = MigrationUtils.getLocalizedString(source);
- var oldHomePageLabel =
- brandBundle.getFormattedString("homePageImport", [appName]);
- var oldHomePage = document.getElementById("oldHomePage");
- oldHomePage.setAttribute("label", oldHomePageLabel);
- oldHomePage.setAttribute("value", oldHomePageURL);
- oldHomePage.removeAttribute("hidden");
- }
- else {
- // if we don't have at least two options, just advance
- this._wiz.advance();
- }
- },
-
- onHomePageMigrationPageAdvanced: function ()
- {
- // we might not have a selectedItem if we're in fallback mode
- try {
- var radioGroup = document.getElementById("homePageRadiogroup");
-
- this._newHomePage = radioGroup.selectedItem.value;
- } catch(ex) {}
- },
-
- // 5 - Migrating
- onMigratingPageShow: function ()
- {
- this._wiz.getButton("cancel").disabled = true;
- this._wiz.canRewind = false;
- this._wiz.canAdvance = false;
-
- // When automigrating, show all of the data that can be received from this source.
- if (this._autoMigrate)
- this._itemsFlags = this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate);
-
- this._listItems("migratingItems");
- setTimeout(this.onMigratingMigrate, 0, this);
- },
-
- onMigratingMigrate: function (aOuter)
- {
- aOuter._migrator.migrate(aOuter._itemsFlags, aOuter._autoMigrate, aOuter._selectedProfile);
- },
-
- _listItems: function (aID)
- {
- var items = document.getElementById(aID);
- while (items.hasChildNodes())
- items.removeChild(items.firstChild);
-
- var brandBundle = document.getElementById("brandBundle");
- var itemID;
- for (var i = 0; i < 16; ++i) {
- var itemID = (this._itemsFlags >> i) & 0x1 ? Math.pow(2, i) : 0;
- if (itemID > 0) {
- var label = document.createElement("label");
- label.id = itemID + "_migrated";
- try {
- label.setAttribute("value",
- MigrationUtils.getLocalizedString(itemID + "_" + this._source));
- items.appendChild(label);
- }
- catch (e) {
- // if the block above throws, we've enumerated all the import data types we
- // currently support and are now just wasting time, break.
- break;
- }
- }
- }
- },
-
- observe: function (aSubject, aTopic, aData)
- {
- switch (aTopic) {
- case "Migration:Started":
- break;
- case "Migration:ItemBeforeMigrate":
- var label = document.getElementById(aData + "_migrated");
- if (label)
- label.setAttribute("style", "font-weight: bold");
- break;
- case "Migration:ItemAfterMigrate":
- var label = document.getElementById(aData + "_migrated");
- if (label)
- label.removeAttribute("style");
- break;
- case "Migration:Ended":
- if (this._autoMigrate) {
- if (this._newHomePage) {
- try {
- // set homepage properly
- var prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefService);
- var prefBranch = prefSvc.getBranch(null);
-
- if (this._newHomePage == "DEFAULT") {
- prefBranch.clearUserPref("browser.startup.homepage");
- }
- else {
- var str = Components.classes["@mozilla.org/supports-string;1"]
- .createInstance(Components.interfaces.nsISupportsString);
- str.data = this._newHomePage;
- prefBranch.setComplexValue("browser.startup.homepage",
- Components.interfaces.nsISupportsString,
- str);
- }
-
- var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties);
- var prefFile = dirSvc.get("ProfDS", Components.interfaces.nsIFile);
- prefFile.append("prefs.js");
- prefSvc.savePrefFile(prefFile);
- } catch(ex) {
- dump(ex);
- }
- }
-
- // We're done now.
- this._wiz.canAdvance = true;
- this._wiz.advance();
-
- setTimeout(close, 5000);
- }
- else {
- this._wiz.canAdvance = true;
- var nextButton = this._wiz.getButton("next");
- nextButton.click();
- }
- break;
- case "Migration:ItemError":
- var type = "undefined";
- switch (parseInt(aData)) {
- case Ci.nsIBrowserProfileMigrator.SETTINGS:
- type = "settings";
- break;
- case Ci.nsIBrowserProfileMigrator.COOKIES:
- type = "cookies";
- break;
- case Ci.nsIBrowserProfileMigrator.HISTORY:
- type = "history";
- break;
- case Ci.nsIBrowserProfileMigrator.FORMDATA:
- type = "form data";
- break;
- case Ci.nsIBrowserProfileMigrator.PASSWORDS:
- type = "passwords";
- break;
- case Ci.nsIBrowserProfileMigrator.BOOKMARKS:
- type = "bookmarks";
- break;
- case Ci.nsIBrowserProfileMigrator.OTHERDATA:
- type = "misc. data";
- break;
- }
- Cc["@mozilla.org/consoleservice;1"]
- .getService(Ci.nsIConsoleService)
- .logStringMessage("some " + type + " did not successfully migrate.");
- break;
- }
- },
-
- onDonePageShow: function ()
- {
- this._wiz.getButton("cancel").disabled = true;
- this._wiz.canRewind = false;
- this._listItems("doneItems");
- }
-};
diff --git a/application/palemoon/components/migration/content/migration.xul b/application/palemoon/components/migration/content/migration.xul
deleted file mode 100644
index 2c8df7b3e..000000000
--- a/application/palemoon/components/migration/content/migration.xul
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.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/.
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<!DOCTYPE dialog SYSTEM "chrome://browser/locale/migration/migration.dtd" >
-
-<wizard id="migrationWizard"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- windowtype="Browser:MigrationWizard"
- title="&migrationWizard.title;"
- onload="MigrationWizard.init()"
- onunload="MigrationWizard.uninit()"
- style="width: 40em;"
- buttons="accept,cancel"
- branded="true">
-
- <script type="application/javascript" src="chrome://browser/content/migration/migration.js"/>
-
- <stringbundle id="brandBundle" src="chrome://branding/locale/brand.properties"/>
-
- <wizardpage id="importSource" pageid="importSource" next="selectProfile"
- label="&importSource.title;"
- onpageadvanced="return MigrationWizard.onImportSourcePageAdvanced();">
- <description id="importAll" control="importSourceGroup">&importFrom.label;</description>
- <description id="importBookmarks" control="importSourceGroup" hidden="true">&importFromBookmarks.label;</description>
-
- <radiogroup id="importSourceGroup" align="start">
- <radio id="firefox" label="&importFromFirefox.label;" accesskey="&importFromFirefox.accesskey;"/>
-#ifdef XP_WIN
- <radio id="ie" label="&importFromIE.label;" accesskey="&importFromIE.accesskey;"/>
- <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/>
- <radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/>
-#elifdef XP_MACOSX
- <radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/>
- <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/>
-#elifdef XP_UNIX
- <radio id="chrome" label="&importFromChrome.label;" accesskey="&importFromChrome.accesskey;"/>
-#endif
- <radio id="nothing" label="&importFromNothing.label;" accesskey="&importFromNothing.accesskey;" hidden="true"/>
- </radiogroup>
- <label id="noSources" hidden="true">&noMigrationSources.label;</label>
- </wizardpage>
-
- <wizardpage id="selectProfile" pageid="selectProfile" label="&selectProfile.title;"
- next="importItems"
- onpageshow="return MigrationWizard.onSelectProfilePageShow();"
- onpagerewound="return MigrationWizard.onSelectProfilePageRewound();"
- onpageadvanced="return MigrationWizard.onSelectProfilePageAdvanced();">
- <description control="profiles">&selectProfile.label;</description>
-
- <radiogroup id="profiles" align="left"/>
- </wizardpage>
-
- <wizardpage id="importItems" pageid="importItems" label="&importItems.title;"
- next="homePageImport"
- onpageshow="return MigrationWizard.onImportItemsPageShow();"
- onpagerewound="return MigrationWizard.onImportItemsPageRewound();"
- onpageadvanced="return MigrationWizard.onImportItemsPageAdvanced();"
- oncommand="MigrationWizard.onImportItemCommand();">
- <description control="dataSources">&importItems.label;</description>
-
- <vbox id="dataSources" style="overflow: auto; -moz-appearance: listbox" align="left" flex="1" role="group"/>
- </wizardpage>
-
- <wizardpage id="homePageImport" pageid="homePageImport"
- next="migrating"
- onpageshow="return MigrationWizard.onHomePageMigrationPageShow();"
- onpageadvanced="return MigrationWizard.onHomePageMigrationPageAdvanced();">
-
- <description id="homePageImportDesc" control="homePageRadioGroup"/>
- <radiogroup id="homePageRadiogroup">
- <radio id="homePageSingleStart" selected="true" />
- <radio id="oldHomePage" hidden="true" />
- </radiogroup>
- </wizardpage>
-
- <wizardpage id="migrating" pageid="migrating" label="&migrating.title;"
- next="done"
- onpageshow="MigrationWizard.onMigratingPageShow();">
- <description control="migratingItems">&migrating.label;</description>
-
- <vbox id="migratingItems" style="overflow: auto;" align="left" role="group"/>
- </wizardpage>
-
- <wizardpage id="done" pageid="done" label="&done.title;"
- onpageshow="MigrationWizard.onDonePageShow();">
- <description control="doneItems">&done.label;</description>
-
- <vbox id="doneItems" style="overflow: auto;" align="left" role="group"/>
- </wizardpage>
-
-</wizard>
-
diff --git a/application/palemoon/components/migration/jar.mn b/application/palemoon/components/migration/jar.mn
deleted file mode 100644
index b369ee1dc..000000000
--- a/application/palemoon/components/migration/jar.mn
+++ /dev/null
@@ -1,7 +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/.
-
-browser.jar:
-* content/browser/migration/migration.xul (content/migration.xul)
- content/browser/migration/migration.js (content/migration.js)
diff --git a/application/palemoon/components/migration/moz.build b/application/palemoon/components/migration/moz.build
deleted file mode 100644
index 4cbf7b8ea..000000000
--- a/application/palemoon/components/migration/moz.build
+++ /dev/null
@@ -1,53 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-JAR_MANIFESTS += ['jar.mn']
-
-XPIDL_SOURCES += [
- 'nsIBrowserProfileMigrator.idl',
-]
-
-XPIDL_MODULE = 'migration'
-
-if CONFIG['OS_ARCH'] == 'WINNT':
- SOURCES += [
- 'nsIEHistoryEnumerator.cpp',
- ]
-
-EXTRA_COMPONENTS += [
- 'FirefoxProfileMigrator.js',
- 'ProfileMigrator.js',
-]
-
-if CONFIG['OS_ARCH'] == 'WINNT':
- EXTRA_COMPONENTS += [
- 'IEProfileMigrator.js',
- ]
- DEFINES['HAS_IE_MIGRATOR'] = True
-
-EXTRA_PP_COMPONENTS += [
- 'BrowserProfileMigrators.manifest',
- 'ChromeProfileMigrator.js',
-]
-
-if CONFIG['OS_ARCH'] == 'WINNT':
- EXTRA_PP_COMPONENTS += [
- 'SafariProfileMigrator.js',
- ]
- DEFINES['HAS_SAFARI_MIGRATOR'] = True
-
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
- EXTRA_PP_COMPONENTS += [
- 'SafariProfileMigrator.js',
- ]
- DEFINES['HAS_SAFARI_MIGRATOR'] = True
-
-EXTRA_PP_JS_MODULES += [
- 'MigrationUtils.jsm',
-]
-
-FINAL_LIBRARY = 'browsercomps'
-
diff --git a/application/palemoon/components/migration/nsIBrowserProfileMigrator.idl b/application/palemoon/components/migration/nsIBrowserProfileMigrator.idl
deleted file mode 100644
index ebff4628c..000000000
--- a/application/palemoon/components/migration/nsIBrowserProfileMigrator.idl
+++ /dev/null
@@ -1,63 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "nsISupports.idl"
-
-interface nsIArray;
-interface nsIProfileStartup;
-
-[scriptable, uuid(30e5a7ec-f71e-4f41-9dbd-7429c02132ec)]
-interface nsIBrowserProfileMigrator : nsISupports
-{
- /**
- * profile items to migrate. use with migrate().
- */
- const unsigned short ALL = 0x0000;
- const unsigned short SETTINGS = 0x0001;
- const unsigned short COOKIES = 0x0002;
- const unsigned short HISTORY = 0x0004;
- const unsigned short FORMDATA = 0x0008;
- const unsigned short PASSWORDS = 0x0010;
- const unsigned short BOOKMARKS = 0x0020;
- const unsigned short OTHERDATA = 0x0040;
-
- /**
- * Copy user profile information to the current active profile.
- * @param aItems list of data items to migrate. see above for values.
- * @param aStartup helper interface which is non-null if called during startup.
- * @param aProfile profile to migrate from, if there is more than one.
- */
- void migrate(in unsigned short aItems, in nsIProfileStartup aStartup, in jsval aProfile);
-
- /**
- * A bit field containing profile items that this migrator
- * offers for import.
- * @param aProfile the profile that we are looking for available data
- * to import
- * @param aDoingStartup "true" if the profile is not currently being used.
- * @return bit field containing profile items (see above)
- * @note a return value of 0 represents no items rather than ALL.
- */
- unsigned short getMigrateData(in jsval aProfile, in boolean aDoingStartup);
-
- /**
- * Whether or not there is any data that can be imported from this
- * browser (i.e. whether or not it is installed, and there exists
- * a user profile)
- */
- readonly attribute boolean sourceExists;
-
-
- /**
- * An enumeration of available profiles. If the import source does
- * not support profiles, this attribute is null.
- */
- readonly attribute jsval sourceProfiles;
-
- /**
- * The import source homepage. Returns null if not present/available
- */
- readonly attribute AUTF8String sourceHomePageURL;
-};
diff --git a/application/palemoon/components/migration/nsIEHistoryEnumerator.cpp b/application/palemoon/components/migration/nsIEHistoryEnumerator.cpp
deleted file mode 100644
index 0b377d27e..000000000
--- a/application/palemoon/components/migration/nsIEHistoryEnumerator.cpp
+++ /dev/null
@@ -1,119 +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/. */
-
-#include "nsIEHistoryEnumerator.h"
-
-#include <urlhist.h>
-#include <shlguid.h>
-
-#include "nsArrayEnumerator.h"
-#include "nsCOMArray.h"
-#include "nsIVariant.h"
-#include "nsNetUtil.h"
-#include "nsStringAPI.h"
-#include "nsWindowsMigrationUtils.h"
-#include "prtime.h"
-
-////////////////////////////////////////////////////////////////////////////////
-//// nsIEHistoryEnumerator
-
-NS_IMPL_ISUPPORTS(nsIEHistoryEnumerator, nsISimpleEnumerator)
-
-nsIEHistoryEnumerator::nsIEHistoryEnumerator()
-{
- ::CoInitialize(nullptr);
-}
-
-nsIEHistoryEnumerator::~nsIEHistoryEnumerator()
-{
- ::CoUninitialize();
-}
-
-void
-nsIEHistoryEnumerator::EnsureInitialized()
-{
- if (mURLEnumerator)
- return;
-
- HRESULT hr = ::CoCreateInstance(CLSID_CUrlHistory,
- nullptr,
- CLSCTX_INPROC_SERVER,
- IID_IUrlHistoryStg2,
- getter_AddRefs(mIEHistory));
- if (FAILED(hr))
- return;
-
- hr = mIEHistory->EnumUrls(getter_AddRefs(mURLEnumerator));
- if (FAILED(hr))
- return;
-}
-
-NS_IMETHODIMP
-nsIEHistoryEnumerator::HasMoreElements(bool* _retval)
-{
- *_retval = false;
-
- EnsureInitialized();
- MOZ_ASSERT(mURLEnumerator, "Should have instanced an IE History URLEnumerator");
- if (!mURLEnumerator)
- return NS_OK;
-
- STATURL statURL;
- ULONG fetched;
-
- // First argument is not implemented, so doesn't matter what we pass.
- HRESULT hr = mURLEnumerator->Next(1, &statURL, &fetched);
- if (FAILED(hr) || fetched != 1UL) {
- // Reached the last entry.
- return NS_OK;
- }
-
- nsCOMPtr<nsIURI> uri;
- if (statURL.pwcsUrl) {
- nsDependentString url(statURL.pwcsUrl);
- nsresult rv = NS_NewURI(getter_AddRefs(uri), url);
- ::CoTaskMemFree(statURL.pwcsUrl);
- if (NS_FAILED(rv)) {
- // Got a corrupt or invalid URI, continue to the next entry.
- return HasMoreElements(_retval);
- }
- }
-
- nsDependentString title(statURL.pwcsTitle ? statURL.pwcsTitle : L"");
-
- bool lastVisitTimeIsValid;
- PRTime lastVisited = WinMigrationFileTimeToPRTime(&(statURL.ftLastVisited), &lastVisitTimeIsValid);
-
- mCachedNextEntry = do_CreateInstance("@mozilla.org/hash-property-bag;1");
- MOZ_ASSERT(mCachedNextEntry, "Should have instanced a new property bag");
- if (mCachedNextEntry) {
- mCachedNextEntry->SetPropertyAsInterface(NS_LITERAL_STRING("uri"), uri);
- mCachedNextEntry->SetPropertyAsAString(NS_LITERAL_STRING("title"), title);
- if (lastVisitTimeIsValid) {
- mCachedNextEntry->SetPropertyAsInt64(NS_LITERAL_STRING("time"), lastVisited);
- }
-
- *_retval = true;
- }
-
- if (statURL.pwcsTitle)
- ::CoTaskMemFree(statURL.pwcsTitle);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-nsIEHistoryEnumerator::GetNext(nsISupports** _retval)
-{
- *_retval = nullptr;
-
- if (!mCachedNextEntry)
- return NS_ERROR_FAILURE;
-
- NS_ADDREF(*_retval = mCachedNextEntry);
- // Release the cached entry, so it can't be returned twice.
- mCachedNextEntry = nullptr;
-
- return NS_OK;
-}
diff --git a/application/palemoon/components/migration/nsIEHistoryEnumerator.h b/application/palemoon/components/migration/nsIEHistoryEnumerator.h
deleted file mode 100644
index 1572a8dd5..000000000
--- a/application/palemoon/components/migration/nsIEHistoryEnumerator.h
+++ /dev/null
@@ -1,37 +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/. */
-
-#ifndef iehistoryenumerator___h___
-#define iehistoryenumerator___h___
-
-#include <urlhist.h>
-
-#include "mozilla/Attributes.h"
-#include "nsCOMPtr.h"
-#include "nsISimpleEnumerator.h"
-#include "nsIWritablePropertyBag2.h"
-
-class nsIEHistoryEnumerator final : public nsISimpleEnumerator
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSISIMPLEENUMERATOR
-
- nsIEHistoryEnumerator();
-
-private:
- ~nsIEHistoryEnumerator();
-
- /**
- * Initializes the history reader, if needed.
- */
- void EnsureInitialized();
-
- RefPtr<IUrlHistoryStg2> mIEHistory;
- RefPtr<IEnumSTATURL> mURLEnumerator;
-
- nsCOMPtr<nsIWritablePropertyBag2> mCachedNextEntry;
-};
-
-#endif
diff --git a/application/palemoon/components/migration/nsWindowsMigrationUtils.h b/application/palemoon/components/migration/nsWindowsMigrationUtils.h
deleted file mode 100644
index 0288d93d3..000000000
--- a/application/palemoon/components/migration/nsWindowsMigrationUtils.h
+++ /dev/null
@@ -1,36 +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/. */
-
-#ifndef windowsmigrationutils__h__
-#define windowsmigrationutils__h__
-
-#include "prtime.h"
-
-static
-PRTime WinMigrationFileTimeToPRTime(FILETIME* filetime, bool* isValid)
-{
- SYSTEMTIME st;
- *isValid = ::FileTimeToSystemTime(filetime, &st);
- if (!*isValid) {
- return 0;
- }
- PRExplodedTime prt;
- prt.tm_year = st.wYear;
- // SYSTEMTIME's day-of-month parameter is 1-based,
- // PRExplodedTime's is 0-based.
- prt.tm_month = st.wMonth - 1;
- prt.tm_mday = st.wDay;
- prt.tm_hour = st.wHour;
- prt.tm_min = st.wMinute;
- prt.tm_sec = st.wSecond;
- prt.tm_usec = st.wMilliseconds * 1000;
- prt.tm_wday = 0;
- prt.tm_yday = 0;
- prt.tm_params.tp_gmt_offset = 0;
- prt.tm_params.tp_dst_offset = 0;
- return PR_ImplodeTime(&prt);
-}
-
-#endif
-
diff --git a/application/palemoon/components/moz.build b/application/palemoon/components/moz.build
index 1c1098f0a..6e83936a9 100644
--- a/application/palemoon/components/moz.build
+++ b/application/palemoon/components/moz.build
@@ -17,7 +17,6 @@ DIRS += [
'search',
'sessionstore',
'shell',
- 'migration',
]
if CONFIG['MOZ_BROWSER_STATUSBAR']:
diff --git a/application/palemoon/components/nsBrowserGlue.js b/application/palemoon/components/nsBrowserGlue.js
index aafdced9f..cdb0b7522 100644
--- a/application/palemoon/components/nsBrowserGlue.js
+++ b/application/palemoon/components/nsBrowserGlue.js
@@ -254,7 +254,8 @@ BrowserGlue.prototype = {
if (!linkHandled.data) {
let win = this.getMostRecentBrowserWindow();
if (win) {
- win.openUILinkIn(data, "tab");
+ data = JSON.parse(data);
+ win.openUILinkIn(data.href, "tab");
linkHandled.data = true;
}
}
diff --git a/application/palemoon/components/places/content/places.js b/application/palemoon/components/places/content/places.js
index af254a7fb..9ecdfebe0 100644
--- a/application/palemoon/components/places/content/places.js
+++ b/application/palemoon/components/places/content/places.js
@@ -4,7 +4,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource:///modules/MigrationUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "BookmarkJSONUtils",
@@ -335,14 +334,6 @@ var PlacesOrganizer = {
},
/**
- * Show the migration wizard for importing passwords,
- * cookies, history, preferences, and bookmarks.
- */
- importFromBrowser: function PO_importFromBrowser() {
- MigrationUtils.showMigrationWizard(window);
- },
-
- /**
* Open a file-picker and import the selected file into the bookmarks store
*/
importFromFile: function PO_importFromFile() {
diff --git a/application/palemoon/components/places/content/places.xul b/application/palemoon/components/places/content/places.xul
index ee1f2ff48..92e8a70e9 100644
--- a/application/palemoon/components/places/content/places.xul
+++ b/application/palemoon/components/places/content/places.xul
@@ -68,8 +68,6 @@
oncommand="PlacesOrganizer.exportBookmarks();"/>
<command id="OrganizerCommand_import"
oncommand="PlacesOrganizer.importFromFile();"/>
- <command id="OrganizerCommand_browserImport"
- oncommand="PlacesOrganizer.importFromBrowser();"/>
<command id="OrganizerCommand_backup"
oncommand="PlacesOrganizer.backupBookmarks();"/>
<command id="OrganizerCommand_restoreFromFile"
@@ -312,11 +310,6 @@
command="OrganizerCommand_export"
label="&exportBookmarksToHTML.label;"
accesskey="&exportBookmarksToHTML.accesskey;"/>
- <menuseparator/>
- <menuitem id="browserImport"
- command="OrganizerCommand_browserImport"
- label="&importOtherBrowser.label;"
- accesskey="&importOtherBrowser.accesskey;"/>
</menupopup>
#ifdef XP_MACOSX
</toolbarbutton>
diff --git a/application/palemoon/locales/en-US/chrome/browser/migration/migration.dtd b/application/palemoon/locales/en-US/chrome/browser/migration/migration.dtd
deleted file mode 100644
index 2848c4e67..000000000
--- a/application/palemoon/locales/en-US/chrome/browser/migration/migration.dtd
+++ /dev/null
@@ -1,36 +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/. -->
-
-
-<!ENTITY migrationWizard.title "Import Wizard">
-
-<!ENTITY importFrom.label "Import Preferences, Bookmarks, History, Passwords and other data from:">
-<!ENTITY importFromBookmarks.label "Import Bookmarks from:">
-
-<!ENTITY importFromIE.label "Microsoft Internet Explorer">
-<!ENTITY importFromIE.accesskey "M">
-<!ENTITY importFromNothing.label "Don't import anything">
-<!ENTITY importFromNothing.accesskey "D">
-<!ENTITY importFromSafari.label "Safari">
-<!ENTITY importFromSafari.accesskey "S">
-<!ENTITY importFromChrome.label "Chrome">
-<!ENTITY importFromChrome.accesskey "C">
-<!ENTITY importFromFirefox.label "Firefox">
-<!ENTITY importFromFirefox.accesskey "X">
-
-<!ENTITY noMigrationSources.label "No programs that contain bookmarks, history or password data could be found.">
-
-<!ENTITY importSource.title "Import Settings and Data">
-<!ENTITY importItems.title "Items to Import">
-<!ENTITY importItems.label "Select which items to import:">
-
-<!ENTITY migrating.title "Importing…">
-<!ENTITY migrating.label "The following items are currently being imported…">
-
-<!ENTITY selectProfile.title "Select Profile">
-<!ENTITY selectProfile.label "The following profiles are available to import from:">
-
-<!ENTITY done.title "Import Complete">
-<!ENTITY done.label "The following items were successfully imported:">
-
diff --git a/application/palemoon/locales/en-US/chrome/browser/migration/migration.properties b/application/palemoon/locales/en-US/chrome/browser/migration/migration.properties
deleted file mode 100644
index b1cb03d0a..000000000
--- a/application/palemoon/locales/en-US/chrome/browser/migration/migration.properties
+++ /dev/null
@@ -1,51 +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/.
-
-profileName_format=%S %S
-
-# Browser Specific
-sourceNameIE=Internet Explorer
-sourceNameSafari=Safari
-sourceNameChrome=Google Chrome
-sourceNameFirefox=Mozilla Firefox
-
-importedBookmarksFolder=From %S
-
-importedSafariReadingList=Reading List (From Safari)
-
-# Import Sources
-# Note: When adding an import source for profile reset, add the string name to
-# resetProfile.js if it should be listed in the reset dialog.
-1_ie=Internet Options
-1_safari=Preferences
-1_chrome=Preferences
-
-2_ie=Cookies
-2_safari=Cookies
-2_chrome=Cookies
-2_firefox=Cookies
-
-4_ie=Browsing History
-4_safari=Browsing History
-4_chrome=Browsing History
-4_firefox_history_and_bookmarks=Browsing History and Bookmarks
-
-8_ie=Saved Form History
-8_safari=Saved Form History
-8_chrome=Saved Form History
-8_firefox=Saved Form History
-
-16_ie=Saved Passwords
-16_safari=Saved Passwords
-16_chrome=Saved Passwords
-16_firefox=Saved Passwords
-
-32_ie=Favorites
-32_safari=Bookmarks
-32_chrome=Bookmarks
-
-64_ie=Other Data
-64_safari=Other Data
-64_chrome=Other Data
-64_firefox_other=Other Data
diff --git a/application/palemoon/locales/en-US/chrome/browser/places/places.dtd b/application/palemoon/locales/en-US/chrome/browser/places/places.dtd
index 949593e7d..9578754d2 100644
--- a/application/palemoon/locales/en-US/chrome/browser/places/places.dtd
+++ b/application/palemoon/locales/en-US/chrome/browser/places/places.dtd
@@ -31,8 +31,6 @@
<!ENTITY importBookmarksFromHTML.accesskey "I">
<!ENTITY exportBookmarksToHTML.label "Export Bookmarks to HTML…">
<!ENTITY exportBookmarksToHTML.accesskey "E">
-<!ENTITY importOtherBrowser.label "Import Data from Another Browser…">
-<!ENTITY importOtherBrowser.accesskey "A">
<!ENTITY cmd.backup.label "Backup…">
<!ENTITY cmd.backup.accesskey "B">
diff --git a/application/palemoon/locales/jar.mn b/application/palemoon/locales/jar.mn
index 6512c683e..f2b9ddeb2 100644
--- a/application/palemoon/locales/jar.mn
+++ b/application/palemoon/locales/jar.mn
@@ -55,8 +55,6 @@
locale/browser/places/moveBookmarks.dtd (%chrome/browser/places/moveBookmarks.dtd)
locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd)
locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)
- locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd)
- locale/browser/migration/migration.properties (%chrome/browser/migration/migration.properties)
locale/browser/preferences/aboutPermissions.dtd (%chrome/browser/preferences/aboutPermissions.dtd)
locale/browser/preferences/aboutPermissions.properties (%chrome/browser/preferences/aboutPermissions.properties)
locale/browser/preferences/advanced.dtd (%chrome/browser/preferences/advanced.dtd)
diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js
index a447880be..83c737977 100644
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -299,24 +299,23 @@ var StarUI = {
parent.setAttribute("open", "true");
}
}
- let panel = this.panel;
- let target = panel;
- if (target.parentNode) {
- // By targeting the panel's parent and using a capturing listener, we
- // can have our listener called before others waiting for the panel to
- // be shown (which probably expect the panel to be fully initialized)
- target = target.parentNode;
- }
- target.addEventListener("popupshown", function shownListener(event) {
- if (event.target == panel) {
- target.removeEventListener("popupshown", shownListener, true);
-
- gEditItemOverlay.initPanel({ node: aNode
- , hiddenRows: ["description", "location",
- "loadInSidebar", "keyword"]
- , focusedElement: "preferred"});
+ let onPanelReady = fn => {
+ let target = this.panel;
+ if (target.parentNode) {
+ // By targeting the panel's parent and using a capturing listener, we
+ // can have our listener called before others waiting for the panel to
+ // be shown (which probably expect the panel to be fully initialized)
+ target = target.parentNode;
}
- }, true);
+ target.addEventListener("popupshown", function(event) {
+ fn();
+ }, {"capture": true, "once": true});
+ };
+ gEditItemOverlay.initPanel({ node: aNode
+ , onPanelReady
+ , hiddenRows: ["description", "location",
+ "loadInSidebar", "keyword"]
+ , focusedElement: "preferred"});
this.panel.openPopup(aAnchorElement, aPosition);
}),
diff --git a/browser/components/places/content/editBookmarkOverlay.js b/browser/components/places/content/editBookmarkOverlay.js
index e26cfb138..d59f5c764 100644
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -57,12 +57,14 @@ var gEditItemOverlay = {
}
}
let focusedElement = aInitInfo.focusedElement;
+ let onPanelReady = aInitInfo.onPanelReady;
return this._paneInfo = { itemId, itemGuid, isItem,
isURI, uri, title,
isBookmark, isFolderShortcut, isParentReadOnly,
bulkTagging, uris,
- visibleRows, postData, isTag, focusedElement };
+ visibleRows, postData, isTag, focusedElement,
+ onPanelReady };
},
get initialized() {
@@ -214,7 +216,8 @@ var gEditItemOverlay = {
let { itemId, isItem, isURI,
isBookmark, bulkTagging, uris,
- visibleRows, focusedElement } = this._setPaneInfo(aInfo);
+ visibleRows, focusedElement,
+ onPanelReady } = this._setPaneInfo(aInfo);
let showOrCollapse =
(rowId, isAppropriateForInput, nameInHiddenRows = null) => {
@@ -286,22 +289,34 @@ var gEditItemOverlay = {
this._observersAdded = true;
}
- // The focusedElement possible values are:
- // * preferred: focus the field that the user touched first the last
- // time the pane was shown (either namePicker or tagsField)
- // * first: focus the first non collapsed textbox
- // Note: since all controls are collapsed by default, we don't get the
- // default XUL dialog behavior, that selects the first control, so we set
- // the focus explicitly.
- let elt;
- if (focusedElement === "preferred") {
- elt = this._element(gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField"));
- } else if (focusedElement === "first") {
- elt = document.querySelector("textbox:not([collapsed=true])");
- }
- if (elt) {
- elt.focus();
- elt.select();
+ let focusElement = () => {
+ // The focusedElement possible values are:
+ // * preferred: focus the field that the user touched first the last
+ // time the pane was shown (either namePicker or tagsField)
+ // * first: focus the first non collapsed textbox
+ // Note: since all controls are collapsed by default, we don't get the
+ // default XUL dialog behavior, that selects the first control, so we set
+ // the focus explicitly.
+ // Note: If focusedElement === "preferred", this file expects gPrefService
+ // to be defined in the global scope.
+ let elt;
+ if (focusedElement === "preferred") {
+ /* eslint-disable no-undef */
+ elt = this._element(gPrefService.getCharPref("browser.bookmarks.editDialog.firstEditField"));
+ /* eslint-enable no-undef */
+ } else if (focusedElement === "first") {
+ elt = document.querySelector("textbox:not([collapsed=true])");
+ }
+ if (elt) {
+ elt.focus();
+ elt.select();
+ }
+ };
+
+ if (onPanelReady) {
+ onPanelReady(focusElement);
+ } else {
+ focusElement();
}
},
@@ -335,10 +350,23 @@ var gEditItemOverlay = {
if (aElement.value != aValue) {
aElement.value = aValue;
- // Clear the undo stack
- let editor = aElement.editor;
- if (editor)
- editor.transactionManager.clear();
+ // Clear the editor's undo stack
+ let transactionManager;
+ try {
+ transactionManager = aElement.editor.transactionManager;
+ } catch (e) {
+ // When retrieving the transaction manager, editor may be null resulting
+ // in a TypeError. Additionally, the transaction manager may not
+ // exist yet, which causes access to it to throw NS_ERROR_FAILURE.
+ // In either event, the transaction manager doesn't exist it, so we
+ // don't need to worry about clearing it.
+ if (!(e instanceof TypeError) && e.result != Cr.NS_ERROR_FAILURE) {
+ throw e;
+ }
+ }
+ if (transactionManager) {
+ transactionManager.clear();
+ }
}
},
diff --git a/build/valgrind/x86_64-redhat-linux-gnu.sup b/build/valgrind/x86_64-redhat-linux-gnu.sup
index d253a3a4e..28656e418 100644
--- a/build/valgrind/x86_64-redhat-linux-gnu.sup
+++ b/build/valgrind/x86_64-redhat-linux-gnu.sup
@@ -105,7 +105,6 @@
fun:g_object_newv
fun:g_object_new_valist
fun:g_object_new
- fun:_ZN13nsLookAndFeel4InitEv
...
}
# set_color() in gtkstyle.c of GTK version 3.4.4 only can leak GdkRGBA
diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
index 110f4384f..59f8de9ac 100644
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4738,6 +4738,8 @@ pref("dom.webnotifications.requireinteraction.enabled", false);
// Alert animation effect, name is disableSlidingEffect for backwards-compat.
pref("alerts.disableSlidingEffect", false);
+// The immediate duration of the alert, in milliseconds.
+pref("alerts.durationImmediate", 20000);
// Show favicons in web notifications.
pref("alerts.showFavicons", false);
diff --git a/toolkit/components/alerts/resources/content/alert.css b/toolkit/components/alerts/resources/content/alert.css
index c4d94a543..81e5cdd35 100644
--- a/toolkit/components/alerts/resources/content/alert.css
+++ b/toolkit/components/alerts/resources/content/alert.css
@@ -3,7 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#alertBox[animate] {
- animation-duration: 20s;
animation-fill-mode: both;
animation-name: alert-animation;
}
diff --git a/toolkit/components/alerts/resources/content/alert.js b/toolkit/components/alerts/resources/content/alert.js
index ead4d503f..ce60ab0fa 100644
--- a/toolkit/components/alerts/resources/content/alert.js
+++ b/toolkit/components/alerts/resources/content/alert.js
@@ -166,7 +166,12 @@ function prefillAlertInfo() {
}
function onAlertLoad() {
- const ALERT_DURATION_IMMEDIATE = 20000;
+ const ALERT_DURATION_IMMEDIATE_MIN = 4000;
+ const ALERT_DURATION_IMMEDIATE_MAX = 60000;
+ let alertDurationImmediate = Services.prefs.getIntPref("alerts.durationImmediate", ALERT_DURATION_IMMEDIATE_MIN);
+ alertDurationImmediate = alertDurationImmediate >= ALERT_DURATION_IMMEDIATE_MIN
+ && alertDurationImmediate <= ALERT_DURATION_IMMEDIATE_MAX
+ ? alertDurationImmediate : ALERT_DURATION_IMMEDIATE_MIN;
let alertTextBox = document.getElementById("alertTextBox");
let alertImageBox = document.getElementById("alertImageBox");
alertImageBox.style.minHeight = alertTextBox.scrollHeight + "px";
@@ -186,7 +191,7 @@ function onAlertLoad() {
// If the require interaction flag is set, prevent auto-closing the notification.
if (!gRequireInteraction) {
if (Services.prefs.getBoolPref("alerts.disableSlidingEffect")) {
- setTimeout(function() { window.close(); }, ALERT_DURATION_IMMEDIATE);
+ setTimeout(function() { window.close(); }, alertDurationImmediate);
} else {
let alertBox = document.getElementById("alertBox");
alertBox.addEventListener("animationend", function hideAlert(event) {
@@ -197,6 +202,7 @@ function onAlertLoad() {
window.close();
}
}, false);
+ alertBox.style.animationDuration = Math.round(alertDurationImmediate / 1000).toString() + "s";
alertBox.setAttribute("animate", true);
}
}
diff --git a/toolkit/components/passwordmgr/content/passwordManager.js b/toolkit/components/passwordmgr/content/passwordManager.js
index 333dc1d24..3fccb5d30 100644
--- a/toolkit/components/passwordmgr/content/passwordManager.js
+++ b/toolkit/components/passwordmgr/content/passwordManager.js
@@ -721,8 +721,10 @@ function escapeKeyHandler() {
window.close();
}
+#if defined(MC_BASILISK) && defined(XP_WIN)
function OpenMigrator() {
const { MigrationUtils } = Cu.import("resource:///modules/MigrationUtils.jsm", {});
// We pass in the type of source we're using for use in telemetry:
MigrationUtils.showMigrationWizard(window, [MigrationUtils.MIGRATION_ENTRYPOINT_PASSWORDS]);
}
+#endif
diff --git a/toolkit/components/passwordmgr/content/passwordManager.xul b/toolkit/components/passwordmgr/content/passwordManager.xul
index d248283b6..78dbd7ebc 100644
--- a/toolkit/components/passwordmgr/content/passwordManager.xul
+++ b/toolkit/components/passwordmgr/content/passwordManager.xul
@@ -113,7 +113,7 @@
label="&removeall.label;" accesskey="&removeall.accesskey;"
oncommand="DeleteAllSignons();"/>
<spacer flex="1"/>
-#if defined(MOZ_BUILD_APP_IS_BROWSER) && defined(XP_WIN)
+#if defined(MC_BASILISK) && defined(XP_WIN)
<button accesskey="&import.accesskey;"
label="&import.label;"
oncommand="OpenMigrator();"/>
diff --git a/toolkit/components/passwordmgr/jar.mn b/toolkit/components/passwordmgr/jar.mn
index 9fa574e49..db6d7ffef 100644
--- a/toolkit/components/passwordmgr/jar.mn
+++ b/toolkit/components/passwordmgr/jar.mn
@@ -5,5 +5,5 @@
toolkit.jar:
% content passwordmgr %content/passwordmgr/
* content/passwordmgr/passwordManager.xul (content/passwordManager.xul)
- content/passwordmgr/passwordManager.js (content/passwordManager.js)
+* content/passwordmgr/passwordManager.js (content/passwordManager.js)
content/passwordmgr/recipes.json (content/recipes.json)
diff --git a/toolkit/locales/en-US/chrome/places/places.properties b/toolkit/locales/en-US/chrome/places/places.properties
index f9edeeff0..5c0134180 100644
--- a/toolkit/locales/en-US/chrome/places/places.properties
+++ b/toolkit/locales/en-US/chrome/places/places.properties
@@ -4,6 +4,7 @@
BookmarksMenuFolderTitle=Bookmarks Menu
BookmarksToolbarFolderTitle=Bookmarks Toolbar
+UnsortedBookmarksFolderTitle=Unsorted Bookmarks
OtherBookmarksFolderTitle=Other Bookmarks
TagsFolderTitle=Tags
MobileBookmarksFolderTitle=Mobile Bookmarks
diff --git a/toolkit/themes/windows/mozapps/jar.mn b/toolkit/themes/windows/mozapps/jar.mn
index 842c8a138..0d77a4e79 100644
--- a/toolkit/themes/windows/mozapps/jar.mn
+++ b/toolkit/themes/windows/mozapps/jar.mn
@@ -15,7 +15,6 @@ toolkit.jar:
skin/classic/mozapps/extensions/category-recent.png (webextensions/category-recent.png)
skin/classic/mozapps/extensions/category-available.png (webextensions/category-available.png)
skin/classic/mozapps/extensions/extensionGeneric-16.png (webextensions/extensionGeneric-16.png)
- skin/classic/mozapps/extensions/extensionGeneric-48.png (webextensions/extensionGeneric-48.png)
skin/classic/mozapps/extensions/themeGeneric.png (webextensions/themeGeneric.png)
skin/classic/mozapps/extensions/themeGeneric-16.png (webextensions/themeGeneric-16.png)
skin/classic/mozapps/extensions/dictionaryGeneric.png (webextensions/dictionaryGeneric.png)
diff --git a/widget/gtk/WidgetStyleCache.cpp b/widget/gtk/WidgetStyleCache.cpp
index fd099681f..f35a451aa 100644
--- a/widget/gtk/WidgetStyleCache.cpp
+++ b/widget/gtk/WidgetStyleCache.cpp
@@ -434,15 +434,6 @@ CreateScrolledWindowWidget()
}
static GtkWidget*
-CreateTextViewWidget()
-{
- GtkWidget* widget = gtk_text_view_new();
- gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_SCROLLED_WINDOW)),
- widget);
- return widget;
-}
-
-static GtkWidget*
CreateMenuSeparatorWidget()
{
GtkWidget* widget = gtk_separator_menu_item_new();
@@ -591,8 +582,6 @@ CreateWidget(WidgetNodeType aWidgetType)
return CreateEntryWidget();
case MOZ_GTK_SCROLLED_WINDOW:
return CreateScrolledWindowWidget();
- case MOZ_GTK_TEXT_VIEW:
- return CreateTextViewWidget();
case MOZ_GTK_TREEVIEW:
return CreateTreeViewWidget();
case MOZ_GTK_TREE_HEADER_CELL:
@@ -637,6 +626,24 @@ GetWidget(WidgetNodeType aWidgetType)
GtkWidget* widget = sWidgetStorage[aWidgetType];
if (!widget) {
widget = CreateWidget(aWidgetType);
+ // Some widgets (MOZ_GTK_COMBOBOX_SEPARATOR for instance) may not be
+ // available or implemented.
+ if (!widget)
+ return nullptr;
+ // In GTK versions prior to 3.18, automatic invalidation of style contexts
+ // for widgets was delayed until the next resize event. Gecko however,
+ // typically uses the style context before the resize event runs and so an
+ // explicit invalidation may be required. This is necessary if a style
+ // property was retrieved before all changes were made to the style
+ // context. One such situation is where gtk_button_construct_child()
+ // retrieves the style property "image-spacing" during construction of the
+ // GtkButton, before its parent is set to provide inheritance of ancestor
+ // properties. More recent GTK versions do not need this, but do not
+ // re-resolve until required and so invalidation does not trigger
+ // unnecessary resolution in general.
+ GtkStyleContext* style = gtk_widget_get_style_context(widget);
+ gtk_style_context_invalidate(style);
+
sWidgetStorage[aWidgetType] = widget;
}
return widget;
@@ -725,6 +732,21 @@ CreateCSSNode(const char* aName, GtkStyleContext* aParentStyle, GType aType)
gtk_style_context_set_parent(context, aParentStyle);
gtk_widget_path_unref(path);
+ // In GTK 3.4, gtk_render_* functions use |theming_engine| on the style
+ // context without ensuring any style resolution sets it appropriately
+ // in style_data_lookup(). e.g.
+ // https://git.gnome.org/browse/gtk+/tree/gtk/gtkstylecontext.c?h=3.4.4#n3847
+ //
+ // That can result in incorrect drawing on first draw. To work around this,
+ // force a style look-up to set |theming_engine|. It is sufficient to do
+ // this only on context creation, instead of after every modification to the
+ // context, because themes typically (Ambiance and oxygen-gtk, at least) set
+ // the "engine" property with the '*' selector.
+ if (GTK_MAJOR_VERSION == 3 && gtk_get_minor_version() < 6) {
+ GdkRGBA unused;
+ gtk_style_context_get_color(context, GTK_STATE_FLAG_NORMAL, &unused);
+ }
+
return context;
}
@@ -747,13 +769,38 @@ GetWidgetRootStyle(WidgetNodeType aNodeType)
case MOZ_GTK_IMAGEMENUITEM:
style = CreateStyleForWidget(gtk_image_menu_item_new(), MOZ_GTK_MENUPOPUP);
break;
- case MOZ_GTK_CHECKMENUITEM_CONTAINER:
+ case MOZ_GTK_CHECKMENUITEM:
style = CreateStyleForWidget(gtk_check_menu_item_new(), MOZ_GTK_MENUPOPUP);
break;
- case MOZ_GTK_RADIOMENUITEM_CONTAINER:
+ case MOZ_GTK_RADIOMENUITEM:
style = CreateStyleForWidget(gtk_radio_menu_item_new(nullptr),
MOZ_GTK_MENUPOPUP);
break;
+ case MOZ_GTK_TEXT_VIEW:
+ style = CreateStyleForWidget(gtk_text_view_new(),
+ MOZ_GTK_SCROLLED_WINDOW);
+ break;
+ case MOZ_GTK_TOOLTIP:
+ if (gtk_check_version(3, 20, 0) != nullptr) {
+ // The tooltip style class is added first in CreateTooltipWidget()
+ // and transfered to style in CreateStyleForWidget().
+ GtkWidget* tooltipWindow = CreateTooltipWidget();
+ style = CreateStyleForWidget(tooltipWindow, nullptr);
+ gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference.
+ } else {
+ // We create this from the path because GtkTooltipWindow is not public.
+ style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP);
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
+ }
+ break;
+ case MOZ_GTK_TOOLTIP_BOX:
+ style = CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0),
+ MOZ_GTK_TOOLTIP);
+ break;
+ case MOZ_GTK_TOOLTIP_BOX_LABEL:
+ style = CreateStyleForWidget(gtk_label_new(nullptr),
+ MOZ_GTK_TOOLTIP_BOX);
+ break;
default:
GtkWidget* widget = GetWidget(aNodeType);
MOZ_ASSERT(widget);
@@ -827,13 +874,13 @@ GetCssNodeStyleInternal(WidgetNodeType aNodeType)
style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK,
MOZ_GTK_CHECKBUTTON_CONTAINER);
break;
- case MOZ_GTK_RADIOMENUITEM:
+ case MOZ_GTK_RADIOMENUITEM_INDICATOR:
style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO,
- MOZ_GTK_RADIOMENUITEM_CONTAINER);
+ MOZ_GTK_RADIOMENUITEM);
break;
- case MOZ_GTK_CHECKMENUITEM:
+ case MOZ_GTK_CHECKMENUITEM_INDICATOR:
style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK,
- MOZ_GTK_CHECKMENUITEM_CONTAINER);
+ MOZ_GTK_CHECKMENUITEM);
break;
case MOZ_GTK_PROGRESS_TROUGH:
/* Progress bar background (trough) */
@@ -844,11 +891,6 @@ GetCssNodeStyleInternal(WidgetNodeType aNodeType)
style = CreateChildCSSNode("progress",
MOZ_GTK_PROGRESS_TROUGH);
break;
- case MOZ_GTK_TOOLTIP:
- // We create this from the path because GtkTooltipWindow is not public.
- style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
- break;
case MOZ_GTK_GRIPPER:
// TODO - create from CSS node
return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER,
@@ -865,10 +907,28 @@ GetCssNodeStyleInternal(WidgetNodeType aNodeType)
// TODO - create from CSS node
return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
GTK_STYLE_CLASS_FRAME);
- case MOZ_GTK_TEXT_VIEW:
- // TODO - create from CSS node
- return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
- GTK_STYLE_CLASS_VIEW);
+ case MOZ_GTK_TEXT_VIEW_TEXT:
+ case MOZ_GTK_RESIZER:
+ style = CreateChildCSSNode("text", MOZ_GTK_TEXT_VIEW);
+ if (aNodeType == MOZ_GTK_RESIZER) {
+ // The "grip" class provides the correct builtin icon from
+ // gtk_render_handle(). The icon is drawn with shaded variants of
+ // the background color, and so a transparent background would lead to
+ // a transparent resizer. gtk_render_handle() also uses the
+ // background color to draw a background, and so this style otherwise
+ // matches what is used in GtkTextView to match the background with
+ // textarea elements.
+ GdkRGBA color;
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
+ &color);
+ if (color.alpha == 0.0) {
+ g_object_unref(style);
+ style = CreateStyleForWidget(gtk_text_view_new(),
+ MOZ_GTK_SCROLLED_WINDOW);
+ }
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
+ }
+ break;
case MOZ_GTK_FRAME_BORDER:
style = CreateChildCSSNode("border", MOZ_GTK_FRAME);
break;
@@ -971,27 +1031,20 @@ GetWidgetStyleInternal(WidgetNodeType aNodeType)
case MOZ_GTK_CHECKBUTTON:
return GetWidgetStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER,
GTK_STYLE_CLASS_CHECK);
- case MOZ_GTK_RADIOMENUITEM:
- return GetWidgetStyleWithClass(MOZ_GTK_RADIOMENUITEM_CONTAINER,
+ case MOZ_GTK_RADIOMENUITEM_INDICATOR:
+ return GetWidgetStyleWithClass(MOZ_GTK_RADIOMENUITEM,
GTK_STYLE_CLASS_RADIO);
- case MOZ_GTK_CHECKMENUITEM:
- return GetWidgetStyleWithClass(MOZ_GTK_CHECKMENUITEM_CONTAINER,
+ case MOZ_GTK_CHECKMENUITEM_INDICATOR:
+ return GetWidgetStyleWithClass(MOZ_GTK_CHECKMENUITEM,
GTK_STYLE_CLASS_CHECK);
case MOZ_GTK_PROGRESS_TROUGH:
return GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR,
GTK_STYLE_CLASS_TROUGH);
- case MOZ_GTK_TOOLTIP: {
- GtkStyleContext* style = sStyleStorage[aNodeType];
- if (style)
- return style;
-
- // The tooltip style class is added first in CreateTooltipWidget() so
- // that gtk_widget_path_append_for_widget() in CreateStyleForWidget()
- // will find it.
- GtkWidget* tooltipWindow = CreateTooltipWidget();
- style = CreateStyleForWidget(tooltipWindow, nullptr);
- gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference.
- sStyleStorage[aNodeType] = style;
+ case MOZ_GTK_PROGRESS_CHUNK: {
+ GtkStyleContext* style =
+ GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR,
+ GTK_STYLE_CLASS_PROGRESSBAR);
+ gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
return style;
}
case MOZ_GTK_GRIPPER:
@@ -1006,9 +1059,25 @@ GetWidgetStyleInternal(WidgetNodeType aNodeType)
case MOZ_GTK_SCROLLED_WINDOW:
return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW,
GTK_STYLE_CLASS_FRAME);
- case MOZ_GTK_TEXT_VIEW:
- return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW,
- GTK_STYLE_CLASS_VIEW);
+ case MOZ_GTK_TEXT_VIEW_TEXT:
+ case MOZ_GTK_RESIZER: {
+ // GTK versions prior to 3.20 do not have the view class on the root
+ // node, but add this to determine the background for the text window.
+ GtkStyleContext* style =
+ GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, GTK_STYLE_CLASS_VIEW);
+ if (aNodeType == MOZ_GTK_RESIZER) {
+ // The "grip" class provides the correct builtin icon from
+ // gtk_render_handle(). The icon is drawn with shaded variants of
+ // the background color, and so a transparent background would lead to
+ // a transparent resizer. gtk_render_handle() also uses the
+ // background color to draw a background, and so this style otherwise
+ // matches MOZ_GTK_TEXT_VIEW_TEXT to match the background with
+ // textarea elements. GtkTextView creates a separate text window and
+ // so the background should not be transparent.
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
+ }
+ return style;
+ }
case MOZ_GTK_FRAME_BORDER:
return GetWidgetRootStyle(MOZ_GTK_FRAME);
case MOZ_GTK_TREEVIEW_VIEW:
diff --git a/widget/gtk/gtk3drawing.cpp b/widget/gtk/gtk3drawing.cpp
index fb95b4cc4..c592fa51c 100644
--- a/widget/gtk/gtk3drawing.cpp
+++ b/widget/gtk/gtk3drawing.cpp
@@ -36,6 +36,10 @@ static gboolean is_initialized;
static gint
moz_gtk_get_tab_thickness(GtkStyleContext *style);
+static gint
+moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
+ GtkWidgetState* state, GtkTextDirection direction);
+
// GetStateFlagsFromGtkWidgetState() can be safely used for the specific
// GtkWidgets that set both prelight and active flags. For other widgets,
// either the GtkStateFlags or Gecko's GtkWidgetState need to be carefully
@@ -167,7 +171,7 @@ moz_gtk_menuitem_get_horizontal_padding(gint* horizontal_padding)
gint
moz_gtk_checkmenuitem_get_horizontal_padding(gint* horizontal_padding)
{
- GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_CHECKMENUITEM_CONTAINER);
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_CHECKMENUITEM);
gtk_style_context_get_style(style,
"horizontal-padding", horizontal_padding,
nullptr);
@@ -463,7 +467,7 @@ moz_gtk_get_widget_min_size(WidgetNodeType aGtkWidgetType, int* width,
}
static void
-moz_gtk_rectangle_inset(GdkRectangle* rect, GtkBorder& aBorder)
+Inset(GdkRectangle* rect, GtkBorder& aBorder)
{
MOZ_ASSERT(rect);
rect->x += aBorder.left;
@@ -472,17 +476,29 @@ moz_gtk_rectangle_inset(GdkRectangle* rect, GtkBorder& aBorder)
rect->height -= aBorder.top + aBorder.bottom;
}
-/* Subtracting margin is used to inset drawing of element which can have margins,
- * like scrollbar, scrollbar's trough, thumb and scrollbar's button */
+// Inset a rectangle by the margins specified in a style context.
static void
-moz_gtk_subtract_margin(GtkStyleContext* style, GdkRectangle* rect)
+InsetByMargin(GdkRectangle* rect, GtkStyleContext* style)
{
MOZ_ASSERT(rect);
GtkBorder margin;
gtk_style_context_get_margin(style, gtk_style_context_get_state(style),
&margin);
- moz_gtk_rectangle_inset(rect, margin);
+ Inset(rect, margin);
+}
+
+// Inset a rectangle by the border and padding specified in a style context.
+static void
+InsetByBorderPadding(GdkRectangle* rect, GtkStyleContext* style)
+{
+ GtkStateFlags state = gtk_style_context_get_state(style);
+ GtkBorder padding, border;
+
+ gtk_style_context_get_padding(style, state, &padding);
+ Inset(rect, padding);
+ gtk_style_context_get_border(style, state, &border);
+ Inset(rect, border);
}
static gint
@@ -528,7 +544,7 @@ moz_gtk_scrollbar_button_paint(cairo_t *cr, const GdkRectangle* aRect,
if (gtk_check_version(3,20,0) == nullptr) {
// The "trough-border" is not used since GTK 3.20. The stepper margin
// box occupies the full width of the "contents" gadget content box.
- moz_gtk_subtract_margin(style, &rect);
+ InsetByMargin(&rect, style);
} else {
// Scrollbar button has to be inset by trough_border because its DOM
// element is filling width of vertical scrollbar's track (or height
@@ -601,7 +617,7 @@ moz_gtk_draw_styled_frame(GtkStyleContext* style, cairo_t *cr,
{
GdkRectangle rect = *aRect;
if (gtk_check_version(3, 6, 0) == nullptr) {
- moz_gtk_subtract_margin(style, &rect);
+ InsetByMargin(&rect, style);
}
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
@@ -656,7 +672,7 @@ moz_gtk_scrollbar_thumb_paint(WidgetNodeType widget,
GdkRectangle rect = *aRect;
GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
- moz_gtk_subtract_margin(style, &rect);
+ InsetByMargin(&rect, style);
gtk_render_slider(style, cr,
rect.x,
@@ -857,7 +873,7 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect,
}
static gint
-moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect,
+moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* aRect,
GtkWidgetState* state,
GtkTextDirection direction)
{
@@ -874,24 +890,24 @@ moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect,
GtkStyleContext* style_frame =
ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags);
- gtk_render_frame(style_frame, cr, rect->x, rect->y, rect->width, rect->height);
+ gtk_render_frame(style_frame, cr,
+ aRect->x, aRect->y, aRect->width, aRect->height);
+
+ GdkRectangle rect = *aRect;
+ InsetByBorderPadding(&rect, style_frame);
- GtkBorder border, padding;
- gtk_style_context_get_border(style_frame, state_flags, &border);
- gtk_style_context_get_padding(style_frame, state_flags, &padding);
ReleaseStyleContext(style_frame);
GtkStyleContext* style =
ClaimStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags);
-
- gint xthickness = border.left + padding.left;
- gint ythickness = border.top + padding.top;
-
- gtk_render_background(style, cr,
- rect->x + xthickness, rect->y + ythickness,
- rect->width - 2 * xthickness,
- rect->height - 2 * ythickness);
-
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
+ ReleaseStyleContext(style);
+ // There is a separate "text" window, which usually provides the
+ // background behind the text. However, this is transparent in Ambiance
+ // for GTK 3.20, in which case the MOZ_GTK_TEXT_VIEW background is
+ // visible.
+ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT, direction, state_flags);
+ gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
@@ -1013,8 +1029,7 @@ moz_gtk_treeview_expander_paint(cairo_t *cr, GdkRectangle* rect,
return MOZ_GTK_SUCCESS;
}
-/* See gtk_separator_draw() for reference.
-*/
+/* See gtk_separator_draw() for reference. */
static gint
moz_gtk_combo_box_paint(cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state,
@@ -1283,6 +1298,7 @@ moz_gtk_tooltip_paint(cairo_t *cr, const GdkRectangle* aRect,
GdkRectangle rect = *aRect;
gtk_render_background(style, cr, rect.x, rect.y, rect.width, rect.height);
gtk_render_frame(style, cr, rect.x, rect.y, rect.width, rect.height);
+ ReleaseStyleContext(style);
// Horizontal Box drawing
//
@@ -1292,33 +1308,26 @@ moz_gtk_tooltip_paint(cairo_t *cr, const GdkRectangle* aRect,
// 6px margin.
// For drawing Horizontal Box we have to inset drawing area by that 6px
// plus its CSS margin.
- GtkStyleContext* boxStyle =
- CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), style);
+ GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX, direction);
rect.x += 6;
rect.y += 6;
rect.width -= 12;
rect.height -= 12;
- moz_gtk_subtract_margin(boxStyle, &rect);
+ InsetByMargin(&rect, boxStyle);
gtk_render_background(boxStyle, cr, rect.x, rect.y, rect.width, rect.height);
gtk_render_frame(boxStyle, cr, rect.x, rect.y, rect.width, rect.height);
// Label drawing
- GtkBorder padding, border;
- gtk_style_context_get_padding(boxStyle, GTK_STATE_FLAG_NORMAL, &padding);
- moz_gtk_rectangle_inset(&rect, padding);
- gtk_style_context_get_border(boxStyle, GTK_STATE_FLAG_NORMAL, &border);
- moz_gtk_rectangle_inset(&rect, border);
+ InsetByBorderPadding(&rect, boxStyle);
+ ReleaseStyleContext(boxStyle);
GtkStyleContext* labelStyle =
- CreateStyleForWidget(gtk_label_new(nullptr), boxStyle);
+ ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL, direction);
moz_gtk_draw_styled_frame(labelStyle, cr, &rect, false);
- g_object_unref(labelStyle);
-
- g_object_unref(boxStyle);
+ ReleaseStyleContext(labelStyle);
- ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1327,17 +1336,9 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state,
GtkTextDirection direction)
{
- GtkStyleContext* style;
-
- // gtk_render_handle() draws a background, so use GtkTextView and its
- // GTK_STYLE_CLASS_VIEW to match the background with textarea elements.
- // The resizer is drawn with shaded variants of the background color, and
- // so a transparent background would lead to a transparent resizer.
- style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW, GTK_TEXT_DIR_LTR,
- GetStateFlagsFromGtkWidgetState(state));
- // TODO - we need to save/restore style when gtk 3.20 CSS node path
- // is used
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP);
+ GtkStyleContext* style =
+ ClaimStyleContext(MOZ_GTK_RESIZER, GTK_TEXT_DIR_LTR,
+ GetStateFlagsFromGtkWidgetState(state));
// Workaround unico not respecting the text direction for resizers.
// See bug 1174248.
@@ -1384,17 +1385,8 @@ moz_gtk_progress_chunk_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction,
WidgetNodeType widget)
{
- GtkStyleContext* style;
-
- if (gtk_check_version(3, 20, 0) != nullptr) {
- /* Ask for MOZ_GTK_PROGRESS_TROUGH instead of MOZ_GTK_PROGRESSBAR
- * because ClaimStyleContext() saves/restores that style */
- style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH, direction);
- gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR);
- } else {
- style = ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction);
- }
+ GtkStyleContext* style =
+ ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction);
if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE ||
widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) {
@@ -1778,6 +1770,13 @@ static gint
moz_gtk_menu_separator_paint(cairo_t *cr, GdkRectangle* rect,
GtkTextDirection direction)
{
+ GtkWidgetState defaultState = { 0 };
+ moz_gtk_menu_item_paint(MOZ_GTK_MENUSEPARATOR, cr, rect,
+ &defaultState, direction);
+
+ if (gtk_get_minor_version() >= 20)
+ return MOZ_GTK_SUCCESS;
+
GtkStyleContext* style;
gboolean wide_separators;
gint separator_height;
@@ -1825,36 +1824,39 @@ moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state, GtkTextDirection direction)
{
gint x, y, w, h;
+ guint minorVersion = gtk_get_minor_version();
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
- if (state->inHover && !state->disabled) {
- GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
- GtkStyleContext* style =
- ClaimStyleContext(widget, direction, state_flags);
-
- bool pre_3_6 = gtk_check_version(3, 6, 0) != nullptr;
- if (pre_3_6) {
- // GTK+ 3.4 saves the style context and adds the menubar class to
- // menubar children, but does each of these only when drawing, not
- // during layout.
- gtk_style_context_save(style);
- if (widget == MOZ_GTK_MENUBARITEM) {
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
- }
+ // GTK versions prior to 3.8 render the background and frame only when not
+ // a separator and in hover prelight.
+ if (minorVersion < 8 && (widget == MOZ_GTK_MENUSEPARATOR ||
+ !(state_flags & GTK_STATE_FLAG_PRELIGHT)))
+ return MOZ_GTK_SUCCESS;
+
+ GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags);
+
+ if (minorVersion < 6) {
+ // GTK+ 3.4 saves the style context and adds the menubar class to
+ // menubar children, but does each of these only when drawing, not
+ // during layout.
+ gtk_style_context_save(style);
+ if (widget == MOZ_GTK_MENUBARITEM) {
+ gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR);
}
+ }
- x = rect->x;
- y = rect->y;
- w = rect->width;
- h = rect->height;
+ x = rect->x;
+ y = rect->y;
+ w = rect->width;
+ h = rect->height;
- gtk_render_background(style, cr, x, y, w, h);
- gtk_render_frame(style, cr, x, y, w, h);
+ gtk_render_background(style, cr, x, y, w, h);
+ gtk_render_frame(style, cr, x, y, w, h);
- if (pre_3_6) {
- gtk_style_context_restore(style);
- }
- ReleaseStyleContext(style);
+ if (minorVersion < 6) {
+ gtk_style_context_restore(style);
}
+ ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -1874,16 +1876,16 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, GdkRectangle* rect,
return MOZ_GTK_SUCCESS;
}
-// See gtk_real_check_menu_item_draw_indicator() for reference.
+// For reference, see gtk_check_menu_item_size_allocate() in GTK versions after
+// 3.20 and gtk_real_check_menu_item_draw_indicator() in earlier versions.
static gint
-moz_gtk_check_menu_item_paint(cairo_t *cr, GdkRectangle* rect,
+moz_gtk_check_menu_item_paint(WidgetNodeType widgetType,
+ cairo_t *cr, GdkRectangle* rect,
GtkWidgetState* state,
- gboolean checked, gboolean isradio,
- GtkTextDirection direction)
+ gboolean checked, GtkTextDirection direction)
{
GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
GtkStyleContext* style;
- GtkBorder padding;
gint indicator_size, horizontal_padding;
gint x, y;
@@ -1893,35 +1895,44 @@ moz_gtk_check_menu_item_paint(cairo_t *cr, GdkRectangle* rect,
state_flags = static_cast<GtkStateFlags>(state_flags|checkbox_check_state);
}
- style = ClaimStyleContext(isradio ? MOZ_GTK_RADIOMENUITEM_CONTAINER :
- MOZ_GTK_CHECKMENUITEM_CONTAINER,
- direction);
+ bool pre_3_20 = gtk_get_minor_version() < 20;
+ gint offset;
+ style = ClaimStyleContext(widgetType, direction);
gtk_style_context_get_style(style,
"indicator-size", &indicator_size,
"horizontal-padding", &horizontal_padding,
NULL);
+ if (pre_3_20) {
+ GtkBorder padding;
+ gtk_style_context_get_padding(style, state_flags, &padding);
+ offset = horizontal_padding + padding.left + 2;
+ } else {
+ GdkRectangle r = { 0 };
+ InsetByMargin(&r, style);
+ InsetByBorderPadding(&r, style);
+ offset = r.x;
+ }
ReleaseStyleContext(style);
- style = ClaimStyleContext(isradio ? MOZ_GTK_RADIOMENUITEM :
- MOZ_GTK_CHECKMENUITEM,
- direction, state_flags);
- gtk_style_context_get_padding(style, state_flags, &padding);
- gint offset = padding.left + 2;
+ bool isRadio = (widgetType == MOZ_GTK_RADIOMENUITEM);
+ WidgetNodeType indicatorType = isRadio ? MOZ_GTK_RADIOMENUITEM_INDICATOR
+ : MOZ_GTK_CHECKMENUITEM_INDICATOR;
+ style = ClaimStyleContext(indicatorType, direction, state_flags);
if (direction == GTK_TEXT_DIR_RTL) {
- x = rect->width - indicator_size - offset - horizontal_padding;
+ x = rect->width - indicator_size - offset;
}
else {
- x = rect->x + offset + horizontal_padding;
+ x = rect->x + offset;
}
y = rect->y + (rect->height - indicator_size) / 2;
- if (gtk_check_version(3, 20, 0) == nullptr) {
+ if (!pre_3_20) {
gtk_render_background(style, cr, x, y, indicator_size, indicator_size);
gtk_render_frame(style, cr, x, y, indicator_size, indicator_size);
}
- if (isradio) {
+ if (isRadio) {
gtk_render_option(style, cr, x, y, indicator_size, indicator_size);
} else {
gtk_render_check(style, cr, x, y, indicator_size, indicator_size);
@@ -2166,12 +2177,15 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
{
// Bug 1274143 for MOZ_GTK_MENUBARITEM
WidgetNodeType type =
- widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM ?
- MOZ_GTK_MENUITEM : MOZ_GTK_CHECKMENUITEM_CONTAINER;
+ widget == MOZ_GTK_MENUBARITEM ? MOZ_GTK_MENUITEM : widget;
style = ClaimStyleContext(type);
- moz_gtk_add_style_padding(style, left, top, right, bottom);
-
+ if (gtk_get_minor_version() < 20) {
+ moz_gtk_add_style_padding(style, left, top, right, bottom);
+ } else {
+ moz_gtk_add_margin_border_padding(style,
+ left, top, right, bottom);
+ }
ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
@@ -2180,7 +2194,6 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
break;
case MOZ_GTK_TOOLTIP:
{
- style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
// In GTK 3 there are 6 pixels of additional margin around the box.
// See details there:
// https://github.com/GNOME/gtk/blob/5ea69a136bd7e4970b3a800390e20314665aaed2/gtk/ui/gtktooltipwindow.ui#L11
@@ -2189,21 +2202,16 @@ moz_gtk_get_widget_border(WidgetNodeType widget, gint* left, gint* top,
// We also need to add margin/padding/borders from Tooltip content.
// Tooltip contains horizontal box, where icon and label is put.
// We ignore icon as long as we don't have support for it.
- GtkStyleContext* boxStyle =
- CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0),
- style);
+ GtkStyleContext* boxStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX);
moz_gtk_add_margin_border_padding(boxStyle,
left, top, right, bottom);
+ ReleaseStyleContext(boxStyle);
- GtkStyleContext* labelStyle =
- CreateStyleForWidget(gtk_label_new(nullptr), boxStyle);
+ GtkStyleContext* labelStyle = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
moz_gtk_add_margin_border_padding(labelStyle,
left, top, right, bottom);
+ ReleaseStyleContext(labelStyle);
- g_object_unref(labelStyle);
- g_object_unref(boxStyle);
-
- ReleaseStyleContext(style);
return MOZ_GTK_SUCCESS;
}
case MOZ_GTK_SCROLLBAR_VERTICAL:
@@ -2492,11 +2500,11 @@ void
moz_gtk_get_scale_metrics(GtkOrientation orient, gint* scale_width,
gint* scale_height)
{
- WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
- MOZ_GTK_SCALE_HORIZONTAL :
- MOZ_GTK_SCALE_VERTICAL;
-
if (gtk_check_version(3, 20, 0) != nullptr) {
+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
+ MOZ_GTK_SCALE_HORIZONTAL :
+ MOZ_GTK_SCALE_VERTICAL;
+
gint thumb_length, thumb_height, trough_border;
moz_gtk_get_scalethumb_metrics(orient, &thumb_length, &thumb_height);
@@ -2512,12 +2520,10 @@ moz_gtk_get_scale_metrics(GtkOrientation orient, gint* scale_width,
}
ReleaseStyleContext(style);
} else {
- GtkStyleContext* style = ClaimStyleContext(widget);
- gtk_style_context_get(style, gtk_style_context_get_state(style),
- "min-width", scale_width,
- "min-height", scale_height,
- nullptr);
- ReleaseStyleContext(style);
+ WidgetNodeType widget = (orient == GTK_ORIENTATION_HORIZONTAL) ?
+ MOZ_GTK_SCALE_TROUGH_HORIZONTAL :
+ MOZ_GTK_SCALE_TROUGH_VERTICAL;
+ moz_gtk_get_widget_min_size(widget, scale_width, scale_height);
}
}
@@ -2540,10 +2546,27 @@ moz_gtk_get_scalethumb_metrics(GtkOrientation orient, gint* thumb_length, gint*
MOZ_GTK_SCALE_THUMB_HORIZONTAL:
MOZ_GTK_SCALE_THUMB_VERTICAL;
GtkStyleContext* style = ClaimStyleContext(widget);
- gtk_style_context_get(style, gtk_style_context_get_state(style),
- "min-width", thumb_length,
- "min-height", thumb_height,
+ gint min_width, min_height;
+ GtkStateFlags state = gtk_style_context_get_state(style);
+ gtk_style_context_get(style, state,
+ "min-width", &min_width,
+ "min-height", &min_height,
nullptr);
+ GtkBorder margin;
+ gtk_style_context_get_margin(style, state, &margin);
+ gint margin_width = margin.left + margin.right;
+ gint margin_height = margin.top + margin.bottom;
+
+ // Negative margin of slider element also determines its minimal size
+ // so use bigger of those two values.
+ if (min_width < -margin_width)
+ min_width = -margin_width;
+ if (min_height < -margin_height)
+ min_height = -margin_height;
+
+ *thumb_length = min_width;
+ *thumb_height = min_height;
+
ReleaseStyleContext(style);
}
@@ -2786,10 +2809,8 @@ moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
break;
case MOZ_GTK_CHECKMENUITEM:
case MOZ_GTK_RADIOMENUITEM:
- return moz_gtk_check_menu_item_paint(cr, rect, state,
- (gboolean) flags,
- (widget == MOZ_GTK_RADIOMENUITEM),
- direction);
+ return moz_gtk_check_menu_item_paint(widget, cr, rect, state,
+ (gboolean) flags, direction);
break;
case MOZ_GTK_SPLITTER_HORIZONTAL:
return moz_gtk_vpaned_paint(cr, rect, state);
diff --git a/widget/gtk/gtkdrawing.h b/widget/gtk/gtkdrawing.h
index 9bbfdefe9..7db5db043 100644
--- a/widget/gtk/gtkdrawing.h
+++ b/widget/gtk/gtkdrawing.h
@@ -145,8 +145,11 @@ typedef enum {
MOZ_GTK_ENTRY,
/* Paints a GtkExpander. */
MOZ_GTK_EXPANDER,
- /* Paints a GtkTextView. */
+ /* Paints a GtkTextView or gets the style context corresponding to the
+ root node of a GtkTextView. */
MOZ_GTK_TEXT_VIEW,
+ /* The "text" window or node of a GtkTextView */
+ MOZ_GTK_TEXT_VIEW_TEXT,
/* Paints a GtkOptionMenu. */
MOZ_GTK_DROPDOWN,
/* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */
@@ -160,11 +163,15 @@ typedef enum {
MOZ_GTK_TOOLBAR_SEPARATOR,
/* Paints a GtkToolTip */
MOZ_GTK_TOOLTIP,
+ /* Paints a GtkBox from GtkToolTip */
+ MOZ_GTK_TOOLTIP_BOX,
+ /* Paints a GtkLabel of GtkToolTip */
+ MOZ_GTK_TOOLTIP_BOX_LABEL,
/* Paints a GtkFrame (e.g. a status bar panel). */
MOZ_GTK_FRAME,
/* Paints the border of a GtkFrame */
MOZ_GTK_FRAME_BORDER,
- /* Paints a resize grip for a GtkWindow */
+ /* Paints a resize grip for a GtkTextView */
MOZ_GTK_RESIZER,
/* Paints a GtkProgressBar. */
MOZ_GTK_PROGRESSBAR,
@@ -211,10 +218,13 @@ typedef enum {
/* Paints items of popup menus. */
MOZ_GTK_MENUITEM,
MOZ_GTK_IMAGEMENUITEM,
- MOZ_GTK_CHECKMENUITEM_CONTAINER,
- MOZ_GTK_RADIOMENUITEM_CONTAINER,
+ /* Paints a menuitem with check indicator, or the gets the style context for
+ a menuitem that contains a checkbox. */
MOZ_GTK_CHECKMENUITEM,
+ /* Gets the style context for a checkbox in a check menuitem. */
+ MOZ_GTK_CHECKMENUITEM_INDICATOR,
MOZ_GTK_RADIOMENUITEM,
+ MOZ_GTK_RADIOMENUITEM_INDICATOR,
MOZ_GTK_MENUSEPARATOR,
/* GtkVPaned base class */
MOZ_GTK_SPLITTER_HORIZONTAL,
diff --git a/widget/gtk/nsLookAndFeel.cpp b/widget/gtk/nsLookAndFeel.cpp
index 53430dfbb..d2b82e495 100644
--- a/widget/gtk/nsLookAndFeel.cpp
+++ b/widget/gtk/nsLookAndFeel.cpp
@@ -47,9 +47,6 @@ nsLookAndFeel::nsLookAndFeel()
: nsXPLookAndFeel(),
#if (MOZ_WIDGET_GTK == 2)
mStyle(nullptr),
-#else
- mBackgroundStyle(nullptr),
- mButtonStyle(nullptr),
#endif
mDefaultFontCached(false), mButtonFontCached(false),
mFieldFontCached(false), mMenuFontCached(false)
@@ -61,13 +58,27 @@ nsLookAndFeel::~nsLookAndFeel()
{
#if (MOZ_WIDGET_GTK == 2)
g_object_unref(mStyle);
-#else
- g_object_unref(mBackgroundStyle);
- g_object_unref(mButtonStyle);
#endif
}
#if MOZ_WIDGET_GTK != 2
+// Modifies color |*aDest| as if a pattern of color |aSource| was painted with
+// CAIRO_OPERATOR_OVER to a surface with color |*aDest|.
+static void
+ApplyColorOver(const GdkRGBA& aSource, GdkRGBA* aDest) {
+ gdouble sourceCoef = aSource.alpha;
+ gdouble destCoef = aDest->alpha * (1.0 - sourceCoef);
+ gdouble resultAlpha = sourceCoef + destCoef;
+ if (resultAlpha != 0.0) { // don't divide by zero
+ destCoef /= resultAlpha;
+ sourceCoef /= resultAlpha;
+ aDest->red = sourceCoef * aSource.red + destCoef * aDest->red;
+ aDest->green = sourceCoef * aSource.green + destCoef * aDest->green;
+ aDest->blue = sourceCoef * aSource.blue + destCoef * aDest->blue;
+ aDest->alpha = resultAlpha;
+ }
+}
+
static void
GetLightAndDarkness(const GdkRGBA& aColor,
double* aLightness, double* aDarkness)
@@ -377,30 +388,39 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
break;
#else
// css2 http://www.w3.org/TR/REC-CSS2/ui.html#system-colors
- case eColorID_activeborder:
+ case eColorID_activeborder: {
// active window border
- gtk_style_context_get_border_color(mBackgroundStyle,
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_border_color(style,
GTK_STATE_FLAG_NORMAL, &gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
- case eColorID_inactiveborder:
+ }
+ case eColorID_inactiveborder: {
// inactive window border
- gtk_style_context_get_border_color(mBackgroundStyle,
- GTK_STATE_FLAG_INSENSITIVE,
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_border_color(style,
+ GTK_STATE_FLAG_INSENSITIVE,
&gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
+ }
case eColorID_graytext: // disabled text in windows, menus, etc.
case eColorID_inactivecaptiontext: // text in inactive window caption
aColor = sMenuTextInactive;
break;
- case eColorID_inactivecaption:
+ case eColorID_inactivecaption: {
// inactive window caption
- gtk_style_context_get_background_color(mBackgroundStyle,
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_WINDOW);
+ gtk_style_context_get_background_color(style,
GTK_STATE_FLAG_INSENSITIVE,
&gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
+ }
#endif
case eColorID_infobackground:
// tooltip background color
@@ -521,18 +541,24 @@ nsLookAndFeel::NativeGetColor(ColorID aID, nscolor& aColor)
case eColorID__moz_fieldtext:
aColor = sMozFieldText;
break;
- case eColorID__moz_buttondefault:
- // default button border color
- gtk_style_context_get_border_color(mButtonStyle,
+ case eColorID__moz_buttondefault: {
+ // default button border color
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_border_color(style,
GTK_STATE_FLAG_NORMAL, &gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
- case eColorID__moz_buttonhoverface:
- gtk_style_context_get_background_color(mButtonStyle,
+ }
+ case eColorID__moz_buttonhoverface: {
+ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON);
+ gtk_style_context_get_background_color(style,
GTK_STATE_FLAG_PRELIGHT,
&gdk_color);
aColor = GDK_RGBA_TO_NS_RGBA(gdk_color);
+ ReleaseStyleContext(style);
break;
+ }
case eColorID__moz_buttonhovertext:
aColor = sButtonHoverText;
break;
@@ -1029,16 +1055,6 @@ nsLookAndFeel::GetFontImpl(FontID aID, nsString& aFontName,
return true;
}
-#if (MOZ_WIDGET_GTK == 3)
-static GtkStyleContext*
-create_context(GtkWidgetPath *path)
-{
- GtkStyleContext *style = gtk_style_context_new();
- gtk_style_context_set_path(style, path);
- return(style);
-}
-#endif
-
void
nsLookAndFeel::Init()
{
@@ -1129,78 +1145,55 @@ nsLookAndFeel::Init()
g_object_set(settings, dark_setting, FALSE, nullptr);
}
- GtkWidgetPath *path = gtk_widget_path_new();
- gtk_widget_path_append_type(path, GTK_TYPE_WINDOW);
-
- mBackgroundStyle = create_context(path);
- gtk_style_context_add_class(mBackgroundStyle, GTK_STYLE_CLASS_BACKGROUND);
-
- mButtonStyle = create_context(path);
- gtk_style_context_add_class(mButtonStyle, GTK_STYLE_CLASS_BUTTON);
-
// Scrollbar colors
- style = create_context(path);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH);
+ style = ClaimStyleContext(MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color);
- g_object_unref(style);
+ ReleaseStyleContext(style);
// Window colors
- style = create_context(path);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND);
+ style = ClaimStyleContext(MOZ_GTK_WINDOW);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMozWindowText = GDK_RGBA_TO_NS_RGBA(color);
- gtk_style_context_restore(style);
- g_object_unref(style);
+ ReleaseStyleContext(style);
// tooltip foreground and background
style = ClaimStyleContext(MOZ_GTK_TOOLTIP);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sInfoBackground = GDK_RGBA_TO_NS_RGBA(color);
- {
- GtkStyleContext* boxStyle =
- CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0),
- style);
- GtkStyleContext* labelStyle =
- CreateStyleForWidget(gtk_label_new(nullptr), boxStyle);
- gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color);
- g_object_unref(labelStyle);
- g_object_unref(boxStyle);
- }
- sInfoText = GDK_RGBA_TO_NS_RGBA(color);
ReleaseStyleContext(style);
- // menu foreground & menu background
- GtkWidget *accel_label = gtk_accel_label_new("M");
- GtkWidget *menuitem = gtk_menu_item_new();
- GtkWidget *menu = gtk_menu_new();
-
- g_object_ref_sink(menu);
-
- gtk_container_add(GTK_CONTAINER(menuitem), accel_label);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-
- style = gtk_widget_get_style_context(accel_label);
+ style = ClaimStyleContext(MOZ_GTK_TOOLTIP_BOX_LABEL);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
- sMenuText = GDK_RGBA_TO_NS_RGBA(color);
- gtk_style_context_get_color(style, GTK_STATE_FLAG_INSENSITIVE, &color);
- sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color);
+ sInfoText = GDK_RGBA_TO_NS_RGBA(color);
+ ReleaseStyleContext(style);
- style = gtk_widget_get_style_context(menu);
+ style = ClaimStyleContext(MOZ_GTK_MENUITEM);
+ {
+ GtkStyleContext* accelStyle =
+ CreateStyleForWidget(gtk_accel_label_new("M"), style);
+ gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_NORMAL, &color);
+ sMenuText = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(accelStyle, GTK_STATE_FLAG_INSENSITIVE, &color);
+ sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color);
+ g_object_unref(accelStyle);
+ }
+ ReleaseStyleContext(style);
+
+ style = ClaimStyleContext(MOZ_GTK_MENUPOPUP);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMenuBackground = GDK_RGBA_TO_NS_RGBA(color);
+ ReleaseStyleContext(style);
- style = gtk_widget_get_style_context(menuitem);
+ style = ClaimStyleContext(MOZ_GTK_MENUITEM);
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
sMenuHover = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color);
- g_object_unref(menu);
+ ReleaseStyleContext(style);
#endif
// button styles
@@ -1211,9 +1204,6 @@ nsLookAndFeel::Init()
GtkWidget *combobox = gtk_combo_box_new();
GtkWidget *comboboxLabel = gtk_label_new("M");
gtk_container_add(GTK_CONTAINER(combobox), comboboxLabel);
-#else
- GtkWidget *combobox = gtk_combo_box_new_with_entry();
- GtkWidget *comboboxLabel = gtk_bin_get_child(GTK_BIN(combobox));
#endif
GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP);
GtkWidget *treeView = gtk_tree_view_new();
@@ -1227,7 +1217,9 @@ nsLookAndFeel::Init()
gtk_container_add(GTK_CONTAINER(parent), button);
gtk_container_add(GTK_CONTAINER(parent), treeView);
gtk_container_add(GTK_CONTAINER(parent), linkButton);
+#if (MOZ_WIDGET_GTK == 2)
gtk_container_add(GTK_CONTAINER(parent), combobox);
+#endif
gtk_container_add(GTK_CONTAINER(parent), menuBar);
gtk_menu_shell_append(GTK_MENU_SHELL(menuBar), menuBarItem);
gtk_container_add(GTK_CONTAINER(window), parent);
@@ -1310,11 +1302,19 @@ nsLookAndFeel::Init()
}
#else
// Text colors
- style = gtk_widget_get_style_context(textView);
- gtk_style_context_save(style);
- gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW);
- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
- sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color);
+ GdkRGBA bgColor;
+ // If the text window background is translucent, then the background of
+ // the textview root node is visible.
+ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
+ &bgColor);
+ ReleaseStyleContext(style);
+
+ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW_TEXT);
+ gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL,
+ &color);
+ ApplyColorOver(color, &bgColor);
+ sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(bgColor);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMozFieldText = GDK_RGBA_TO_NS_RGBA(color);
@@ -1327,26 +1327,34 @@ nsLookAndFeel::Init()
static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED),
&color);
sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color);
- gtk_style_context_restore(style);
+ ReleaseStyleContext(style);
- // Button text, background, border
- style = gtk_widget_get_style_context(label);
- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
- sButtonText = GDK_RGBA_TO_NS_RGBA(color);
- gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
- sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
+ // Button text color
+ style = ClaimStyleContext(MOZ_GTK_BUTTON);
+ {
+ GtkStyleContext* labelStyle =
+ CreateStyleForWidget(gtk_label_new("M"), style);
+ gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color);
+ sButtonText = GDK_RGBA_TO_NS_RGBA(color);
+ gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_PRELIGHT, &color);
+ sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color);
+ g_object_unref(labelStyle);
+ }
+ ReleaseStyleContext(style);
// Combobox text color
- style = gtk_widget_get_style_context(comboboxLabel);
+ style = ClaimStyleContext(MOZ_GTK_COMBOBOX_ENTRY_TEXTAREA);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
sComboBoxText = GDK_RGBA_TO_NS_RGBA(color);
+ ReleaseStyleContext(style);
// Menubar text and hover text colors
- style = gtk_widget_get_style_context(menuBarItem);
+ style = ClaimStyleContext(MOZ_GTK_MENUBARITEM);
gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color);
sMenuBarText = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color);
sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color);
+ ReleaseStyleContext(style);
// GTK's guide to fancy odd row background colors:
// 1) Check if a theme explicitly defines an odd row color
@@ -1354,7 +1362,7 @@ nsLookAndFeel::Init()
// slightly by a hardcoded value (gtkstyle.c)
// 3) If neither are defined, take the base background color and
// darken that by a hardcoded value
- style = gtk_widget_get_style_context(treeView);
+ style = ClaimStyleContext(MOZ_GTK_TREEVIEW);
// Get odd row background color
gtk_style_context_save(style);
@@ -1362,8 +1370,7 @@ nsLookAndFeel::Init()
gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color);
sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color);
gtk_style_context_restore(style);
-
- gtk_widget_path_free(path);
+ ReleaseStyleContext(style);
// GtkFrame has a "border" subnode on which Adwaita draws the border.
// Some themes do not draw on this node but draw a border on the widget
@@ -1448,12 +1455,6 @@ nsLookAndFeel::RefreshImpl()
#if (MOZ_WIDGET_GTK == 2)
g_object_unref(mStyle);
mStyle = nullptr;
-#else
- g_object_unref(mBackgroundStyle);
- g_object_unref(mButtonStyle);
-
- mBackgroundStyle = nullptr;
- mButtonStyle = nullptr;
#endif
Init();
diff --git a/widget/gtk/nsLookAndFeel.h b/widget/gtk/nsLookAndFeel.h
index 9058250b9..726859b41 100644
--- a/widget/gtk/nsLookAndFeel.h
+++ b/widget/gtk/nsLookAndFeel.h
@@ -33,9 +33,6 @@ public:
protected:
#if (MOZ_WIDGET_GTK == 2)
struct _GtkStyle *mStyle;
-#else
- struct _GtkStyleContext *mBackgroundStyle;
- struct _GtkStyleContext *mButtonStyle;
#endif
// Cached fonts
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
index d97b35002..e4e69c1b4 100644
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -6627,6 +6627,22 @@ nsWindow::GetDragInfo(WidgetMouseEvent* aMouseEvent,
return false;
}
+ if (mIsX11Display) {
+ // Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=789054
+ // To avoid crashes disable double-click on WM without _NET_WM_MOVERESIZE.
+ // See _should_perform_ewmh_drag() at gdkwindow-x11.c
+ GdkScreen* screen = gdk_window_get_screen(gdk_window);
+ GdkAtom atom = gdk_atom_intern("_NET_WM_MOVERESIZE", FALSE);
+ if (!gdk_x11_screen_supports_net_wm_hint(screen, atom)) {
+ static unsigned int lastTimeStamp = 0;
+ if (lastTimeStamp != aMouseEvent->mTime) {
+ lastTimeStamp = aMouseEvent->mTime;
+ } else {
+ return false;
+ }
+ }
+ }
+
// FIXME: It would be nice to have the widget position at the time
// of the event, but it's relatively unlikely that the widget has
// moved since the mousedown. (On the other hand, it's quite likely