Bug 1179129 - about:profiles, r=ehsan

This commit is contained in:
Andrea Marchesini 2015-12-15 14:12:06 +00:00
parent 5a69dbfe1d
commit 43c8b0cfb3
12 changed files with 401 additions and 0 deletions

View File

@ -100,6 +100,10 @@ static RedirEntry kRedirMap[] = {
nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
nsIAboutModule::ALLOW_SCRIPT
},
{
"profiles", "chrome://global/content/aboutProfiles.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
// about:srcdoc is unresolvable by specification. It is included here
// because the security manager would disallow srcdoc iframes otherwise.
{

View File

@ -180,6 +180,7 @@ const mozilla::Module::ContractIDEntry kDocShellContracts[] = {
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "plugins", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "serviceworkers", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "profiles", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "srcdoc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID },

View File

@ -0,0 +1,219 @@
/* 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 {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
XPCOMUtils.defineLazyServiceGetter(
this,
'ProfileService',
'@mozilla.org/toolkit/profile-service;1',
'nsIToolkitProfileService'
);
const bundle = Services.strings.createBundle(
'chrome://global/locale/aboutProfiles.properties');
function refreshUI() {
let parent = document.getElementById('profiles');
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
let iter = ProfileService.profiles;
while (iter.hasMoreElements()) {
let profile = iter.getNext().QueryInterface(Ci.nsIToolkitProfile);
display({ profile: profile,
isDefault: profile == ProfileService.defaultProfile,
isCurrentProfile: profile == ProfileService.selectedProfile });
}
let createButton = document.getElementById('create-button');
createButton.onclick = createProfileWizard;
let restartSafeModeButton = document.getElementById('restart-in-safe-mode-button');
restartSafeModeButton.onclick = function() { restart(true); }
let restartNormalModeButton = document.getElementById('restart-button');
restartNormalModeButton.onclick = function() { restart(false); }
}
function display(profileData) {
let parent = document.getElementById('profiles');
let div = document.createElement('div');
parent.appendChild(div);
let name = document.createElement('h2');
let nameStr = bundle.formatStringFromName('name', [profileData.profile.name], 1);
name.appendChild(document.createTextNode(nameStr));
div.appendChild(name);
if (profileData.isCurrentProfile) {
let currentProfile = document.createElement('h3');
let currentProfileStr = bundle.GetStringFromName('currentProfile');
currentProfile.appendChild(document.createTextNode(currentProfileStr));
div.appendChild(currentProfile);
}
let table = document.createElement('table');
div.appendChild(table);
let tbody = document.createElement('tbody');
table.appendChild(tbody);
function createItem(title, value) {
let tr = document.createElement('tr');
tbody.appendChild(tr);
let th = document.createElement('th');
th.setAttribute('class', 'column');
th.appendChild(document.createTextNode(title));
tr.appendChild(th);
let td = document.createElement('td');
td.appendChild(document.createTextNode(value));
tr.appendChild(td);
}
createItem(bundle.GetStringFromName('isDefault'),
profileData.isDefault ? bundle.GetStringFromName('yes') : bundle.GetStringFromName('no'));
createItem(bundle.GetStringFromName('rootDir'), profileData.profile.rootDir.path);
if (profileData.profile.localDir.path != profileData.profile.rootDir.path) {
createItem(bundle.GetStringFromName('localDir'), profileData.profile.localDir.path);
}
let renameButton = document.createElement('button');
renameButton.appendChild(document.createTextNode(bundle.GetStringFromName('rename')));
renameButton.onclick = function() {
renameProfile(profileData.profile);
};
div.appendChild(renameButton);
if (!profileData.isCurrentProfile) {
let removeButton = document.createElement('button');
removeButton.appendChild(document.createTextNode(bundle.GetStringFromName('remove')));
removeButton.onclick = function() {
removeProfile(profileData.profile);
};
div.appendChild(removeButton);
}
if (!profileData.isDefault) {
let defaultButton = document.createElement('button');
defaultButton.appendChild(document.createTextNode(bundle.GetStringFromName('setAsDefault')));
defaultButton.onclick = function() {
defaultProfile(profileData.profile);
};
div.appendChild(defaultButton);
}
let sep = document.createElement('hr');
div.appendChild(sep);
}
function CreateProfile(profile) {
ProfileService.flush();
refreshUI();
}
function createProfileWizard() {
// This should be rewritten in HTML eventually.
window.openDialog('chrome://mozapps/content/profile/createProfileWizard.xul',
'', 'centerscreen,chrome,modal,titlebar',
ProfileService);
}
function renameProfile(profile) {
let title = bundle.GetStringFromName('renameProfileTitle');
let msg = bundle.formatStringFromName('renameProfile', [profile.name], 1);
let newName = { value: profile.name };
if (Services.prompt.prompt(window, title, msg, newName, null,
{ value: 0 })) {
newName = newName.value;
if (newName == profile.name) {
return;
}
try {
profile.name = newName;
} catch(e) {
let title = bundle.GetStringFromName('invalidProfileNameTitle');
let msg = bundle.formatStringFromName('invalidProfileName', [newName], 1);
Services.prompt.alert(window, title, msg);
return;
}
ProfileService.flush();
refreshUI();
}
}
function removeProfile(profile) {
let deleteFiles = false;
if (profile.rootDir.exists()) {
let title = bundle.GetStringFromName('deleteProfileTitle');
let msg = bundle.formatStringFromName('deleteProfileConfirm',
[profile.rootDir.path], 1);
let buttonPressed = Services.prompt.confirmEx(window, title, msg,
(Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0) +
(Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1) +
(Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_2),
bundle.GetStringFromName('dontDeleteFiles'),
null,
bundle.GetStringFromName('deleteFiles'),
null, {value:0});
if (buttonPressed == 1) {
return;
}
if (buttonPressed == 2) {
deleteFiles = true;
}
}
profile.remove(deleteFiles);
ProfileService.flush();
refreshUI();
}
function defaultProfile(profile) {
ProfileService.defaultProfile = profile;
ProfileService.flush();
refreshUI();
}
function restart(safeMode) {
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
.createInstance(Ci.nsISupportsPRBool);
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
if (cancelQuit.data) {
return;
}
let flags = Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestartNotSameProfile;
if (safeMode) {
Services.startup.restartInSafeMode(flags);
} else {
Services.startup.quit(flags);
}
}
window.addEventListener('DOMContentLoaded', function load() {
window.removeEventListener('DOMContentLoaded', load);
refreshUI();
});

View File

@ -0,0 +1,40 @@
<?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 % globalDTD SYSTEM "chrome://global/locale/global.dtd"> %globalDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> %brandDTD;
<!ENTITY % profilesDTD SYSTEM "chrome://global/locale/aboutProfiles.dtd"> %profilesDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&aboutProfiles.title;</title>
<link rel="icon" type="image/png" id="favicon" href="chrome://branding/content/icon32.png"/>
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css" type="text/css"/>
<link rel="stylesheet" href="chrome://mozapps/skin/aboutProfiles.css" type="text/css" />
<script type="application/javascript;version=1.7" src="chrome://global/content/aboutProfiles.js" />
</head>
<body id="body">
<div id="action-box">
<div>
<h3>&aboutProfiles.restart.title;</h3>
<button id="restart-in-safe-mode-button">&aboutProfiles.restart.inSafeMode;</button>
<button id="restart-button">&aboutProfiles.restart.normal;</button>
</div>
</div>
<h1>&aboutProfiles.title;</h1>
<div class="page-subtitle">&aboutProfiles.subtitle;</div>
<div>
<button id="create-button">&aboutProfiles.create;</button>
</div>
<div id="profiles" class="tab"></div>
</body>
</html>

View File

@ -216,6 +216,16 @@
</td>
</tr>
<tr class="no-copy">
<th class="column">
&aboutSupport.appBasicsProfiles;
</th>
<td>
<a href="about:profiles">about:profiles</a>
</td>
</tr>
</tbody>
</table>

View File

@ -23,6 +23,8 @@ toolkit.jar:
#endif
content/global/aboutNetworking.js
content/global/aboutNetworking.xhtml
content/global/aboutProfiles.js
content/global/aboutProfiles.xhtml
content/global/aboutServiceWorkers.js
content/global/aboutServiceWorkers.xhtml
content/global/aboutwebrtc/aboutWebrtc.css (aboutwebrtc/aboutWebrtc.css)

View File

@ -0,0 +1,10 @@
<!-- 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 aboutProfiles.title "About Profiles">
<!ENTITY aboutProfiles.subtitle "This page helps you to manage your profiles. Each profile is a separate world which contains separate history, bookmarks, settings and add-ons.">
<!ENTITY aboutProfiles.create "Create a New Profile">
<!ENTITY aboutProfiles.restart.title "Restart">
<!ENTITY aboutProfiles.restart.inSafeMode "Restart with Add-ons Disabled…">
<!ENTITY aboutProfiles.restart.normal "Restart normally…">

View File

@ -0,0 +1,33 @@
# 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/.
name = Profile: %S
isDefault = Default Profile
rootDir = Root Directory
# LOCALIZATION NOTE: localDir is used to show the directory corresponding to
# the main profile directory that exists for the purpose of storing data on the
# local filesystem, including cache files or other data files that may not
# represent critical user data. (e.g., this directory may not be included as
# part of a backup scheme.)
# In case localDIr and rootDir are equal, localDir is not shown.
localDir = Local Directory
currentProfile = This is the profile in use and it cannot be deleted.
rename = Rename
remove = Remove
setAsDefault = Set as default profile
yes = yes
no = no
renameProfileTitle = Rename Profile
renameProfile = Rename profile %S
invalidProfileNameTitle = Invalid profile name
invalidProfileName = The profile name "%S" is not allowed.
deleteProfileTitle = Delete Profile
deleteProfileConfirm = Deleting a profile will remove the profile from the list of available profiles and cannot be undone.\nYou may also choose to delete the profile data files, including your settings, certificates and other user-related data. This option will delete the folder "%S" and cannot be undone.\nWould you like to delete the profile data files?
deleteFiles = Delete Files
dontDeleteFiles = Don't Delete Files

View File

@ -59,6 +59,8 @@ Windows/Mac use the term "Folder" instead of "Directory" -->
<!-- LOCALIZATION NOTE the term "Service Workers" should not be translated. -->
<!ENTITY aboutSupport.appBasicsServiceWorkers "Registered Service Workers">
<!ENTITY aboutSupport.appBasicsProfiles "Profiles">
<!ENTITY aboutSupport.appBasicsMultiProcessSupport "Multiprocess Windows">
<!ENTITY aboutSupport.appBasicsSafeMode "Safe Mode">

View File

@ -11,6 +11,8 @@
locale/@AB_CD@/global/aboutReader.properties (%chrome/global/aboutReader.properties)
locale/@AB_CD@/global/aboutRights.dtd (%chrome/global/aboutRights.dtd)
locale/@AB_CD@/global/aboutNetworking.dtd (%chrome/global/aboutNetworking.dtd)
locale/@AB_CD@/global/aboutProfiles.dtd (%chrome/global/aboutProfiles.dtd)
locale/@AB_CD@/global/aboutProfiles.properties (%chrome/global/aboutProfiles.properties)
locale/@AB_CD@/global/aboutServiceWorkers.dtd (%chrome/global/aboutServiceWorkers.dtd)
locale/@AB_CD@/global/aboutServiceWorkers.properties (%chrome/global/aboutServiceWorkers.properties)
locale/@AB_CD@/global/aboutSupport.dtd (%chrome/global/aboutSupport.dtd)

View File

@ -0,0 +1,77 @@
/* 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/. */
html {
--aboutSupport-table-background: #ebebeb;
background-color: var(--in-content-page-background);
}
body {
margin: 40px 48px;
}
.page-subtitle {
margin-bottom: 3em;
}
button {
-moz-margin-start: 0;
-moz-margin-end: 8px;
}
table {
background-color: var(--aboutSupport-table-background);
color: var(--in-content-text-color);
font: message-box;
text-align: start;
width: 100%;
border: 1px solid var(--in-content-border-color);
border-spacing: 0px;
}
th, td {
border: 1px solid var(--in-content-border-color);
padding: 4px;
}
th {
text-align: start;
background-color: var(--in-content-table-header-background);
color: var(--in-content-selected-text);
}
th.column {
white-space: nowrap;
width: 0px;
}
td {
text-align: start;
border-color: var(--in-content-table-border-dark-color);
}
#action-box {
background-color: var(--aboutSupport-table-background);
border: 1px solid var(--in-content-border-color);
color: var(--in-content-text-color);
float: right;
margin-top: 2em;
margin-bottom: 20px;
-moz-margin-start: 20px;
-moz-margin-end: 0;
padding: 16px;
width: 30%;
}
#action-box:-moz-dir(rtl) {
float: left;
}
#reset-box > h3 {
margin-top: 0;
}
#action-box button {
display: block;
}

View File

@ -17,6 +17,7 @@
skin/classic/mozapps/formautofill/requestAutocomplete.css (../../shared/formautofill/requestAutocomplete.css)
skin/classic/mozapps/plugins/pluginProblem.css (../../shared/plugins/pluginProblem.css)
skin/classic/mozapps/aboutNetworking.css (../../shared/aboutNetworking.css)
skin/classic/mozapps/aboutProfiles.css (../../shared/aboutProfiles.css)
skin/classic/mozapps/aboutServiceWorkers.css (../../shared/aboutServiceWorkers.css)
skin/classic/mozapps/plugins/contentPluginActivate.png (../../shared/plugins/contentPluginActivate.png)
skin/classic/mozapps/plugins/contentPluginBlocked.png (../../shared/plugins/contentPluginBlocked.png)