deleted file mode 100644
--- a/browser/base/content/aboutTabGroupsMigration.js
+++ /dev/null
@@ -1,46 +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";
-
-
-Cu.import("resource:///modules/TabGroupsMigrator.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
- "resource://gre/modules/PlacesUtils.jsm");
-
-const SUPPORT_URL = "https://support.mozilla.org/kb/tab-groups-removal";
-
-function createLink() {
- let link = document.getElementById("sumolink");
- link.href = SUPPORT_URL;
- link.target = "_blank";
-}
-
-let loadPromise = new Promise(resolve => {
- let loadHandler = e => {
- window.removeEventListener("DOMContentLoaded", loadHandler);
- createLink();
- resolve();
- };
- window.addEventListener("DOMContentLoaded", loadHandler, false);
-});
-
-let tabGroupsBookmarkItemId;
-// If the session wasn't restored this run/session, this might be null.
-// Then we shouldn't show the button:
-if (TabGroupsMigrator.bookmarkedGroupsPromise) {
- let bookmarkPromise = TabGroupsMigrator.bookmarkedGroupsPromise.then(bm => {
- return PlacesUtils.promiseItemId(bm.guid);
- }).then(itemId => { tabGroupsBookmarkItemId = itemId });
-
- Promise.all([bookmarkPromise, loadPromise]).then(function() {
- document.getElementById("show-migrated-bookmarks-button").style.removeProperty("display");
- });
-}
-
-function showMigratedGroups() {
- let browserWin = getBrowserWindow();
- browserWin.PlacesCommandHook.showPlacesOrganizer(["BookmarksMenu", tabGroupsBookmarkItemId]);
-}
-
deleted file mode 100644
--- a/browser/base/content/aboutTabGroupsMigration.xhtml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-# 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/.
--->
-<!DOCTYPE html [
- <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
- %htmlDTD;
- <!ENTITY % netErrorDTD SYSTEM "chrome://global/locale/netError.dtd">
- %netErrorDTD;
- <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
- %globalDTD;
- <!ENTITY % restorepageDTD SYSTEM "chrome://browser/locale/aboutSessionRestore.dtd">
- %restorepageDTD;
-]>
-
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <head>
- <title>&tabgroupsmigration.tabtitle;</title>
- <link rel="stylesheet" href="chrome://global/skin/in-content/info-pages.css" type="text/css" media="all"/>
- <link rel="stylesheet" href="chrome://browser/skin/aboutSessionRestore.css" type="text/css" media="all"/>
- <link rel="icon" type="image/png" href="chrome://global/skin/icons/warning-16.png"/>
-
- <script type="application/javascript;version=1.8" src="chrome://browser/content/aboutSessionRestore.js"/>
- <script type="application/javascript;version=1.8" src="chrome://browser/content/aboutTabGroupsMigration.js"/>
- </head>
-
- <body dir="&locale.dir;">
-
- <div class="container restore-chosen">
-
- <div class="title">
- <h1 class="title-text">&tabgroupsmigration.pagetitle2;</h1>
- </div>
- <div class="description">
- <p id="mainDescription">&tabgroupsmigration.description2;<br /><a id="sumolink">&tabgroupsmigration.learnaboutaddons;</a></p>
- <button id="show-migrated-bookmarks-button" style="display:none" onclick="showMigratedGroups()">&tabgroupsmigration.bookmarkbutton;</button>
-
- <p>&tabgroupsmigration.restoredescription;</p>
- </div>
- <div class="tree-container" available="true">
- <xul:tree id="tabList" seltype="single" hidecolumnpicker="true"
- onclick="onListClick(event);" onkeydown="onListKeyDown(event);"
- _window_label="&restorepage.windowLabel;">
- <xul:treecols>
- <xul:treecol cycler="true" id="restore" type="checkbox" label="&restorepage.restoreHeader;"/>
- <xul:splitter class="tree-splitter"/>
- <xul:treecol primary="true" id="title" label="&restorepage.listHeader;" flex="1"/>
- </xul:treecols>
- <xul:treechildren flex="1"/>
- </xul:tree>
- </div>
- <div class="button-container">
-#ifdef XP_UNIX
- <xul:button id="errorCancel"
- label="&restorepage.closeButton;"
- accesskey="&restorepage.close.access;"
- oncommand="startNewSession();"/>
- <xul:button class="primary"
- id="errorTryAgain"
- label="&restorepage.tryagainButton;"
- accesskey="&restorepage.restore.access;"
- oncommand="restoreSession();"/>
-#else
- <xul:button class="primary"
- id="errorTryAgain"
- label="&restorepage.tryagainButton;"
- accesskey="&restorepage.restore.access;"
- oncommand="restoreSession();"/>
- <xul:button id="errorCancel"
- label="&restorepage.closeButton;"
- accesskey="&restorepage.close.access;"
- oncommand="startNewSession();"/>
-#endif
- </div>
- <!-- holds the session data for when the tab is closed -->
- <input type="text" id="sessionData" style="display: none;"/>
- </div>
-
- </body>
-</html>
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -63,18 +63,16 @@ browser.jar:
content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png)
content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png)
content/browser/aboutSocialError.xhtml (content/aboutSocialError.xhtml)
content/browser/aboutProviderDirectory.xhtml (content/aboutProviderDirectory.xhtml)
content/browser/aboutTabCrashed.css (content/aboutTabCrashed.css)
content/browser/aboutTabCrashed.js (content/aboutTabCrashed.js)
content/browser/aboutTabCrashed.xhtml (content/aboutTabCrashed.xhtml)
-* content/browser/aboutTabGroupsMigration.xhtml (content/aboutTabGroupsMigration.xhtml)
- content/browser/aboutTabGroupsMigration.js (content/aboutTabGroupsMigration.js)
* content/browser/browser.css (content/browser.css)
content/browser/browser.js (content/browser.js)
* content/browser/browser.xul (content/browser.xul)
content/browser/browser-addons.js (content/browser-addons.js)
content/browser/browser-ctrlTab.js (content/browser-ctrlTab.js)
content/browser/browser-customization.js (content/browser-customization.js)
content/browser/browser-data-submission-info-bar.js (content/browser-data-submission-info-bar.js)
content/browser/browser-devedition.js (content/browser-devedition.js)
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -57,17 +57,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
["ReaderParent", "resource:///modules/ReaderParent.jsm"],
["RecentWindow", "resource:///modules/RecentWindow.jsm"],
["RemotePrompt", "resource:///modules/RemotePrompt.jsm"],
["SelfSupportBackend", "resource:///modules/SelfSupportBackend.jsm"],
["SessionStore", "resource:///modules/sessionstore/SessionStore.jsm"],
["ShellService", "resource:///modules/ShellService.jsm"],
["SimpleServiceDiscovery", "resource://gre/modules/SimpleServiceDiscovery.jsm"],
["TabCrashHandler", "resource:///modules/ContentCrashHandlers.jsm"],
- ["TabGroupsMigrator", "resource:///modules/TabGroupsMigrator.jsm"],
["Task", "resource://gre/modules/Task.jsm"],
["UITour", "resource:///modules/UITour.jsm"],
["URLBarZoom", "resource:///modules/URLBarZoom.jsm"],
["WebChannel", "resource://gre/modules/WebChannel.jsm"],
["WindowsRegistry", "resource://gre/modules/WindowsRegistry.jsm"],
["webrtcUI", "resource:///modules/webrtcUI.jsm"],
].forEach(([name, resource]) => XPCOMUtils.defineLazyModuleGetter(this, name, resource));
@@ -650,19 +649,16 @@ BrowserGlue.prototype = {
// check if we're in safe mode
if (Services.appinfo.inSafeMode) {
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1231112#c7 . We need to
// register the observer early if we have to migrate tab groups
let currentUIVersion = 0;
try {
currentUIVersion = Services.prefs.getIntPref("browser.migration.version");
} catch (ex) {}
- if (currentUIVersion < 35) {
- this._maybeMigrateTabGroups();
- }
Services.ww.openWindow(null, "chrome://browser/content/safeMode.xul",
"_blank", "chrome,centerscreen,modal,resizable=no", null);
}
// apply distribution customizations
// prefs are applied in _onAppDefaults()
this._distributionCustomizer.applyCustomizations();
@@ -1252,24 +1248,16 @@ BrowserGlue.prototype = {
return OS.File.makeDir(newProfilePath);
}).then(null, e => {
Cu.reportError("Could not empty profile 'default': " + e);
});
}
}
},
- _maybeMigrateTabGroups() {
- let migrationObserver = (stateAsSupportsString, topic) => {
- Services.obs.removeObserver(migrationObserver, "sessionstore-state-read");
- TabGroupsMigrator.migrate(stateAsSupportsString);
- };
- Services.obs.addObserver(migrationObserver, "sessionstore-state-read", false);
- },
-
_onQuitRequest: function BG__onQuitRequest(aCancelQuit, aQuitType) {
// If user has already dismissed quit request, then do nothing
if ((aCancelQuit instanceof Ci.nsISupportsPRBool) && aCancelQuit.data)
return;
// There are several cases where we won't show a dialog here:
// 1. There is only 1 tab open in 1 window
// 2. The session will be restored at startup, indicated by
@@ -2064,20 +2052,17 @@ BrowserGlue.prototype = {
xulStore.removeValue(BROWSER_DOCURL, "bookmarks-menu-button", "class");
xulStore.removeValue(BROWSER_DOCURL, "home-button", "class");
}
if (currentUIVersion < 32) {
this._notifyNotificationsUpgrade().catch(Cu.reportError);
}
- // Only do this outside of safe mode, because in safe mode we do this earlier.
- if (currentUIVersion < 35 && !Services.appinfo.inSafeMode) {
- this._maybeMigrateTabGroups();
- }
+ // version 35 migrated tab groups data.
if (currentUIVersion < 36) {
xulStore.removeValue("chrome://passwordmgr/content/passwordManager.xul",
"passwordCol",
"hidden");
}
if (currentUIVersion < 37) {
--- a/browser/components/sessionstore/content/aboutSessionRestore.js
+++ b/browser/components/sessionstore/content/aboutSessionRestore.js
@@ -65,17 +65,17 @@ function initTreeView() {
return;
}
var tabList = document.getElementById("tabList");
var winLabel = tabList.getAttribute("_window_label");
gTreeData = [];
gStateObject.windows.forEach(function(aWinData, aIx) {
var winState = {
- label: aWinData.tabGroupsMigrationTitle || winLabel.replace("%S", (aIx + 1)),
+ label: winLabel.replace("%S", (aIx + 1)),
open: true,
checked: true,
ix: aIx
};
winState.tabs = aWinData.tabs.map(function(aTabData) {
var entry = aTabData.entries[aTabData.index - 1] || { url: "about:blank" };
var iconURL = aTabData.image || null;
// don't initiate a connection just to fetch a favicon (see bug 462863)
--- a/browser/locales/en-US/chrome/browser/aboutSessionRestore.dtd
+++ b/browser/locales/en-US/chrome/browser/aboutSessionRestore.dtd
@@ -44,17 +44,8 @@ before and after the the "learn more" li
Localizers can use one of them, or both, to better adapt this sentence to
their language.
-->
<!ENTITY welcomeback2.beforelink.pageInfo2 "Your add-ons and customizations have been removed and your browser settings have been restored to their defaults. If this didn’t fix your issue, ">
<!ENTITY welcomeback2.afterlink.pageInfo2 "">
<!ENTITY welcomeback2.link.pageInfo2 "learn more about what you can do.">
-<!-- LOCALIZATION NOTE: The following 'tabgroupsmigration' strings are for
- the tab groups (panorama) migration page, not about:sessionrestore -->
-<!ENTITY tabgroupsmigration.tabtitle "Migrate your other Tab Groups">
-<!ENTITY tabgroupsmigration.pagetitle2 "We’ve removed Tab Groups, but saved your tabs">
-<!ENTITY tabgroupsmigration.learnaboutaddons "Learn about Tab Groups replacement add-ons.">
-<!ENTITY tabgroupsmigration.description2 "&brandShortName; has bookmarked all your groups so you haven’t lost anything.">
-<!ENTITY tabgroupsmigration.bookmarkbutton "Show Bookmarked Tab Groups">
-<!ENTITY tabgroupsmigration.restoredescription "You can also choose to restore some or all background groups into windows now:">
-
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -708,21 +708,16 @@ revokeOverride.accesskey = D
# LOCALIZATION NOTE (certErrorDetails*.label): These are text strings that
# appear in the about:certerror page, so that the user can copy and send them to
# the server administrators for troubleshooting.
certErrorDetailsHSTS.label = HTTP Strict Transport Security: %S
certErrorDetailsKeyPinning.label = HTTP Public Key Pinning: %S
certErrorDetailsCertChain.label = Certificate chain:
-# LOCALIZATION NOTE (tabgroups.migration.anonGroup):
-# %S is the group number/ID
-tabgroups.migration.anonGroup = Group %S
-tabgroups.migration.tabGroupBookmarkFolderName = Bookmarked Tab Groups
-
# LOCALIZATION NOTE (pendingCrashReports2.label): Semi-colon list of plural forms
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 is the number of pending crash reports
pendingCrashReports2.label = You have an unsent crash report;You have #1 unsent crash reports
pendingCrashReports.viewAll = View
pendingCrashReports.send = Send
pendingCrashReports.alwaysSend = Always Send
deleted file mode 100644
--- a/browser/modules/TabGroupsMigrator.jsm
+++ /dev/null
@@ -1,297 +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 = ["TabGroupsMigrator"];
-
-const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "Task", "resource://gre/modules/Task.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown", "resource://gre/modules/AsyncShutdown.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
- return Services.strings.createBundle('chrome://browser/locale/browser.properties');
-});
-
-const RECOVERY_URL = "chrome://browser/content/aboutTabGroupsMigration.xhtml";
-
-
-this.TabGroupsMigrator = {
- bookmarkedGroupsPromise: null,
-
- /**
- * If this state contains tab groups, migrate the user's data. This means:
- * - make a backup of the user's data.
- * - create bookmarks of all the user's tab groups in a single folder
- * - append a tab to the active window that lets the user restore background
- * groups.
- * - remove all the tabs hidden through tab groups from the state data.
- */
- migrate(stateAsSupportsString) {
- stateAsSupportsString.QueryInterface(Ci.nsISupportsString);
- let stateStr = stateAsSupportsString.data;
- // If this is the very first startup of this profile, this is going to be empty:
- if (!stateStr) {
- return;
- }
- let state;
- try {
- state = JSON.parse(stateStr);
- } catch (ex) {
- Cu.reportError("Failed to parse sessionstore state JSON to migrate tab groups: " + ex);
- return; // can't recover from invalid JSON
- }
-
- let groupData = this._gatherGroupData(state);
-
- // This strips out the hidden tab groups and puts them in a different object.
- // It also removes all tabview metadata.
- // We always do this, and always reassign the new state back into the
- // nsISupportsString for use by sessionstore, in order to tidy up the state
- // object.
- let hiddenTabState = this._removeHiddenTabGroupsFromState(state, groupData);
-
- // However, we will only create a backup file, bookmarks and a new tab to
- // restore hidden tabs if tabs were actually removed from |state| by
- // _removeHiddenTabGroupsFromState.
- if (hiddenTabState.windows.length) {
- // We create the backup with the original string, from before all our
- // changes:
- this._createBackup(stateStr);
-
- this._createBackgroundTabGroupRestorationPage(state, hiddenTabState);
-
- // Bookmark creation is async. We need to return synchronously,
- // so we purposefully don't wait for this to be finished here. We do
- // store the promise it creates and use that in the session restore page
- // to be able to link to the bookmarks folder...
- let bookmarksFinishedPromise = this._bookmarkAllGroupsFromState(groupData);
- // ... and we make sure we finish before shutting down:
- AsyncShutdown.profileBeforeChange.addBlocker(
- "Tab groups migration bookmarks",
- bookmarksFinishedPromise
- );
- }
-
- // We always write this back to ensure that any spurious tab groups data is
- // removed:
- stateAsSupportsString.data = JSON.stringify(state);
- },
-
- /**
- * Returns a Map from window state objects to per-window group data.
- * Specifically, the values in the Map are themselves Maps from group IDs to
- * JS Objects which have these properties:
- * - tabGroupsMigrationTitle: the title of the group (or empty string)
- * - tabs: an array of the tabs objects in this group.
- */
- _gatherGroupData(state) {
- let allGroupData = new Map();
- let globalAnonGroupID = 0;
- for (let win of state.windows) {
- if (win.extData && win.extData["tabview-group"]) {
- let groupInfo = {};
- try {
- groupInfo = JSON.parse(win.extData["tabview-group"]);
- } catch (ex) {
- // This is annoying, but we'll try to deal with this.
- }
-
- let windowGroupData = new Map();
- let activeGroupID = null;
- let tabsWithoutGroup = [];
- for (let tab of win.tabs) {
- let group;
- // Get a string group ID:
- try {
- let tabViewData = tab.extData && tab.extData["tabview-tab"] &&
- JSON.parse(tab.extData["tabview-tab"]);
- if (tabViewData && ("groupID" in tabViewData)) {
- group = tabViewData.groupID + "";
- }
- } catch (ex) {
- // Ignore errors reading group info, treat as active group
- }
- if (!group) {
- // We didn't find group info. If we already have an active group,
- // pretend this is part of that group:
- if (activeGroupID) {
- group = activeGroupID;
- } else {
- if (!tabsWithoutGroup) {
- Cu.reportError("ERROR: the list of tabs without groups was " +
- "nulled out, but there's no active group ID? " +
- "This should never happen!");
- tabsWithoutGroup = [];
- }
- // Otherwise, add to the list of tabs with no group and move to
- // the next tab immediately. We'll add all these tabs at the
- // beginning of the active group as soon as we find a tab in it,
- // so as to preserve their order.
- tabsWithoutGroup.push(tab);
- continue;
- }
- }
- let groupData = windowGroupData.get(group);
- if (!groupData) {
- let title = (groupInfo[group] && groupInfo[group].title) || "";
- groupData = {
- tabs: [],
- tabGroupsMigrationTitle: title,
- };
- if (!title) {
- groupData.anonGroupID = ++globalAnonGroupID;
- groupData.tabGroupsMigrationTitle =
- gBrowserBundle.formatStringFromName("tabgroups.migration.anonGroup",
- [groupData.anonGroupID], 1);
- }
- // If this is the active group, set the active group ID and add
- // all the already-known tabs (that didn't list a group ID), if any.
- if (!activeGroupID && !tab.hidden) {
- activeGroupID = group;
- groupData.tabs = tabsWithoutGroup;
- tabsWithoutGroup = null;
- }
- windowGroupData.set(group, groupData);
- }
- groupData.tabs.push(tab);
- }
-
- // If we found tabs but no active group, assume there's just 1 group:
- if (tabsWithoutGroup && tabsWithoutGroup.length) {
- windowGroupData.set("active group", {
- tabs: tabsWithoutGroup,
- anonGroupID: ++globalAnonGroupID,
- });
- }
-
- allGroupData.set(win, windowGroupData);
- }
- }
- return allGroupData;
- },
-
- _createBackup(stateStr) {
- let dest = Services.dirsvc.get("ProfD", Ci.nsIFile);
- dest.append("tabgroups-session-backup.json");
- let promise = OS.File.writeAtomic(dest.path, stateStr, {encoding: "utf-8"});
- AsyncShutdown.webWorkersShutdown.addBlocker("TabGroupsMigrator", promise);
- return promise;
- },
-
- _groupSorter(a, b) {
- if (!a.anonGroupID) {
- return -1;
- }
- if (!b.anonGroupID) {
- return 1;
- }
- return a.anonGroupID - b.anonGroupID;
- },
-
- _bookmarkAllGroupsFromState: Task.async(function*(groupData) {
- // First create a folder in which to put all these bookmarks:
- this.bookmarkedGroupsPromise = PlacesUtils.bookmarks.insert({
- parentGuid: PlacesUtils.bookmarks.menuGuid,
- type: PlacesUtils.bookmarks.TYPE_FOLDER,
- index: 0,
- title: gBrowserBundle.GetStringFromName("tabgroups.migration.tabGroupBookmarkFolderName"),
- }).catch(Cu.reportError);
- let tabgroupsFolder = yield this.bookmarkedGroupsPromise;
-
- for (let [, windowGroupMap] of groupData) {
- let windowGroups = [... windowGroupMap.values()].sort(this._groupSorter);
- for (let group of windowGroups) {
- let groupFolder = yield PlacesUtils.bookmarks.insert({
- parentGuid: tabgroupsFolder.guid,
- type: PlacesUtils.bookmarks.TYPE_FOLDER,
- title: group.tabGroupsMigrationTitle
- }).catch(Cu.reportError);
-
- for (let tab of group.tabs) {
- let entry = tab.entries[tab.index - 1];
- yield PlacesUtils.bookmarks.insert({
- parentGuid: groupFolder.guid,
- title: tab.title || entry.title,
- url: entry.url,
- }).catch(Cu.reportError);
- }
- }
- }
- }),
-
- _removeHiddenTabGroupsFromState(state, groups) {
- let stateToReturn = {windows: []};
- for (let win of state.windows) {
- let groupInfoForWindow = groups.get(win);
- let hiddenGroupIDs = new Set();
- for (let i = win.tabs.length - 1; i >= 0; i--) {
- let tab = win.tabs[i];
- // Determine whether the tab is grouped:
- let tabGroupInfo = null;
- try {
- tabGroupInfo = tab.extData && tab.extData["tabview-tab"] &&
- JSON.parse(tab.extData["tabview-tab"]);
- } catch (ex) {}
-
- // Then remove this data.
- if (tab.extData) {
- delete tab.extData["tabview-tab"];
- if (Object.keys(tab.extData).length == 0) {
- delete tab.extData;
- }
- }
-
- // If the tab was grouped and hidden, remove it:
- if (tabGroupInfo && tab.hidden) {
- hiddenGroupIDs.add(tabGroupInfo.groupID);
- win.tabs.splice(i, 1);
- // Make sure we unhide it, or it won't get restored correctly
- tab.hidden = false;
- }
- }
-
- // We then convert any hidden groups into windows for the state object
- // we show in about:tabgroupsdata
- if (groupInfoForWindow) {
- let windowsToReturn = [];
- for (let groupID of hiddenGroupIDs) {
- let group = groupInfoForWindow.get("" + groupID);
- if (group) {
- windowsToReturn.push(group);
- }
- }
- windowsToReturn.sort(this._groupSorter);
- stateToReturn.windows = stateToReturn.windows.concat(windowsToReturn);
- }
-
- // Finally we remove tab groups data from the window:
- if (win.extData) {
- delete win.extData["tabview-group"];
- delete win.extData["tabview-groups"];
- delete win.extData["tabview-ui"];
- delete win.extData["tabview-visibility"];
- if (Object.keys(win.extData).length == 0) {
- delete win.extData;
- }
- }
- }
- return stateToReturn;
- },
-
- _createBackgroundTabGroupRestorationPage(state, backgroundData) {
- let win = state.windows[(state.selectedWindow || 1) - 1];
- let formdata = {id: {sessionData: JSON.stringify(backgroundData)}, url: RECOVERY_URL};
- let newTab = { entries: [{url: RECOVERY_URL}], formdata, index: 1 };
- // Add tab and mark it as selected:
- win.selected = win.tabs.push(newTab);
- },
-};
-
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -39,17 +39,16 @@ EXTRA_JS_MODULES += [
'ReaderParent.jsm',
'RecentWindow.jsm',
'RemotePrompt.jsm',
'Sanitizer.jsm',
'SelfSupportBackend.jsm',
'SitePermissions.jsm',
'Social.jsm',
'SocialService.jsm',
- 'TabGroupsMigrator.jsm',
'TransientPrefs.jsm',
'URLBarZoom.jsm',
'webrtcUI.jsm',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXTRA_JS_MODULES += [
'Windows8WindowFrameColor.jsm',
deleted file mode 100644
--- a/browser/modules/test/xpcshell/test_TabGroupsMigrator.js
+++ /dev/null
@@ -1,406 +0,0 @@
-"use strict";
-
-Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
-Components.utils.import("resource://gre/modules/osfile.jsm");
-Components.utils.import("resource:///modules/TabGroupsMigrator.jsm");
-
-var gProfD = do_get_profile();
-
-const TEST_STATES = {
- TWO_GROUPS: {
- selectedWindow: 1,
- windows: [
- {
- tabs: [
- {
- entries: [{
- url: "about:robots",
- title: "Robots 1",
- }],
- index: 1,
- hidden: false,
- extData: {
- "tabview-tab": "{\"groupID\":2,\"active\":true}",
- },
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 2",
- }],
- index: 1,
- hidden: false,
- extData: {
- "tabview-tab": "{\"groupID\":2}",
- },
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 3",
- }],
- index: 1,
- hidden: true,
- extData: {
- "tabview-tab": "{\"groupID\":13}",
- },
- }
- ],
- extData: {
- "tabview-group": "{\"2\":{},\"13\":{\"title\":\"Foopy\"}}",
- "tabview-groups": "{\"nextID\":20,\"activeGroupId\":2,\"totalNumber\":2}",
- "tabview-visibility": "false"
- },
- },
- ]
- },
- NAMED_ACTIVE_GROUP: {
- selectedWindow: 1,
- windows: [
- {
- tabs: [
- {
- entries: [{
- url: "about:mozilla",
- title: "Mozilla 1",
- }],
- index: 1,
- hidden: false,
- extData: {
- "tabview-tab": "{\"groupID\":2,\"active\":true}",
- },
- },
- ],
- extData: {
- "tabview-group": "{\"2\":{\"title\":\"Foopy\"}}",
- "tabview-groups": "{\"nextID\":20,\"activeGroupId\":2,\"totalNumber\":1}",
- "tabview-visibility": "false"
- },
- }
- ],
- },
- TAB_WITHOUT_GROUP: {
- selectedWindow: 1,
- windows: [
- {
- tabs: [
- {
- entries: [{
- url: "about:robots",
- title: "Robots 1",
- }],
- index: 1,
- hidden: false,
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 2",
- }],
- index: 1,
- hidden: false,
- extData: {
- "tabview-tab": "{\"groupID\":2}",
- },
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 3",
- }],
- index: 1,
- hidden: true,
- extData: {
- "tabview-tab": "{\"groupID\":1}",
- },
- }
- ],
- extData: {
- "tabview-group": "{\"2\":{}, \"1\": {}}",
- "tabview-groups": "{\"nextID\":20,\"activeGroupId\":2,\"totalNumber\":2}",
- "tabview-visibility": "false"
- },
- }
- ],
- },
- ONLY_UNGROUPED_TABS: {
- selectedWindow: 1,
- windows: [
- {
- tabs: [
- {
- entries: [{
- url: "about:robots",
- title: "Robots 1",
- }],
- index: 1,
- hidden: false,
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 2",
- }],
- index: 1,
- hidden: false,
- extData: {
- "tabview-tab": "{}",
- },
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 3",
- }],
- index: 1,
- hidden: true,
- extData: {
- },
- }
- ],
- extData: {
- "tabview-group": "{\"2\":{}}",
- },
- }
- ],
- },
- SORTING_NAMING_RESTORE_PAGE: {
- windows: [
- {
- tabs: [
- {
- entries: [{
- url: "about:robots",
- title: "Robots 1",
- }],
- index: 1,
- hidden: false,
- extData: {
- "tabview-tab": "{\"groupID\":2,\"active\":true}",
- },
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 2",
- }],
- index: 1,
- hidden: false,
- extData: {
- "tabview-tab": "{\"groupID\":2}",
- },
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 3",
- }],
- index: 1,
- hidden: true,
- extData: {
- "tabview-tab": "{\"groupID\":13}",
- },
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 4",
- }],
- index: 1,
- hidden: true,
- extData: {
- "tabview-tab": "{\"groupID\":15}",
- },
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 5",
- }],
- index: 1,
- hidden: true,
- extData: {
- "tabview-tab": "{\"groupID\":16}",
- },
- },
- {
- entries: [{
- url: "about:robots",
- title: "Robots 6",
- }],
- index: 1,
- hidden: true,
- extData: {
- "tabview-tab": "{\"groupID\":17}",
- },
- }
- ],
- extData: {
- "tabview-group": "{\"2\":{},\"13\":{\"title\":\"Foopy\"}, \"15\":{\"title\":\"Barry\"}, \"16\":{}, \"17\":{}}",
- "tabview-groups": "{\"nextID\":20,\"activeGroupId\":2,\"totalNumber\":5}",
- "tabview-visibility": "false"
- },
- },
- ]
- },
-};
-
-add_task(function* gatherGroupDataTest() {
- let groupInfo = TabGroupsMigrator._gatherGroupData(TEST_STATES.TWO_GROUPS);
- Assert.equal(groupInfo.size, 1, "Information about 1 window");
- let singleWinGroups = [... groupInfo.values()][0];
- Assert.equal(singleWinGroups.size, 2, "2 groups");
- let group2 = singleWinGroups.get("2");
- Assert.ok(!!group2, "group 2 should exist");
- Assert.equal(group2.tabs.length, 2, "2 tabs in group 2");
- // Note that this has groupID 2 in the internal representation of tab groups,
- // but because it was the first group we encountered when migrating, it was
- // labeled "group 1" for the user
- Assert.equal(group2.tabGroupsMigrationTitle, "Group 1", "We assign a numeric title to untitled groups");
- Assert.equal(group2.anonGroupID, "1", "We mark an untitled group with an anonymous id");
- let group13 = singleWinGroups.get("13");
- Assert.ok(!!group13, "group 13 should exist");
- Assert.equal(group13.tabs.length, 1, "1 tabs in group 13");
- Assert.equal(group13.tabGroupsMigrationTitle, "Foopy", "Group with title has correct title");
- Assert.ok(!("anonGroupID" in group13), "We don't mark a titled group with an anonymous id");
-});
-
-add_task(function* bookmarkingTest() {
- let stateClone = JSON.parse(JSON.stringify(TEST_STATES.TWO_GROUPS));
- let groupInfo = TabGroupsMigrator._gatherGroupData(stateClone);
- let removedGroups = TabGroupsMigrator._removeHiddenTabGroupsFromState(stateClone, groupInfo);
- yield TabGroupsMigrator._bookmarkAllGroupsFromState(groupInfo);
- let bmCounter = 0;
- let bmParents = {};
- let bookmarks = [];
- let onResult = bm => {
- bmCounter++;
- bmParents[bm.parentGuid] = (bmParents[bm.parentGuid] || 0) + 1;
- Assert.ok(bm.title.startsWith("Robots "), "Bookmark title(" + bm.title + ") should start with 'Robots '");
- };
- yield PlacesUtils.bookmarks.fetch({url: "about:robots"}, onResult);
- Assert.equal(bmCounter, 3, "Should have seen 3 bookmarks");
- Assert.equal(Object.keys(bmParents).length, 2, "Should be in 2 folders");
-
- let ancestorGuid;
- let parents = Object.keys(bmParents).map(guid => {
- PlacesUtils.bookmarks.fetch({guid}, bm => {
- ancestorGuid = bm.parentGuid;
- if (bmParents[bm.guid] == 1) {
- Assert.equal(bm.title, "Foopy", "Group with 1 kid has right title");
- } else {
- Assert.ok(bm.title.includes("1"), "Group with more kids should have anon ID in title (" + bm.title + ")");
- }
- });
- });
- yield Promise.all(parents);
-
- yield PlacesUtils.bookmarks.fetch({guid: ancestorGuid}, bm => {
- Assert.equal(bm.title,
- gBrowserBundle.GetStringFromName("tabgroups.migration.tabGroupBookmarkFolderName"),
- "Should have the right title");
- });
-});
-
-add_task(function* bookmarkNamedActiveGroup() {
- let stateClone = JSON.parse(JSON.stringify(TEST_STATES.NAMED_ACTIVE_GROUP));
- let groupInfo = TabGroupsMigrator._gatherGroupData(stateClone);
- let removedGroups = TabGroupsMigrator._removeHiddenTabGroupsFromState(stateClone, groupInfo);
- yield TabGroupsMigrator._bookmarkAllGroupsFromState(groupInfo);
- let bmParents = {};
- let bmCounter = 0;
- let onResult = bm => {
- bmCounter++;
- bmParents[bm.parentGuid] = (bmParents[bm.parentGuid] || 0) + 1;
- Assert.ok(bm.title.startsWith("Mozilla "), "Bookmark title (" + bm.title + ") should start with 'Mozilla '");
- };
- yield PlacesUtils.bookmarks.fetch({url: "about:mozilla"}, onResult);
- Assert.equal(bmCounter, 1, "Should have seen 1 bookmarks");
- let parentPromise = PlacesUtils.bookmarks.fetch({guid: Object.keys(bmParents)[0]}, bm => {
- Assert.equal(bm.title, "Foopy", "Group with 1 kid has right title");
- });
- yield parentPromise;
-});
-
-add_task(function* removingTabGroupsFromJSONTest() {
- let stateClone = JSON.parse(JSON.stringify(TEST_STATES.TWO_GROUPS));
- let groupInfo = TabGroupsMigrator._gatherGroupData(stateClone);
- let removedGroups = TabGroupsMigrator._removeHiddenTabGroupsFromState(stateClone, groupInfo);
- Assert.equal(removedGroups.windows.length, 1, "Removed 1 group which looks like a window in removed data");
- Assert.equal(removedGroups.windows[0].tabs.length, 1, "Removed group had 1 tab");
- Assert.ok(!stateClone.windows[0].extData, "extData removed from window");
- stateClone.windows[0].tabs.forEach(tab => {
- Assert.ok(!tab.extData, "extData removed from tab");
- });
- Assert.ok(stateClone.windows[0].tabs.length, 2, "Only 2 tabs remain in the window");
-});
-
-add_task(function* backupTest() {
- yield TabGroupsMigrator._createBackup(JSON.stringify(TEST_STATES.TWO_GROUPS));
- let f = Services.dirsvc.get("ProfD", Components.interfaces.nsIFile);
- f.append("tabgroups-session-backup.json");
- ok(f.exists(), "Should have created the file");
-
- let txt = (new TextDecoder()).decode(yield OS.File.read(f.path));
- Assert.deepEqual(JSON.parse(txt), TEST_STATES.TWO_GROUPS, "Should have written the expected state.");
-
- f.remove(false);
-});
-
-add_task(function* migrationPageDataTest() {
- let stateClone = JSON.parse(JSON.stringify(TEST_STATES.TWO_GROUPS));
- let groupInfo = TabGroupsMigrator._gatherGroupData(stateClone);
- let removedGroups = TabGroupsMigrator._removeHiddenTabGroupsFromState(stateClone, groupInfo);
- TabGroupsMigrator._createBackgroundTabGroupRestorationPage(stateClone, removedGroups);
- Assert.equal(stateClone.windows.length, 1, "Should still only have 1 window");
- Assert.equal(stateClone.windows[0].tabs.length, 3, "Should now have 3 tabs");
-
- let url = "chrome://browser/content/aboutTabGroupsMigration.xhtml";
- let formdata = {id: {sessionData: JSON.stringify(removedGroups)}, url};
- Assert.deepEqual(stateClone.windows[0].tabs[2],
- {
- entries: [{url}],
- formdata,
- index: 1
- },
- "Should have added expected tab at the end of the tab list.");
-});
-
-add_task(function* correctMissingTabGroupInfo() {
- let stateClone = JSON.parse(JSON.stringify(TEST_STATES.TAB_WITHOUT_GROUP));
- let groupInfo = TabGroupsMigrator._gatherGroupData(stateClone);
- Assert.equal(groupInfo.size, 1, "Should have 1 window");
- let windowGroups = [...groupInfo][0][1];
- Assert.equal(windowGroups.size, 2, "Window should have 2 groups");
- let group2 = windowGroups.get("2");
- Assert.ok(group2, "Group 2 should exist");
- Assert.equal(group2.tabs.length, 2, "There should be 2 tabs in group 2");
- Assert.equal(group2.tabs[0].entries[0].title, "Robots 1", "The first tab of group 2 should be the tab with no group info.");
-});
-
-add_task(function* dealWithNoGroupInfo() {
- let stateClone = JSON.parse(JSON.stringify(TEST_STATES.ONLY_UNGROUPED_TABS));
- let groupInfo = TabGroupsMigrator._gatherGroupData(stateClone);
- Assert.equal(groupInfo.size, 1, "Should have 1 window");
- let windowGroups = [...groupInfo][0][1];
- Assert.equal(windowGroups.size, 1, "Window should have 1 group");
- let fallbackActiveGroup = windowGroups.get("active group");
- Assert.ok(fallbackActiveGroup, "Fallback group should exist");
- Assert.equal(fallbackActiveGroup.tabs.length, 3, "There should be 3 tabs in the fallback group");
-});
-
-add_task(function* groupSortingInRemovedDataUsedForRestorePage() {
- let stateClone = JSON.parse(JSON.stringify(TEST_STATES.SORTING_NAMING_RESTORE_PAGE));
- let groupInfo = TabGroupsMigrator._gatherGroupData(stateClone);
- let removedGroups = TabGroupsMigrator._removeHiddenTabGroupsFromState(stateClone, groupInfo);
- Assert.equal(stateClone.windows.length, 1, "Should still only have 1 window");
- Assert.equal(stateClone.windows[0].tabs.length, 2, "Should now have 2 tabs");
-
- let restoredWindowTitles = removedGroups.windows.map(win => win.tabGroupsMigrationTitle);
- // Note that group 1 is the active group and as such it won't appear in the list of
- // things the user can restore:
- Assert.deepEqual(restoredWindowTitles,
- ["Barry", "Foopy", "Group 2", "Group 3"]);
-});
-
--- a/browser/modules/test/xpcshell/xpcshell.ini
+++ b/browser/modules/test/xpcshell/xpcshell.ini
@@ -3,10 +3,9 @@ head =
tail =
firefox-appdir = browser
skip-if = toolkit == 'android' || toolkit == 'gonk'
[test_AttributionCode.js]
skip-if = os != 'win'
[test_DirectoryLinksProvider.js]
[test_SitePermissions.js]
-[test_TabGroupsMigrator.js]
[test_LaterRun.js]