aboutProfiles.js 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. 'use strict';
  5. const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
  6. Cu.import('resource://gre/modules/Services.jsm');
  7. Cu.import('resource://gre/modules/XPCOMUtils.jsm');
  8. XPCOMUtils.defineLazyServiceGetter(
  9. this,
  10. 'ProfileService',
  11. '@mozilla.org/toolkit/profile-service;1',
  12. 'nsIToolkitProfileService'
  13. );
  14. const bundle = Services.strings.createBundle(
  15. 'chrome://global/locale/aboutProfiles.properties');
  16. // nsIToolkitProfileService.selectProfile can be used only during the selection
  17. // of the profile in the ProfileManager. If we are showing about:profiles in a
  18. // tab, the selectedProfile returns the default profile.
  19. // In this function we use the ProfD to find the current profile.
  20. function findCurrentProfile() {
  21. let cpd;
  22. try {
  23. cpd = Cc["@mozilla.org/file/directory_service;1"]
  24. .getService(Ci.nsIProperties)
  25. .get("ProfD", Ci.nsIFile);
  26. } catch (e) {}
  27. if (cpd) {
  28. let itr = ProfileService.profiles;
  29. while (itr.hasMoreElements()) {
  30. let profile = itr.getNext().QueryInterface(Ci.nsIToolkitProfile);
  31. if (profile.rootDir.path == cpd.path) {
  32. return profile;
  33. }
  34. }
  35. }
  36. // selectedProfile can trow if nothing is selected or if the selected profile
  37. // has been deleted.
  38. try {
  39. return ProfileService.selectedProfile;
  40. } catch (e) {
  41. return null;
  42. }
  43. }
  44. function refreshUI() {
  45. let parent = document.getElementById('profiles');
  46. while (parent.firstChild) {
  47. parent.removeChild(parent.firstChild);
  48. }
  49. let defaultProfile;
  50. try {
  51. defaultProfile = ProfileService.defaultProfile;
  52. } catch (e) {}
  53. let currentProfile = findCurrentProfile() || defaultProfile;
  54. let iter = ProfileService.profiles;
  55. while (iter.hasMoreElements()) {
  56. let profile = iter.getNext().QueryInterface(Ci.nsIToolkitProfile);
  57. display({ profile: profile,
  58. isDefault: profile == defaultProfile,
  59. isCurrentProfile: profile == currentProfile });
  60. }
  61. let createButton = document.getElementById('create-button');
  62. createButton.onclick = createProfileWizard;
  63. let restartSafeModeButton = document.getElementById('restart-in-safe-mode-button');
  64. restartSafeModeButton.onclick = function() { restart(true); }
  65. let restartNormalModeButton = document.getElementById('restart-button');
  66. restartNormalModeButton.onclick = function() { restart(false); }
  67. }
  68. function openDirectory(dir) {
  69. let nsLocalFile = Components.Constructor("@mozilla.org/file/local;1",
  70. "nsILocalFile", "initWithPath");
  71. new nsLocalFile(dir).reveal();
  72. }
  73. function display(profileData) {
  74. let parent = document.getElementById('profiles');
  75. let div = document.createElement('div');
  76. parent.appendChild(div);
  77. let nameStr = bundle.formatStringFromName('name', [profileData.profile.name], 1);
  78. let name = document.createElement('h2');
  79. name.appendChild(document.createTextNode(nameStr));
  80. div.appendChild(name);
  81. if (profileData.isCurrentProfile) {
  82. let currentProfile = document.createElement('h3');
  83. let currentProfileStr = bundle.GetStringFromName('currentProfile');
  84. currentProfile.appendChild(document.createTextNode(currentProfileStr));
  85. div.appendChild(currentProfile);
  86. }
  87. let table = document.createElement('table');
  88. div.appendChild(table);
  89. let tbody = document.createElement('tbody');
  90. table.appendChild(tbody);
  91. function createItem(title, value, dir = false) {
  92. let tr = document.createElement('tr');
  93. tbody.appendChild(tr);
  94. let th = document.createElement('th');
  95. th.setAttribute('class', 'column');
  96. th.appendChild(document.createTextNode(title));
  97. tr.appendChild(th);
  98. let td = document.createElement('td');
  99. td.appendChild(document.createTextNode(value));
  100. tr.appendChild(td);
  101. if (dir) {
  102. td.appendChild(document.createTextNode(' '));
  103. let button = document.createElement('button');
  104. #ifdef XP_WIN
  105. let string = 'winOpenDir2';
  106. #else
  107. let string = 'openDir';
  108. #endif
  109. let buttonText = document.createTextNode(bundle.GetStringFromName(string));
  110. button.appendChild(buttonText);
  111. td.appendChild(button);
  112. button.addEventListener('click', function(e) {
  113. openDirectory(value);
  114. });
  115. }
  116. }
  117. createItem(bundle.GetStringFromName('isDefault'),
  118. profileData.isDefault ? bundle.GetStringFromName('yes') : bundle.GetStringFromName('no'));
  119. createItem(bundle.GetStringFromName('rootDir'), profileData.profile.rootDir.path, true);
  120. if (profileData.profile.localDir.path != profileData.profile.rootDir.path) {
  121. createItem(bundle.GetStringFromName('localDir'), profileData.profile.localDir.path, true);
  122. }
  123. let renameButton = document.createElement('button');
  124. renameButton.appendChild(document.createTextNode(bundle.GetStringFromName('rename')));
  125. renameButton.onclick = function() {
  126. renameProfile(profileData.profile);
  127. };
  128. div.appendChild(renameButton);
  129. if (!profileData.isCurrentProfile) {
  130. let removeButton = document.createElement('button');
  131. removeButton.appendChild(document.createTextNode(bundle.GetStringFromName('remove')));
  132. removeButton.onclick = function() {
  133. removeProfile(profileData.profile);
  134. };
  135. div.appendChild(removeButton);
  136. }
  137. if (!profileData.isDefault) {
  138. let defaultButton = document.createElement('button');
  139. defaultButton.appendChild(document.createTextNode(bundle.GetStringFromName('setAsDefault')));
  140. defaultButton.onclick = function() {
  141. defaultProfile(profileData.profile);
  142. };
  143. div.appendChild(defaultButton);
  144. }
  145. if (!profileData.isCurrentProfile) {
  146. let runButton = document.createElement('button');
  147. runButton.appendChild(document.createTextNode(bundle.GetStringFromName('launchProfile')));
  148. runButton.onclick = function() {
  149. openProfile(profileData.profile);
  150. };
  151. div.appendChild(runButton);
  152. }
  153. let sep = document.createElement('hr');
  154. div.appendChild(sep);
  155. }
  156. function CreateProfile(profile) {
  157. ProfileService.selectedProfile = profile;
  158. ProfileService.flush();
  159. refreshUI();
  160. }
  161. function createProfileWizard() {
  162. // This should be rewritten in HTML eventually.
  163. window.openDialog('chrome://mozapps/content/profile/createProfileWizard.xul',
  164. '', 'centerscreen,chrome,modal,titlebar',
  165. ProfileService);
  166. }
  167. function renameProfile(profile) {
  168. let title = bundle.GetStringFromName('renameProfileTitle');
  169. let msg = bundle.formatStringFromName('renameProfile', [profile.name], 1);
  170. let newName = { value: profile.name };
  171. if (Services.prompt.prompt(window, title, msg, newName, null,
  172. { value: 0 })) {
  173. newName = newName.value;
  174. if (newName == profile.name) {
  175. return;
  176. }
  177. try {
  178. profile.name = newName;
  179. } catch (e) {
  180. let title = bundle.GetStringFromName('invalidProfileNameTitle');
  181. let msg = bundle.formatStringFromName('invalidProfileName', [newName], 1);
  182. Services.prompt.alert(window, title, msg);
  183. return;
  184. }
  185. ProfileService.flush();
  186. refreshUI();
  187. }
  188. }
  189. function removeProfile(profile) {
  190. let deleteFiles = false;
  191. if (profile.rootDir.exists()) {
  192. let title = bundle.GetStringFromName('deleteProfileTitle');
  193. let msg = bundle.formatStringFromName('deleteProfileConfirm',
  194. [profile.rootDir.path], 1);
  195. let buttonPressed = Services.prompt.confirmEx(window, title, msg,
  196. (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0) +
  197. (Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1) +
  198. (Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_2),
  199. bundle.GetStringFromName('dontDeleteFiles'),
  200. null,
  201. bundle.GetStringFromName('deleteFiles'),
  202. null, {value:0});
  203. if (buttonPressed == 1) {
  204. return;
  205. }
  206. if (buttonPressed == 2) {
  207. deleteFiles = true;
  208. }
  209. }
  210. // If we are deleting the selected or the default profile we must choose a
  211. // different one.
  212. let isSelected = false;
  213. try {
  214. isSelected = ProfileService.selectedProfile == profile;
  215. } catch (e) {}
  216. let isDefault = false;
  217. try {
  218. isDefault = ProfileService.defaultProfile == profile;
  219. } catch (e) {}
  220. if (isSelected || isDefault) {
  221. let itr = ProfileService.profiles;
  222. while (itr.hasMoreElements()) {
  223. let p = itr.getNext().QueryInterface(Ci.nsIToolkitProfile);
  224. if (profile == p) {
  225. continue;
  226. }
  227. if (isSelected) {
  228. ProfileService.selectedProfile = p;
  229. }
  230. if (isDefault) {
  231. ProfileService.defaultProfile = p;
  232. }
  233. break;
  234. }
  235. }
  236. profile.remove(deleteFiles);
  237. ProfileService.flush();
  238. refreshUI();
  239. }
  240. function defaultProfile(profile) {
  241. ProfileService.defaultProfile = profile;
  242. ProfileService.selectedProfile = profile;
  243. ProfileService.flush();
  244. refreshUI();
  245. }
  246. function openProfile(profile) {
  247. let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
  248. .createInstance(Ci.nsISupportsPRBool);
  249. Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
  250. if (cancelQuit.data) {
  251. return;
  252. }
  253. Services.startup.createInstanceWithProfile(profile);
  254. }
  255. function restart(safeMode) {
  256. let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"]
  257. .createInstance(Ci.nsISupportsPRBool);
  258. Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
  259. if (cancelQuit.data) {
  260. return;
  261. }
  262. let flags = Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestartNotSameProfile;
  263. if (safeMode) {
  264. Services.startup.restartInSafeMode(flags);
  265. } else {
  266. Services.startup.quit(flags);
  267. }
  268. }
  269. window.addEventListener('DOMContentLoaded', function load() {
  270. window.removeEventListener('DOMContentLoaded', load);
  271. refreshUI();
  272. });