summaryrefslogtreecommitdiffstats
path: root/comm/suite/components/pref/content
diff options
context:
space:
mode:
Diffstat (limited to 'comm/suite/components/pref/content')
-rw-r--r--comm/suite/components/pref/content/pref-advanced.js90
-rw-r--r--comm/suite/components/pref/content/pref-advanced.xul174
-rw-r--r--comm/suite/components/pref/content/pref-appearance.js102
-rw-r--r--comm/suite/components/pref/content/pref-appearance.xul103
-rw-r--r--comm/suite/components/pref/content/pref-applicationManager.js100
-rw-r--r--comm/suite/components/pref/content/pref-applicationManager.xul56
-rw-r--r--comm/suite/components/pref/content/pref-applications.js1606
-rw-r--r--comm/suite/components/pref/content/pref-applications.xul113
-rw-r--r--comm/suite/components/pref/content/pref-cache.js113
-rw-r--r--comm/suite/components/pref/content/pref-cache.xul142
-rw-r--r--comm/suite/components/pref/content/pref-colors.js26
-rw-r--r--comm/suite/components/pref/content/pref-colors.xul131
-rw-r--r--comm/suite/components/pref/content/pref-content.js141
-rw-r--r--comm/suite/components/pref/content/pref-content.xul131
-rw-r--r--comm/suite/components/pref/content/pref-cookies.js34
-rw-r--r--comm/suite/components/pref/content/pref-cookies.xul89
-rw-r--r--comm/suite/components/pref/content/pref-debugging.js15
-rw-r--r--comm/suite/components/pref/content/pref-debugging.xul120
-rw-r--r--comm/suite/components/pref/content/pref-download.js197
-rw-r--r--comm/suite/components/pref/content/pref-download.xul120
-rw-r--r--comm/suite/components/pref/content/pref-findasyoutype.js15
-rw-r--r--comm/suite/components/pref/content/pref-findasyoutype.xul70
-rw-r--r--comm/suite/components/pref/content/pref-fonts.js220
-rw-r--r--comm/suite/components/pref/content/pref-fonts.xul260
-rw-r--r--comm/suite/components/pref/content/pref-history.js55
-rw-r--r--comm/suite/components/pref/content/pref-history.xul99
-rw-r--r--comm/suite/components/pref/content/pref-http.js42
-rw-r--r--comm/suite/components/pref/content/pref-http.xul82
-rw-r--r--comm/suite/components/pref/content/pref-images.xul47
-rw-r--r--comm/suite/components/pref/content/pref-keynav.js54
-rw-r--r--comm/suite/components/pref/content/pref-keynav.xul104
-rw-r--r--comm/suite/components/pref/content/pref-languages-add.js147
-rw-r--r--comm/suite/components/pref/content/pref-languages-add.xul54
-rw-r--r--comm/suite/components/pref/content/pref-languages.js200
-rw-r--r--comm/suite/components/pref/content/pref-languages.xul124
-rw-r--r--comm/suite/components/pref/content/pref-links.js15
-rw-r--r--comm/suite/components/pref/content/pref-links.xul78
-rw-r--r--comm/suite/components/pref/content/pref-locationbar.js42
-rw-r--r--comm/suite/components/pref/content/pref-locationbar.xul127
-rw-r--r--comm/suite/components/pref/content/pref-media.xul60
-rw-r--r--comm/suite/components/pref/content/pref-mousewheel.js45
-rw-r--r--comm/suite/components/pref/content/pref-mousewheel.xul298
-rw-r--r--comm/suite/components/pref/content/pref-navigator.js262
-rw-r--r--comm/suite/components/pref/content/pref-navigator.xul188
-rw-r--r--comm/suite/components/pref/content/pref-offlineapps.js178
-rw-r--r--comm/suite/components/pref/content/pref-offlineapps.xul81
-rw-r--r--comm/suite/components/pref/content/pref-popups.js95
-rw-r--r--comm/suite/components/pref/content/pref-popups.xul132
-rw-r--r--comm/suite/components/pref/content/pref-privatedata.js30
-rw-r--r--comm/suite/components/pref/content/pref-privatedata.xul181
-rw-r--r--comm/suite/components/pref/content/pref-proxies-advanced.xul194
-rw-r--r--comm/suite/components/pref/content/pref-proxies.js188
-rw-r--r--comm/suite/components/pref/content/pref-proxies.xul156
-rw-r--r--comm/suite/components/pref/content/pref-scripts.js29
-rw-r--r--comm/suite/components/pref/content/pref-scripts.xul92
-rwxr-xr-xcomm/suite/components/pref/content/pref-search.js60
-rwxr-xr-xcomm/suite/components/pref/content/pref-search.xul50
-rw-r--r--comm/suite/components/pref/content/pref-security.js15
-rw-r--r--comm/suite/components/pref/content/pref-security.xul108
-rw-r--r--comm/suite/components/pref/content/pref-smartupdate.js87
-rw-r--r--comm/suite/components/pref/content/pref-smartupdate.xul139
-rw-r--r--comm/suite/components/pref/content/pref-spelling.js119
-rw-r--r--comm/suite/components/pref/content/pref-spelling.xul80
-rw-r--r--comm/suite/components/pref/content/pref-sync.js143
-rw-r--r--comm/suite/components/pref/content/pref-sync.xul158
-rw-r--r--comm/suite/components/pref/content/pref-tabs.xul113
-rw-r--r--comm/suite/components/pref/content/preferences.js99
-rw-r--r--comm/suite/components/pref/content/preferences.xul264
-rwxr-xr-xcomm/suite/components/pref/content/prefpanels.css33
-rw-r--r--comm/suite/components/pref/content/prefpanels.xml59
70 files changed, 9174 insertions, 0 deletions
diff --git a/comm/suite/components/pref/content/pref-advanced.js b/comm/suite/components/pref/content/pref-advanced.js
new file mode 100644
index 0000000000..1f1c290329
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-advanced.js
@@ -0,0 +1,90 @@
+/* -*- Mode: Java; 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/. */
+
+const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+const {ShellService} = ChromeUtils.import("resource:///modules/ShellService.jsm");
+
+var defaultClient = 0;
+var defaultApps = 0;
+
+function Startup()
+{
+ InitPlatformIntegration();
+ CrashReportsCheck();
+}
+
+/**
+ * System preferences
+ */
+
+function InitPlatformIntegration() {
+ if (ShellService) {
+ try {
+ this.defaultApps = ShellService.shouldBeDefaultClientFor;
+ ["Browser", "Mail", "News", "Rss"].forEach(function(aType) {
+ let button = document.getElementById("setDefault" + aType);
+ try {
+ let client = Ci.nsIShellService[aType.toUpperCase()];
+ let isDefault = ShellService.isDefaultClient(false, client);
+ if (isDefault) {
+ this.defaultClient |= client;
+ }
+ button.disabled = isDefault;
+ document.getElementById("defaultClientGroup").hidden = false;
+ } catch (e) {
+ button.hidden = true;
+ }
+ });
+ } catch (e) {
+ }
+ }
+}
+
+function ApplySetAsDefaultClient() {
+ let pane = document.getElementById("advanced_pane");
+ ShellService.setDefaultClient(false, false, pane.defaultClient);
+ ShellService.shouldBeDefaultClientFor = pane.defaultApps;
+}
+
+function onSetDefault(aButton, aType) {
+ if (document.documentElement.instantApply) {
+ ShellService.setDefaultClient(false, false, Ci.nsIShellService[aType]);
+ ShellService.shouldBeDefaultClientFor |= Ci.nsIShellService[aType];
+ } else {
+ this.defaultClient |= Ci.nsIShellService[aType];
+ this.defaultApps |= Ci.nsIShellService[aType];
+ window.addEventListener("dialogaccept", this.ApplySetAsDefaultClient, true);
+ }
+
+ aButton.disabled = true;
+}
+
+function onNewsChange(aChecked) {
+ let snws = document.getElementById("network.protocol-handler.external.snews");
+ let nntp = document.getElementById("network.protocol-handler.external.nntp");
+
+ if (!snws.locked)
+ snws.value = aChecked;
+
+ if (!nntp.locked)
+ nntp.value = aChecked;
+}
+
+function CrashReportsCheck()
+{
+ if (AppConstants.MOZ_CRASHREPORTER) {
+ var cr = Cc["@mozilla.org/toolkit/crash-reporter;1"]
+ .getService(Ci.nsICrashReporter);
+ document.getElementById("crashReports").hidden = !cr.enabled;
+ document.getElementById("submitCrashes").checked = cr.submitReports;
+ }
+}
+
+function updateSubmitCrashes(aChecked)
+{
+ Cc["@mozilla.org/toolkit/crash-reporter;1"]
+ .getService(Ci.nsICrashReporter)
+ .submitReports = aChecked;
+}
diff --git a/comm/suite/components/pref/content/pref-advanced.xul b/comm/suite/components/pref/content/pref-advanced.xul
new file mode 100644
index 0000000000..6b77581e4c
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-advanced.xul
@@ -0,0 +1,174 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> %brandDTD;
+ <!ENTITY % prefAdvancedDTD SYSTEM "chrome://communicator/locale/pref/pref-advanced.dtd"> %prefAdvancedDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="advanced_pane"
+ label="&pref.advanced.title;"
+ script="chrome://communicator/content/pref/pref-advanced.js">
+
+ <preferences id="advanced_preferences">
+ <preference id="shell.checkDefaultClient"
+ name="shell.checkDefaultClient"
+ type="bool"/>
+ <preference id="pref.browser.disable_button.default_browser"
+ name="pref.browser.disable_button.default_browser"
+ type="bool"
+ readonly="true"/>
+ <preference id="system.windows.lock_ui.defaultMailClient"
+ name="system.windows.lock_ui.defaultMailClient"
+ type="bool"
+ readonly="true"/>
+ <preference id="system.windows.lock_ui.defaultNewsClient"
+ name="system.windows.lock_ui.defaultNewsClient"
+ type="bool"
+ readonly="true"/>
+ <preference id="system.windows.lock_ui.defaultFeedClient"
+ name="system.windows.lock_ui.defaultFeedClient"
+ type="bool"
+ readonly="true"/>
+ <preference id="network.protocol-handler.external.mailto"
+ name="network.protocol-handler.external.mailto"
+ type="bool"
+ inverted="true"/>
+ <preference id="network.protocol-handler.external.news"
+ name="network.protocol-handler.external.news"
+ type="bool"
+ inverted="true"/>
+ <preference id="network.protocol-handler.external.snews"
+ name="network.protocol-handler.external.snews"
+ type="bool"
+ inverted="true"/>
+ <preference id="network.protocol-handler.external.nntp"
+ name="network.protocol-handler.external.nntp"
+ type="bool"
+ inverted="true"/>
+ <preference id="print.use_native_print_dialog"
+ name="print.use_native_print_dialog"
+ type="bool"/>
+ <preference id="print.use_global_printsettings"
+ name="print.use_global_printsettings"
+ type="bool"/>
+ <preference id="devtools.debugger.remote-enabled"
+ name="devtools.debugger.remote-enabled"
+ type="bool"/>
+ <preference id="devtools.debugger.force-local"
+ name="devtools.debugger.force-local"
+ inverted="true"
+ type="bool"/>
+ <preference id="devtools.debugger.prompt-connection"
+ name="devtools.debugger.prompt-connection"
+ type="bool"/>
+ <preference id="devtools.debugger.remote-port"
+ name="devtools.debugger.remote-port"
+ type="int"/>
+ </preferences>
+
+ <groupbox id="defaultClientGroup" hidden="true">
+ <caption label="&prefCheckDefault.caption;"/>
+ <checkbox id="checkDefaultClient"
+ label="&prefCheckDefaultClient.label;"
+ accesskey="&prefCheckDefaultClient.accesskey;"
+ preference="shell.checkDefaultClient"/>
+ <vbox>
+ <separator class="thin"/>
+
+ <description>&defaultClientFor.description;</description>
+ <hbox class="indent" align="center">
+ <button id="setDefaultBrowser"
+ label="&setDefaultBrowser.label;"
+ accesskey="&setDefaultBrowser.accesskey;"
+ oncommand="onSetDefault(this, 'BROWSER');"
+ preference="pref.browser.disable_button.default_browser"/>
+ <button id="setDefaultMail"
+ label="&setDefaultMail.label;"
+ accesskey="&setDefaultMail.accesskey;"
+ oncommand="onSetDefault(this, 'MAIL');"
+ preference="system.windows.lock_ui.defaultMailClient"/>
+ <button id="setDefaultNews"
+ label="&setDefaultNews.label;"
+ accesskey="&setDefaultNews.accesskey;"
+ oncommand="onSetDefault(this, 'NEWS');"
+ preference="system.windows.lock_ui.defaultNewsClient"/>
+ <button id="setDefaultRss"
+ label="&setDefaultFeed.label;"
+ accesskey="&setDefaultFeed.accesskey;"
+ oncommand="onSetDefault(this, 'RSS');"
+ preference="system.windows.lock_ui.defaultFeedClient"/>
+ </hbox>
+ </vbox>
+
+ <separator class="thin"/>
+
+ <description>&useInternalSettings.description;</description>
+ <hbox class="indent" align="center">
+ <checkbox id="useInternalMail"
+ label="&useInternalMail.label;"
+ accesskey="&useInternalMail.accesskey;"
+ preference="network.protocol-handler.external.mailto"/>
+ <checkbox id="useInternalNews"
+ label="&useInternalNews.label;"
+ accesskey="&useInternalNews.accesskey;"
+ oncommand="onNewsChange(this.checked);"
+ preference="network.protocol-handler.external.news"/>
+ </hbox>
+ </groupbox>
+
+ <groupbox id="printing">
+ <caption label="&printing.label;"/>
+ <checkbox id="nglayoutUseNativePrintDialog"
+ label="&useNativePrintDialog.label;"
+ accesskey="&useNativePrintDialog.accesskey;"
+ preference="print.use_native_print_dialog"/>
+ <checkbox id="printUseGlobalPrintSettings"
+ label="&useGlobalPrintSettings.label;"
+ accesskey="&useGlobalPrintSettings.accesskey;"
+ preference="print.use_global_printsettings"/>
+ </groupbox>
+
+ <groupbox id="crashReports" hidden="true">
+ <caption id="crashReportsCaption" label="&crashReports.caption;"/>
+ <checkbox id="submitCrashes"
+ label="&submitCrashes.label;"
+ accesskey="&submitCrashes.accesskey;"
+ oncommand="updateSubmitCrashes(this.checked);"/>
+ </groupbox>
+
+ <groupbox id="devTools">
+ <caption id="devToolsCaption" label="&devTools.caption;"/>
+ <checkbox id="allowDebugger"
+ label="&allowDebugger.label;"
+ accesskey="&allowDebugger.accesskey;"
+ preference="devtools.debugger.remote-enabled"/>
+ <checkbox id="allowRemoteConnections"
+ label="&allowRemoteConnections.label;"
+ accesskey="&allowRemoteConnections.accesskey;"
+ preference="devtools.debugger.force-local"/>
+ <checkbox id="connectionPrompt"
+ label="&connectionPrompt.label;"
+ accesskey="&connectionPrompt.accesskey;"
+ preference="devtools.debugger.prompt-connection"/>
+
+ <hbox align="center">
+ <label id="remoteDebuggerPortBefore"
+ value="&remoteDebuggerPort.label;"
+ accesskey="&remoteDebuggerPort.accesskey;"
+ control="remoteDebuggerPort"/>
+ <textbox id="remoteDebuggerPort"
+ type="number"
+ min="0"
+ max="65535"
+ size="5"
+ preference="devtools.debugger.remote-port"
+ aria-labelledby="remoteDebuggerPortBefore remoteDebuggerPort"/>
+ </hbox>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-appearance.js b/comm/suite/components/pref/content/pref-appearance.js
new file mode 100644
index 0000000000..a54b14786d
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-appearance.js
@@ -0,0 +1,102 @@
+/* -*- Mode: Java; 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/. */
+
+// Load spell-checker module to properly determine language strings
+var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+function Startup()
+{
+ SwitchLocales_Load();
+ NumberLocales_Load();
+}
+
+/**
+ * From locale switcher's switch.js:
+ * Load available locales into selection menu
+ */
+function SwitchLocales_Load() {
+ var menulist = document.getElementById("switchLocales");
+
+ var cr = Cc["@mozilla.org/chrome/chrome-registry;1"]
+ .getService(Ci.nsIToolkitChromeRegistry);
+
+ var langNames = document.getElementById("languageNamesBundle");
+ var regNames = document.getElementById("regionNamesBundle");
+
+ var matched = false;
+ var currentLocale = Services.locale.getRequestedLocale() || undefined;
+ var locales = cr.getLocalesForPackage("global");
+
+ while (locales.hasMore()) {
+ var locale = locales.getNext();
+
+ var parts = locale.split(/-/);
+
+ var displayName;
+ try {
+ displayName = langNames.getString(parts[0]);
+ if (parts.length > 1) {
+ try {
+ displayName += " (" + regNames.getString(parts[1].toLowerCase()) + ")";
+ }
+ catch (e) {
+ displayName += " (" + parts[1] + ")";
+ }
+ }
+ }
+ catch (e) {
+ displayName = locale;
+ }
+
+ var item = menulist.appendItem(displayName, locale);
+ if (!matched && currentLocale && currentLocale == locale) {
+ matched = true;
+ menulist.selectedItem = item;
+ }
+ }
+ // If somehow we have not found the current locale, select the first in list.
+ if (!matched) {
+ menulist.selectedIndex = 1;
+ }
+}
+
+/**
+ * Determine the appropriate value to set and set it.
+ */
+function SelectLocale(aElement) {
+ var locale = aElement.value;
+ var currentLocale = Services.locale.getRequestedLocale() || undefined;
+ if (!currentLocale || (currentLocale && currentLocale != locale)) {
+ Services.locale.setRequestedLocales([locale]);
+ }
+}
+
+/**
+ * When starting up, determine application and regional locale settings
+ * and add the respective strings to the prefpane labels.
+ */
+function NumberLocales_Load()
+{
+ const osprefs =
+ Cc["@mozilla.org/intl/ospreferences;1"]
+ .getService(Ci.mozIOSPreferences);
+
+ let appLocale = Services.locale.appLocalesAsBCP47[0];
+ let rsLocale = osprefs.regionalPrefsLocales[0];
+ let names = Services.intl.getLocaleDisplayNames(undefined, [appLocale, rsLocale]);
+
+ let appLocaleRadio = document.getElementById("appLocale");
+ let rsLocaleRadio = document.getElementById("rsLocale");
+ let prefutilitiesBundle = document.getElementById("bundle_prefutilities");
+
+ let appLocaleLabel = prefutilitiesBundle.getFormattedString("appLocale.label",
+ [names[0]]);
+ let rsLocaleLabel = prefutilitiesBundle.getFormattedString("rsLocale.label",
+ [names[1]]);
+ appLocaleRadio.setAttribute("label", appLocaleLabel);
+ rsLocaleRadio.setAttribute("label", rsLocaleLabel);
+ appLocaleRadio.accessKey = prefutilitiesBundle.getString("appLocale.accesskey");
+ rsLocaleRadio.accessKey = prefutilitiesBundle.getString("rsLocale.accesskey");
+}
diff --git a/comm/suite/components/pref/content/pref-appearance.xul b/comm/suite/components/pref/content/pref-appearance.xul
new file mode 100644
index 0000000000..132e0a614e
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-appearance.xul
@@ -0,0 +1,103 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> %brandDTD;
+ <!ENTITY % prefAppearanceDTD SYSTEM "chrome://communicator/locale/pref/pref-appearance.dtd"> %prefAppearanceDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="appearance_pane"
+ label="&pref.appearance.title;"
+ script="chrome://communicator/content/pref/pref-appearance.js">
+
+ <preferences id="appearance_preferences">
+ <preference id="general.startup.browser"
+ name="general.startup.browser"
+ type="bool"/>
+ <preference id="browser.chrome.toolbar_style"
+ name="browser.chrome.toolbar_style"
+ type="int"/>
+ <preference id="browser.chrome.toolbar_tips"
+ name="browser.chrome.toolbar_tips"
+ type="bool"/>
+ <preference id="browser.toolbars.grippyhidden"
+ name="browser.toolbars.grippyhidden"
+ type="bool"/>
+ <preference id="intl.regional_prefs.use_os_locales"
+ name="intl.regional_prefs.use_os_locales"
+ type="bool"/>
+ </preferences>
+
+ <hbox>
+ <groupbox id="generalStartupPreferences" align="start" flex="1">
+ <caption label="&onStartLegend.label;"/>
+
+ <checkbox id="generalStartupBrowser"
+ label="&navCheck.label;"
+ accesskey="&navCheck.accesskey;"
+ preference="general.startup.browser"/>
+ </groupbox>
+
+ <groupbox id="toolbarStyleBox" align="start" flex="1">
+ <caption label="&showToolsLegend.label;"/>
+
+ <radiogroup id="toolbarStyle"
+ preference="browser.chrome.toolbar_style">
+ <radio value="2"
+ label="&picsNtextRadio.label;"
+ accesskey="&picsNtextRadio.accesskey;"/>
+ <radio value="0"
+ label="&picsOnlyRadio.label;"
+ accesskey="&picsOnlyRadio.accesskey;"/>
+ <radio value="1"
+ label="&textonlyRadio.label;"
+ accesskey="&textonlyRadio.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+ </hbox>
+
+ <vbox class="box-padded" align="start">
+ <checkbox id="showHideTooltips"
+ label="&showHideTooltips.label;"
+ accesskey="&showHideTooltips.accesskey;"
+ preference="browser.chrome.toolbar_tips"/>
+ </vbox>
+#ifndef XP_MACOSX
+ <vbox class="box-padded"
+ align="start">
+ <checkbox id="showHideGrippies"
+ label="&showHideGrippies.label;"
+ accesskey="&showHideGrippies.accesskey;"
+ preference="browser.toolbars.grippyhidden"/>
+ </vbox>
+#endif
+ <groupbox id="switchLocaleBox" align="start">
+ <caption label="&pref.locales.title;"/>
+ <description>&selectLocale.label;</description>
+
+ <menulist id="switchLocales"
+ onselect="SelectLocale(this);"/>
+
+ </groupbox>
+
+ <groupbox id="dateTimeFormatting" align="start">
+ <caption label="&dateTimeFormatting.label;"/>
+ <radiogroup id="formatLocale"
+ preference="intl.regional_prefs.use_os_locales"
+ orient="vertical">
+ <radio id="appLocale"
+ value="false"/>
+ <!-- label and accesskey will be set dynamically -->
+ <radio id="rsLocale"
+ value="true"/>
+ <!-- label and accesskey will be set dynamically -->
+ </radiogroup>
+ </groupbox>
+
+ <description>&restartOnLocaleChange.label;</description>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-applicationManager.js b/comm/suite/components/pref/content/pref-applicationManager.js
new file mode 100644
index 0000000000..83d18953ef
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-applicationManager.js
@@ -0,0 +1,100 @@
+/* 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 { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+var gAppManagerDialog = {
+ _removed: [],
+
+ init: function appManager_init() {
+ this.handlerInfo = window.arguments[0];
+
+ var bundle = document.getElementById("appManagerBundle");
+ var contentText;
+ if (this.handlerInfo.type == TYPE_MAYBE_FEED)
+ contentText = bundle.getString("descriptionHandleWebFeeds");
+ else {
+ var description = gApplicationsPane._describeType(this.handlerInfo);
+ var key =
+ (this.handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo) ?
+ "descriptionHandleFile" :
+ "descriptionHandleProtocol";
+ contentText = bundle.getFormattedString(key, [description]);
+ }
+ document.getElementById("appDescription").textContent = contentText;
+
+ var list = document.getElementById("appList");
+ var apps = this.handlerInfo.possibleApplicationHandlers.enumerate();
+ while (apps.hasMoreElements()) {
+ let app = apps.getNext();
+ if (!gApplicationsPane.isValidHandlerApp(app))
+ continue;
+
+ app.QueryInterface(Ci.nsIHandlerApp);
+ var item = list.appendItem(app.name);
+ item.className = "listitem-iconic";
+ item.setAttribute("image",
+ gApplicationsPane._getIconURLForHandlerApp(app));
+ item.app = app;
+ }
+
+ list.selectedIndex = 0;
+ },
+
+ onOK: function appManager_onOK() {
+ if (!this._removed.length) {
+ // return early to avoid calling the |store| method.
+ return;
+ }
+
+ for (var i = 0; i < this._removed.length; ++i)
+ this.handlerInfo.removePossibleApplicationHandler(this._removed[i]);
+
+ this.handlerInfo.store();
+ },
+
+ onCancel: function appManager_onCancel() {
+ // do nothing
+ },
+
+ remove: function appManager_remove() {
+ var list = document.getElementById("appList");
+ this._removed.push(list.selectedItem.app);
+ var index = list.selectedIndex;
+ list.removeItemAt(index);
+ if (list.getRowCount() == 0) {
+ // The list is now empty, make the bottom part disappear
+ document.getElementById("appDetails").hidden = true;
+ }
+ else {
+ // Select the item at the same index, if we removed the last
+ // item of the list, select the previous item
+ if (index == list.getRowCount())
+ --index;
+ list.selectedIndex = index;
+ }
+ },
+
+ onSelect: function appManager_onSelect() {
+ var list = document.getElementById("appList");
+ if (!list.selectedItem) {
+ document.getElementById("cmd_delete").setAttribute("disabled", "true");
+ return;
+ }
+ document.getElementById("cmd_delete").removeAttribute("disabled");
+ var app = list.selectedItem.app;
+ var address = "";
+ if (app instanceof Ci.nsILocalHandlerApp)
+ address = app.executable.path;
+ else if (app instanceof Ci.nsIWebHandlerApp)
+ address = app.uriTemplate;
+ else if (app instanceof Ci.nsIWebContentHandlerInfo)
+ address = app.uri;
+ document.getElementById("appLocation").value = address;
+ var bundle = document.getElementById("appManagerBundle");
+ var appType = app instanceof Ci.nsILocalHandlerApp ? "descriptionLocalApp"
+ : "descriptionWebApp";
+ document.getElementById("appType").value = bundle.getString(appType);
+ }
+};
diff --git a/comm/suite/components/pref/content/pref-applicationManager.xul b/comm/suite/components/pref/content/pref-applicationManager.xul
new file mode 100644
index 0000000000..38988e1080
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-applicationManager.xul
@@ -0,0 +1,56 @@
+<?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://communicator/skin/"?>
+
+<!DOCTYPE dialog SYSTEM "chrome://communicator/locale/pref/pref-applicationManager.dtd">
+
+<dialog id="appManager"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ buttons="accept,cancel"
+ onload="gAppManagerDialog.init();"
+ ondialogaccept="gAppManagerDialog.onOK();"
+ ondialogcancel="gAppManagerDialog.onCancel();"
+ title="&appManager.title;"
+ style="&appManager.style;"
+ persist="screenX screenY">
+
+ <script src="chrome://communicator/content/pref/pref-applications.js"/>
+ <script src="chrome://communicator/content/pref/pref-applicationManager.js"/>
+
+ <commandset id="appManagerCommandSet">
+ <command id="cmd_delete"
+ oncommand="gAppManagerDialog.remove();"
+ disabled="true"/>
+ </commandset>
+
+ <keyset id="appManagerKeyset">
+ <key id="delete" keycode="VK_DELETE" command="cmd_delete"/>
+ </keyset>
+
+ <stringbundleset id="appManagerBundleset">
+ <stringbundle id="appManagerBundle"
+ src="chrome://communicator/locale/pref/pref-applicationManager.properties"/>
+ </stringbundleset>
+
+ <description id="appDescription"/>
+ <separator class="thin"/>
+ <hbox flex="1">
+ <listbox id="appList" onselect="gAppManagerDialog.onSelect();" flex="1"/>
+ <vbox>
+ <button id="remove"
+ label="&remove.label;"
+ accesskey="&remove.accesskey;"
+ command="cmd_delete"/>
+ <spacer flex="1"/>
+ </vbox>
+ </hbox>
+ <vbox id="appDetails">
+ <separator class="thin"/>
+ <label id="appType"/>
+ <textbox id="appLocation" readonly="true" class="plain"/>
+ </vbox>
+</dialog>
diff --git a/comm/suite/components/pref/content/pref-applications.js b/comm/suite/components/pref/content/pref-applications.js
new file mode 100644
index 0000000000..b3ca0d71fd
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-applications.js
@@ -0,0 +1,1606 @@
+/* -*- Mode: Java; tab-width: 2; 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/. */
+
+const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+const {ShellService} = ChromeUtils.import("resource:///modules/ShellService.jsm");
+// Needed as this script is also loaded by pref-applicationManager.xul.
+const {XPCOMUtils} =
+ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function Startup()
+{
+ gApplicationsPane.init();
+}
+
+XPCOMUtils.defineLazyServiceGetters(this, {
+ gCategoryManager: ["@mozilla.org/categorymanager;1", "nsICategoryManager"],
+ gHandlerService: ["@mozilla.org/uriloader/handler-service;1", "nsIHandlerService"],
+ gMIMEService: ["@mozilla.org/mime;1", "nsIMIMEService"],
+ gWebContentConverterService: ["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1", "nsIWebContentConverterService"],
+});
+
+//****************************************************************************//
+// Constants & Enumeration Values
+
+const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
+const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
+const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
+
+/*
+ * Preferences where we store handling information about the feed type.
+ *
+ * browser.feeds.handler
+ * - "messenger", "reader" (clarified further using the .default preference),
+ * or "ask" -- indicates the default handler being used to process feeds;
+ * "messenger" is obsolete, use "reader" instead; to specify that the
+ * handler is messenger, set browser.feeds.handler.default to "messenger";
+ *
+ * browser.feeds.handler.default
+ * - "messenger", "client" or "web" -- indicates the chosen feed reader used
+ * to display feeds, either transiently (i.e., when the "use as default"
+ * checkbox is unchecked, corresponds to when browser.feeds.handler=="ask")
+ * or more permanently (i.e., the item displayed in the dropdown in Feeds
+ * preferences)
+ *
+ * browser.feeds.handler.webservice
+ * - the URL of the currently selected web service used to read feeds
+ *
+ * browser.feeds.handlers.application
+ * - nsIFile, stores the current client-side feed reading app if one has
+ * been chosen
+ */
+const PREF_FEED_SELECTED_APP = "browser.feeds.handlers.application";
+const PREF_FEED_SELECTED_WEB = "browser.feeds.handlers.webservice";
+const PREF_FEED_SELECTED_ACTION = "browser.feeds.handler";
+const PREF_FEED_SELECTED_READER = "browser.feeds.handler.default";
+
+const PREF_VIDEO_FEED_SELECTED_APP = "browser.videoFeeds.handlers.application";
+const PREF_VIDEO_FEED_SELECTED_WEB = "browser.videoFeeds.handlers.webservice";
+const PREF_VIDEO_FEED_SELECTED_ACTION = "browser.videoFeeds.handler";
+const PREF_VIDEO_FEED_SELECTED_READER = "browser.videoFeeds.handler.default";
+
+const PREF_AUDIO_FEED_SELECTED_APP = "browser.audioFeeds.handlers.application";
+const PREF_AUDIO_FEED_SELECTED_WEB = "browser.audioFeeds.handlers.webservice";
+const PREF_AUDIO_FEED_SELECTED_ACTION = "browser.audioFeeds.handler";
+const PREF_AUDIO_FEED_SELECTED_READER = "browser.audioFeeds.handler.default";
+
+// The nsHandlerInfoAction enumeration values in nsIHandlerInfo identify
+// the actions the application can take with content of various types.
+const kActionChooseApp = -2;
+const kActionManageApp = -1;
+
+//****************************************************************************//
+// Utilities
+
+function getFileDisplayName(aFile) {
+ if (AppConstants.platform == "win" &&
+ aFile instanceof Ci.nsILocalFileWin) {
+ try {
+ return aFile.getVersionInfoField("FileDescription");
+ } catch (e) {}
+ } else if (AppConstants.platform == "macosx" &&
+ aFile instanceof Ci.nsILocalFileMac) {
+ try {
+ return aFile.bundleDisplayName;
+ } catch (e) {}
+ }
+ return aFile.leafName;
+}
+
+function getLocalHandlerApp(aFile) {
+ var localHandlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]
+ .createInstance(Ci.nsILocalHandlerApp);
+ localHandlerApp.name = getFileDisplayName(aFile);
+ localHandlerApp.executable = aFile;
+
+ return localHandlerApp;
+}
+
+/**
+ * An enumeration of items in a JS array.
+ *
+ * FIXME: use ArrayConverter once it lands (bug 380839).
+ *
+ * @constructor
+ */
+function ArrayEnumerator(aItems) {
+ this._index = 0;
+ this._contents = aItems;
+}
+
+ArrayEnumerator.prototype = {
+ _index: 0,
+
+ hasMoreElements: function() {
+ return this._index < this._contents.length;
+ },
+
+ getNext: function() {
+ return this._contents[this._index++];
+ }
+};
+
+function isFeedType(t) {
+ return t == TYPE_MAYBE_FEED || t == TYPE_MAYBE_VIDEO_FEED || t == TYPE_MAYBE_AUDIO_FEED;
+}
+
+//****************************************************************************//
+// HandlerInfoWrapper
+
+/**
+ * This object wraps nsIHandlerInfo with some additional functionality
+ * the Applications prefpane needs to display and allow modification of
+ * the list of handled types.
+ *
+ * We create an instance of this wrapper for each entry we might display
+ * in the prefpane, and we compose the instances from various sources,
+ * including the handler service.
+ *
+ * We don't implement all the original nsIHandlerInfo functionality,
+ * just the stuff that the prefpane needs.
+ *
+ * In theory, all of the custom functionality in this wrapper should get
+ * pushed down into nsIHandlerInfo eventually.
+ */
+function HandlerInfoWrapper(aType, aHandlerInfo) {
+ this.type = aType;
+ this.wrappedHandlerInfo = aHandlerInfo;
+}
+
+HandlerInfoWrapper.prototype = {
+ // The wrapped nsIHandlerInfo object. In general, this object is private,
+ // but there are a couple cases where callers access it directly for things
+ // we haven't (yet?) implemented, so we make it a public property.
+ wrappedHandlerInfo: null,
+
+
+ //**************************************************************************//
+ // nsIHandlerInfo
+
+ // The MIME type or protocol scheme.
+ type: null,
+
+ get description() {
+ if (this.wrappedHandlerInfo.description)
+ return this.wrappedHandlerInfo.description;
+
+ if (this.primaryExtension) {
+ var extension = this.primaryExtension.toUpperCase();
+ return gApplicationsPane._prefsBundle.getFormattedString("fileEnding",
+ [extension]);
+ }
+
+ return this.type;
+ },
+
+ get preferredApplicationHandler() {
+ return this.wrappedHandlerInfo.preferredApplicationHandler;
+ },
+
+ set preferredApplicationHandler(aNewValue) {
+ this.wrappedHandlerInfo.preferredApplicationHandler = aNewValue;
+
+ // Make sure the preferred handler is in the set of possible handlers.
+ if (aNewValue)
+ this.addPossibleApplicationHandler(aNewValue);
+ },
+
+ get possibleApplicationHandlers() {
+ return this.wrappedHandlerInfo.possibleApplicationHandlers;
+ },
+
+ addPossibleApplicationHandler(aNewHandler) {
+ var possibleApps = this.possibleApplicationHandlers.enumerate();
+ while (possibleApps.hasMoreElements()) {
+ if (possibleApps.getNext().equals(aNewHandler))
+ return;
+ }
+ this.possibleApplicationHandlers.appendElement(aNewHandler);
+ },
+
+ removePossibleApplicationHandler(aHandler) {
+ var defaultApp = this.preferredApplicationHandler;
+ if (defaultApp && aHandler.equals(defaultApp)) {
+ // If the app we remove was the default app, we must make sure
+ // it won't be used anymore
+ this.alwaysAskBeforeHandling = true;
+ this.preferredApplicationHandler = null;
+ }
+
+ var handlers = this.possibleApplicationHandlers;
+ for (var i = 0; i < handlers.length; ++i) {
+ var handler = handlers.queryElementAt(i, Ci.nsIHandlerApp);
+ if (handler.equals(aHandler)) {
+ handlers.removeElementAt(i);
+ break;
+ }
+ }
+ },
+
+ get hasDefaultHandler() {
+ return this.wrappedHandlerInfo.hasDefaultHandler;
+ },
+
+ get defaultDescription() {
+ return this.wrappedHandlerInfo.defaultDescription;
+ },
+
+ // What to do with content of this type.
+ get preferredAction() {
+ // If the action is to use a helper app, but we don't have a preferred
+ // handler app, then switch to using the system default, if any; otherwise
+ // fall back to saving to disk, which is the default action in nsMIMEInfo.
+ // Note: "save to disk" is an invalid value for protocol info objects,
+ // but the alwaysAskBeforeHandling getter will detect that situation
+ // and always return true in that case to override this invalid value.
+ if (this.wrappedHandlerInfo.preferredAction == Ci.nsIHandlerInfo.useHelperApp &&
+ !gApplicationsPane.isValidHandlerApp(this.preferredApplicationHandler)) {
+ return this.wrappedHandlerInfo.hasDefaultHandler ?
+ Ci.nsIHandlerInfo.useSystemDefault :
+ Ci.nsIHandlerInfo.saveToDisk;
+ }
+
+ return this.wrappedHandlerInfo.preferredAction;
+ },
+
+ set preferredAction(aNewValue) {
+ this.wrappedHandlerInfo.preferredAction = aNewValue;
+ },
+
+ get alwaysAskBeforeHandling() {
+ // If this is a protocol type and the preferred action is "save to disk",
+ // which is invalid for such types, then return true here to override that
+ // action. This could happen when the preferred action is to use a helper
+ // app, but the preferredApplicationHandler is invalid, and there isn't
+ // a default handler, so the preferredAction getter returns save to disk
+ // instead.
+ if (!(this.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo) &&
+ this.preferredAction == Ci.nsIHandlerInfo.saveToDisk)
+ return true;
+
+ return this.wrappedHandlerInfo.alwaysAskBeforeHandling;
+ },
+
+ set alwaysAskBeforeHandling(aNewValue) {
+ this.wrappedHandlerInfo.alwaysAskBeforeHandling = aNewValue;
+ },
+
+
+ //**************************************************************************//
+ // nsIMIMEInfo
+
+ // The primary file extension associated with this type, if any.
+ get primaryExtension() {
+ try {
+ if (this.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo &&
+ this.wrappedHandlerInfo.primaryExtension)
+ return this.wrappedHandlerInfo.primaryExtension;
+ } catch(ex) {}
+
+ return null;
+ },
+
+ //**************************************************************************//
+ // Storage
+
+ store() {
+ gHandlerService.store(this.wrappedHandlerInfo);
+ },
+
+
+ //**************************************************************************//
+ // Icons
+
+ get smallIcon() {
+ return this._getIcon(16);
+ },
+
+ get largeIcon() {
+ return this._getIcon(32);
+ },
+
+ _getIcon(aSize) {
+ if (this.primaryExtension)
+ return "moz-icon://goat." + this.primaryExtension + "?size=" + aSize;
+
+ if (this.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo)
+ return "moz-icon://goat?size=" + aSize + "&contentType=" + this.type;
+
+ // We're falling back to a generic icon when we can't get a URL for one
+ // (for example in the case of protocol schemes).
+ return null;
+ },
+
+ // The type class is used for setting icons through CSS for types that don't
+ // explicitly set their icons.
+ typeClass: "unknown"
+
+};
+
+
+//****************************************************************************//
+// Feed Handler Info
+
+/**
+ * This object implements nsIHandlerInfo for the feed types. It's a separate
+ * object because we currently store handling information for the feed type
+ * in a set of preferences rather than the nsIHandlerService-managed datastore.
+ *
+ * This object inherits from HandlerInfoWrapper in order to get functionality
+ * that isn't special to the feed type.
+ *
+ * XXX Should we inherit from HandlerInfoWrapper? After all, we override
+ * most of that wrapper's properties and methods, and we have to dance around
+ * the fact that the wrapper expects to have a wrappedHandlerInfo, which we
+ * don't provide.
+ */
+
+function FeedHandlerInfo(aMIMEType) {
+ HandlerInfoWrapper.call(this, aMIMEType, null);
+}
+
+FeedHandlerInfo.prototype = {
+ __proto__: HandlerInfoWrapper.prototype,
+
+ //**************************************************************************//
+ // nsIHandlerInfo
+
+ get description() {
+ return gApplicationsPane._prefsBundle.getString(this.typeClass);
+ },
+
+ get preferredApplicationHandler() {
+ switch (document.getElementById(this._prefSelectedReader).value) {
+ case "client":
+ var file = document.getElementById(this._prefSelectedApp).value;
+ if (file)
+ return getLocalHandlerApp(file);
+
+ return null;
+
+ case "web":
+ var uri = document.getElementById(this._prefSelectedWeb).value;
+ if (!uri)
+ return null;
+ return gWebContentConverterService.getWebContentHandlerByURI(this.type, uri);
+
+ case "messenger":
+ default:
+ // When the pref is set to messenger, we handle feeds internally,
+ // we don't forward them to a local or web handler app, so there is
+ // no preferred handler.
+ return null;
+ }
+ },
+
+ set preferredApplicationHandler(aNewValue) {
+ if (aNewValue instanceof Ci.nsILocalHandlerApp) {
+ document.getElementById(this._prefSelectedApp).value = aNewValue.executable;
+ document.getElementById(this._prefSelectedReader).value = "client";
+ }
+ else if (aNewValue instanceof Ci.nsIWebContentHandlerInfo) {
+ document.getElementById(this._prefSelectedWeb).value = aNewValue.uri;
+ document.getElementById(this._prefSelectedReader).value = "web";
+ // Make the web handler be the new "auto handler" for feeds.
+ // Note: we don't have to unregister the auto handler when the user picks
+ // a non-web handler (local app, RSS News & Blogs, etc.) because the service
+ // only uses the "auto handler" when the selected reader is a web handler.
+ // We also don't have to unregister it when the user turns on "always ask"
+ // (i.e. preview in browser), since that also overrides the auto handler.
+ gWebContentConverterService.setAutoHandler(this.type, aNewValue);
+ }
+ },
+
+ _possibleApplicationHandlers: null,
+
+ get possibleApplicationHandlers() {
+ if (this._possibleApplicationHandlers)
+ return this._possibleApplicationHandlers;
+
+ // A minimal implementation of nsIMutableArray. It only supports the two
+ // methods its callers invoke, namely appendElement, nsIArray::enumerate
+ // and nsIArray::indexOf.
+ this._possibleApplicationHandlers = {
+ _inner: [],
+ _removed: [],
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIMutableArray, Ci.nsIArray]),
+
+ get length() {
+ return this._inner.length;
+ },
+
+ enumerate: function() {
+ return new ArrayEnumerator(this._inner);
+ },
+
+ indexOf: function indexOf(startIndex, element) {
+ return this._inner.indexOf(element, startIndex);
+ },
+
+ appendElement: function(aHandlerApp) {
+ this._inner.push(aHandlerApp);
+ },
+
+ removeElementAt: function(aIndex) {
+ this._removed.push(this._inner[aIndex]);
+ this._inner.splice(aIndex, 1);
+ },
+
+ queryElementAt: function(aIndex, aInterface) {
+ return this._inner[aIndex].QueryInterface(aInterface);
+ },
+ };
+
+ // Add the selected local app if it's different from the OS default handler.
+ // Unlike for other types, we can store only one local app at a time for the
+ // feed type, since we store it in a preference that historically stores
+ // only a single path. But we display all the local apps the user chooses
+ // while the prefpane is open, only dropping the list when the user closes
+ // the prefpane, for maximum usability and consistency with other types.
+ var preferredAppFile = document.getElementById(this._prefSelectedApp).value;
+ if (preferredAppFile) {
+ let preferredApp = getLocalHandlerApp(preferredAppFile);
+ let defaultApp = this._defaultApplicationHandler;
+ if (!defaultApp || !defaultApp.equals(preferredApp))
+ this._possibleApplicationHandlers.appendElement(preferredApp);
+ }
+
+ // Add the registered web handlers. There can be any number of these.
+ var webHandlers = gWebContentConverterService.getContentHandlers(this.type);
+ for (let webHandler of webHandlers)
+ this._possibleApplicationHandlers.appendElement(webHandler);
+
+ return this._possibleApplicationHandlers;
+ },
+
+ __defaultApplicationHandler: undefined,
+ get _defaultApplicationHandler() {
+ if (this.__defaultApplicationHandler !== undefined)
+ return this.__defaultApplicationHandler;
+
+ var defaultFeedReader = null;
+ try {
+ defaultFeedReader = ShellService.defaultFeedReader;
+ }
+ catch(ex) {
+ // no default reader
+ }
+
+ if (defaultFeedReader) {
+ let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]
+ .createInstance(Ci.nsIHandlerApp);
+ handlerApp.name = getFileDisplayName(defaultFeedReader);
+ handlerApp.QueryInterface(Ci.nsILocalHandlerApp);
+ handlerApp.executable = defaultFeedReader;
+
+ this.__defaultApplicationHandler = handlerApp;
+ }
+ else {
+ this.__defaultApplicationHandler = null;
+ }
+
+ return this.__defaultApplicationHandler;
+ },
+
+ get hasDefaultHandler() {
+ try {
+ if (ShellService.defaultFeedReader)
+ return true;
+ }
+ catch(ex) {
+ // no default reader
+ }
+
+ return false;
+ },
+
+ get defaultDescription() {
+ if (this.hasDefaultHandler)
+ return this._defaultApplicationHandler.name;
+
+ // Should we instead return null?
+ return "";
+ },
+
+ // What to do with content of this type.
+ get preferredAction() {
+ switch (document.getElementById(this._prefSelectedAction).value) {
+
+ case "reader": {
+ let preferredApp = this.preferredApplicationHandler;
+ let defaultApp = this._defaultApplicationHandler;
+
+ // If we have a valid preferred app, return useSystemDefault if it's
+ // the default app; otherwise return useHelperApp.
+ if (gApplicationsPane.isValidHandlerApp(preferredApp)) {
+ if (defaultApp && defaultApp.equals(preferredApp))
+ return Ci.nsIHandlerInfo.useSystemDefault;
+
+ return Ci.nsIHandlerInfo.useHelperApp;
+ }
+
+ // The pref is set to "reader", but we don't have a valid preferred app.
+ // What do we do now? Not sure this is the best option (perhaps we
+ // should direct the user to the default app, if any), but for now let's
+ // direct the user to live bookmarks.
+ return Ci.nsIHandlerInfo.handleInternally;
+ }
+
+ // If the action is "ask", then alwaysAskBeforeHandling will override
+ // the action, so it doesn't matter what we say it is, it just has to be
+ // something that doesn't cause the controller to hide the type.
+ case "ask":
+ case "messenger":
+ default:
+ return Ci.nsIHandlerInfo.handleInternally;
+ }
+ },
+
+ set preferredAction(aNewValue) {
+ switch (aNewValue) {
+
+ case Ci.nsIHandlerInfo.handleInternally:
+ document.getElementById(this._prefSelectedReader).value = "messenger";
+ break;
+
+ case Ci.nsIHandlerInfo.useHelperApp:
+ document.getElementById(this._prefSelectedAction).value = "reader";
+ // The controller has already set preferredApplicationHandler
+ // to the new helper app.
+ break;
+
+ case Ci.nsIHandlerInfo.useSystemDefault:
+ document.getElementById(this._prefSelectedAction).value = "reader";
+ this.preferredApplicationHandler = this._defaultApplicationHandler;
+ break;
+ }
+ },
+
+ get alwaysAskBeforeHandling() {
+ return document.getElementById(this._prefSelectedAction).value == "ask";
+ },
+
+ set alwaysAskBeforeHandling(aNewValue) {
+ if (aNewValue)
+ document.getElementById(this._prefSelectedAction).value = "ask";
+ else
+ document.getElementById(this._prefSelectedAction).value = "reader";
+ },
+
+ // Whether or not we are currently storing the action selected by the user.
+ // We use this to suppress notification-triggered updates to the list when
+ // we make changes that may spawn such updates, specifically when we change
+ // the action for the feed type, which results in feed preference updates,
+ // which spawn "pref changed" notifications that would otherwise cause us
+ // to rebuild the view unnecessarily.
+ _storingAction: false,
+
+
+ //**************************************************************************//
+ // nsIMIMEInfo
+
+ primaryExtension: "xml",
+
+
+ //**************************************************************************//
+ // Storage
+
+ // Changes to the preferred action and handler take effect immediately
+ // (we write them out to the preferences right as they happen),
+ // so we when the controller calls store() after modifying the handlers,
+ // the only thing we need to store is the removal of possible handlers
+ // XXX Should we hold off on making the changes until this method gets called?
+ store() {
+ for (let app of this._possibleApplicationHandlers._removed) {
+ if (app instanceof Ci.nsILocalHandlerApp) {
+ let pref = document.getElementById(PREF_FEED_SELECTED_APP);
+ var preferredAppFile = pref.value;
+ if (preferredAppFile) {
+ let preferredApp = getLocalHandlerApp(preferredAppFile);
+ if (app.equals(preferredApp))
+ pref.reset();
+ }
+ }
+ else {
+ app.QueryInterface(Ci.nsIWebContentHandlerInfo);
+ gWebContentConverterService.removeContentHandler(app.contentType,
+ app.uri);
+ }
+ }
+ this._possibleApplicationHandlers._removed = [];
+ },
+
+
+ //**************************************************************************//
+ // Icons
+
+ smallIcon: null,
+
+ largeIcon: null,
+
+ // The type class is used for setting icons through CSS for types that don't
+ // explicitly set their icons.
+ typeClass: "webFeed",
+};
+
+var feedHandlerInfo = {
+ __proto__: new FeedHandlerInfo(TYPE_MAYBE_FEED),
+ _prefSelectedApp: PREF_FEED_SELECTED_APP,
+ _prefSelectedWeb: PREF_FEED_SELECTED_WEB,
+ _prefSelectedAction: PREF_FEED_SELECTED_ACTION,
+ _prefSelectedReader: PREF_FEED_SELECTED_READER,
+ typeClass: "webFeed",
+};
+
+var videoFeedHandlerInfo = {
+ __proto__: new FeedHandlerInfo(TYPE_MAYBE_VIDEO_FEED),
+ _prefSelectedApp: PREF_VIDEO_FEED_SELECTED_APP,
+ _prefSelectedWeb: PREF_VIDEO_FEED_SELECTED_WEB,
+ _prefSelectedAction: PREF_VIDEO_FEED_SELECTED_ACTION,
+ _prefSelectedReader: PREF_VIDEO_FEED_SELECTED_READER,
+ typeClass: "videoPodcastFeed",
+};
+
+var audioFeedHandlerInfo = {
+ __proto__: new FeedHandlerInfo(TYPE_MAYBE_AUDIO_FEED),
+ _prefSelectedApp: PREF_AUDIO_FEED_SELECTED_APP,
+ _prefSelectedWeb: PREF_AUDIO_FEED_SELECTED_WEB,
+ _prefSelectedAction: PREF_AUDIO_FEED_SELECTED_ACTION,
+ _prefSelectedReader: PREF_AUDIO_FEED_SELECTED_READER,
+ typeClass: "audioPodcastFeed",
+};
+
+
+//****************************************************************************//
+// Prefpane Controller
+
+var gApplicationsPane = {
+ // The set of types the app knows how to handle. A hash of HandlerInfoWrapper
+ // objects, indexed by type.
+ _handledTypes: {},
+
+ // The list of types we can show, sorted by the sort column/direction.
+ // An array of HandlerInfoWrapper objects. We build this list when we first
+ // load the data and then rebuild it when users change a pref that affects
+ // what types we can show or change the sort column/direction.
+ // Note: this isn't necessarily the list of types we *will* show; if the user
+ // provides a filter string, we'll only show the subset of types in this list
+ // that match that string.
+ _visibleTypes: [],
+
+ // A count of the number of times each visible type description appears.
+ // We use these counts to determine whether or not to annotate descriptions
+ // with their types to distinguish duplicate descriptions from each other.
+ // A hash of integer counts, indexed by string description.
+ _visibleTypeDescriptionCount: {},
+
+
+ //**************************************************************************//
+ // Convenience & Performance Shortcuts
+
+ // These get defined by init().
+ _brandShortName : null,
+ _prefsBundle : null,
+ _list : null,
+ _filter : null,
+
+
+ //**************************************************************************//
+ // Initialization & Destruction
+
+ init() {
+ // Initialize shortcuts to some commonly accessed elements & values.
+ this._brandShortName =
+ document.getElementById("bundleBrand").getString("brandShortName");
+ this._prefsBundle = document.getElementById("bundlePrefApplications");
+ this._list = document.getElementById("handlersView");
+ this._filter = document.getElementById("filter");
+
+ // Observe preferences that influence what we display so we can rebuild
+ // the view when they change.
+ Services.prefs.addObserver(PREF_FEED_SELECTED_APP, this);
+ Services.prefs.addObserver(PREF_FEED_SELECTED_WEB, this);
+ Services.prefs.addObserver(PREF_FEED_SELECTED_ACTION, this);
+
+ Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_APP, this);
+ Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_WEB, this);
+ Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_ACTION, this);
+
+ Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_APP, this);
+ Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_WEB, this);
+ Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_ACTION, this);
+
+ // Listen for window unload so we can remove our preference observers.
+ window.addEventListener("unload", this);
+
+ // Listen for user events on the listbox and its children
+ this._list.addEventListener("select", this);
+ this._list.addEventListener("command", this);
+
+ // Figure out how we should be sorting the list. We persist sort settings
+ // across sessions, so we can't assume the default sort column/direction.
+ this._sortColumn = document.getElementById("typeColumn");
+ if (document.getElementById("actionColumn").hasAttribute("sortDirection")) {
+ this._sortColumn = document.getElementById("actionColumn");
+ // The typeColumn element always has a sortDirection attribute,
+ // either because it was persisted or because the default value
+ // from the xul file was used. If we are sorting on the other
+ // column, we should remove it.
+ document.getElementById("typeColumn").removeAttribute("sortDirection");
+ }
+
+ // Load the data and build the list of handlers.
+ this._loadData();
+ this._rebuildVisibleTypes();
+ this._sortVisibleTypes();
+ this._rebuildView();
+
+ // Notify observers that the UI is now ready
+ Services.obs.notifyObservers(window, "app-handler-pane-loaded");
+ },
+
+ destroy() {
+ this._list.removeEventListener("command", this);
+ this._list.removeEventListener("select", this);
+ window.removeEventListener("unload", this);
+ Services.prefs.removeObserver(PREF_FEED_SELECTED_APP, this);
+ Services.prefs.removeObserver(PREF_FEED_SELECTED_WEB, this);
+ Services.prefs.removeObserver(PREF_FEED_SELECTED_ACTION, this);
+
+ Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_APP, this);
+ Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_WEB, this);
+ Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_ACTION, this);
+
+ Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_APP, this);
+ Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_WEB, this);
+ Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_ACTION, this);
+ },
+
+
+ //**************************************************************************//
+ // nsISupports
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
+ Ci.nsIDOMEventListener]),
+
+ //**************************************************************************//
+ // nsIObserver
+
+ observe(aSubject, aTopic, aData) {
+ // Rebuild the list when there are changes to preferences that influence
+ // whether or not to show certain entries in the list.
+ if (aTopic == "nsPref:changed" && !this._storingAction) {
+ // All the prefs we observe can affect what we display, so we rebuild
+ // the view when any of them changes.
+ this._rebuildView();
+ }
+ },
+
+
+ //**************************************************************************//
+ // nsIDOMEventListener
+
+ handleEvent(aEvent) {
+ switch (aEvent.type) {
+ case "unload":
+ this.destroy();
+ break;
+ case "select":
+ if (this._list.selectedItem)
+ this._list.setAttribute("lastSelectedType",
+ this._list.selectedItem.type);
+ break;
+ case "command":
+ var target = aEvent.originalTarget;
+ switch (target.localName) {
+ case "listitem":
+ if (!this._list.disabled &&
+ target.type == this._list.getAttribute("lastSelectedType"))
+ this._list.selectedItem = target;
+ break;
+ case "listcell":
+ this.rebuildActionsMenu();
+ break;
+ case "menuitem":
+ switch (parseInt(target.value)) {
+ case kActionChooseApp:
+ this.chooseApp();
+ break;
+ case kActionManageApp:
+ this.manageApp();
+ break;
+ default:
+ this.onSelectAction(target);
+ break;
+ }
+ break;
+ }
+ }
+ },
+
+
+ //**************************************************************************//
+ // Composed Model Construction
+
+ _loadData() {
+ this._loadFeedHandler();
+ this._loadApplicationHandlers();
+ },
+
+ _loadFeedHandler() {
+ this._handledTypes[TYPE_MAYBE_FEED] = feedHandlerInfo;
+
+ this._handledTypes[TYPE_MAYBE_VIDEO_FEED] = videoFeedHandlerInfo;
+
+ this._handledTypes[TYPE_MAYBE_AUDIO_FEED] = audioFeedHandlerInfo;
+ },
+
+ /**
+ * Load the set of handlers defined by the application datastore.
+ */
+ _loadApplicationHandlers() {
+ var wrappedHandlerInfos = gHandlerService.enumerate();
+ while (wrappedHandlerInfos.hasMoreElements()) {
+ let wrappedHandlerInfo =
+ wrappedHandlerInfos.getNext().QueryInterface(Ci.nsIHandlerInfo);
+ let type = wrappedHandlerInfo.type;
+
+ let handlerInfoWrapper;
+ if (type in this._handledTypes)
+ handlerInfoWrapper = this._handledTypes[type];
+ else {
+ handlerInfoWrapper = new HandlerInfoWrapper(type, wrappedHandlerInfo);
+ this._handledTypes[type] = handlerInfoWrapper;
+ }
+ }
+ },
+
+
+ //**************************************************************************//
+ // View Construction
+
+ _rebuildVisibleTypes() {
+ // Reset the list of visible types and the visible type description counts.
+ this._visibleTypes = [];
+ this._visibleTypeDescriptionCount = {};
+
+ for (let type in this._handledTypes) {
+ let handlerInfo = this._handledTypes[type];
+
+ // We couldn't find any reason to exclude the type, so include it.
+ this._visibleTypes.push(handlerInfo);
+
+ if (handlerInfo.description in this._visibleTypeDescriptionCount)
+ this._visibleTypeDescriptionCount[handlerInfo.description]++;
+ else
+ this._visibleTypeDescriptionCount[handlerInfo.description] = 1;
+ }
+ },
+
+ _rebuildView() {
+ // Clear the list of entries (the first 2 elements are <listcols> and
+ // <listhead>, they should never get removed).
+ while (this._list.childNodes.length > 2)
+ this._list.lastChild.remove();
+
+ var visibleTypes = this._visibleTypes;
+
+ // If the user is filtering the list, then only show matching types.
+ if (this._filter.value)
+ visibleTypes = visibleTypes.filter(this._matchesFilter, this);
+
+ for (let visibleType of visibleTypes) {
+ let item = document.createElement("listitem");
+ item.setAttribute("allowevents", "true");
+ item.setAttribute("type", visibleType.type);
+ item.setAttribute("typeDescription", this._describeType(visibleType));
+ if (visibleType.smallIcon)
+ item.setAttribute("typeIcon", visibleType.smallIcon);
+ else
+ item.setAttribute("typeClass", visibleType.typeClass);
+ item.setAttribute("actionDescription",
+ this._describePreferredAction(visibleType));
+
+ if (!this._setIconClassForPreferredAction(visibleType, item)) {
+ var sysIcon = this._getIconURLForPreferredAction(visibleType);
+ if (sysIcon)
+ item.setAttribute("actionIcon", sysIcon);
+ else
+ item.setAttribute("appHandlerIcon", "app");
+ }
+
+ this._list.appendChild(item);
+ }
+ },
+
+ _matchesFilter(aType) {
+ var filterValue = this._filter.value.toLowerCase();
+ return this._describeType(aType).toLowerCase().includes(filterValue) ||
+ this._describePreferredAction(aType).toLowerCase().includes(filterValue);
+ },
+
+ /**
+ * Describe, in a human-readable fashion, the type represented by the given
+ * handler info object. Normally this is just the description provided by
+ * the info object, but if more than one object presents the same description,
+ * then we annotate the duplicate descriptions with the type itself to help
+ * users distinguish between those types.
+ *
+ * @param aHandlerInfo {nsIHandlerInfo} the type being described
+ * @returns {string} a description of the type
+ */
+ _describeType(aHandlerInfo) {
+ if (this._visibleTypeDescriptionCount[aHandlerInfo.description] > 1)
+ return this._prefsBundle.getFormattedString("typeDescriptionWithType",
+ [aHandlerInfo.description,
+ aHandlerInfo.type]);
+
+ return aHandlerInfo.description;
+ },
+
+ /**
+ * Describe, in a human-readable fashion, the preferred action to take on
+ * the type represented by the given handler info object.
+ *
+ * XXX Should this be part of the HandlerInfoWrapper interface? It would
+ * violate the separation of model and view, but it might make more sense
+ * nonetheless (f.e. it would make sortTypes easier).
+ *
+ * @param aHandlerInfo {nsIHandlerInfo} the type whose preferred action
+ * is being described
+ * @returns {string} a description of the action
+ */
+ _describePreferredAction(aHandlerInfo) {
+ // alwaysAskBeforeHandling overrides the preferred action, so if that flag
+ // is set, then describe that behavior instead. For most types, this is
+ // the "alwaysAsk" string, but for the feed type we show something special.
+ if (aHandlerInfo.alwaysAskBeforeHandling) {
+ if (isFeedType(aHandlerInfo.type))
+ return this._prefsBundle.getFormattedString("previewInApp",
+ [this._brandShortName]);
+ return this._prefsBundle.getString("alwaysAsk");
+ }
+
+ // The nsHandlerInfoAction enumeration values in nsIHandlerInfo identify
+ // the actions the application can take with content of various types.
+ // But since we've stopped support for plugins, there's no value
+ // identifying the "use plugin" action, so we use this constant instead.
+ const kActionUsePlugin = -3;
+
+ switch (aHandlerInfo.preferredAction) {
+ case Ci.nsIHandlerInfo.saveToDisk:
+ return this._prefsBundle.getString("saveFile");
+
+ case Ci.nsIHandlerInfo.useHelperApp:
+ var preferredApp = aHandlerInfo.preferredApplicationHandler;
+ var name = (preferredApp instanceof Ci.nsILocalHandlerApp) ?
+ getFileDisplayName(preferredApp.executable) :
+ preferredApp.name;
+ return this._prefsBundle.getFormattedString("useApp", [name]);
+
+ case Ci.nsIHandlerInfo.handleInternally:
+ // For the feed type, handleInternally means News & Blogs.
+ if (isFeedType(aHandlerInfo.type))
+ return this._prefsBundle.getFormattedString("addNewsBlogsInApp",
+ [this._brandShortName]);
+
+ // For other types, handleInternally looks like either useHelperApp
+ // or useSystemDefault depending on whether or not there's a preferred
+ // handler app.
+ return (this.isValidHandlerApp(aHandlerInfo.preferredApplicationHandler)) ?
+ aHandlerInfo.preferredApplicationHandler.name :
+ aHandlerInfo.defaultDescription;
+
+ // XXX Why don't we say the app will handle the type internally?
+ // Is it because the app can't actually do that? But if that's true,
+ // then why would a preferredAction ever get set to this value
+ // in the first place?
+
+ case Ci.nsIHandlerInfo.useSystemDefault:
+ return this._prefsBundle.getFormattedString("useDefault",
+ [aHandlerInfo.defaultDescription]);
+
+ // We no longer support plugins, select "ask" instead:
+ case kActionUsePlugin:
+ return this._prefsBundle.getString("alwaysAsk");
+ }
+ // we should never end up here but do a return to end up with a value
+ return null;
+ },
+
+ /**
+ * Whether or not the given handler app is valid.
+ *
+ * @param aHandlerApp {nsIHandlerApp} the handler app in question
+ *
+ * @returns {boolean} whether or not it's valid
+ */
+ isValidHandlerApp(aHandlerApp) {
+ if (!aHandlerApp)
+ return false;
+
+ if (aHandlerApp instanceof Ci.nsILocalHandlerApp)
+ return this._isValidHandlerExecutable(aHandlerApp.executable);
+
+ if (aHandlerApp instanceof Ci.nsIWebHandlerApp)
+ return aHandlerApp.uriTemplate;
+
+ if (aHandlerApp instanceof Ci.nsIWebContentHandlerInfo)
+ return aHandlerApp.uri;
+
+ if (aHandlerApp instanceof Ci.nsIGIOMimeApp)
+ return aHandlerApp.command;
+
+ return false;
+ },
+
+ _isValidHandlerExecutable(aExecutable) {
+ var file = Services.dirsvc.get("XREExeF",
+ Ci.nsIFile);
+ return aExecutable &&
+ aExecutable.exists() &&
+ aExecutable.isExecutable() &&
+ aExecutable.leafName != file.leafName;
+ },
+
+ /**
+ * Rebuild the actions menu for the selected entry. Gets called by
+ * the listcell constructor when an entry in the list gets selected.
+ * Note that this would not work from onselect on the listbox because
+ * the XBL needs to be applied _before_ calling this function!
+ */
+ rebuildActionsMenu() {
+ var typeItem = this._list.selectedItem;
+ var handlerInfo = this._handledTypes[typeItem.type];
+ var cell =
+ document.getAnonymousElementByAttribute(typeItem, "anonid", "action-cell");
+ var menu =
+ document.getAnonymousElementByAttribute(cell, "anonid", "action-menu");
+ var menuPopup = menu.menupopup;
+
+ // Clear out existing items.
+ while (menuPopup.hasChildNodes())
+ menuPopup.lastChild.remove();
+
+ {
+ let askMenuItem = document.createElement("menuitem");
+ askMenuItem.setAttribute("class", "handler-action");
+ askMenuItem.setAttribute("value", Ci.nsIHandlerInfo.alwaysAsk);
+ let label;
+ if (isFeedType(handlerInfo.type))
+ label = this._prefsBundle.getFormattedString("previewInApp",
+ [this._brandShortName]);
+ else
+ label = this._prefsBundle.getString("alwaysAsk");
+ askMenuItem.setAttribute("label", label);
+ askMenuItem.setAttribute("tooltiptext", label);
+ askMenuItem.setAttribute("appHandlerIcon", "ask");
+ menuPopup.appendChild(askMenuItem);
+ }
+
+ // Create a menu item for saving to disk.
+ // Note: this option isn't available to protocol types, since we don't know
+ // what it means to save a URL having a certain scheme to disk, nor is it
+ // available to feeds, since the feed code doesn't implement the capability.
+ if ((handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo) &&
+ !isFeedType(handlerInfo.type)) {
+ let saveMenuItem = document.createElement("menuitem");
+ saveMenuItem.setAttribute("class", "handler-action");
+ saveMenuItem.setAttribute("value", Ci.nsIHandlerInfo.saveToDisk);
+ let label = this._prefsBundle.getString("saveFile");
+ saveMenuItem.setAttribute("label", label);
+ saveMenuItem.setAttribute("tooltiptext", label);
+ saveMenuItem.setAttribute("appHandlerIcon", "save");
+ menuPopup.appendChild(saveMenuItem);
+ }
+
+ // If this is the feed type, add a News & Blogs item.
+ if (isFeedType(handlerInfo.type)) {
+ let internalMenuItem = document.createElement("menuitem");
+ internalMenuItem.setAttribute("class", "handler-action");
+ internalMenuItem.setAttribute("value", Ci.nsIHandlerInfo.handleInternally);
+ let label = this._prefsBundle.getFormattedString("addNewsBlogsInApp",
+ [this._brandShortName]);
+ internalMenuItem.setAttribute("label", label);
+ internalMenuItem.setAttribute("tooltiptext", label);
+ internalMenuItem.setAttribute("appHandlerIcon", "feed");
+ menuPopup.appendChild(internalMenuItem);
+ }
+
+ // Add a separator to distinguish these items from the helper app items
+ // that follow them.
+ let menuSeparator = document.createElement("menuseparator");
+ menuPopup.appendChild(menuSeparator);
+
+ // Create a menu item for the OS default application, if any.
+ if (handlerInfo.hasDefaultHandler) {
+ let defaultMenuItem = document.createElement("menuitem");
+ defaultMenuItem.setAttribute("class", "handler-action");
+ defaultMenuItem.setAttribute("value", Ci.nsIHandlerInfo.useSystemDefault);
+ let label = this._prefsBundle.getFormattedString("useDefault",
+ [handlerInfo.defaultDescription]);
+ defaultMenuItem.setAttribute("label", label);
+ defaultMenuItem.setAttribute("tooltiptext", handlerInfo.defaultDescription);
+ let sysIcon = this._getIconURLForSystemDefault(handlerInfo);
+ if (sysIcon)
+ defaultMenuItem.setAttribute("image", sysIcon);
+ else
+ defaultMenuItem.setAttribute("appHandlerIcon", "app");
+
+ menuPopup.appendChild(defaultMenuItem);
+ }
+
+ // Create menu items for possible handlers.
+ let preferredApp = handlerInfo.preferredApplicationHandler;
+ let possibleApps = handlerInfo.possibleApplicationHandlers.enumerate();
+ var possibleAppMenuItems = [];
+ while (possibleApps.hasMoreElements()) {
+ let possibleApp = possibleApps.getNext();
+ if (!this.isValidHandlerApp(possibleApp))
+ continue;
+
+ let menuItem = document.createElement("menuitem");
+ menuItem.setAttribute("class", "handler-action");
+ menuItem.setAttribute("value", Ci.nsIHandlerInfo.useHelperApp);
+ let label;
+ if (possibleApp instanceof Ci.nsILocalHandlerApp)
+ label = getFileDisplayName(possibleApp.executable);
+ else
+ label = possibleApp.name;
+ label = this._prefsBundle.getFormattedString("useApp", [label]);
+ menuItem.setAttribute("label", label);
+ menuItem.setAttribute("tooltiptext", label);
+ let sysIcon = this._getIconURLForHandlerApp(possibleApp);
+ if (sysIcon)
+ menuItem.setAttribute("image", sysIcon);
+ else
+ menuItem.setAttribute("appHandlerIcon", "app");
+
+ // Attach the handler app object to the menu item so we can use it
+ // to make changes to the datastore when the user selects the item.
+ menuItem.handlerApp = possibleApp;
+
+ menuPopup.appendChild(menuItem);
+ possibleAppMenuItems.push(menuItem);
+ }
+
+// Add gio handlers
+ if (Cc["@mozilla.org/gio-service;1"]) {
+ let gIOSvc = Cc["@mozilla.org/gio-service;1"]
+ .getService(Ci.nsIGIOService);
+ var gioApps = gIOSvc.getAppsForURIScheme(typeItem.type);
+ let enumerator = gioApps.enumerate();
+ let possibleHandlers = handlerInfo.possibleApplicationHandlers;
+ while (enumerator.hasMoreElements()) {
+ let handler = enumerator.getNext().QueryInterface(Ci.nsIHandlerApp);
+ // OS handler share the same name, it's most likely the same app, skipping...
+ if (handler.name == handlerInfo.defaultDescription) {
+ continue;
+ }
+ // Check if the handler is already in possibleHandlers
+ let appAlreadyInHandlers = false;
+ for (let i = possibleHandlers.length - 1; i >= 0; --i) {
+ let app = possibleHandlers.queryElementAt(i, Ci.nsIHandlerApp);
+ // nsGIOMimeApp::Equals is able to compare with Ci.nsILocalHandlerApp
+ if (handler.equals(app)) {
+ appAlreadyInHandlers = true;
+ break;
+ }
+ }
+ if (!appAlreadyInHandlers) {
+ let menuItem = document.createElement("menuitem");
+ menuItem.setAttribute("action", Ci.nsIHandlerInfo.useHelperApp);
+ let label = this._prefsBundle.getFormattedString("useApp", [handler.name]);
+ menuItem.setAttribute("label", label);
+ menuItem.setAttribute("tooltiptext", label);
+ menuItem.setAttribute("image", this._getIconURLForHandlerApp(handler));
+
+ // Attach the handler app object to the menu item so we can use it
+ // to make changes to the datastore when the user selects the item.
+ menuItem.handlerApp = handler;
+
+ menuPopup.appendChild(menuItem);
+ possibleAppMenuItems.push(menuItem);
+ }
+ }
+ }
+
+ // Create a menu item for selecting a local application.
+ let canOpenWithOtherApp = true;
+ if (AppConstants.platform == "win") {
+ // On Windows, selecting an application to open another application
+ // would be meaningless so we special case executables.
+ let executableType = gMIMEService.getTypeFromExtension("exe");
+ canOpenWithOtherApp = handlerInfo.type != executableType;
+ }
+ if (canOpenWithOtherApp)
+ {
+ let menuItem = document.createElement("menuitem");
+ menuItem.setAttribute("class", "handler-action");
+ menuItem.setAttribute("value", kActionChooseApp);
+ let label = this._prefsBundle.getString("useOtherApp");
+ menuItem.setAttribute("label", label);
+ menuItem.setAttribute("tooltiptext", label);
+ menuPopup.appendChild(menuItem);
+ }
+
+ // Create a menu item for managing applications.
+ if (possibleAppMenuItems.length) {
+ let menuItem = document.createElement("menuseparator");
+ menuPopup.appendChild(menuItem);
+ menuItem = document.createElement("menuitem");
+ menuItem.setAttribute("class", "handler-action");
+ menuItem.setAttribute("value", kActionManageApp);
+ menuItem.setAttribute("label", this._prefsBundle.getString("manageApp"));
+ menuPopup.appendChild(menuItem);
+ }
+
+ // Select the item corresponding to the preferred action. If the always
+ // ask flag is set, it overrides the preferred action. Otherwise we pick
+ // the item identified by the preferred action (when the preferred action
+ // is to use a helper app, we have to pick the specific helper app item).
+ if (handlerInfo.alwaysAskBeforeHandling)
+ menu.value = Ci.nsIHandlerInfo.alwaysAsk;
+ else if (handlerInfo.preferredAction == Ci.nsIHandlerInfo.useHelperApp &&
+ preferredApp)
+ menu.selectedItem =
+ possibleAppMenuItems.filter(v => v.handlerApp.equals(preferredApp))[0];
+ else
+ menu.value = handlerInfo.preferredAction;
+ },
+
+
+ //**************************************************************************//
+ // Sorting & Filtering
+
+ _sortColumn: null,
+
+ /**
+ * Sort the list when the user clicks on a column header.
+ */
+ sort(event) {
+ var column = event.target;
+
+ // If the user clicked on a new sort column, remove the direction indicator
+ // from the old column.
+ if (this._sortColumn && this._sortColumn != column)
+ this._sortColumn.removeAttribute("sortDirection");
+
+ this._sortColumn = column;
+
+ // Set (or switch) the sort direction indicator.
+ if (column.getAttribute("sortDirection") == "ascending")
+ column.setAttribute("sortDirection", "descending");
+ else
+ column.setAttribute("sortDirection", "ascending");
+
+ this._sortVisibleTypes();
+ this._rebuildView();
+ },
+
+ /**
+ * Sort the list of visible types by the current sort column/direction.
+ */
+ _sortVisibleTypes() {
+ if (!this._sortColumn)
+ return;
+
+ var t = this;
+
+ function sortByType(a, b) {
+ return t._describeType(a).toLowerCase()
+ .localeCompare(t._describeType(b).toLowerCase());
+ }
+
+ function sortByAction(a, b) {
+ return t._describePreferredAction(a).toLowerCase()
+ .localeCompare(t._describePreferredAction(b).toLowerCase());
+ }
+
+ switch (this._sortColumn.getAttribute("value")) {
+ case "type":
+ this._visibleTypes.sort(sortByType);
+ break;
+ case "action":
+ this._visibleTypes.sort(sortByAction);
+ break;
+ }
+
+ if (this._sortColumn.getAttribute("sortDirection") == "descending")
+ this._visibleTypes.reverse();
+ },
+
+
+ //**************************************************************************//
+ // Changes
+
+ onSelectAction(aActionItem) {
+ this._storingAction = true;
+
+ try {
+ this._storeAction(aActionItem);
+ }
+ finally {
+ this._storingAction = false;
+ }
+ },
+
+ _storeAction(aActionItem) {
+ var typeItem = this._list.selectedItem;
+ var handlerInfo = this._handledTypes[typeItem.type];
+
+ let action = parseInt(aActionItem.getAttribute("value"));
+
+ // Set the preferred application handler.
+ // We leave the existing preferred app in the list when we set
+ // the preferred action to something other than useHelperApp so that
+ // legacy datastores that don't have the preferred app in the list
+ // of possible apps still include the preferred app in the list of apps
+ // the user can choose to handle the type.
+ if (action == Ci.nsIHandlerInfo.useHelperApp)
+ handlerInfo.preferredApplicationHandler = aActionItem.handlerApp;
+
+ // Set the preferred action.
+ handlerInfo.preferredAction = action;
+
+ // Set the "always ask" flag.
+ handlerInfo.alwaysAskBeforeHandling = action == Ci.nsIHandlerInfo.alwaysAsk;
+
+ handlerInfo.store();
+
+ // Make sure the handler info object is flagged to indicate that there is
+ // now some user configuration for the type.
+
+ // Update the action label and image to reflect the new preferred action.
+ typeItem.setAttribute("actionDescription",
+ this._describePreferredAction(handlerInfo));
+ if (!this._setIconClassForPreferredAction(handlerInfo, typeItem)) {
+ var sysIcon = this._getIconURLForPreferredAction(handlerInfo);
+ if (sysIcon)
+ typeItem.setAttribute("actionIcon", sysIcon);
+ else
+ typeItem.setAttribute("appHandlerIcon", "app");
+ }
+ },
+
+ manageApp() {
+ var typeItem = this._list.selectedItem;
+ var handlerInfo = this._handledTypes[typeItem.type];
+
+ document.documentElement.openSubDialog("chrome://communicator/content/pref/pref-applicationManager.xul",
+ "", handlerInfo);
+
+ // Rebuild the actions menu so that we revert to the previous selection,
+ // or "Always ask" if the previous default application has been removed
+ this.rebuildActionsMenu();
+
+ // update the listitem too. Will be visible when selecting another row
+ typeItem.setAttribute("actionDescription",
+ this._describePreferredAction(handlerInfo));
+ if (!this._setIconClassForPreferredAction(handlerInfo, typeItem)) {
+ var sysIcon = this._getIconURLForPreferredAction(handlerInfo);
+ if (sysIcon)
+ typeItem.setAttribute("actionIcon", sysIcon);
+ else
+ typeItem.setAttribute("appHandlerIcon", "app");
+ }
+ },
+
+ handlerApp: null,
+
+ finishChooseApp() {
+ if (this.handlerApp) {
+ // Add the app to the type's list of possible handlers.
+ let handlerInfo = this._handledTypes[this._list.selectedItem.type];
+ handlerInfo.addPossibleApplicationHandler(this.handlerApp);
+ }
+
+ // Rebuild the actions menu whether the user picked an app or canceled.
+ // If they picked an app, we want to add the app to the menu and select it.
+ // If they canceled, we want to go back to their previous selection.
+ this.rebuildActionsMenu();
+
+ // If the user picked a new app from the menu, select it.
+ if (this.handlerApp) {
+ var actionsCell =
+ document.getAnonymousElementByAttribute(this._list.selectedItem,
+ "anonid", "action-cell");
+ var actionsMenu =
+ document.getAnonymousElementByAttribute(actionsCell,
+ "anonid", "action-menu");
+ let menuItems = actionsMenu.menupopup.childNodes;
+ for (let i = 0; i < menuItems.length; i++) {
+ let menuItem = menuItems[i];
+ if (menuItem.handlerApp &&
+ menuItem.handlerApp.equals(this.handlerApp)) {
+ actionsMenu.selectedIndex = i;
+ this.onSelectAction(menuItem);
+ break;
+ }
+ }
+ }
+ },
+
+ chooseApp() {
+ this.handlerApp = null;
+
+ if (AppConstants.platform == "win") {
+ let params = {};
+ let handlerInfo = this._handledTypes[this._list.selectedItem.type];
+
+ if (isFeedType(handlerInfo.type)) {
+ // MIME info will be null, create a temp object.
+ params.mimeInfo =
+ gMIMEService.getFromTypeAndExtension(handlerInfo.type,
+ handlerInfo.primaryExtension);
+ } else {
+ params.mimeInfo = handlerInfo.wrappedHandlerInfo;
+ }
+
+ params.title = this._prefsBundle.getString("fpTitleChooseApp");
+ params.description = handlerInfo.description;
+ params.filename = null;
+ params.handlerApp = null;
+
+ window.openDialog("chrome://global/content/appPicker.xul", null,
+ "chrome,modal,centerscreen,titlebar,dialog=yes",
+ params);
+
+ if (this.isValidHandlerApp(params.handlerApp)) {
+ this.handlerApp = params.handlerApp;
+ }
+ this.finishChooseApp();
+ } else if (Services.prefs.getBoolPref("browser.download.useAppChooser", true) && ("@mozilla.org/applicationchooser;1" in Cc)) {
+ let mimeInfo;
+ let handlerInfo = this._handledTypes[this._list.selectedItem.type];
+ if (isFeedType(handlerInfo.type)) {
+ // MIME info will be null, create a temp object.
+ mimeInfo =
+ gMIMEService.getFromTypeAndExtension(handlerInfo.type,
+ handlerInfo.primaryExtension);
+ } else {
+ mimeInfo = handlerInfo.wrappedHandlerInfo;
+ }
+
+ var appChooser = Cc["@mozilla.org/applicationchooser;1"]
+ .createInstance(Ci.nsIApplicationChooser);
+ appChooser.init(window, this._prefsBundle.getString("fpTitleChooseApp"));
+ var contentTypeDialogObj = this;
+ let appChooserCallback = function appChooserCallback_done(aResult) {
+ if (aResult) {
+ contentTypeDialogObj.handlerApp = aResult.QueryInterface(Ci.nsILocalHandlerApp);
+ }
+ contentTypeDialogObj.finishChooseApp();
+ };
+ appChooser.open(mimeInfo.MIMEType, appChooserCallback);
+ // The finishChooseApp is called from appChooserCallback
+ } else {
+ let fp = Cc["@mozilla.org/filepicker;1"]
+ .createInstance(Ci.nsIFilePicker);
+ let winTitle = this._prefsBundle.getString("fpTitleChooseApp");
+ fp.init(window, winTitle, Ci.nsIFilePicker.modeOpen);
+ fp.appendFilters(Ci.nsIFilePicker.filterApps);
+
+ // Prompt the user to pick an app. If they pick one, and it's a valid
+ // selection, then add it to the list of possible handlers.
+ fp.open(rv => {
+ if (rv == Ci.nsIFilePicker.returnOK && fp.file &&
+ this._isValidHandlerExecutable(fp.file)) {
+ let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]
+ .createInstance(Ci.nsILocalHandlerApp);
+ handlerApp.name = getFileDisplayName(fp.file);
+ handlerApp.executable = fp.file;
+ this.handlerApp = handlerApp;
+ }
+ this.finishChooseApp();
+ });
+ }
+ },
+
+ _setIconClassForPreferredAction(aHandlerInfo, aElement) {
+ // If this returns true, the attribute that CSS sniffs for was set to something
+ // so you shouldn't manually set an icon URI.
+ // This removes the existing actionIcon attribute if any, even if returning false.
+ aElement.removeAttribute("actionIcon");
+
+ if (aHandlerInfo.alwaysAskBeforeHandling) {
+ aElement.setAttribute("appHandlerIcon", "ask");
+ return true;
+ }
+
+ switch (aHandlerInfo.preferredAction) {
+ case Ci.nsIHandlerInfo.saveToDisk:
+ aElement.setAttribute("appHandlerIcon", "save");
+ return true;
+
+ case Ci.nsIHandlerInfo.handleInternally:
+ if (isFeedType(aHandlerInfo.type)) {
+ aElement.setAttribute("appHandlerIcon", "feed");
+ return true;
+ }
+ break;
+ }
+ aElement.removeAttribute("appHandlerIcon");
+ return false;
+ },
+
+ _getIconURLForPreferredAction(aHandlerInfo) {
+ switch (aHandlerInfo.preferredAction) {
+ case Ci.nsIHandlerInfo.useSystemDefault:
+ return this._getIconURLForSystemDefault(aHandlerInfo);
+
+ case Ci.nsIHandlerInfo.useHelperApp:
+ let preferredApp = aHandlerInfo.preferredApplicationHandler;
+ if (this.isValidHandlerApp(preferredApp))
+ return this._getIconURLForHandlerApp(preferredApp);
+ break;
+ }
+ // This should never happen, but if preferredAction is set to some weird
+ // value, then fall back to the generic application icon.
+ return null;
+ },
+
+ _getIconURLForHandlerApp(aHandlerApp) {
+ if (aHandlerApp instanceof Ci.nsILocalHandlerApp)
+ return this._getIconURLForFile(aHandlerApp.executable);
+
+ if (Services.prefs.getBoolPref("browser.chrome.favicons")) { // q.v. Bug 514671
+ if (aHandlerApp instanceof Ci.nsIWebHandlerApp)
+ return this._getIconURLForWebApp(aHandlerApp.uriTemplate);
+
+ if (aHandlerApp instanceof Ci.nsIWebContentHandlerInfo)
+ return this._getIconURLForWebApp(aHandlerApp.uri);
+ }
+
+ // We know nothing about other kinds of handler apps.
+ return "";
+ },
+
+ _getIconURLForFile(aFile) {
+ var fph = Services.io.getProtocolHandler("file")
+ .QueryInterface(Ci.nsIFileProtocolHandler);
+ var urlSpec = fph.getURLSpecFromFile(aFile);
+
+ return "moz-icon://" + urlSpec + "?size=16";
+ },
+
+ _getIconURLForWebApp(aWebAppURITemplate) {
+ var uri = Services.io.newURI(aWebAppURITemplate);
+
+ // Unfortunately we need to use favicon.ico here, but we don't know
+ // about any other possibility to retrieve an icon for the web app/site
+ // without loading a specific full URL and parsing it for a possible
+ // shortcut icon.
+
+ return /^https?/.test(uri.scheme) ? uri.resolve("/favicon.ico") : "";
+ },
+
+ _getIconURLForSystemDefault(aHandlerInfo) {
+ // Handler info objects for MIME types on some OSes implement a property bag
+ // interface from which we can get an icon for the default app, so if we're
+ // dealing with a MIME type on one of those OSes, then try to get the icon.
+ if ("wrappedHandlerInfo" in aHandlerInfo) {
+ let wrappedHandlerInfo = aHandlerInfo.wrappedHandlerInfo;
+
+ if (wrappedHandlerInfo instanceof Ci.nsIMIMEInfo &&
+ wrappedHandlerInfo instanceof Ci.nsIPropertyBag) {
+ try {
+ let url = wrappedHandlerInfo.getProperty("defaultApplicationIconURL");
+ if (url)
+ return url + "?size=16";
+ }
+ catch(ex) {}
+ }
+ }
+
+ // If this isn't a MIME type object on an OS that supports retrieving
+ // the icon, or if we couldn't retrieve the icon for some other reason,
+ // then use a generic icon.
+ return null;
+ }
+
+};
diff --git a/comm/suite/components/pref/content/pref-applications.xul b/comm/suite/components/pref/content/pref-applications.xul
new file mode 100644
index 0000000000..351c254252
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-applications.xul
@@ -0,0 +1,113 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> %brandDTD;
+ <!ENTITY % prefApplicationsDTD SYSTEM "chrome://communicator/locale/pref/pref-applications.dtd"> %prefApplicationsDTD;
+]>
+
+<overlay id="ApplicationsPaneOverlay"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <prefpane id="applications_pane"
+ label="&pref.applications.title;"
+ script="chrome://communicator/content/pref/pref-applications.js">
+
+ <preferences id="feedsPreferences">
+ <preference id="browser.feeds.handler"
+ name="browser.feeds.handler"
+ type="string"/>
+ <preference id="browser.feeds.handler.default"
+ name="browser.feeds.handler.default"
+ type="string"/>
+ <preference id="browser.feeds.handlers.application"
+ name="browser.feeds.handlers.application"
+ type="file"/>
+ <preference id="browser.feeds.handlers.webservice"
+ name="browser.feeds.handlers.webservice"
+ type="string"/>
+
+ <preference id="browser.videoFeeds.handler"
+ name="browser.videoFeeds.handler"
+ type="string"/>
+ <preference id="browser.videoFeeds.handler.default"
+ name="browser.videoFeeds.handler.default"
+ type="string"/>
+ <preference id="browser.videoFeeds.handlers.application"
+ name="browser.videoFeeds.handlers.application"
+ type="file"/>
+ <preference id="browser.videoFeeds.handlers.webservice"
+ name="browser.videoFeeds.handlers.webservice"
+ type="string"/>
+
+ <preference id="browser.audioFeeds.handler"
+ name="browser.audioFeeds.handler"
+ type="string"/>
+ <preference id="browser.audioFeeds.handler.default"
+ name="browser.audioFeeds.handler.default"
+ type="string"/>
+ <preference id="browser.audioFeeds.handlers.application"
+ name="browser.audioFeeds.handlers.application"
+ type="file"/>
+ <preference id="browser.audioFeeds.handlers.webservice"
+ name="browser.audioFeeds.handlers.webservice"
+ type="string"/>
+
+ <preference id="pref.downloads.disable_button.edit_actions"
+ name="pref.downloads.disable_button.edit_actions"
+ type="bool"/>
+ <preference id="browser.download.useAppChooser"
+ name="browser.download.useAppChooser"
+ type="bool"/>
+ </preferences>
+
+ <stringbundleset id="appBundleset">
+ <stringbundle id="bundleBrand"
+ src="chrome://branding/locale/brand.properties"/>
+ <stringbundle id="bundlePrefApplications"
+ src="chrome://communicator/locale/pref/pref-applications.properties"/>
+ </stringbundleset>
+
+ <hbox align="center">
+ <textbox id="filter"
+ flex="1"
+ type="search"
+ placeholder="&search.placeholder;"
+ clickSelectsAll="true"
+ aria-controls="handlersView"
+ oncommand="gApplicationsPane._rebuildView();"/>
+ </hbox>
+
+ <separator class="thin"/>
+
+ <listbox id="handlersView" persist="lastSelectedType" flex="1"
+ preference="pref.downloads.disable_button.edit_actions">
+ <listcols>
+ <listcol width="1" flex="1"/>
+ <listcol width="1" flex="1"/>
+ </listcols>
+ <listhead>
+ <listheader id="typeColumn" label="&typeColumn.label;" value="type"
+ accesskey="&typeColumn.accesskey;" persist="sortDirection"
+ onclick="gApplicationsPane.sort(event);"
+ sortDirection="ascending"/>
+ <listheader id="actionColumn" label="&actionColumn2.label;" value="action"
+ accesskey="&actionColumn2.accesskey;" persist="sortDirection"
+ onclick="gApplicationsPane.sort(event);"/>
+ </listhead>
+ </listbox>
+#ifdef XP_LINUX
+ <separator class="thin"/>
+
+ <hbox align="center">
+ <checkbox id="downloadUseAppChooser"
+ label="&useAppChooser.label;"
+ accesskey="&useAppChooser.accesskey;"
+ preference="browser.download.useAppChooser"/>
+ </hbox>
+#endif
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-cache.js b/comm/suite/components/pref/content/pref-cache.js
new file mode 100644
index 0000000000..be2245b98b
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-cache.js
@@ -0,0 +1,113 @@
+/* -*- Mode: Java; 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/. */
+
+var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+const {DownloadUtils} = ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm");
+
+var {AppConstants} = ChromeUtils.import(
+ "resource://gre/modules/AppConstants.jsm"
+);
+
+function Startup()
+{
+ updateActualCacheSize();
+}
+
+// Needs to be global because the cache service only keeps a weak reference.
+var CacheObserver = {
+ /* nsICacheStorageConsumptionObserver */
+ onNetworkCacheDiskConsumption: function(aConsumption) {
+ var actualSizeLabel = document.getElementById("cacheSizeInfo");
+ var sizeStrings = DownloadUtils.convertByteUnits(aConsumption);
+ var prefStrBundle = document.getElementById("bundle_prefutilities");
+ var sizeStr = prefStrBundle.getFormattedString("cacheSizeInfo",
+ sizeStrings);
+ actualSizeLabel.textContent = sizeStr;
+ },
+
+ /* nsISupports */
+ QueryInterface: XPCOMUtils.generateQI(
+ [Ci.nsICacheStorageConsumptionObserver,
+ Ci.nsISupportsWeakReference])
+};
+
+// because the cache is in kilobytes, and the UI is in megabytes.
+function ReadCacheDiskCapacity()
+{
+ var pref = document.getElementById("browser.cache.disk.capacity");
+ return pref.value >> 10;
+}
+
+function WriteCacheDiskCapacity(aField)
+{
+ return aField.value << 10;
+}
+
+function ReadCacheFolder(aField)
+{
+ var pref = document.getElementById("browser.cache.disk.parent_directory");
+ var file = pref.value;
+
+ if (!file)
+ {
+ try
+ {
+ // no disk cache folder pref set; default to profile directory
+ file = GetSpecialDirectory(Services.dirsvc.has("ProfLD") ? "ProfLD"
+ : "ProfD");
+ }
+ catch (ex) {}
+ }
+
+ if (file) {
+ aField.file = file;
+ aField.label = AppConstants.platform == "macosx" ? file.leafName : file.path;
+ }
+}
+
+function CacheSelectFolder()
+{
+ let fp = Cc["@mozilla.org/filepicker;1"]
+ .createInstance(Ci.nsIFilePicker);
+ let title = document.getElementById("bundle_prefutilities")
+ .getString("cachefolder");
+
+ fp.init(window, title, Ci.nsIFilePicker.modeGetFolder);
+ fp.displayDirectory =
+ document.getElementById("browser.cache.disk.parent_directory").value;
+ fp.appendFilters(Ci.nsIFilePicker.filterAll);
+
+ fp.open(rv => {
+ if (rv != Ci.nsIFilePicker.returnOK || !fp.file) {
+ return;
+ }
+ document.getElementById("browser.cache.disk.parent_directory").value = fp.file;
+ });
+}
+
+function ClearDiskAndMemCache()
+{
+ Services.cache2.clear();
+ updateActualCacheSize();
+}
+
+function updateCacheSizeUI(cacheSizeEnabled)
+{
+ document.getElementById("browserCacheDiskCacheBefore").disabled = cacheSizeEnabled;
+ document.getElementById("browserCacheDiskCache").disabled = cacheSizeEnabled;
+ document.getElementById("browserCacheDiskCacheAfter").disabled = cacheSizeEnabled;
+}
+
+function ReadSmartSizeEnabled()
+{
+ var enabled = document.getElementById("browser.cache.disk.smart_size.enabled").value;
+ updateCacheSizeUI(enabled);
+ return enabled;
+}
+
+function updateActualCacheSize()
+{
+ Services.cache2.asyncGetDiskConsumption(CacheObserver);
+}
diff --git a/comm/suite/components/pref/content/pref-cache.xul b/comm/suite/components/pref/content/pref-cache.xul
new file mode 100644
index 0000000000..6b60ddef2b
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-cache.xul
@@ -0,0 +1,142 @@
+<?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/. -->
+<!DOCTYPE overlay [
+<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+%brandDTD;
+<!ENTITY % prefCacheDTD SYSTEM "chrome://communicator/locale/pref/pref-cache.dtd">
+%prefCacheDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="cache_pane"
+ label="&pref.cache.title;"
+ script="chrome://communicator/content/pref/pref-cache.js">
+
+ <preferences>
+ <preference id="browser.cache.disk.capacity"
+ name="browser.cache.disk.capacity"
+ type="int"/>
+ <preference id="browser.cache.disk.smart_size.enabled"
+ name="browser.cache.disk.smart_size.enabled"
+ type="bool"/>
+ <preference id="pref.advanced.cache.disable_button.clear_disk"
+ name="pref.advanced.cache.disable_button.clear_disk"
+ type="bool"/>
+ <preference id="browser.cache.check_doc_frequency"
+ name="browser.cache.check_doc_frequency"
+ type="int"/>
+ <preference id="network.prefetch-next"
+ name="network.prefetch-next"
+ type="bool"/>
+ <preference id="browser.cache.disk.parent_directory"
+ name="browser.cache.disk.parent_directory"
+ type="file"/>
+ <preference id="browser.cache.disk.enable"
+ name="browser.cache.disk.enable"
+ type="bool"/>
+ <preference id="browser.cache.memory.enable"
+ name="browser.cache.memory.enable"
+ type="bool"/>
+ </preferences>
+
+ <groupbox>
+ <caption label="&pref.cache.caption;"/>
+
+ <description>&cachePara;</description>
+
+ <vbox align="start">
+ <label id="cacheSizeInfo"/>
+ <checkbox id="allowSmartSize"
+ label="&cacheCheck.label;"
+ accesskey="&cacheCheck.accesskey;"
+ onsyncfrompreference="return document.getElementById('cache_pane').ReadSmartSizeEnabled();"
+ preference="browser.cache.disk.smart_size.enabled"/>
+ </vbox>
+ <hbox align="center">
+ <label id="browserCacheDiskCacheBefore"
+ value="&diskCacheUpTo.label;"
+ accesskey="&diskCacheUpTo.accesskey;"
+ control="browserCacheDiskCache"/>
+ <textbox id="browserCacheDiskCache"
+ size="5"
+ type="number"
+ aria-labelledby="browserCacheDiskCacheBefore browserCacheDiskCache browserCacheDiskCacheAfter"
+ preference="browser.cache.disk.capacity"
+ onsyncfrompreference="return document.getElementById('cache_pane').ReadCacheDiskCapacity();"
+ onsynctopreference="return document.getElementById('cache_pane').WriteCacheDiskCapacity(this);"/>
+ <label id="browserCacheDiskCacheAfter"
+ value="&spaceMbytes;"/>
+ <button label="&clearDiskCache.label;"
+ accesskey="&clearDiskCache.accesskey;"
+ oncommand="ClearDiskAndMemCache();"
+ id="clearDiskCache"
+ preference="pref.advanced.cache.disable_button.clear_disk"/>
+ </hbox>
+
+ <vbox>
+ <label value="&diskCacheFolder.label;"/>
+ <hbox align="center">
+ <filefield id="browserCacheDiskCacheFolder"
+ flex="1"
+ preference="browser.cache.disk.parent_directory"
+ preference-editable="true"
+ onsyncfrompreference="return document.getElementById('cache_pane').ReadCacheFolder(this);"/>
+ <button label="&chooseDiskCacheFolder.label;"
+ accesskey="&chooseDiskCacheFolder.accesskey;"
+ oncommand="CacheSelectFolder();"
+ id="chooseDiskCacheFolder">
+ <observes element="browserCacheDiskCacheFolder"
+ attribute="disabled"/>
+ </button>
+ </hbox>
+ </vbox>
+ <description>&diskCacheFolderExplanation;</description>
+
+ <separator class="thin"/>
+
+ <label control="browserCacheCheckDocFrequency"
+ value="&docCache.label;"
+ accesskey="&docCache.accesskey;"/>
+ <hbox align="start">
+ <menulist id="browserCacheCheckDocFrequency"
+ class="indent"
+ preference="browser.cache.check_doc_frequency">
+ <menupopup>
+ <menuitem value="1" label="&checkEveryTime.label;"/>
+ <menuitem value="3" label="&checkAutomatically.label;"/>
+ <menuitem value="0" label="&checkOncePerSession.label;"/>
+ <menuitem value="2" label="&checkNever.label;"/>
+ </menupopup>
+ </menulist>
+ </hbox>
+
+ </groupbox>
+
+ <groupbox id="prefetch">
+ <caption id="prefetchLabel" label="&prefetchTitle.label;"/>
+ <vbox id="prefetchBox" align="start">
+ <checkbox id="enablePrefetch"
+ label="&enablePrefetch.label;"
+ accesskey="&enablePrefetch.accesskey;"
+ preference="network.prefetch-next"/>
+ </vbox>
+ </groupbox>
+
+ <groupbox id="debugCache">
+ <caption label="&debugCache.label;"/>
+ <hbox align="center">
+ <checkbox id="browserEnableDiskCache"
+ label="&debugEnableDiskCache.label;"
+ accesskey="&debugEnableDiskCache.accesskey;"
+ preference="browser.cache.disk.enable"/>
+ <checkbox id="browserEnableCache"
+ label="&debugEnableMemCache.label;"
+ accesskey="&debugEnableMemCache.accesskey;"
+ preference="browser.cache.memory.enable"/>
+ </hbox>
+ </groupbox>
+
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-colors.js b/comm/suite/components/pref/content/pref-colors.js
new file mode 100644
index 0000000000..619af1bd5e
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-colors.js
@@ -0,0 +1,26 @@
+/* -*- Mode: Java; 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/. */
+
+function Startup()
+{
+ ToggleCustomColorPickers(document.getElementById("browser.display.use_system_colors").value);
+}
+
+function ToggleCustomColorPickers(aChecked)
+{
+ TogglePickerDisability(aChecked, "browserForegroundColor");
+ TogglePickerDisability(aChecked, "browserBackgroundColor");
+}
+
+function TogglePickerDisability(aDisable, aPicker)
+{
+ var element = document.getElementById(aPicker);
+ aDisable = aDisable ||
+ document.getElementById(element.getAttribute("preference")).locked;
+
+ element.disabled = aDisable;
+ element = document.getElementById(aPicker + "Label");
+ element.disabled = aDisable;
+}
diff --git a/comm/suite/components/pref/content/pref-colors.xul b/comm/suite/components/pref/content/pref-colors.xul
new file mode 100644
index 0000000000..97c5d0c631
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-colors.xul
@@ -0,0 +1,131 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-colors.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="colors_pane"
+ label="&pref.colors.title;"
+ script="chrome://communicator/content/pref/pref-colors.js">
+
+ <preferences id="colors_preferences">
+ <preference id="browser.display.foreground_color"
+ name="browser.display.foreground_color"
+ type="string"/>
+ <preference id="browser.display.background_color"
+ name="browser.display.background_color"
+ type="string"/>
+ <preference id="browser.display.use_system_colors"
+ name="browser.display.use_system_colors"
+ type="bool"
+ onchange="ToggleCustomColorPickers(this.value);"/>
+ <preference id="browser.anchor_color"
+ name="browser.anchor_color"
+ type="string"/>
+ <preference id="browser.active_color"
+ name="browser.active_color"
+ type="string"/>
+ <preference id="browser.visited_color"
+ name="browser.visited_color"
+ type="string"/>
+ <preference id="browser.underline_anchors"
+ name="browser.underline_anchors"
+ type="bool"/>
+ <preference id="browser.display.document_color_use"
+ name="browser.display.document_color_use"
+ type="int"/>
+ </preferences>
+ <hbox>
+ <groupbox flex="1" id="pageColours">
+ <caption label="&color;"/>
+ <hbox align="center">
+ <label id="browserForegroundColorLabel"
+ value="&textColor.label;"
+ accesskey="&textColor.accesskey;"
+ flex="1"
+ control="browserForegroundColor"/>
+ <colorpicker id="browserForegroundColor"
+ type="button"
+ palettename="standard"
+ preference="browser.display.foreground_color"/>
+ </hbox>
+ <hbox align="center" style="margin-top: 5px">
+ <label id="browserBackgroundColorLabel"
+ value="&backgroundColor.label;"
+ accesskey="&backgroundColor.accesskey;"
+ flex="1"
+ control="browserBackgroundColor"/>
+ <colorpicker id="browserBackgroundColor"
+ type="button"
+ palettename="standard"
+ preference="browser.display.background_color"/>
+ </hbox>
+ <separator class="thin"/>
+ <hbox align="center">
+ <checkbox id="browserUseSystemColors"
+ label="&useSystemColors.label;"
+ accesskey="&useSystemColors.accesskey;"
+ preference="browser.display.use_system_colors"/>
+ </hbox>
+ </groupbox>
+
+ <groupbox flex="1">
+ <caption label="&links;"/>
+ <hbox align="center">
+ <label value="&linkColor.label;"
+ accesskey="&linkColor.accesskey;"
+ flex="1"
+ control="browserAnchorColor"/>
+ <colorpicker id="browserAnchorColor"
+ type="button"
+ palettename="standard"
+ preference="browser.anchor_color"/>
+ </hbox>
+ <hbox align="center" style="margin-top: 5px">
+ <label value="&activeLinkColor.label;"
+ accesskey="&activeLinkColor.accesskey;"
+ flex="1"
+ control="browserActiveColor"/>
+ <colorpicker id="browserActiveColor"
+ type="button"
+ palettename="standard"
+ preference="browser.active_color"/>
+ </hbox>
+ <hbox align="center" style="margin-top: 5px">
+ <label value="&visitedLinkColor.label;"
+ accesskey="&visitedLinkColor.accesskey;"
+ flex="1"
+ control="browserVisitedColor"/>
+ <colorpicker id="browserVisitedColor"
+ type="button"
+ palettename="standard"
+ preference="browser.visited_color"/>
+ </hbox>
+ <separator class="thin"/>
+ <hbox align="center">
+ <checkbox id="browserUnderlineAnchors"
+ label="&underlineLinks.label;"
+ accesskey="&underlineLinks.accesskey;"
+ preference="browser.underline_anchors"/>
+ </hbox>
+ </groupbox>
+ </hbox>
+
+ <groupbox>
+ <caption label="&someProvColors;"/>
+
+ <radiogroup id="browserDocumentColorUse"
+ preference="browser.display.document_color_use">
+ <radio value="1" label="&alwaysUseDocumentColors.label;"
+ accesskey="&alwaysUseDocumentColors.accesskey;"/>
+ <radio value="2" label="&useMyColors.label;"
+ accesskey="&useMyColors.accesskey;"/>
+ <radio value="0" label="&automaticColors.label;"
+ accesskey="&automaticColors.accesskey;"/>
+ </radiogroup>
+
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-content.js b/comm/suite/components/pref/content/pref-content.js
new file mode 100644
index 0000000000..964c216a28
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-content.js
@@ -0,0 +1,141 @@
+/* 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/. */
+
+var {AppConstants} = ChromeUtils.import(
+ "resource://gre/modules/AppConstants.jsm"
+);
+
+var minMinValue;
+var maxMinValue;
+
+/**
+ * When starting up, obtain min and max values for the zoom-range controls
+ * from the first and last values of the zoom-levels array.
+ */
+function Startup()
+{
+ let minElement = document.getElementById("minZoom");
+ let maxElement = document.getElementById("maxZoom");
+ let minMaxLimit = 200;
+ let maxMinLimit = 50; // allow reasonable amounts of overlap
+ let zoomValues = Services.prefs.getCharPref("toolkit.zoomManager.zoomValues")
+ .split(",").map(parseFloat);
+ zoomValues.sort((a, b) => a - b);
+
+ let firstValue = Math.round(100 * zoomValues[0]);
+ let lastValue = Math.round(100 * zoomValues[zoomValues.length - 1]);
+
+ minMinValue = firstValue;
+ minElement.min = minMinValue;
+ minElement.max = lastValue > minMaxLimit ? minMaxLimit : lastValue;
+
+ maxMinValue = firstValue < maxMinLimit ? maxMinLimit : firstValue;
+ maxElement.min = maxMinValue;
+ maxElement.max = lastValue;
+
+ /* defaultZoom stuff */
+
+ let defaultElement = document.getElementById("defaultZoom");
+
+ defaultElement.min = Services.prefs.getIntPref("zoom.minPercent");
+ defaultElement.max = Services.prefs.getIntPref("zoom.maxPercent");
+
+ var zoomValue = Services.contentPrefs2
+ .getCachedGlobal("browser.content.full-zoom", null);
+ if (zoomValue && zoomValue.value) {
+ defaultElement.value = Math.round(zoomValue.value * 100);
+ return;
+ }
+
+ defaultElement.value = 100;
+ Services.contentPrefs2.getGlobal("browser.content.full-zoom", null, {
+ handleResult(pref) {
+ defaultElement.value = Math.round(pref.value * 100);
+ },
+ handleCompletion(reason) {}
+ });
+}
+
+/**
+ * Suspend "min" value while manually typing in a number.
+ */
+function DisableMinCheck(element)
+{
+ element.min = 0;
+}
+
+/**
+ * Modify the maxZoom setting if minZoom was chosen to be larger than it.
+ */
+function AdjustMaxZoom()
+{
+ let minElement = document.getElementById("minZoom");
+ let maxElement = document.getElementById("maxZoom");
+ let maxPref = document.getElementById("zoom.maxPercent");
+
+ if(minElement.valueNumber > maxElement.valueNumber)
+ maxPref.value = minElement.value;
+
+ minElement.min = minMinValue;
+
+ let defaultElement = document.getElementById("defaultZoom");
+ if (defaultElement.valueNumber < minElement.valueNumber) {
+ defaultElement.valueNumber = minElement.valueNumber;
+ SetDefaultZoom();
+ }
+ defaultElement.min = minElement.valueNumber;
+}
+
+/**
+ * Modify the minZoom setting if maxZoom was chosen to be smaller than it,
+ * adjusting maxZoom first if it's below maxMinValue.
+ */
+function AdjustMinZoom()
+{
+ let minElement = document.getElementById("minZoom");
+ let maxElement = document.getElementById("maxZoom");
+ let minPref = document.getElementById("zoom.minPercent");
+ let maxValue = maxElement.valueNumber < maxMinValue ?
+ maxMinValue : maxElement.valueNumber;
+
+ if(maxValue < minElement.valueNumber)
+ minPref.value = maxValue;
+
+ maxElement.min = maxMinValue;
+
+ let defaultElement = document.getElementById("defaultZoom");
+ if (defaultElement.valueNumber > maxElement.valueNumber) {
+ defaultElement.valueNumber = maxElement.valueNumber;
+ SetDefaultZoom();
+ }
+ defaultElement.max = maxElement.valueNumber;
+}
+
+/**
+ * Set default zoom.
+ */
+function SetDefaultZoom()
+{
+ let defaultElement = document.getElementById("defaultZoom");
+
+ if (defaultElement.valueNumber == 100) {
+ Services.contentPrefs2.removeGlobal("browser.content.full-zoom", null);
+ return;
+ }
+
+ let new_value = defaultElement.valueNumber / 100.;
+ Services.contentPrefs2.setGlobal("browser.content.full-zoom", new_value,
+ null);
+}
+
+/**
+ * When the user toggles the layers.acceleration.disabled pref,
+ * sync its new value to the gfx.direct2d.disabled pref too.
+ */
+function updateHardwareAcceleration(aVal)
+{
+ if (AppConstants.platform == "win") {
+ document.getElementById("gfx.direct2d.disabled").value = aVal;
+ }
+}
diff --git a/comm/suite/components/pref/content/pref-content.xul b/comm/suite/components/pref/content/pref-content.xul
new file mode 100644
index 0000000000..513027c03c
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-content.xul
@@ -0,0 +1,131 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> %brandDTD;
+ <!ENTITY % prefContentDTD SYSTEM "chrome://communicator/locale/pref/pref-content.dtd"> %prefContentDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="content_pane"
+ label="&pref.content.title;"
+ script="chrome://communicator/content/pref/pref-content.js">
+
+ <preferences id="content_preferences">
+ <preference id="general.autoScroll"
+ name="general.autoScroll"
+ type="bool"/>
+ <preference id="general.smoothScroll"
+ name="general.smoothScroll"
+ type="bool"/>
+ <preference id="zoom.minPercent"
+ name="zoom.minPercent"
+ type="int"/>
+ <preference id="zoom.maxPercent"
+ name="zoom.maxPercent"
+ type="int"/>
+ <preference id="browser.zoom.full"
+ name="browser.zoom.full"
+ type="bool" inverted="true"/>
+ <preference id="browser.zoom.siteSpecific"
+ name="browser.zoom.siteSpecific"
+ type="bool"/>
+ <preference id="browser.zoom.showZoomStatusPanel"
+ name="browser.zoom.showZoomStatusPanel"
+ type="bool"/>
+ <preference id="browser.enable_automatic_image_resizing"
+ name="browser.enable_automatic_image_resizing"
+ type="bool"/>
+ <preference id="gfx.direct2d.disabled"
+ name="gfx.direct2d.disabled"
+ type="bool" inverted="true"/>
+ <preference id="layers.acceleration.disabled"
+ name="layers.acceleration.disabled"
+ type="bool" inverted="true"
+ onchange="updateHardwareAcceleration(this.value);"/>
+ </preferences>
+
+ <description>&pref.content.description;</description>
+
+ <groupbox id="scrollingGroup" align="start">
+ <caption label="&scrolling.label;"/>
+
+ <checkbox id="useAutoScroll"
+ label="&useAutoScroll.label;"
+ accesskey="&useAutoScroll.accesskey;"
+ preference="general.autoScroll"/>
+ <checkbox id="useSmoothScroll"
+ label="&useSmoothScroll.label;"
+ accesskey="&useSmoothScroll.accesskey;"
+ preference="general.smoothScroll"/>
+ </groupbox>
+
+ <groupbox id="zoomPreferences" align="start">
+ <caption label="&zoomPrefs.label;"/>
+
+ <hbox align="center">
+ <label value="&minZoom.label;"
+ accesskey="&minZoom.accesskey;"
+ control="minZoom"/>
+ <textbox id="minZoom"
+ type="number"
+ size="3"
+ increment="10"
+ preference="zoom.minPercent"
+ oninput="DisableMinCheck(this);"
+ onchange="AdjustMaxZoom();"/>
+ <label value="&maxZoom.label;"
+ accesskey="&maxZoom.accesskey;"
+ control="maxZoom"/>
+ <textbox id="maxZoom"
+ type="number"
+ size="3"
+ increment="10"
+ preference="zoom.maxPercent"
+ oninput="DisableMinCheck(this);"
+ onchange="AdjustMinZoom();"/>
+ <label value="&percent.label;"/>
+ </hbox>
+
+ <checkbox id="textZoomOnly"
+ label="&textZoomOnly.label;"
+ accesskey="&textZoomOnly.accesskey;"
+ preference="browser.zoom.full"/>
+ <checkbox id="zoomSiteSpecific"
+ label="&siteSpecific.label;"
+ accesskey="&siteSpecific.accesskey;"
+ preference="browser.zoom.siteSpecific"/>
+ <checkbox id="showZoomStatusPanel"
+ label="&showZoomStatusPanel.label;"
+ accesskey="&showZoomStatusPanel.accesskey;"
+ preference="browser.zoom.showZoomStatusPanel"/>
+ <checkbox id="enableAutomaticImageResizing"
+ label="&enableAutomaticImageResizing.label;"
+ accesskey="&enableAutomaticImageResizing.accesskey;"
+ preference="browser.enable_automatic_image_resizing"/>
+
+ <hbox align="center">
+ <label value="&defaultZoom.label;"
+ accesskey="&defaultZoom.accesskey;"
+ control="defaultZoom"/>
+ <textbox id="defaultZoom"
+ type="number"
+ size="3"
+ increment="10"
+ onchange="SetDefaultZoom();"/>
+ <label value="&percent.label;"/>
+ </hbox>
+ </groupbox>
+
+ <vbox class="box-padded" align="start">
+ <checkbox id="allowHWAccel"
+ label="&allowHWAccel.label;"
+ accesskey="&allowHWAccel.accesskey;"
+ preference="layers.acceleration.disabled"/>
+ </vbox>
+
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-cookies.js b/comm/suite/components/pref/content/pref-cookies.js
new file mode 100644
index 0000000000..fd51881735
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-cookies.js
@@ -0,0 +1,34 @@
+/* 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/. */
+
+function Startup()
+{
+ SetDisables(false);
+}
+
+function SetDisables(aSetFocus)
+{
+ // Policy 1 was "ask before accepting" and is no longer valid.
+
+ // const for Cookie Accept Policy
+ const kCookiesDisabled = 2;
+ // const for Cookie Lifetime Policy
+ const kAcceptForNDays = 3;
+
+ var behavior = document.getElementById("networkCookieBehavior");
+ var behaviorPref = document.getElementById(behavior.getAttribute("preference"));
+
+ var lifetime = document.getElementById("networkCookieLifetime");
+ var lifetimePref = document.getElementById(lifetime.getAttribute("preference"));
+ var days = document.getElementById("lifetimeDays");
+ var daysPref = document.getElementById(days.getAttribute("preference"));
+
+ var cookiesDisabled = (behaviorPref.value == kCookiesDisabled);
+ lifetime.disabled = cookiesDisabled || lifetimePref.locked;
+ days.disabled = cookiesDisabled || daysPref.locked ||
+ (lifetimePref.value != kAcceptForNDays);
+
+ if (!days.disabled && aSetFocus)
+ days.focus();
+}
diff --git a/comm/suite/components/pref/content/pref-cookies.xul b/comm/suite/components/pref/content/pref-cookies.xul
new file mode 100644
index 0000000000..c41be21dc7
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-cookies.xul
@@ -0,0 +1,89 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-cookies.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="cookies_pane"
+ label="&pref.cookies.title;"
+ script="chrome://communicator/content/pref/pref-cookies.js">
+ <preferences id="cookies_preferences">
+ <preference id="network.cookie.cookieBehavior"
+ name="network.cookie.cookieBehavior"
+ type="int"
+ onchange="SetDisables(false);"/>
+ <preference id="network.cookie.lifetimePolicy"
+ name="network.cookie.lifetimePolicy"
+ type="int"
+ onchange="SetDisables(this.value == '3');"/>
+ <preference id="network.cookie.lifetime.days"
+ name="network.cookie.lifetime.days"
+ type="int"/>
+ <preference id="pref.advanced.cookies.disable_button.view_cookies"
+ name="pref.advanced.cookies.disable_button.view_cookies"
+ type="bool"/>
+ </preferences>
+
+ <groupbox id="networkCookieAcceptPolicy">
+ <caption label="&cookiePolicy.label;"/>
+ <radiogroup id="networkCookieBehavior"
+ preference="network.cookie.cookieBehavior">
+ <radio value="2"
+ label="&disableCookies.label;"
+ accesskey="&disableCookies.accesskey;"/>
+ <radio value="1"
+ label="&accNo3rdPartyCookies.label;"
+ accesskey="&accNo3rdPartyCookies.accesskey;"/>
+ <radio value="3"
+ label="&acc3rdPartyVisited.label;"
+ accesskey="&acc3rdPartyVisited.accesskey;"/>
+ <radio value="0"
+ label="&accAllCookies.label;"
+ accesskey="&accAllCookies.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+ <groupbox id="networkCookieLifetimePolicy">
+ <caption label="&cookieRetentionPolicy.label;"/>
+ <radiogroup id="networkCookieLifetime"
+ preference="network.cookie.lifetimePolicy">
+ <radio value="0"
+ label="&acceptNormally.label;"
+ accesskey="&acceptNormally.accesskey;"/>
+ <radio value="2"
+ label="&acceptForSession.label;"
+ accesskey="&acceptForSession.accesskey;"/>
+ <hbox align="center">
+ <radio id="acceptForNDays"
+ value="3"
+ label="&acceptforNDays.label;"
+ accesskey="&acceptforNDays.accesskey;"
+ aria-labelledby="acceptForNDays lifetimeDays daysLabel"/>
+ <textbox id="lifetimeDays"
+ type="number"
+ max="999"
+ min="0"
+ size="3"
+ maxlength="3"
+ preference="network.cookie.lifetime.days"
+ aria-labelledby="acceptForNDays lifetimeDays daysLabel"/>
+ <label id="daysLabel"
+ value="&days.label;"/>
+ </hbox>
+ </radiogroup>
+ </groupbox>
+ <groupbox id="manageCookiesAndSites">
+ <caption label="&manageCookies.label;"/>
+ <description>&manageCookiesDescription.label;</description>
+ <hbox pack="end">
+ <button id="viewCookieButton"
+ label="&viewCookies.label;"
+ accesskey="&viewCookies.accesskey;"
+ preference="pref.advanced.cookies.disable_button.view_cookies"
+ oncommand="toDataManager('|cookies');"/>
+ </hbox>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-debugging.js b/comm/suite/components/pref/content/pref-debugging.js
new file mode 100644
index 0000000000..269a0afeac
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-debugging.js
@@ -0,0 +1,15 @@
+/* -*- Mode: Java; 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/. */
+
+function Startup() {
+ let paintFlashing = document.getElementById("nglayout.debug.paint_flashing");
+ enableFlashingChrome(paintFlashing.value);
+}
+
+function enableFlashingChrome(aValue) {
+ var paintFlashingChrome = document.getElementById("nglayoutDebugPaintFlashingChrome");
+
+ paintFlashingChrome.disabled = aValue;
+}
diff --git a/comm/suite/components/pref/content/pref-debugging.xul b/comm/suite/components/pref/content/pref-debugging.xul
new file mode 100644
index 0000000000..8e42f6f756
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-debugging.xul
@@ -0,0 +1,120 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-debugging.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="debugging_pane"
+ label="&pref.debugging.title;"
+ script="chrome://communicator/content/pref/pref-debugging.js">
+
+ <preferences id="debugging_preferences">
+ <preference id="nglayout.debug.paint_flashing"
+ name="nglayout.debug.paint_flashing"
+ type="bool"
+ onchange="enableFlashingChrome(this.value);"/>
+ <preference id="nglayout.debug.paint_flashing_chrome"
+ name="nglayout.debug.paint_flashing_chrome"
+ type="bool"/>
+ <preference id="nglayout.debug.paint_dumping"
+ name="nglayout.debug.paint_dumping"
+ type="bool"/>
+ <preference id="nglayout.debug.invalidate_dumping"
+ name="nglayout.debug.invalidate_dumping"
+ type="bool"/>
+ <preference id="nglayout.debug.event_dumping"
+ name="nglayout.debug.event_dumping"
+ type="bool"/>
+ <preference id="nglayout.debug.motion_event_dumping"
+ name="nglayout.debug.motion_event_dumping"
+ type="bool"/>
+ <preference id="nglayout.debug.crossing_event_dumping"
+ name="nglayout.debug.crossing_event_dumping"
+ type="bool"/>
+ <preference id="layout.reflow.showframecounts"
+ name="layout.reflow.showframecounts"
+ type="bool"/>
+ <preference id="layout.reflow.dumpframecounts"
+ name="layout.reflow.dumpframecounts"
+ type="bool"/>
+ <preference id="layout.reflow.dumpframebyframecounts"
+ name="layout.reflow.dumpframebyframecounts"
+ type="bool"/>
+ <preference id="xul.debug.box"
+ name="xul.debug.box"
+ type="bool"/>
+ <preference id="nglayout.debug.disable_xul_cache"
+ name="nglayout.debug.disable_xul_cache"
+ type="bool"/>
+ </preferences>
+
+ <hbox>
+ <!-- Event Debugging -->
+ <groupbox id="eventDebugging" align="start" flex="1">
+ <caption label="&debugEvents.label;"/>
+ <checkbox id="nglayoutDebugPaintFlashing"
+ label="&debugPaintFlashing.label;"
+ accesskey="&debugPaintFlashing.accesskey;"
+ preference="nglayout.debug.paint_flashing"/>
+ <checkbox id="nglayoutDebugPaintFlashingChrome"
+ label="&debugPaintFlashingChrome.label;"
+ accesskey="&debugPaintFlashingChrome.accesskey;"
+ preference="nglayout.debug.paint_flashing_chrome"/>
+ <checkbox id="nglayoutDebugPaintDumping"
+ label="&debugPaintDumping.label;"
+ accesskey="&debugPaintDumping.accesskey;"
+ preference="nglayout.debug.paint_dumping"/>
+ <checkbox id="nglayoutDebugInvalidateDumping"
+ label="&debugInvalidateDumping.label;"
+ accesskey="&debugInvalidateDumping.accesskey;"
+ preference="nglayout.debug.invalidate_dumping"/>
+ <checkbox id="nglayoutDebugEventDumping"
+ label="&debugEventDumping.label;"
+ accesskey="&debugEventDumping.accesskey;"
+ preference="nglayout.debug.event_dumping"/>
+ <checkbox id="nglayoutDebugMotionEventDumping"
+ label="&debugMotionEventDumping.label;"
+ accesskey="&debugMotionEventDumping.accesskey;"
+ preference="nglayout.debug.motion_event_dumping"/>
+ <checkbox id="nglayoutDebugCrossingEventDumping"
+ label="&debugCrossingEventDumping.label;"
+ accesskey="&debugCrossingEventDumping.accesskey;"
+ preference="nglayout.debug.crossing_event_dumping"/>
+ </groupbox>
+
+ <vbox align="start" flex="1">
+ <!-- Reflow Event Debugging -->
+ <groupbox id="reflowEventDebugging">
+ <caption label="&debugReflowEvents.label;"/>
+ <checkbox id="layoutReflowShowFrameCounts"
+ label="&debugReflowShowFrameCounts.label;"
+ accesskey="&debugReflowShowFrameCounts.accesskey;"
+ preference="layout.reflow.showframecounts"/>
+ <checkbox id="layoutReflowDumpFrameCounts"
+ label="&debugReflowDumpFrameCounts.label;"
+ accesskey="&debugReflowDumpFrameCounts.accesskey;"
+ preference="layout.reflow.dumpframecounts"/>
+ <checkbox id="layoutReflowDumpFrameByFrameCounts"
+ label="&debugReflowDumpFrameByFrameCounts.label;"
+ accesskey="&debugReflowDumpFrameByFrameCounts.accesskey;"
+ preference="layout.reflow.dumpframebyframecounts"/>
+ </groupbox>
+
+ <!-- Render Debugging -->
+ <groupbox id="renderDebugging">
+ <caption label="&debugRendering.label;"/>
+ <checkbox id="debugXULBoxes"
+ label="&debugXULBox.label;"
+ accesskey="&debugXULBox.accesskey;"
+ preference="xul.debug.box"/>
+ <checkbox id="nglayoutDebugDisableXULCache"
+ label="&debugDisableXULCache.label;"
+ accesskey="&debugDisableXULCache.accesskey;"
+ preference="nglayout.debug.disable_xul_cache"/>
+ </groupbox>
+ </vbox>
+ </hbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-download.js b/comm/suite/components/pref/content/pref-download.js
new file mode 100644
index 0000000000..bc52f800b6
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-download.js
@@ -0,0 +1,197 @@
+/* -*- Mode: Java; 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/. */
+
+var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { FileUtils } =
+ ChromeUtils.import("resource://gre/modules/FileUtils.jsm");
+
+ChromeUtils.defineModuleGetter(this, "Downloads",
+ "resource://gre/modules/Downloads.jsm");
+
+const kDesktop = 0;
+const kDownloads = 1;
+const kUserDir = 2;
+var gFPHandler;
+var gSoundUrlPref;
+
+function Startup()
+{
+ // Define globals
+ gFPHandler = Services.io.getProtocolHandler("file")
+ .QueryInterface(Ci.nsIFileProtocolHandler);
+ gSoundUrlPref = document.getElementById("browser.download.finished_sound_url");
+ setSoundEnabled(document.getElementById("browser.download.finished_download_sound").value);
+}
+
+/**
+ * Enables/disables the folder field and Browse button based on whether a
+ * default download directory is being used.
+ */
+function readUseDownloadDir()
+{
+ var downloadFolder = document.getElementById("downloadFolder");
+ var chooseFolder = document.getElementById("chooseFolder");
+ var preference = document.getElementById("browser.download.useDownloadDir");
+ downloadFolder.disabled = !preference.value;
+ chooseFolder.disabled = !preference.value;
+}
+
+/**
+ * Displays a file picker in which the user can choose the location where
+ * downloads are automatically saved, updating preferences and UI in
+ * response to the choice, if one is made.
+ */
+function chooseFolder()
+{
+ return chooseFolderTask().catch(Cu.reportError);
+}
+
+async function chooseFolderTask()
+{
+ let title = document.getElementById("bundle_prefutilities")
+ .getString("downloadfolder");
+ let folderListPref = document.getElementById("browser.download.folderList");
+ let currentDirPref = await _indexToFolder(folderListPref.value);
+ let defDownloads = await _indexToFolder(kDownloads);
+ let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+
+ fp.init(window, title, Ci.nsIFilePicker.modeGetFolder);
+ fp.appendFilters(Ci.nsIFilePicker.filterAll);
+ // First try to open what's currently configured
+ if (currentDirPref && currentDirPref.exists()) {
+ fp.displayDirectory = currentDirPref;
+ } else if (defDownloads && defDownloads.exists()) {
+ // Try the system's download dir
+ fp.displayDirectory = defDownloads;
+ } else {
+ // Fall back to Desktop
+ fp.displayDirectory = await _indexToFolder(kDesktop);
+ }
+
+ let result = await new Promise(resolve => fp.open(resolve));
+ if (result != Ci.nsIFilePicker.returnOK) {
+ return;
+ }
+
+ document.getElementById("browser.download.dir").value = fp.file;
+ folderListPref.value = await _folderToIndex(fp.file);
+ // Note, the real prefs will not be updated yet, so dnld manager's
+ // userDownloadsDirectory may not return the right folder after
+ // this code executes. displayDownloadDirPref will be called on
+ // the assignment above to update the UI.
+}
+
+/**
+ * Initializes the download folder display settings based on the user's
+ * preferences.
+ */
+function displayDownloadDirPref()
+{
+ displayDownloadDirPrefTask().catch(Cu.reportError);
+}
+
+async function displayDownloadDirPrefTask()
+{
+ var folderListPref = document.getElementById("browser.download.folderList");
+ var currentDirPref = await _indexToFolder(folderListPref.value); // file
+ var prefutilitiesBundle = document.getElementById("bundle_prefutilities");
+ var iconUrlSpec = gFPHandler.getURLSpecFromFile(currentDirPref);
+ var downloadFolder = document.getElementById("downloadFolder");
+ downloadFolder.image = "moz-icon://" + iconUrlSpec + "?size=16";
+
+ // Display a 'pretty' label or the path in the UI.
+ switch (folderListPref.value) {
+ case kDesktop:
+ downloadFolder.label = prefutilitiesBundle.getString("desktopFolderName");
+ break;
+ case kDownloads:
+ downloadFolder.label = prefutilitiesBundle.getString("downloadsFolderName");
+ break;
+ default:
+ downloadFolder.label = currentDirPref ? currentDirPref.path : "";
+ break;
+ }
+}
+
+/**
+ * Returns the Downloads folder. If aFolder is "Desktop", then the Downloads
+ * folder returned is the desktop folder; otherwise, it is a folder whose name
+ * indicates that it is a download folder and whose path is as determined by
+ * the XPCOM directory service via the download manager's attribute
+ * defaultDownloadsDirectory.
+ *
+ * @throws if aFolder is not "Desktop" or "Downloads"
+ */
+async function _getDownloadsFolder(aFolder)
+{
+ switch (aFolder) {
+ case "Desktop":
+ return Services.dirsvc.get("Desk", Ci.nsIFile);
+ case "Downloads":
+ let downloadsDir = await Downloads.getSystemDownloadsDirectory();
+ return new FileUtils.File(downloadsDir);
+ }
+ throw "ASSERTION FAILED: folder type should be 'Desktop' or 'Downloads'";
+}
+
+/**
+ * Determines the type of the given folder.
+ *
+ * @param aFolder
+ * the folder whose type is to be determined
+ * @returns integer
+ * kDesktop if aFolder is the Desktop or is unspecified,
+ * kDownloads if aFolder is the Downloads folder,
+ * kUserDir otherwise
+ */
+async function _folderToIndex(aFolder)
+{
+ if (!aFolder || aFolder.equals(await _getDownloadsFolder("Desktop"))) {
+ return kDesktop;
+ }
+
+ if (aFolder.equals(await _getDownloadsFolder("Downloads"))) {
+ return kDownloads;
+ }
+
+ return kUserDir;
+ }
+
+/**
+ * Converts an integer into the corresponding folder.
+ *
+ * @param aIndex
+ * an integer
+ * @returns the Desktop folder if aIndex == kDesktop,
+ * the Downloads folder if aIndex == kDownloads,
+ * the folder stored in browser.download.dir
+ */
+async function _indexToFolder(aIndex)
+{
+ var folder;
+ switch (aIndex) {
+ case kDownloads:
+ folder = await _getDownloadsFolder("Downloads");
+ break;
+ case kDesktop:
+ folder = await _getDownloadsFolder("Desktop");
+ break;
+ default:
+ folder = document.getElementById("browser.download.dir").value;
+ break;
+ }
+ if (!folder ||
+ !folder.exists()) {
+ return "";
+ }
+
+ return folder;
+}
+
+function setSoundEnabled(aEnable)
+{
+ EnableElementById("downloadSndURL", aEnable, false);
+ document.getElementById("downloadSndPlay").disabled = !aEnable;
+}
diff --git a/comm/suite/components/pref/content/pref-download.xul b/comm/suite/components/pref/content/pref-download.xul
new file mode 100644
index 0000000000..e3f626204c
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-download.xul
@@ -0,0 +1,120 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+%brandDTD;
+<!ENTITY % prefDownloadDTD SYSTEM "chrome://communicator/locale/pref/pref-download.dtd">
+%prefDownloadDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="download_pane"
+ label="&pref.download.title;"
+ script="chrome://communicator/content/pref/pref-download.js">
+
+ <preferences>
+ <preference id="browser.download.manager.behavior"
+ name="browser.download.manager.behavior"
+ type="int"/>
+ <preference id="browser.download.manager.focusWhenStarting"
+ name="browser.download.manager.focusWhenStarting"
+ type="bool" inverted="true"/>
+ <preference id="browser.download.useDownloadDir"
+ name="browser.download.useDownloadDir"
+ type="bool"/>
+ <preference id="browser.download.dir"
+ name="browser.download.dir"
+ type="file"/>
+ <preference id="browser.download.folderList"
+ name="browser.download.folderList"
+ type="int"
+ onchange="displayDownloadDirPref();"/>
+ <preference id="browser.download.finished_download_sound"
+ name="browser.download.finished_download_sound"
+ type="bool"
+ onchange="setSoundEnabled(this.value);"/>
+ <preference id="browser.download.finished_sound_url"
+ name="browser.download.finished_sound_url"
+ type="string"/>
+ </preferences>
+
+ <groupbox>
+ <caption label="&downloadBehavior.label;"/>
+ <radiogroup id="downloadBehavior"
+ preference="browser.download.manager.behavior">
+ <radio value="2"
+ label="&doNothing.label;"
+ accesskey="&doNothing.accesskey;"/>
+ <radio value="1"
+ label="&openProgressDialog.label;"
+ accesskey="&openProgressDialog.accesskey;"/>
+ <radio value="0"
+ label="&openDM.label;"
+ accesskey="&openDM.accesskey;"/>
+ </radiogroup>
+ <checkbox id="focusWhenStarting"
+ class="indent"
+ preference="browser.download.manager.focusWhenStarting"
+ label="&flashWhenOpen.label;"
+ accesskey="&flashWhenOpen.accesskey;"/>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&downloadLocation.label;"/>
+ <radiogroup id="saveWhere"
+ preference="browser.download.useDownloadDir"
+ onsyncfrompreference="return document.getElementById('download_pane').readUseDownloadDir();">
+ <hbox id="saveToRow">
+ <radio id="saveTo" value="true"
+ label="&saveTo.label;"
+ accesskey="&saveTo.accesskey;"
+ aria-labelledby="saveTo downloadFolder"/>
+ <filefield id="downloadFolder" flex="1"
+ preference="browser.download.dir"
+ preference-editable="true"
+ aria-labelledby="saveTo"
+ onsyncfrompreference="document.getElementById('download_pane').displayDownloadDirPref();"/>
+ <button id="chooseFolder" oncommand="chooseFolder();"
+ label="&chooseDownloadFolder.label;"
+ accesskey="&chooseDownloadFolder.accesskey;"/>
+ </hbox>
+ <radio id="alwaysAsk" value="false"
+ label="&alwaysAsk.label;"
+ accesskey="&alwaysAsk.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&finishedBehavior.label;"/>
+ <hbox align="center">
+ <checkbox id="finishedNotificationSound"
+ label="&playSound.label;"
+ preference="browser.download.finished_download_sound"
+ accesskey="&playSound.accesskey;"/>
+ </hbox>
+
+ <hbox align="center" class="indent">
+ <filefield id="downloadSndURL"
+ flex="1"
+ preference="browser.download.finished_sound_url"
+ preference-editable="true"
+ onsyncfrompreference="return WriteSoundField(this, document.getElementById('download_pane').gSoundUrlPref.value);"/>
+ <hbox align="center">
+ <button id="downloadSndBrowse"
+ label="&browse.label;"
+ accesskey="&browse.accesskey;"
+ oncommand="SelectSound(gSoundUrlPref);">
+ <observes element="downloadSndURL" attribute="disabled"/>
+ </button>
+ <button id="downloadSndPlay"
+ label="&playButton.label;"
+ accesskey="&playButton.accesskey;"
+ oncommand="PlaySound(gSoundUrlPref.value, false);"/>
+ </hbox>
+ </hbox>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-findasyoutype.js b/comm/suite/components/pref/content/pref-findasyoutype.js
new file mode 100644
index 0000000000..fefd5a0d46
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-findasyoutype.js
@@ -0,0 +1,15 @@
+/* -*- Mode: Java; 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/. */
+
+function Startup()
+{
+ var prefAutostart = document.getElementById("accessibility.typeaheadfind.autostart");
+ SetLinksOnlyEnabled(prefAutostart.value);
+}
+
+function SetLinksOnlyEnabled(aEnable)
+{
+ EnableElementById("findAsYouTypeAutoWhat", aEnable, false);
+}
diff --git a/comm/suite/components/pref/content/pref-findasyoutype.xul b/comm/suite/components/pref/content/pref-findasyoutype.xul
new file mode 100644
index 0000000000..612b3fa768
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-findasyoutype.xul
@@ -0,0 +1,70 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-findasyoutype.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="findasyoutype_pane"
+ label="&pref.findAsYouType.title;"
+ script="chrome://communicator/content/pref/pref-findasyoutype.js">
+
+ <preferences id="findasyoutype_preferences">
+ <preference id="accessibility.typeaheadfind.autostart"
+ name="accessibility.typeaheadfind.autostart"
+ onchange="SetLinksOnlyEnabled(this.value);"
+ type="bool"/>
+ <preference id="accessibility.typeaheadfind.linksonly"
+ name="accessibility.typeaheadfind.linksonly"
+ type="bool"/>
+ <preference id="accessibility.typeaheadfind.enablesound"
+ name="accessibility.typeaheadfind.enablesound"
+ type="bool"/>
+ <preference id="accessibility.typeaheadfind.enabletimeout"
+ name="accessibility.typeaheadfind.enabletimeout"
+ type="bool"/>
+ <preference id="accessibility.typeaheadfind.usefindbar"
+ name="accessibility.typeaheadfind.usefindbar"
+ type="bool"/>
+ </preferences>
+
+ <groupbox align="start">
+ <caption label="&findAsYouTypeBehavior.label;"/>
+ <checkbox id="findAsYouTypeEnableAuto"
+ label="&findAsYouTypeEnableAuto.label;"
+ accesskey="&findAsYouTypeEnableAuto.accesskey;"
+ preference="accessibility.typeaheadfind.autostart"/>
+ <radiogroup id="findAsYouTypeAutoWhat"
+ class="indent"
+ preference="accessibility.typeaheadfind.linksonly">
+ <radio value="false"
+ label="&findAsYouTypeAutoText.label;"
+ accesskey="&findAsYouTypeAutoText.accesskey;"/>
+ <radio value="true"
+ label="&findAsYouTypeAutoLinks.label;"
+ accesskey="&findAsYouTypeAutoLinks.accesskey;"/>
+ </radiogroup>
+ <description>&findAsYouTypeTip.label;</description>
+
+ <vbox class="box-padded"
+ align="start">
+ <separator class="thin" />
+ <checkbox id="findAsYouTypeSound"
+ label="&findAsYouTypeSound.label;"
+ accesskey="&findAsYouTypeSound.accesskey;"
+ preference="accessibility.typeaheadfind.enablesound"/>
+ <checkbox id="findAsYouTypeTimeout"
+ label="&findAsYouTypeTimeout.label;"
+ accesskey="&findAsYouTypeTimeout.accesskey;"
+ preference="accessibility.typeaheadfind.enabletimeout"/>
+ <checkbox id="findAsYouTypeFindbarEnable"
+ label="&findAsYouTypeFindbarEnable.label;"
+ accesskey="&findAsYouTypeFindbarEnable.accesskey;"
+ preference="accessibility.typeaheadfind.usefindbar"/>
+ </vbox>
+ <description>&findAsYouTypeFindbarEnableTip.label;</description>
+ </groupbox>
+
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-fonts.js b/comm/suite/components/pref/content/pref-fonts.js
new file mode 100644
index 0000000000..aa226c89af
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-fonts.js
@@ -0,0 +1,220 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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/. */
+
+var gAllFonts = null;
+var gFontEnumerator = null;
+var gDisabled = false;
+
+function GetFontEnumerator()
+{
+ if (!gFontEnumerator)
+ {
+ gFontEnumerator = Cc["@mozilla.org/gfx/fontenumerator;1"]
+ .createInstance(Ci.nsIFontEnumerator);
+ }
+ return gFontEnumerator;
+}
+
+function BuildFontList(aLanguage, aFontType, aMenuList, aPreference)
+{
+ var defaultFont = null;
+ // Load Font Lists
+ var fonts = GetFontEnumerator().EnumerateFonts(aLanguage, aFontType);
+ if (fonts.length)
+ {
+ defaultFont = GetFontEnumerator().getDefaultFont(aLanguage, aFontType);
+ }
+ else
+ {
+ fonts = GetFontEnumerator().EnumerateFonts(aLanguage, "");
+ if (fonts.length)
+ defaultFont = GetFontEnumerator().getDefaultFont(aLanguage, "");
+ }
+
+ if (!gAllFonts)
+ gAllFonts = GetFontEnumerator().EnumerateAllFonts();
+
+ // Reset the list
+ while (aMenuList.hasChildNodes())
+ aMenuList.lastChild.remove();
+
+ // Build the UI for the Default Font and Fonts for this CSS type.
+ var popup = document.createElement("menupopup");
+ var separator;
+ if (fonts.length > 0)
+ {
+ const prefutilitiesBundle = document.getElementById("bundle_prefutilities");
+ let label = defaultFont ?
+ prefutilitiesBundle.getFormattedString("labelDefaultFont2", [defaultFont]) :
+ prefutilitiesBundle.getString("labelDefaultFontUnnamed");
+ let menuitem = document.createElement("menuitem");
+ menuitem.setAttribute("label", label);
+ menuitem.setAttribute("value", ""); // Default Font has a blank value
+ popup.appendChild(menuitem);
+
+ separator = document.createElement("menuseparator");
+ popup.appendChild(separator);
+
+ for (let font of fonts)
+ {
+ menuitem = document.createElement("menuitem");
+ menuitem.setAttribute("value", font);
+ menuitem.setAttribute("label", font);
+ popup.appendChild(menuitem);
+ }
+ }
+
+ // Build the UI for the remaining fonts.
+ if (gAllFonts.length > fonts.length)
+ {
+ // Both lists are sorted, and the Fonts-By-Type list is a subset of the
+ // All-Fonts list, so walk both lists side-by-side, skipping values we've
+ // already created menu items for.
+
+ if (fonts.length)
+ {
+ separator = document.createElement("menuseparator");
+ popup.appendChild(separator);
+ }
+
+ for (i = 0; i < gAllFonts.length; ++i)
+ {
+ if (fonts.lastIndexOf(gAllFonts[i], 0) == 0)
+ {
+ fonts.shift(); //Remove matched font from array
+ }
+ else
+ {
+ menuitem = document.createElement("menuitem");
+ menuitem.setAttribute("value", gAllFonts[i]);
+ menuitem.setAttribute("label", gAllFonts[i]);
+ popup.appendChild(menuitem);
+ }
+ }
+ }
+ aMenuList.appendChild(popup);
+
+ // Fully populated so re-enable menulist before setting preference,
+ // unless panel is locked.
+ if (!gDisabled)
+ aMenuList.disabled = false;
+ aMenuList.setAttribute("preference", aPreference.id);
+ aPreference.setElementValue(aMenuList);
+}
+
+function ReadFontLanguageGroup()
+{
+ var prefs = [{format: "default", type: "string", element: "defaultFontType", fonttype: "" },
+ {format: "name.", type: "unichar", element: "serif", fonttype: "serif" },
+ {format: "name.", type: "unichar", element: "sans-serif", fonttype: "sans-serif"},
+ {format: "name.", type: "unichar", element: "monospace", fonttype: "monospace" },
+ {format: "name.", type: "unichar", element: "cursive", fonttype: "cursive" },
+ {format: "name.", type: "unichar", element: "fantasy", fonttype: "fantasy" },
+ {format: "name-list.", type: "unichar", element: null, fonttype: "serif" },
+ {format: "name-list.", type: "unichar", element: null, fonttype: "sans-serif"},
+ {format: "name-list.", type: "unichar", element: null, fonttype: "monospace" },
+ {format: "name-list.", type: "unichar", element: null, fonttype: "cursive" },
+ {format: "name-list.", type: "unichar", element: null, fonttype: "fantasy" },
+ {format: "size.variable", type: "int", element: "sizeVar", fonttype: "" },
+ {format: "size.fixed", type: "int", element: "sizeMono", fonttype: "" },
+ {format: "minimum-size", type: "int", element: "minSize", fonttype: "" }];
+ gDisabled = document.getElementById("browser.display.languageList").locked;
+ var fontLanguage = document.getElementById("font.language.group");
+ if (gDisabled)
+ fontLanguage.disabled = true;
+ var languageGroup = fontLanguage.value;
+ var preferences = document.getElementById("fonts_preferences");
+ for (var i = 0; i < prefs.length; ++i)
+ {
+ var name = "font."+ prefs[i].format + prefs[i].fonttype + "." + languageGroup;
+ var preference = document.getElementById(name);
+ if (!preference)
+ {
+ preference = document.createElement("preference");
+ preference.id = name;
+ preference.setAttribute("name", name);
+ preference.setAttribute("type", prefs[i].type);
+ preferences.appendChild(preference);
+ }
+
+ if (!prefs[i].element)
+ continue;
+
+ var element = document.getElementById(prefs[i].element);
+ if (element)
+ {
+ if (prefs[i].fonttype)
+ {
+ // Set an empty label so it does not jump when items are added.
+ element.setAttribute("label", "");
+ // Disable menulist for the moment.
+ element.disabled = true;
+ // Lazily populate font lists, each gets re-enabled at the end.
+ window.setTimeout(BuildFontList, 0, languageGroup,
+ prefs[i].fonttype, element, preference);
+ }
+ else
+ {
+ // Unless the panel is locked, make sure these elements are not
+ // disabled just in case they were in the last language group.
+ element.disabled = gDisabled;
+ element.setAttribute("preference", preference.id);
+ preference.setElementValue(element);
+ }
+ }
+ }
+}
+
+function ReadFontSelection(aElement)
+{
+ // Determine the appropriate value to select, for the following cases:
+ // - there is no setting
+ // - the font selected by the user is no longer present (e.g. deleted from
+ // fonts folder)
+ var preference = document.getElementById(aElement.getAttribute("preference"));
+ if (preference.value)
+ {
+ var fontItems = aElement.getElementsByAttribute("value", preference.value);
+
+ // There is a setting that actually is in the list. Respect it.
+ if (fontItems.length)
+ return undefined;
+ }
+
+ var defaultValue = aElement.firstChild.firstChild.getAttribute("value");
+ var languagePref = document.getElementById("font.language.group");
+ preference = document.getElementById("font.name-list." + aElement.id + "." + languagePref.value);
+ if (!preference || !preference.hasUserValue)
+ return defaultValue;
+
+ var fontNames = preference.value.split(",");
+
+ for (var i = 0; i < fontNames.length; ++i)
+ {
+ fontItems = aElement.getElementsByAttribute("value", fontNames[i].trim());
+ if (fontItems.length)
+ return fontItems[0].getAttribute("value");
+ }
+ return defaultValue;
+}
+
+function ReadFontPref(aElement, aDefaultValue)
+{
+ // Check to see if preference value exists,
+ // if not return given default value.
+ var preference = document.getElementById(aElement.getAttribute("preference"));
+ return preference.value || aDefaultValue;
+}
+
+function ReadUseDocumentFonts()
+{
+ var preference = document.getElementById("browser.display.use_document_fonts");
+ return preference.value == 1;
+}
+
+function WriteUseDocumentFonts(aUseDocumentFonts)
+{
+ return aUseDocumentFonts.checked ? 1 : 0;
+}
diff --git a/comm/suite/components/pref/content/pref-fonts.xul b/comm/suite/components/pref/content/pref-fonts.xul
new file mode 100644
index 0000000000..554f161a73
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-fonts.xul
@@ -0,0 +1,260 @@
+<?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/. -->
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-fonts.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="fonts_pane"
+ label="&pref.fonts.title;"
+ script="chrome://communicator/content/pref/pref-fonts.js">
+ <preferences id="fonts_preferences">
+ <preference id="font.language.group"
+ name="font.language.group"
+ type="wstring"/>
+ <preference id="browser.display.use_document_fonts"
+ name="browser.display.use_document_fonts"
+ type="int"/>
+ <preference id="browser.display.languageList"
+ name="browser.display.languageList"
+ type="wstring"/>
+ </preferences>
+
+ <groupbox>
+ <caption align="center">
+ <label value="&language.label;"
+ accesskey="&language.accesskey;"
+ control="selectLangs"/>
+ <menulist id="selectLangs" preference="font.language.group"
+ onsyncfrompreference="document.getElementById('fonts_pane').ReadFontLanguageGroup();">
+ <menupopup>
+ <menuitem value="ar" label="&font.langGroup.arabic;"/>
+ <menuitem value="x-armn" label="&font.langGroup.armenian;"/>
+ <menuitem value="x-beng" label="&font.langGroup.bengali;"/>
+ <menuitem value="zh-CN" label="&font.langGroup.simpl-chinese;"/>
+ <menuitem value="zh-TW" label="&font.langGroup.trad-chinese;"/>
+ <menuitem value="zh-HK" label="&font.langGroup.trad-chinese-hk;"/>
+ <menuitem value="x-cyrillic" label="&font.langGroup.cyrillic;"/>
+ <menuitem value="x-devanagari" label="&font.langGroup.devanagari;"/>
+ <menuitem value="x-ethi" label="&font.langGroup.ethiopic;"/>
+ <menuitem value="x-geor" label="&font.langGroup.georgian;"/>
+ <menuitem value="el" label="&font.langGroup.el;"/>
+ <menuitem value="x-gujr" label="&font.langGroup.gujarati;"/>
+ <menuitem value="x-guru" label="&font.langGroup.gurmukhi;"/>
+ <menuitem value="he" label="&font.langGroup.hebrew;"/>
+ <menuitem value="ja" label="&font.langGroup.japanese;"/>
+ <menuitem value="x-knda" label="&font.langGroup.kannada;"/>
+ <menuitem value="x-khmr" label="&font.langGroup.khmer;"/>
+ <menuitem value="ko" label="&font.langGroup.korean;"/>
+ <menuitem value="x-western" label="&font.langGroup.latin;"/>
+ <menuitem value="x-mlym" label="&font.langGroup.malayalam;"/>
+ <menuitem value="x-math" label="&font.langGroup.math;"/>
+ <menuitem value="x-orya" label="&font.langGroup.odia;"/>
+ <menuitem value="x-sinh" label="&font.langGroup.sinhala;"/>
+ <menuitem value="x-tamil" label="&font.langGroup.tamil;"/>
+ <menuitem value="x-telu" label="&font.langGroup.telugu;"/>
+ <menuitem value="th" label="&font.langGroup.thai;"/>
+ <menuitem value="x-tibt" label="&font.langGroup.tibetan;"/>
+ <menuitem value="x-cans" label="&font.langGroup.canadian;"/>
+ <menuitem value="x-unicode" label="&font.langGroup.other;"/>
+ </menupopup>
+ </menulist>
+ </caption>
+
+ <separator class="thin"/>
+
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ <column/>
+ </columns>
+
+ <rows>
+ <row align="center">
+ <spacer/>
+ <label value="&typefaces.label;"/>
+ <label value="&sizes.label;"/>
+ </row>
+ <row>
+ <separator class="thin"/>
+ </row>
+ <row align="center">
+ <hbox align="center" pack="end">
+ <label value="&proportional.label;"
+ accesskey="&proportional.accesskey;"
+ control="defaultFontType"/>
+ </hbox>
+ <menulist id="defaultFontType" flex="1" style="width: 0px;"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadFontSelection(this);">
+ <menupopup>
+ <menuitem value="serif"
+ label="&useDefaultFontSerif.label;"/>
+ <menuitem value="sans-serif"
+ label="&useDefaultFontSansSerif.label;"/>
+ </menupopup>
+ </menulist>
+ <menulist id="sizeVar" class="small-margin"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadFontPref(this, 16);">
+ <menupopup>
+ <menuitem value="8" label="8"/>
+ <menuitem value="9" label="9"/>
+ <menuitem value="10" label="10"/>
+ <menuitem value="11" label="11"/>
+ <menuitem value="12" label="12"/>
+ <menuitem value="13" label="13"/>
+ <menuitem value="14" label="14"/>
+ <menuitem value="15" label="15"/>
+ <menuitem value="16" label="16"/>
+ <menuitem value="17" label="17"/>
+ <menuitem value="18" label="18"/>
+ <menuitem value="20" label="20"/>
+ <menuitem value="22" label="22"/>
+ <menuitem value="24" label="24"/>
+ <menuitem value="26" label="26"/>
+ <menuitem value="28" label="28"/>
+ <menuitem value="30" label="30"/>
+ <menuitem value="32" label="32"/>
+ <menuitem value="34" label="34"/>
+ <menuitem value="36" label="36"/>
+ <menuitem value="40" label="40"/>
+ <menuitem value="44" label="44"/>
+ <menuitem value="48" label="48"/>
+ <menuitem value="56" label="56"/>
+ <menuitem value="64" label="64"/>
+ <menuitem value="72" label="72"/>
+ </menupopup>
+ </menulist>
+ </row>
+ <row>
+ <separator class="thin"/>
+ </row>
+ <row align="center">
+ <hbox align="center" pack="end">
+ <label value="&serif.label;"
+ accesskey="&serif.accesskey;"
+ control="serif"/>
+ </hbox>
+ <menulist id="serif" class="prefpanel-font-list"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadFontSelection(this);"/>
+ <spacer/>
+ </row>
+ <row align="center">
+ <hbox align="center" pack="end">
+ <label value="&sans-serif.label;"
+ accesskey="&sans-serif.accesskey;"
+ control="sans-serif"/>
+ </hbox>
+ <menulist id="sans-serif" class="prefpanel-font-list"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadFontSelection(this);"/>
+ <spacer/>
+ </row>
+ <row align="center">
+ <hbox align="center" pack="end">
+ <label value="&cursive.label;"
+ accesskey="&cursive.accesskey;"
+ control="cursive"/>
+ </hbox>
+ <menulist id="cursive" class="prefpanel-font-list"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadFontSelection(this);"/>
+ <spacer/>
+ </row>
+ <row align="center">
+ <hbox align="center" pack="end">
+ <label value="&fantasy.label;"
+ accesskey="&fantasy.accesskey;"
+ control="fantasy"/>
+ </hbox>
+ <menulist id="fantasy" class="prefpanel-font-list"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadFontSelection(this);"/>
+ <spacer/>
+ </row>
+ <row>
+ <separator class="thin"/>
+ </row>
+ <row align="center">
+ <hbox align="center" pack="end">
+ <label value="&monospace.label;"
+ accesskey="&monospace.accesskey;"
+ control="monospace"/>
+ </hbox>
+ <menulist id="monospace" class="prefpanel-font-list"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadFontSelection(this);"/>
+ <menulist id="sizeMono"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadFontPref(this, 12);">
+ <menupopup>
+ <menuitem value="8" label="8"/>
+ <menuitem value="9" label="9"/>
+ <menuitem value="10" label="10"/>
+ <menuitem value="11" label="11"/>
+ <menuitem value="12" label="12"/>
+ <menuitem value="13" label="13"/>
+ <menuitem value="14" label="14"/>
+ <menuitem value="15" label="15"/>
+ <menuitem value="16" label="16"/>
+ <menuitem value="17" label="17"/>
+ <menuitem value="18" label="18"/>
+ <menuitem value="20" label="20"/>
+ <menuitem value="22" label="22"/>
+ <menuitem value="24" label="24"/>
+ <menuitem value="26" label="26"/>
+ <menuitem value="28" label="28"/>
+ <menuitem value="30" label="30"/>
+ <menuitem value="32" label="32"/>
+ <menuitem value="34" label="34"/>
+ <menuitem value="36" label="36"/>
+ <menuitem value="40" label="40"/>
+ <menuitem value="44" label="44"/>
+ <menuitem value="48" label="48"/>
+ <menuitem value="56" label="56"/>
+ <menuitem value="64" label="64"/>
+ <menuitem value="72" label="72"/>
+ </menupopup>
+ </menulist>
+ </row>
+ <row>
+ <separator class="thin"/>
+ </row>
+ <row>
+ <spacer/>
+ <hbox align="center" pack="end">
+ <label value="&minSize.label;"
+ accesskey="&minSize.accesskey;"
+ control="minSize"/>
+ </hbox>
+ <menulist id="minSize"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadFontPref(this, 0);">
+ <menupopup>
+ <menuitem value="0" label="&minSize.none;"/>
+ <menuitem value="9" label="9"/>
+ <menuitem value="10" label="10"/>
+ <menuitem value="11" label="11"/>
+ <menuitem value="12" label="12"/>
+ <menuitem value="13" label="13"/>
+ <menuitem value="14" label="14"/>
+ <menuitem value="15" label="15"/>
+ <menuitem value="16" label="16"/>
+ <menuitem value="17" label="17"/>
+ <menuitem value="18" label="18"/>
+ <menuitem value="20" label="20"/>
+ <menuitem value="22" label="22"/>
+ <menuitem value="24" label="24"/>
+ </menupopup>
+ </menulist>
+ </row>
+ </rows>
+ </grid>
+ </groupbox>
+
+ <separator class="thin"/>
+
+ <!-- Unchecking this removes the ability to select dynamic fonts -->
+ <checkbox id="browserUseDocumentFonts"
+ label="&useDocumentFonts.label;"
+ accesskey="&useDocumentFonts.accesskey;"
+ preference="browser.display.use_document_fonts"
+ onsyncfrompreference="return document.getElementById('fonts_pane').ReadUseDocumentFonts();"
+ onsynctopreference="return document.getElementById('fonts_pane').WriteUseDocumentFonts(this);"/>
+
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-history.js b/comm/suite/components/pref/content/pref-history.js
new file mode 100644
index 0000000000..8f22073241
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-history.js
@@ -0,0 +1,55 @@
+/* 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/. */
+
+function Startup()
+{
+ var urlbarHistButton = document.getElementById("ClearUrlBarHistoryButton");
+ var lastUrlPref = document.getElementById("general.open_location.last_url");
+ var locBarPref = document.getElementById("browser.urlbar.historyEnabled");
+
+ var isBtnDisabled = lastUrlPref.locked || !locBarPref.value;
+
+ try {
+ if (!isBtnDisabled && !lastUrlPref.hasUserValue) {
+ var file = GetUrlbarHistoryFile();
+ if (!file.exists())
+ isBtnDisabled = true;
+ else {
+ var connection = Services.storage.openDatabase(file);
+ isBtnDisabled = !connection.tableExists("urlbarhistory");
+ connection.close();
+ }
+ }
+ urlbarHistButton.disabled = isBtnDisabled;
+ }
+ catch(ex) {
+ }
+ var globalHistButton = document.getElementById("browserClearHistory");
+ var globalHistory = Cc["@mozilla.org/browser/nav-history-service;1"]
+ .getService(Ci.nsINavHistoryService);
+ if (!globalHistory.hasHistoryEntries)
+ globalHistButton.disabled = true;
+}
+
+function prefClearGlobalHistory()
+{
+ const {PlacesUtils} = ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
+ PlacesUtils.history.clear();
+}
+
+function prefClearUrlbarHistory(aButton)
+{
+ document.getElementById("general.open_location.last_url").valueFromPreferences = "";
+ var file = GetUrlbarHistoryFile();
+ if (file.exists())
+ file.remove(false);
+ aButton.disabled = true;
+}
+
+function prefUrlBarHistoryToggle(aChecked)
+{
+ var file = GetUrlbarHistoryFile();
+ if (file.exists())
+ document.getElementById("ClearUrlBarHistoryButton").disabled = !aChecked;
+}
diff --git a/comm/suite/components/pref/content/pref-history.xul b/comm/suite/components/pref/content/pref-history.xul
new file mode 100644
index 0000000000..63638544c5
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-history.xul
@@ -0,0 +1,99 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-history.dtd" >
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <prefpane id="history_pane"
+ label="&pref.history.title;"
+ script="chrome://communicator/content/pref/pref-history.js">
+ <preferences id="history_preferences">
+ <preference id="places.history.enabled"
+ name="places.history.enabled"
+ type="bool"/>
+ <preference id="pref.browser.history.disable_button.clear_hist"
+ name="pref.browser.history.disable_button.clear_hist"
+ type="bool"/>
+ <preference id="pref.browser.history.disable_button.clear_urlbar"
+ name="pref.browser.history.disable_button.clear_urlbar"
+ type="bool"/>
+ <preference id="browser.urlbar.historyEnabled"
+ name="browser.urlbar.historyEnabled"
+ type="bool"/>
+ <preference id="general.open_location.last_url"
+ name="general.open_location.last_url"
+ type="string"/>
+ <preference id="browser.formfill.enable"
+ name="browser.formfill.enable"
+ type="bool"/>
+ <preference id="browser.formfill.expire_days"
+ name="browser.formfill.expire_days"
+ type="int"/>
+ </preferences>
+
+ <groupbox>
+ <caption label="&pref.history.caption;"/>
+ <hbox align="center">
+ <description flex="1">&historyPages.label;</description>
+ <hbox align="center"
+ pack="end">
+ <button label="&clearHistory.label;"
+ accesskey="&clearHistory.accesskey;"
+ oncommand="prefClearGlobalHistory();"
+ id="browserClearHistory"
+ preference="pref.browser.history.disable_button.clear_hist"/>
+ </hbox>
+ </hbox>
+ <checkbox id="histEnable"
+ label="&enableHistory.label;"
+ accesskey="&enableHistory.accesskey;"
+ preference="places.history.enabled"/>
+ </groupbox>
+
+ <!-- no honey, I haven't been viewing porn, honest! -->
+ <groupbox>
+ <caption label="&locationBarHistory.caption;"/>
+ <hbox align="center">
+ <vbox pack="end">
+ <checkbox id="urlbarHistoryEnabled"
+ label="&urlBarHistoryEnabled.caption;"
+ accesskey="&urlBarHistoryEnabled.accesskey;"
+ preference="browser.urlbar.historyEnabled"
+ oncommand="prefUrlBarHistoryToggle(this.checked);"/>
+ <hbox align="center"
+ pack="end">
+ <description flex="1">&clearLocationBar.label;</description>
+ <button id="ClearUrlBarHistoryButton"
+ label="&clearLocationBarButton.label;"
+ accesskey="&clearLocationBarButton.accesskey;"
+ oncommand="prefClearUrlbarHistory(this); this.disabled = true;"
+ preference="pref.browser.history.disable_button.clear_urlbar"/>
+ </hbox>
+ </vbox>
+ </hbox>
+ </groupbox>
+
+ <!-- form history -->
+ <groupbox>
+ <caption label="&formfillHistory.caption;"/>
+ <checkbox id="formfillEnable"
+ label="&enableFormfill.label;"
+ accesskey="&enableFormfill.accesskey;"
+ preference="browser.formfill.enable"/>
+ <hbox align="center">
+ <label value="&formfillExpire.label;"
+ accesskey="&formfillExpire.accesskey;"
+ control="formfillDay"/>
+ <textbox id="formfillDay"
+ type="number"
+ size="4"
+ preference="browser.formfill.expire_days"/>
+ <label value="&formfillDays.label;"/>
+ </hbox>
+ </groupbox>
+ </prefpane>
+
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-http.js b/comm/suite/components/pref/content/pref-http.js
new file mode 100644
index 0000000000..eb04b9f274
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-http.js
@@ -0,0 +1,42 @@
+/* -*- Mode: Java; 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/. */
+
+function Startup() {
+ let compatMode = document.getElementById("uaFirefoxCompat");
+ let modeFirefox =
+ document.getElementById("general.useragent.compatMode.firefox");
+ let modeStrict =
+ document.getElementById("general.useragent.compatMode.strict-firefox");
+
+ if (modeStrict.value)
+ compatMode.value = "strict";
+ else if (modeFirefox.value)
+ compatMode.value = "compat";
+ else
+ compatMode.value = "none";
+}
+
+function updateUAPrefs(aCompatMode) {
+ let modeFirefox =
+ document.getElementById("general.useragent.compatMode.firefox");
+ // The strict option will only work in builds compiled from a SeaMonkey
+ // release branch. Additional code needs to be added to the mozilla sources.
+ // See Bug 1242294 for the needed changes.
+ let modeStrict =
+ document.getElementById("general.useragent.compatMode.strict-firefox");
+ switch (aCompatMode.value) {
+ case "strict":
+ modeStrict.value = true;
+ modeFirefox.value = false;
+ break;
+ case "compat":
+ modeStrict.value = false;
+ modeFirefox.value = true;
+ break;
+ case "none":
+ modeStrict.value = false;
+ modeFirefox.value = false;
+ }
+}
diff --git a/comm/suite/components/pref/content/pref-http.xul b/comm/suite/components/pref/content/pref-http.xul
new file mode 100644
index 0000000000..bea6545418
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-http.xul
@@ -0,0 +1,82 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-http.dtd">
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="http_pane"
+ label="&pref.http.title;"
+ script="chrome://communicator/content/pref/pref-http.js">
+
+ <preferences>
+ <preference id="network.http.version"
+ name="network.http.version"
+ type="string"/>
+ <preference id="network.http.proxy.version"
+ name="network.http.proxy.version"
+ type="string"/>
+ <preference id="general.useragent.compatMode.firefox"
+ name="general.useragent.compatMode.firefox"
+ type="bool"/>
+ <preference id="general.useragent.compatMode.strict-firefox"
+ name="general.useragent.compatMode.strict-firefox"
+ type="bool"/>
+ </preferences>
+
+ <description>&prefPara;</description>
+
+ <hbox align="start">
+ <groupbox flex="1">
+ <caption label="&prefDirect.label;"/>
+ <vbox class="indent" align="start">
+ <radiogroup id="httpVersion"
+ preference="network.http.version">
+ <radio value="1.0"
+ label="&prefEnableHTTP10.label;"
+ accesskey="&prefEnableHTTP10.accesskey;"/>
+ <radio value="1.1"
+ label="&prefEnableHTTP11.label;"
+ accesskey="&prefEnableHTTP11.accesskey;"/>
+ </radiogroup>
+ </vbox>
+ </groupbox>
+
+ <groupbox flex="1">
+ <caption label="&prefProxy.label;"/>
+ <vbox class="indent" align="start">
+ <radiogroup id="httpVersionProxy"
+ preference="network.http.proxy.version">
+ <radio value="1.0"
+ label="&prefEnableHTTP10.label;"
+ accesskey="&prefEnableHTTP10Proxy.accesskey;"/>
+ <radio value="1.1"
+ label="&prefEnableHTTP11.label;"
+ accesskey="&prefEnableHTTP11Proxy.accesskey;"/>
+ </radiogroup>
+ </vbox>
+ </groupbox>
+ </hbox>
+
+ <separator class="thin"/>
+
+ <groupbox>
+ <caption label="&prefUseragent.label;"/>
+ <radiogroup id="uaFirefoxCompat"
+ oncommand="updateUAPrefs(this);">
+ <radio value="strict"
+ label="&prefFirefoxStrict.label;"
+ accesskey="&prefFirefoxStrict.accesskey;"/>
+ <radio value="none"
+ label="&prefFirefoxNone.label;"
+ accesskey="&prefFirefoxNone.accesskey;"/>
+ <radio value="compat"
+ label="&prefFirefoxCompat2.label;"
+ accesskey="&prefFirefoxCompat2.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+
+ <description>&prefCompatWarning2.desc;</description>
+ </prefpane>
+
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-images.xul b/comm/suite/components/pref/content/pref-images.xul
new file mode 100644
index 0000000000..92c048dc56
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-images.xul
@@ -0,0 +1,47 @@
+<?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/. -->
+<!DOCTYPE overlay [
+<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
+%brandDTD;
+<!ENTITY % prefImagesDTD SYSTEM "chrome://communicator/locale/pref/pref-images.dtd" >
+%prefImagesDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="images_pane"
+ label="&pref.images.title;">
+ <preferences id="images_preferences">
+ <preference id="permissions.default.image"
+ name="permissions.default.image" type="int"/>
+ <preference id="pref.advanced.images.disable_button.view_image" type="bool"
+ name="pref.advanced.images.disable_button.view_image"/>
+ </preferences>
+
+ <groupbox id="imagesArea">
+ <caption label="&imageBlocking.label;"/>
+
+ <description>&imageDetails;</description>
+
+ <radiogroup id="networkImageBehaviour"
+ preference="permissions.default.image">
+ <radio value="2" label="&loadNoImagesRadio.label;"
+ accesskey="&loadNoImagesRadio.accesskey;"/>
+ <radio value="3" label="&loadOrgImagesRadio.label;"
+ accesskey="&loadOrgImagesRadio.accesskey;"/>
+ <radio value="1" label="&loadAllImagesRadio.label;"
+ accesskey="&loadAllImagesRadio.accesskey;"/>
+ </radiogroup>
+
+ <hbox pack="end">
+ <button id="viewImages"
+ label="&viewPermissions.label;"
+ accesskey="&viewPermissions.accesskey;"
+ oncommand="toDataManager('|permissions');"
+ preference="pref.advanced.images.disable_button.view_image"/>
+ </hbox>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-keynav.js b/comm/suite/components/pref/content/pref-keynav.js
new file mode 100644
index 0000000000..5210fdbe5c
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-keynav.js
@@ -0,0 +1,54 @@
+/* -*- Mode: Java; 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/. */
+
+var {AppConstants} = ChromeUtils.import(
+ "resource://gre/modules/AppConstants.jsm"
+);
+
+const kTabToLinks = 4;
+const kTabToForms = 2;
+const kTabToTextboxes = 1;
+
+function Startup()
+{
+ if (AppConstants.platform == "macosx") {
+ document.getElementById("tabNavigationPrefs").setAttribute("hidden", true);
+ }
+
+ UpdateBrowseWithCaretItems();
+}
+
+function ReadTabNav(aField)
+{
+ var curval = document.getElementById("accessibility.tabfocus").value;
+ // Return the right bit based on the id of "aField"
+ if (aField.id == "tabNavigationLinks")
+ return (curval & kTabToLinks) != 0;
+
+ return (curval & kTabToForms) != 0;
+}
+
+function WriteTabNav(aField)
+{
+ var curval = document.getElementById("accessibility.tabfocus").value;
+ // Textboxes are always part of the tab order
+ curval |= kTabToTextboxes;
+ // Select the bit, we have to change, based on the id of "aField"
+ var bit = kTabToForms;
+ if (aField.id == "tabNavigationLinks")
+ bit = kTabToLinks;
+
+ if (aField.checked)
+ return curval | bit;
+
+ return curval & ~bit;
+}
+
+function UpdateBrowseWithCaretItems()
+{
+ document.getElementById("browseWithCaretWarn").disabled =
+ !document.getElementById("accessibility.browsewithcaret_shortcut.enabled").value ||
+ document.getElementById("accessibility.browsewithcaret").locked;
+}
diff --git a/comm/suite/components/pref/content/pref-keynav.xul b/comm/suite/components/pref/content/pref-keynav.xul
new file mode 100644
index 0000000000..39ea0e7d1f
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-keynav.xul
@@ -0,0 +1,104 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-keynav.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="keynav_pane"
+ label="&pref.keyNav.title;"
+ script="chrome://communicator/content/pref/pref-keynav.js">
+
+ <preferences id="keynav_preferences">
+ <preference id="accessibility.tabfocus"
+ name="accessibility.tabfocus"
+ type="int"/>
+ <preference id="accessibility.browsewithcaret"
+ name="accessibility.browsewithcaret"
+ type="bool"/>
+ <preference id="accessibility.browsewithcaret_shortcut.enabled"
+ name="accessibility.browsewithcaret_shortcut.enabled"
+ type="bool"
+ onchange="UpdateBrowseWithCaretItems();"/>
+ <preference id="accessibility.warn_on_browsewithcaret"
+ name="accessibility.warn_on_browsewithcaret"
+ type="bool"/>
+ <preference id="ui.key.accelKey"
+ name="ui.key.accelKey"
+ type="int"/>
+ <preference id="ui.key.menuAccessKey"
+ name="ui.key.menuAccessKey"
+ type="int"/>
+ </preferences>
+
+ <groupbox id="tabNavigationPrefs"
+ align="start">
+ <caption label="&tabNavigationBehavior.label;"/>
+ <description>&tabNavigationDesc.label;</description>
+
+ <checkbox id="tabNavigationLinks"
+ label="&tabNavigationLinks.label;"
+ accesskey="&tabNavigationLinks.accesskey;"
+ preference="accessibility.tabfocus"
+ onsyncfrompreference="return document.getElementById('keynav_pane').ReadTabNav(this);"
+ onsynctopreference="return document.getElementById('keynav_pane').WriteTabNav(this);"/>
+ <checkbox id="tabNavigationForms"
+ label="&tabNavigationForms.label;"
+ accesskey="&tabNavigationForms.accesskey;"
+ preference="accessibility.tabfocus"
+ onsyncfrompreference="return document.getElementById('keynav_pane').ReadTabNav(this);"
+ onsynctopreference="return document.getElementById('keynav_pane').WriteTabNav(this);"/>
+ <description>&tabNavigationTextboxes.label;</description>
+ </groupbox>
+
+ <groupbox id="browseWithCaretPrefs"
+ align="start">
+ <caption label="&accessibilityBrowseWithCaret.label;"/>
+ <description>&browseWithCaretDesc.label;</description>
+ <checkbox id="browseWithCaretUse"
+ label="&browseWithCaretUse.label;"
+ accesskey="&browseWithCaretUse.accesskey;"
+ preference="accessibility.browsewithcaret"/>
+ <checkbox id="browseWithCaretShortCut"
+ label="&browseWithCaretShortCut.label;"
+ accesskey="&browseWithCaretShortCut.accesskey;"
+ preference="accessibility.browsewithcaret_shortcut.enabled"/>
+ <checkbox id="browseWithCaretWarn"
+ class="indent"
+ label="&browseWithCaretWarn.label;"
+ accesskey="&browseWithCaretWarn.accesskey;"
+ preference="accessibility.warn_on_browsewithcaret"/>
+ </groupbox>
+
+ <groupbox id="modifiers">
+ <caption label="&modifiers.label;"/>
+ <hbox align="center">
+ <label id="acceleratorKey"
+ value="&acceleratorKey.label;"
+ accesskey="&acceleratorKey.accesskey;"
+ control="acceleratorKeyValue"/>
+ <textbox id="acceleratorKeyValue"
+ type="number"
+ min="0"
+ max="255"
+ size="3"
+ preference="ui.key.accelKey"
+ aria-labelledby="acceleratorKey acceleratorKeyValue"/>
+ <label id="menuAccessKey"
+ value="&menuAccessKey.label;"
+ accesskey="&menuAccessKey.accesskey;"
+ control="menuAccessKeyValue"/>
+ <textbox id="menuAccessKeyValue"
+ type="number"
+ min="0"
+ max="255"
+ size="3"
+ preference="ui.key.menuAccessKey"
+ aria-labelledby="menuAccessKey menuAccessKeyValue"/>
+ </hbox>
+ <description>&modifiersDesc.label;</description>
+ </groupbox>
+
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-languages-add.js b/comm/suite/components/pref/content/pref-languages-add.js
new file mode 100644
index 0000000000..e539b961cc
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-languages-add.js
@@ -0,0 +1,147 @@
+/* -*- Mode: Java; tab-width: 4; 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/. */
+
+var gLanguageNames;
+var gAvailableLanguages;
+var gOtherLanguages;
+var gSelectedLanguages = [];
+var gInvalidLanguages;
+
+function OnLoadAddLanguages()
+{
+ gLanguageNames = window.arguments[0];
+ gAvailableLanguages = document.getElementById("availableLanguages");
+ gSelectedLanguages = document.getElementById("intl.accept_languages").value
+ .toLowerCase().split(/\s*,\s*/);
+ gOtherLanguages = document.getElementById("otherLanguages");
+
+ if (gLanguageNames)
+ {
+ for (var i = 0; i < gLanguageNames.length; i++)
+ {
+ if (!gSelectedLanguages.includes(gLanguageNames[i][1]))
+ gAvailableLanguages.appendItem(gLanguageNames[i][0],
+ gLanguageNames[i][1]);
+ }
+ }
+}
+
+function IsRFC1766LangTag(aCandidate)
+{
+ /* reject bogus lang strings, INCLUDING those with HTTP "q"
+ values kludged on the end of them
+
+ Valid language codes examples:
+ i.e. ja-JP-kansai (Kansai dialect of Japanese)
+ en-US-texas (Texas dialect)
+ i-klingon-tng (did TOS Klingons speak in non-English?)
+ sgn-US-MA (Martha Vineyard's Sign Language)
+ */
+ var tags = aCandidate.split('-');
+ var checkedTags = 0;
+
+ if (/^[ix]$/.test(tags[0]))
+ {
+ if (tags.length < 2)
+ return false;
+ checkedTags++;
+ }
+ else
+ /* if not IANA "i" or a private "x" extension, the primary
+ tag should be a ISO 639 country code, two or three letters long.
+ we don't check if the country code is bogus or not.
+ */
+ {
+ if (!/^[a-z]{2,3}$/.test(tags[0]))
+ return false;
+ checkedTags++;
+
+ /* the first subtag can be either a 2 letter ISO 3166 country code,
+ or an IANA registered tag from 3 to 8 characters.
+ */
+ if (tags.length > 1)
+ {
+ if (!/^[a-z0-9]{2,8}$/.test(tags[1]))
+ return false;
+
+ /* do not allow user-assigned ISO 3166 country codes */
+ if (/^(aa|zz|x[a-z]|q[m-z])$/.test(tags[1]))
+ return false;
+ checkedTags++;
+ }
+ }
+
+ /* any remaining subtags must be one to eight alphabetic characters */
+
+ while (checkedTags < tags.length)
+ {
+ if (!/^[a-z0-9]{1,8}$/.test(tags[checkedTags]))
+ return false;
+ checkedTags++;
+ }
+ return true;
+}
+
+function WriteAddedLanguages(aListbox)
+{
+ var invalidLangs = [];
+ // selected languages
+ var languages = aListbox.selectedItems;
+ var addedLang = Array.from(languages, e => e.value);
+
+ // user-defined languages
+ languages = gOtherLanguages.value;
+ if (languages)
+ {
+ let languageIds = languages.replace(/\s+/g, "").toLowerCase().split(",");
+ for (var i = 0; i < languageIds.length; i++)
+ {
+ let languageId = languageIds[i];
+ if (IsRFC1766LangTag(languageId))
+ {
+ if (!addedLang.includes(languageId) &&
+ !gSelectedLanguages.includes(languageId))
+ addedLang.push(languageId);
+ }
+ else
+ {
+ invalidLangs.push(languageId);
+ }
+ }
+ }
+
+ if (invalidLangs.length)
+ gInvalidLanguages = invalidLangs.join(", ");
+ else
+ gSelectedLanguages = gSelectedLanguages.concat(addedLang);
+
+ return gSelectedLanguages.join(",");
+}
+
+function OnAccept()
+{
+ if (!gInvalidLanguages)
+ return true;
+
+ let prefLangBundle = document.getElementById("prefLangAddBundle");
+ const kErrorMsg = prefLangBundle.getString("illegalOtherLanguage") + " " +
+ gInvalidLanguages;
+ const kErrorTitle = prefLangBundle.getString("illegalOtherLanguageTitle");
+ Services.prompt.alert(this.window, kErrorTitle, kErrorMsg);
+
+ gInvalidLanguages = null;
+ gOtherLanguages.focus();
+ return false;
+}
+
+function HandleDoubleClick()
+{
+ document.documentElement.acceptDialog();
+}
+
+function DoBeforeAccept()
+{
+ gAvailableLanguages.doCommand();
+}
diff --git a/comm/suite/components/pref/content/pref-languages-add.xul b/comm/suite/components/pref/content/pref-languages-add.xul
new file mode 100644
index 0000000000..0ae11aee9b
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-languages-add.xul
@@ -0,0 +1,54 @@
+<?xml version="1.0"?> <!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
+<!--
+
+ 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://communicator/skin/" type="text/css"?>
+
+<!DOCTYPE prefwindow SYSTEM "chrome://communicator/locale/pref/pref-languages.dtd" >
+
+
+<prefwindow xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="addLanguagesPreferences"
+ title="&languages.customize.add.title.label;"
+ type="child"
+ onload="OnLoadAddLanguages();"
+ onbeforeaccept="DoBeforeAccept();"
+ ondialogaccept="return OnAccept();">
+
+ <script src="chrome://communicator/content/pref/pref-languages-add.js"/>
+
+ <prefpane id="addLanguagesPane">
+ <preferences id="addLanguages">
+ <preference id="intl.accept_languages"
+ name="intl.accept_languages"
+ type="wstring"/>
+ </preferences>
+
+ <stringbundleset id="langAddBundleset">
+ <stringbundle id="prefLangAddBundle"
+ src="chrome://communicator/locale/pref/pref-languages.properties"/>
+ </stringbundleset>
+
+ <description style="width: 1px;">&languages.customize.prefAddLangDescript;</description>
+ <separator class="thin"/>
+ <description style="width: 1px;">&languages.customize.available.label;</description>
+
+ <listbox id="availableLanguages"
+ flex="1"
+ seltype="multiple"
+ preference="intl.accept_languages"
+ ondblclick="HandleDoubleClick();"
+ onsynctopreference="return WriteAddedLanguages(this);"/>
+
+ <hbox align="center">
+ <label value="&languages.customize.others.label;"
+ accesskey="&languages.customize.others.accesskey;"
+ control="otherLanguages"/>
+ <textbox id="otherLanguages" size="12" flex="1"/>
+ <label value="&languages.customize.others.examples;" control="otherLanguages"/>
+ </hbox>
+ </prefpane>
+</prefwindow>
diff --git a/comm/suite/components/pref/content/pref-languages.js b/comm/suite/components/pref/content/pref-languages.js
new file mode 100644
index 0000000000..de2895ee11
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-languages.js
@@ -0,0 +1,200 @@
+/* -*- Mode: Java; tab-width: 4; 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/. */
+
+var gActiveLanguages;
+var gLanguages;
+var gLanguageNames = [];
+var gLanguageTitles = {};
+
+function Startup()
+{
+ gActiveLanguages = document.getElementById("activeLanguages");
+ // gLanguages stores the ordered list of languages, due to the nature
+ // of childNodes it is live and updates automatically.
+ gLanguages = gActiveLanguages.childNodes;
+
+ ReadAvailableLanguages();
+}
+
+function AddLanguage()
+{
+ document.documentElement.openSubDialog("chrome://communicator/content/pref/pref-languages-add.xul", "addlangwindow", gLanguageNames);
+}
+
+function ReadAvailableLanguages()
+{
+ var i = 0;
+ var languagesBundle = document.getElementById("languageNamesBundle");
+ var prefLangBundle = document.getElementById("prefLangBundle");
+ var regionsBundle = document.getElementById("regionNamesBundle");
+ var langStrings = document.getElementById("acceptedBundle").strings;
+
+ while (langStrings.hasMoreElements())
+ {
+ // Progress through the bundle.
+ var curItem = langStrings.getNext();
+
+ if (!(curItem instanceof Ci.nsIPropertyElement))
+ break;
+
+ var stringNameProperty = curItem.key.split('.');
+
+ var str = stringNameProperty[0];
+ if (str && stringNameProperty[1] == 'accept')
+ {
+ var stringLangRegion = str.split('-');
+
+ if (stringLangRegion[0])
+ {
+ var language = "";
+ var region = null;
+
+ try
+ {
+ language = languagesBundle.getString(stringLangRegion[0]);
+ }
+ catch (ex) {}
+
+ if (stringLangRegion.length > 1)
+ {
+ try
+ {
+ region = regionsBundle.getString(stringLangRegion[1]);
+ }
+ catch (ex) {}
+ }
+
+ var title;
+ if (region)
+ title = prefLangBundle.getFormattedString("languageRegionCodeFormat",
+ [language, region, str]);
+ else
+ title = prefLangBundle.getFormattedString("languageCodeFormat",
+ [language, str]);
+ gLanguageTitles[str] = title;
+ if (curItem.value == "true")
+ gLanguageNames.push([title, str]);
+ }
+ }
+ }
+
+ // Sort on first element.
+ gLanguageNames.sort(
+ function compareFn(a, b)
+ {
+ return a[0].localeCompare(b[0]);
+ }
+ );
+}
+
+function ReadActiveLanguages()
+{
+ var arrayOfPrefs = document.getElementById("intl.accept_languages").value
+ .toLowerCase().split(/\s*,\s*/);
+
+ // No need to rebuild listitems if languages in prefs and listitems match.
+ if (InSync(arrayOfPrefs))
+ return;
+
+ while (gActiveLanguages.hasChildNodes())
+ gActiveLanguages.lastChild.remove();
+
+ arrayOfPrefs.forEach(
+ function(aKey)
+ {
+ if (aKey)
+ {
+ let langTitle = gLanguageTitles.hasOwnProperty(aKey) ?
+ gLanguageTitles[aKey] : "[" + aKey + "]";
+ gActiveLanguages.appendItem(langTitle, aKey);
+ }
+ }
+ );
+
+ SelectLanguage();
+
+ return;
+}
+
+// Checks whether listitems and pref values matches, returns false if not.
+function InSync(aPrefArray)
+{
+ // Can't match if they don't have the same length.
+ if (aPrefArray.length != gLanguages.length)
+ return false;
+
+ return aPrefArray.every(
+ function(aElement, aIndex)
+ {
+ return aElement == gLanguages[aIndex].value;
+ }
+ );
+}
+
+// Called on onsynctopreference.
+function WriteActiveLanguages()
+{
+ return Array.from(gLanguages, e => e.value).join(",");
+}
+
+function MoveUp()
+{
+ var selected = gActiveLanguages.selectedItem;
+ var before = selected.previousSibling;
+ if (before)
+ {
+ before.parentNode.insertBefore(selected, before);
+ gActiveLanguages.selectItem(selected);
+ gActiveLanguages.ensureElementIsVisible(selected);
+ }
+
+ SelectLanguage();
+ gActiveLanguages.doCommand();
+}
+
+function MoveDown()
+{
+ var selected = gActiveLanguages.selectedItem;
+ if (selected.nextSibling)
+ {
+ var before = selected.nextSibling.nextSibling;
+ gActiveLanguages.insertBefore(selected, before);
+ gActiveLanguages.selectItem(selected);
+ }
+
+ SelectLanguage();
+ gActiveLanguages.doCommand();
+}
+
+function RemoveActiveLanguage(aEvent)
+{
+ if (aEvent && aEvent.keyCode != aEvent.DOM_VK_DELETE &&
+ aEvent.keyCode != aEvent.DOM_VK_BACK_SPACE)
+ return;
+
+ var nextNode = null;
+
+ while (gActiveLanguages.selectedItem)
+ {
+ var selectedNode = gActiveLanguages.selectedItem;
+ nextNode = selectedNode.nextSibling || selectedNode.previousSibling;
+ selectedNode.remove();
+ }
+
+ if (nextNode)
+ gActiveLanguages.selectItem(nextNode);
+
+ SelectLanguage();
+ gActiveLanguages.doCommand();
+}
+
+function SelectLanguage()
+{
+ var len = gActiveLanguages.selectedItems.length;
+ EnableElementById("langRemove", len, false);
+ var selected = gActiveLanguages.selectedItem;
+ EnableElementById("langDown", (len == 1) && selected.nextSibling, false);
+ EnableElementById("langUp", (len == 1) && selected.previousSibling, false);
+}
diff --git a/comm/suite/components/pref/content/pref-languages.xul b/comm/suite/components/pref/content/pref-languages.xul
new file mode 100644
index 0000000000..a17deae032
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-languages.xul
@@ -0,0 +1,124 @@
+<?xml version="1.0"?> <!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
+<!--
+
+ 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 overlay [
+ <!ENTITY % prefLanguagesDTD SYSTEM "chrome://communicator/locale/pref/pref-languages.dtd"> %prefLanguagesDTD;
+ <!ENTITY % prefUtilitiesDTD SYSTEM "chrome://communicator/locale/pref/prefutilities.dtd"> %prefUtilitiesDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="languages_pane"
+ label="&languages.customize.title;"
+ script="chrome://communicator/content/pref/pref-languages.js">
+
+ <preferences id="languages_preferences">
+ <preference id="intl.accept_languages"
+ name="intl.accept_languages"
+ type="wstring"/>
+ <preference id="pref.browser.language.disable_button.up"
+ name="pref.browser.language.disable_button.up"
+ type="bool"/>
+ <preference id="pref.browser.language.disable_button.down"
+ name="pref.browser.language.disable_button.down"
+ type="bool"/>
+ <preference id="pref.browser.language.disable_button.add"
+ name="pref.browser.language.disable_button.add"
+ type="bool"/>
+ <preference id="pref.browser.language.disable_button.remove"
+ name="pref.browser.language.disable_button.remove"
+ type="bool"/>
+ <preference id="intl.charset.fallback.override"
+ name="intl.charset.fallback.override"
+ type="string"/>
+ </preferences>
+
+ <stringbundleset id="langBundleset">
+ <stringbundle id="acceptedBundle"
+ src="resource://gre/res/language.properties"/>
+ <stringbundle id="prefLangBundle"
+ src="chrome://communicator/locale/pref/pref-languages.properties"/>
+ </stringbundleset>
+
+ <groupbox flex="1">
+ <caption label="&langtitle.label;"/>
+ <description>&languages.customize.prefLangDescript;</description>
+ <label accesskey="&languages.customize.active.accesskey;"
+ control="activeLanguages">&languages.customize.active.label;</label>
+ <hbox flex="1">
+ <listbox id="activeLanguages"
+ flex="1"
+ style="width: 0px; height: 0px;"
+ seltype="multiple"
+ preference="intl.accept_languages"
+ onkeypress="RemoveActiveLanguage(event);"
+ onselect="SelectLanguage();"
+ onsynctopreference="return document.getElementById('languages_pane').WriteActiveLanguages();"
+ onsyncfrompreference="return document.getElementById('languages_pane').ReadActiveLanguages(this);"/>
+ <vbox>
+ <button id="langUp"
+ class="up"
+ disabled="true"
+ label="&languages.customize.moveUp.label;"
+ accesskey="&languages.customize.moveUp.accesskey;"
+ preference="pref.browser.language.disable_button.up"
+ oncommand="MoveUp();"/>
+ <button id="langDown"
+ class="down"
+ disabled="true"
+ label="&languages.customize.moveDown.label;"
+ accesskey="&languages.customize.moveDown.accesskey;"
+ preference="pref.browser.language.disable_button.down"
+ oncommand="MoveDown();"/>
+ <spacer flex="1"/>
+ <button id="langAdd"
+ label="&languages.customize.addButton.label;"
+ accesskey="&languages.customize.addButton.accesskey;"
+ preference="pref.browser.language.disable_button.add"
+ oncommand="AddLanguage();"/>
+ <button id="langRemove"
+ disabled="true"
+ label="&languages.customize.deleteButton.label;"
+ accesskey="&languages.customize.deleteButton.accesskey;"
+ preference="pref.browser.language.disable_button.remove"
+ oncommand="RemoveActiveLanguage(null);"/>
+ </vbox>
+ </hbox>
+ </groupbox>
+
+ <groupbox align="start">
+ <caption label="&languages.customize.Fallback2.grouplabel;"/>
+ <description>&languages.customize.Fallback2.desc;</description>
+ <hbox align="center">
+ <label value="&languages.customize.Fallback2.label;"
+ accesskey="&languages.customize.Fallback2.accesskey;"
+ control="defaultCharsetList"/>
+ <menulist id="defaultCharsetList"
+ preference="intl.charset.fallback.override">
+ <menupopup>
+ <menuitem label="&FallbackCharset.auto;" value=""/>
+ <menuitem label="&FallbackCharset.arabic;" value="windows-1256"/>
+ <menuitem label="&FallbackCharset.baltic;" value="windows-1257"/>
+ <menuitem label="&FallbackCharset.ceiso;" value="ISO-8859-2"/>
+ <menuitem label="&FallbackCharset.cewindows;" value="windows-1250"/>
+ <menuitem label="&FallbackCharset.simplified;" value="gbk"/>
+ <menuitem label="&FallbackCharset.traditional;" value="Big5"/>
+ <menuitem label="&FallbackCharset.cyrillic;" value="windows-1251"/>
+ <menuitem label="&FallbackCharset.greek;" value="ISO-8859-7"/>
+ <menuitem label="&FallbackCharset.hebrew;" value="windows-1255"/>
+ <menuitem label="&FallbackCharset.japanese;" value="Shift_JIS"/>
+ <menuitem label="&FallbackCharset.korean;" value="EUC-KR"/>
+ <menuitem label="&FallbackCharset.thai;" value="windows-874"/>
+ <menuitem label="&FallbackCharset.turkish;" value="windows-1254"/>
+ <menuitem label="&FallbackCharset.vietnamese;" value="windows-1258"/>
+ <menuitem label="&FallbackCharset.other;" value="windows-1252"/>
+ </menupopup>
+ </menulist>
+ </hbox>
+ </groupbox>
+
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-links.js b/comm/suite/components/pref/content/pref-links.js
new file mode 100644
index 0000000000..2ca7a3e921
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-links.js
@@ -0,0 +1,15 @@
+/* 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/. */
+
+function Startup()
+{
+ ToggleRestrictionGroup(document.getElementById("browser.link.open_newwindow").value);
+}
+
+function ToggleRestrictionGroup(value)
+{
+ document.getElementById("restrictionGroup").disabled =
+ value == Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW ||
+ document.getElementById("browser.link.open_newwindow.restriction").locked;
+}
diff --git a/comm/suite/components/pref/content/pref-links.xul b/comm/suite/components/pref/content/pref-links.xul
new file mode 100644
index 0000000000..6ebb8d9cb2
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-links.xul
@@ -0,0 +1,78 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-links.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <prefpane id="links_pane"
+ label="&linksHeader.label;"
+ script="chrome://communicator/content/pref/pref-links.js">
+
+ <preferences id="links_preferences">
+ <preference id="browser.link.open_newwindow"
+ name="browser.link.open_newwindow"
+ type="int"
+ onchange="ToggleRestrictionGroup(this.value);"/>
+ <preference id="browser.link.open_newwindow.restriction"
+ name="browser.link.open_newwindow.restriction"
+ type="int"/>
+ <preference id="browser.link.open_external"
+ name="browser.link.open_external"
+ type="int"/>
+ </preferences>
+
+ <groupbox>
+ <caption label="&newWindow.label;"/>
+ <description>&newWindowDescription.label;</description>
+ <radiogroup id="newWindowGroup"
+ class="indent"
+ preference="browser.link.open_newwindow">
+ <radio value="1"
+ label="&openCurrent.label;"
+ accesskey="&newWindowGroupCurrent.accesskey;"/>
+ <radio value="3"
+ label="&openTab.label;"
+ accesskey="&newWindowGroupTab.accesskey;"/>
+ <radio value="2"
+ label="&openWindow.label;"
+ accesskey="&newWindowGroupWindow.accesskey;"/>
+ </radiogroup>
+ <separator class="thin"/>
+ <description>&newWindowRestriction.label;</description>
+ <radiogroup id="restrictionGroup"
+ class="indent"
+ preference="browser.link.open_newwindow.restriction">
+ <radio value="0"
+ label="&divertAll.label;"
+ accesskey="&divertAll.accesskey;"/>
+ <radio value="2"
+ label="&divertNoFeatures.label;"
+ accesskey="&divertNoFeatures.accesskey;"/>
+ <radio value="1"
+ label="&dontDivert.label;"
+ accesskey="&dontDivert.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&external.label;"/>
+ <description>&externalDescription.label;</description>
+ <radiogroup id="externalGroup"
+ class="indent"
+ preference="browser.link.open_external">
+ <radio value="1"
+ label="&openCurrent.label;"
+ accesskey="&externalGroupCurrent.accesskey;"/>
+ <radio value="3"
+ label="&openTab.label;"
+ accesskey="&externalGroupTab.accesskey;"/>
+ <radio value="2"
+ label="&openWindow.label;"
+ accesskey="&externalGroupWindow.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-locationbar.js b/comm/suite/components/pref/content/pref-locationbar.js
new file mode 100644
index 0000000000..042621eb35
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-locationbar.js
@@ -0,0 +1,42 @@
+/* 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/. */
+
+function Startup()
+{
+ // On systems that has the file view component, autoFill and showPopup will
+ // return results from local browsing "history", even if autocomplete.enabled
+ // is turned off, so we'll need to remove the dependent look in the ui.
+
+ if ("@mozilla.org/autocomplete/search;1?name=file" in Cc)
+ {
+ // We indent the checkboxes with the class attribute set to "indent", so
+ // just remove the attribute.
+ document.getElementById("autoFill").removeAttribute("class");
+ document.getElementById("showPopup").removeAttribute("class");
+ }
+
+ updateDependent();
+}
+
+function updateDependent()
+{
+ var matchHistoryPref = document.getElementById("browser.urlbar.suggest.history");
+ EnableElementById("matchOnlyTyped", matchHistoryPref.value);
+
+ var matchBookmarkPref = document.getElementById("browser.urlbar.suggest.bookmark");
+ var autoCompleteEnabled = matchHistoryPref.value || matchBookmarkPref.value;
+ EnableElementById("matchBehavior", autoCompleteEnabled);
+
+ // If autoFill has a class attribute, we don't have the file view component.
+ // We then need to update autoFill and showPopup.
+ if (document.getElementById("autoFill").hasAttribute("class"))
+ {
+ EnableElementById("autoFill", autoCompleteEnabled);
+ EnableElementById("showPopup", autoCompleteEnabled);
+ }
+
+ // We need to update autocomplete.enabled as the backend still respects it.
+ document.getElementById("browser.urlbar.autocomplete.enabled").value =
+ autoCompleteEnabled;
+}
diff --git a/comm/suite/components/pref/content/pref-locationbar.xul b/comm/suite/components/pref/content/pref-locationbar.xul
new file mode 100644
index 0000000000..3c781e4c60
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-locationbar.xul
@@ -0,0 +1,127 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-locationbar.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <prefpane id="locationBar_pane"
+ label="&pref.locationBar.title;"
+ script="chrome://communicator/content/pref/pref-locationbar.js">
+
+ <preferences id="locationBar_preferences">
+ <!-- The suggest preferences need to come first otherwise the backend
+ will enable both bookmarks and history if either is enabled -->
+ <preference id="browser.urlbar.suggest.bookmark"
+ name="browser.urlbar.suggest.bookmark"
+ type="bool"
+ onchange="updateDependent();"/>
+ <preference id="browser.urlbar.suggest.history"
+ name="browser.urlbar.suggest.history"
+ type="bool"
+ onchange="updateDependent();"/>
+ <preference id="browser.urlbar.suggest.history.onlyTyped"
+ name="browser.urlbar.suggest.history.onlyTyped"
+ type="bool"/>
+ <preference id="browser.urlbar.autocomplete.enabled"
+ name="browser.urlbar.autocomplete.enabled"
+ type="bool"/>
+ <preference id="browser.urlbar.matchBehavior"
+ name="browser.urlbar.matchBehavior"
+ type="int"/>
+ <preference id="browser.urlbar.autoFill"
+ name="browser.urlbar.autoFill"
+ type="bool"
+ onchange="updateMatchPrefs();"/>
+ <preference id="browser.urlbar.showPopup"
+ name="browser.urlbar.showPopup"
+ type="bool"
+ onchange="updateMatchPrefs();"/>
+ <preference id="browser.urlbar.showSearch"
+ name="browser.urlbar.showSearch"
+ type="bool"/>
+ <preference id="browser.urlbar.formatting.enabled"
+ name="browser.urlbar.formatting.enabled"
+ type="bool"/>
+ <preference id="browser.urlbar.highlight.secure"
+ name="browser.urlbar.highlight.secure"
+ type="bool"/>
+ <preference id="browser.fixup.alternate.enabled"
+ name="browser.fixup.alternate.enabled"
+ type="bool"/>
+ <preference id="keyword.enabled"
+ name="keyword.enabled"
+ type="bool"/>
+ </preferences>
+
+ <groupbox>
+ <caption label="&autoComplete.label;"/>
+ <checkbox id="matchHistory"
+ label="&autoCompleteMatchHistory.label;"
+ accesskey="&autoCompleteMatchHistory.accesskey;"
+ preference="browser.urlbar.suggest.history"/>
+ <checkbox id="matchOnlyTyped"
+ class="indent"
+ label="&autoCompleteMatchOnlyTyped.label;"
+ accesskey="&autoCompleteMatchOnlyTyped.accesskey;"
+ preference="browser.urlbar.suggest.history.onlyTyped"/>
+ <checkbox id="matchBookmark"
+ label="&autoCompleteMatchBookmarks.label;"
+ accesskey="&autoCompleteMatchBookmarks.accesskey;"
+ preference="browser.urlbar.suggest.bookmark"/>
+ <hbox align="center" class="indent">
+ <label value="&autoCompleteMatch.label;" control="matchBehavior"
+ accesskey="&autoCompleteMatch.accesskey;"/>
+ <menulist id="matchBehavior"
+ preference="browser.urlbar.matchBehavior">
+ <menupopup>
+ <menuitem value="0" label="&autoCompleteMatchAnywhere;"/>
+ <menuitem value="1" label="&autoCompleteMatchWordsFirst;"/>
+ <menuitem value="2" label="&autoCompleteMatchWords;"/>
+ <menuitem value="3" label="&autoCompleteMatchStart;"/>
+ </menupopup>
+ </menulist>
+ </hbox>
+ <checkbox id="autoFill"
+ class="indent"
+ label="&autoCompleteAutoFill.label;"
+ accesskey="&autoCompleteAutoFill.accesskey;"
+ preference="browser.urlbar.autoFill"/>
+ <checkbox id="showPopup"
+ class="indent"
+ label="&autoCompleteShowPopup.label;"
+ accesskey="&autoCompleteShowPopup.accesskey;"
+ preference="browser.urlbar.showPopup"/>
+ <checkbox id="showSearch"
+ label="&showInternetSearch.label;"
+ accesskey="&showInternetSearch.accesskey;"
+ preference="browser.urlbar.showSearch"/>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&formatting.label;"/>
+ <checkbox id="domainFormattingEnabled"
+ label="&domainFormatting.label;"
+ accesskey="&domainFormatting.accesskey;"
+ preference="browser.urlbar.formatting.enabled"/>
+ <checkbox id="highlightSecureEnabled"
+ label="&highlightSecure.label;"
+ accesskey="&highlightSecure.accesskey;"
+ preference="browser.urlbar.highlight.secure"/>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&unknownLocations.label;"/>
+ <checkbox id="domainGuessingEnabled"
+ label="&domainGuessing.label;"
+ accesskey="&domainGuessing.accesskey;"
+ preference="browser.fixup.alternate.enabled"/>
+ <checkbox id="browserGoBrowsingEnabled"
+ label="&keywords.label;"
+ accesskey="&keywords.accesskey;"
+ preference="keyword.enabled"/>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-media.xul b/comm/suite/components/pref/content/pref-media.xul
new file mode 100644
index 0000000000..3a2411a634
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-media.xul
@@ -0,0 +1,60 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-media.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <prefpane id="media_pane"
+ label="&pref.media.title;">
+
+ <preferences id="media_preferences">
+ <preference id="media.autoplay.enabled"
+ name="media.autoplay.enabled"
+ type="bool"/>
+ <preference id="media.eme.enabled"
+ name="media.eme.enabled"
+ type="bool"/>
+ <preference id="image.animation_mode"
+ name="image.animation_mode"
+ type="string"/>
+ </preferences>
+
+ <groupbox id="mediaHTML5Preferences" align="start">
+ <caption label="&mediaHTML5Preferences.label;"/>
+ <checkbox id="autoplay"
+ label="&allowMediaAutoplay.label;"
+ accesskey="&allowMediaAutoplay.accesskey;"
+ preference="media.autoplay.enabled"/>
+ </groupbox>
+
+ <!-- REMOVE #ifndef once EME are ready for prime time, meta bug 1015800 -->
+#ifndef RELEASE_OR_BETA
+ <groupbox id="drmPreferences">
+ <caption label="&enableDrmMedia.label;"/>
+ <checkbox id="emeForSuite"
+ label="&enableEmeForSuite.label;"
+ accesskey="&enableEmeForSuite.accesskey;"
+ preference="media.eme.enabled"/>
+ </groupbox>
+#endif
+
+ <groupbox>
+ <caption label="&animLoopingTitle.label;"/>
+ <radiogroup id="imageLooping"
+ preference="image.animation_mode">
+ <radio value="normal"
+ label="&animLoopAsSpecified.label;"
+ accesskey="&animLoopAsSpecified.accesskey;"/>
+ <radio value="once"
+ label="&animLoopOnce.label;"
+ accesskey="&animLoopOnce.accesskey;"/>
+ <radio value="none"
+ label="&animLoopNever.label;"
+ accesskey="&animLoopNever.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-mousewheel.js b/comm/suite/components/pref/content/pref-mousewheel.js
new file mode 100644
index 0000000000..6902a0c3cf
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-mousewheel.js
@@ -0,0 +1,45 @@
+/* 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/. */
+
+function doEnabling(aElement)
+{
+ var preference = document.getElementById(aElement.getAttribute("preference"));
+ var prefix = aElement.id.replace(/action$/, "");
+ var vertical = document.getElementById(prefix + "delta_multiplier_y");
+ EnableElement(vertical, preference.value);
+ updateCheckbox(vertical);
+ var actionX = document.getElementById(prefix + "action_x");
+ if (actionX.value < 0)
+ doEnablingX(actionX);
+}
+
+function doEnablingX(aElement)
+{
+ var preference = document.getElementById(aElement.getAttribute("preference"));
+ var prefix = aElement.id.replace(/action_x$/, "");
+ var value = preference.value;
+ if (value < 0) {
+ var action = document.getElementById(prefix + "action");
+ preference = document.getElementById(action.getAttribute("preference"));
+ value = preference.value;
+ }
+ var horizontal = document.getElementById(prefix + "delta_multiplier_x");
+ EnableElement(horizontal, value);
+ updateCheckbox(horizontal);
+}
+
+function updateCheckbox(aTextbox)
+{
+ var preference = document.getElementById(aTextbox.getAttribute("preference"));
+ var checkbox = aTextbox.parentNode.lastChild;
+ checkbox.checked = preference.value < 0;
+ checkbox.disabled = !preference.value || aTextbox.disabled
+}
+
+function updateTextbox(aCheckbox)
+{
+ var textbox = aCheckbox.previousSibling.previousSibling;
+ var preference = document.getElementById(textbox.getAttribute("preference"));
+ preference.value = -preference.value;
+}
diff --git a/comm/suite/components/pref/content/pref-mousewheel.xul b/comm/suite/components/pref/content/pref-mousewheel.xul
new file mode 100644
index 0000000000..63346781cc
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-mousewheel.xul
@@ -0,0 +1,298 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-mousewheel.dtd" >
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="mousewheel_pane"
+ label="&pref.mouseWheel.title;"
+ script="chrome://communicator/content/pref/pref-mousewheel.js">
+
+ <preferences id="mousewheel_preferences">
+ <preference id="mousewheel.default.action"
+ name="mousewheel.default.action"
+ type="int"/>
+ <preference id="mousewheel.default.delta_multiplier_y"
+ name="mousewheel.default.delta_multiplier_y"
+ type="int"/>
+ <preference id="mousewheel.default.action.override_x"
+ name="mousewheel.default.action.override_x"
+ type="int"/>
+ <preference id="mousewheel.default.delta_multiplier_x"
+ name="mousewheel.default.delta_multiplier_x"
+ type="int"/>
+ <preference id="mousewheel.with_alt.action"
+ name="mousewheel.with_alt.action"
+ type="int"/>
+ <preference id="mousewheel.with_alt.delta_multiplier_y"
+ name="mousewheel.with_alt.delta_multiplier_y"
+ type="int"/>
+ <preference id="mousewheel.with_alt.action.override_x"
+ name="mousewheel.with_alt.action.override_x"
+ type="int"/>
+ <preference id="mousewheel.with_alt.delta_multiplier_x"
+ name="mousewheel.with_alt.delta_multiplier_x"
+ type="int"/>
+ <preference id="mousewheel.with_control.action"
+ name="mousewheel.with_control.action"
+ type="int"/>
+ <preference id="mousewheel.with_control.delta_multiplier_y"
+ name="mousewheel.with_control.delta_multiplier_y"
+ type="int"/>
+ <preference id="mousewheel.with_control.action.override_x"
+ name="mousewheel.with_control.action.override_x"
+ type="int"/>
+ <preference id="mousewheel.with_control.delta_multiplier_x"
+ name="mousewheel.with_control.delta_multiplier_x"
+ type="int"/>
+ <preference id="mousewheel.with_shift.action"
+ name="mousewheel.with_shift.action"
+ type="int"/>
+ <preference id="mousewheel.with_shift.delta_multiplier_y"
+ name="mousewheel.with_shift.delta_multiplier_y"
+ type="int"/>
+ <preference id="mousewheel.with_shift.action.override_x"
+ name="mousewheel.with_shift.action.override_x"
+ type="int"/>
+ <preference id="mousewheel.with_shift.delta_multiplier_x"
+ name="mousewheel.with_shift.delta_multiplier_x"
+ type="int"/>
+ </preferences>
+
+ <description>&mouseWheelPanel.label;</description>
+
+ <tabbox class="spaced">
+ <tabs>
+ <tab label="&usingJustTheWheel.label;"/>
+#ifndef XP_MACOSX
+ <tab label="&usingWheelAndAlt.label2;"/>
+#else
+ <tab label="&usingWheelAndOption.label;"/>
+#endif
+ <tab label="&usingWheelAndCtrl.label2;"/>
+ <tab label="&usingWheelAndShft.label2;"/>
+ </tabs>
+
+ <tabpanels>
+
+ <!-- no key modifiers -->
+ <vbox>
+ <groupbox>
+ <caption label="&mouseWheelGroup.label;"/>
+ <radiogroup id="mousewheel_default_action"
+ preference="mousewheel.default.action"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').doEnabling(this);">
+ <radio value="0" label="&doNothing.label;" accesskey="&doNothing.accesskey;"/>
+ <radio value="1" label="&scrollDocument.label;" accesskey="&scrollDocument.accesskey;"/>
+ <radio value="2" label="&history.label;" accesskey="&history.accesskey;"/>
+ <radio value="3" label="&zoom.label;" accesskey="&zoom.accesskey;"/>
+ </radiogroup>
+ <hbox align="center">
+ <label control="mousewheel_default_delta_multiplier_y"
+ value="&wheelSpeed.label;"/>
+ <textbox type="number" min="-999999" max="999999" size="6"
+ id="mousewheel_default_delta_multiplier_y"
+ accesskey="&wheelSpeed.accesskey;"
+ preference="mousewheel.default.delta_multiplier_y"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').updateCheckbox(this);"/>
+ <label value="%"/>
+ <checkbox label="&reverseDirection.label;"
+ accesskey="&reverseDirection.accesskey;"
+ oncommand="updateTextbox(this);"/>
+ </hbox>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&mouseWheelHorizGroup.label;"/>
+ <radiogroup id="mousewheel_default_action_x"
+ preference="mousewheel.default.action.override_x"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').doEnablingX(this);">
+ <radio value="-1" label="&sameAsVertical.label;" accesskey="&sameAsVertical.accesskey;"/>
+ <radio value="0" label="&doNothing.label;" accesskey="&doNothingHoriz.accesskey;"/>
+ <radio value="1" label="&scrollDocument.label;" accesskey="&scrollDocumentHoriz.accesskey;"/>
+ <radio value="2" label="&history.label;" accesskey="&historyHoriz.accesskey;"/>
+ <radio value="3" label="&zoom.label;" accesskey="&zoomHoriz.accesskey;"/>
+ </radiogroup>
+ <hbox align="center">
+ <label control="mousewheel_default_delta_multiplier_x"
+ value="&wheelSpeed.label;"/>
+ <textbox type="number" min="-999999" max="999999" size="6"
+ id="mousewheel_default_delta_multiplier_x"
+ accesskey="&wheelSpeedHoriz.accesskey;"
+ preference="mousewheel.default.delta_multiplier_x"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').updateCheckbox(this);"/>
+ <label value="%"/>
+ <checkbox label="&reverseDirection.label;"
+ accesskey="&reverseDirectionHoriz.accesskey;"
+ oncommand="updateTextbox(this);"/>
+ </hbox>
+ </groupbox>
+ </vbox>
+
+ <!-- alt modifiers -->
+ <vbox>
+ <groupbox>
+ <caption label="&mouseWheelGroup.label;"/>
+ <radiogroup id="mousewheel_with_alt_action"
+ preference="mousewheel.with_alt.action"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').doEnabling(this);">
+ <radio value="0" label="&doNothing.label;" accesskey="&doNothing.accesskey;"/>
+ <radio value="1" label="&scrollDocument.label;" accesskey="&scrollDocument.accesskey;"/>
+ <radio value="2" label="&history.label;" accesskey="&history.accesskey;"/>
+ <radio value="3" label="&zoom.label;" accesskey="&zoom.accesskey;"/>
+ </radiogroup>
+ <hbox align="center">
+ <label control="mousewheel_with_alt_delta_multiplier_y"
+ value="&wheelSpeed.label;"/>
+ <textbox type="number" min="-999999" max="999999" size="6"
+ id="mousewheel_with_alt_delta_multiplier_y"
+ accesskey="&wheelSpeed.accesskey;"
+ preference="mousewheel.with_alt.delta_multiplier_y"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').updateCheckbox(this);"/>
+ <label value="%"/>
+ <checkbox label="&reverseDirection.label;"
+ accesskey="&reverseDirection.accesskey;"
+ oncommand="updateTextbox(this);"/>
+ </hbox>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&mouseWheelHorizGroup.label;"/>
+ <radiogroup id="mousewheel_with_alt_action_x"
+ preference="mousewheel.with_alt.action.override_x"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').doEnablingX(this);">
+ <radio value="-1" label="&sameAsVertical.label;" accesskey="&sameAsVertical.accesskey;"/>
+ <radio value="0" label="&doNothing.label;" accesskey="&doNothingHoriz.accesskey;"/>
+ <radio value="1" label="&scrollDocument.label;" accesskey="&scrollDocumentHoriz.accesskey;"/>
+ <radio value="2" label="&history.label;" accesskey="&historyHoriz.accesskey;"/>
+ <radio value="3" label="&zoom.label;" accesskey="&zoomHoriz.accesskey;"/>
+ </radiogroup>
+ <hbox align="center">
+ <label control="mousewheel_with_alt_delta_multiplier_x"
+ value="&wheelSpeed.label;"/>
+ <textbox type="number" min="-999999" max="999999" size="6"
+ id="mousewheel_with_alt_delta_multiplier_x"
+ accesskey="&wheelSpeedHoriz.accesskey;"
+ preference="mousewheel.with_alt.delta_multiplier_x"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').updateCheckbox(this);"/>
+ <label value="%"/>
+ <checkbox label="&reverseDirection.label;"
+ accesskey="&reverseDirectionHoriz.accesskey;"
+ oncommand="updateTextbox(this);"/>
+ </hbox>
+ </groupbox>
+ </vbox>
+
+ <!-- control modifiers -->
+ <vbox>
+ <groupbox>
+ <caption label="&mouseWheelGroup.label;"/>
+ <radiogroup id="mousewheel_with_control_action"
+ preference="mousewheel.with_control.action"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').doEnabling(this);">
+ <radio value="0" label="&doNothing.label;" accesskey="&doNothing.accesskey;"/>
+ <radio value="1" label="&scrollDocument.label;" accesskey="&scrollDocument.accesskey;"/>
+ <radio value="2" label="&history.label;" accesskey="&history.accesskey;"/>
+ <radio value="3" label="&zoom.label;" accesskey="&zoom.accesskey;"/>
+ </radiogroup>
+ <hbox align="center">
+ <label control="mousewheel_with_control_delta_multiplier_y"
+ value="&wheelSpeed.label;"/>
+ <textbox type="number" min="-999999" max="999999" size="6"
+ id="mousewheel_with_control_delta_multiplier_y"
+ accesskey="&wheelSpeed.accesskey;"
+ preference="mousewheel.with_control.delta_multiplier_y"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').updateCheckbox(this);"/>
+ <label value="%"/>
+ <checkbox label="&reverseDirection.label;"
+ accesskey="&reverseDirection.accesskey;"
+ oncommand="updateTextbox(this);"/>
+ </hbox>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&mouseWheelHorizGroup.label;"/>
+ <radiogroup id="mousewheel_with_control_action_x"
+ preference="mousewheel.with_control.action.override_x"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').doEnablingX(this);">
+ <radio value="-1" label="&sameAsVertical.label;" accesskey="&sameAsVertical.accesskey;"/>
+ <radio value="0" label="&doNothing.label;" accesskey="&doNothingHoriz.accesskey;"/>
+ <radio value="1" label="&scrollDocument.label;" accesskey="&scrollDocumentHoriz.accesskey;"/>
+ <radio value="2" label="&history.label;" accesskey="&historyHoriz.accesskey;"/>
+ <radio value="3" label="&zoom.label;" accesskey="&zoomHoriz.accesskey;"/>
+ </radiogroup>
+ <hbox align="center">
+ <label control="mousewheel_with_control_delta_multiplier_x"
+ value="&wheelSpeed.label;"/>
+ <textbox type="number" min="-999999" max="999999" size="6"
+ id="mousewheel_with_control_delta_multiplier_x"
+ accesskey="&wheelSpeedHoriz.accesskey;"
+ preference="mousewheel.with_control.delta_multiplier_x"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').updateCheckbox(this);"/>
+ <label value="%"/>
+ <checkbox label="&reverseDirection.label;"
+ accesskey="&reverseDirectionHoriz.accesskey;"
+ oncommand="updateTextbox(this);"/>
+ </hbox>
+ </groupbox>
+ </vbox>
+
+ <!-- shift modifiers -->
+ <vbox>
+ <groupbox>
+ <caption label="&mouseWheelGroup.label;"/>
+ <radiogroup id="mousewheel_with_shift_action"
+ preference="mousewheel.with_shift.action"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').doEnabling(this);">
+ <radio value="0" label="&doNothing.label;" accesskey="&doNothing.accesskey;"/>
+ <radio value="1" label="&scrollDocument.label;" accesskey="&scrollDocument.accesskey;"/>
+ <radio value="2" label="&history.label;" accesskey="&history.accesskey;"/>
+ <radio value="3" label="&zoom.label;" accesskey="&zoom.accesskey;"/>
+ </radiogroup>
+ <hbox align="center">
+ <label control="mousewheel_with_shift_delta_multiplier_y"
+ value="&wheelSpeed.label;"/>
+ <textbox type="number" min="-999999" max="999999" size="6"
+ id="mousewheel_with_shift_delta_multiplier_y"
+ accesskey="&wheelSpeed.accesskey;"
+ preference="mousewheel.with_shift.delta_multiplier_y"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').updateCheckbox(this);"/>
+ <label value="%"/>
+ <checkbox label="&reverseDirection.label;"
+ accesskey="&reverseDirection.accesskey;"
+ oncommand="updateTextbox(this);"/>
+ </hbox>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&mouseWheelHorizGroup.label;"/>
+ <radiogroup id="mousewheel_with_shift_action_x"
+ preference="mousewheel.with_shift.action.override_x"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').doEnablingX(this);">
+ <radio value="-1" label="&sameAsVertical.label;" accesskey="&sameAsVertical.accesskey;"/>
+ <radio value="0" label="&doNothing.label;" accesskey="&doNothingHoriz.accesskey;"/>
+ <radio value="1" label="&scrollDocument.label;" accesskey="&scrollDocumentHoriz.accesskey;"/>
+ <radio value="2" label="&history.label;" accesskey="&historyHoriz.accesskey;"/>
+ <radio value="3" label="&zoom.label;" accesskey="&zoomHoriz.accesskey;"/>
+ </radiogroup>
+ <hbox align="center">
+ <label control="mousewheel_with_shift_delta_multiplier_x"
+ value="&wheelSpeed.label;"/>
+ <textbox type="number" min="-999999" max="999999" size="6"
+ id="mousewheel_with_shift_delta_multiplier_x"
+ accesskey="&wheelSpeedHoriz.accesskey;"
+ preference="mousewheel.with_shift.delta_multiplier_x"
+ onsyncfrompreference="document.getElementById('mousewheel_pane').updateCheckbox(this);"/>
+ <label value="%"/>
+ <checkbox label="&reverseDirection.label;"
+ accesskey="&reverseDirectionHoriz.accesskey;"
+ oncommand="updateTextbox(this);"/>
+ </hbox>
+ </groupbox>
+ </vbox>
+ </tabpanels>
+ </tabbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-navigator.js b/comm/suite/components/pref/content/pref-navigator.js
new file mode 100644
index 0000000000..5ff271dc2b
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-navigator.js
@@ -0,0 +1,262 @@
+/* -*- Mode: Java; 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/. */
+
+const {ShellService} = ChromeUtils.import("resource:///modules/ShellService.jsm");
+
+// The contents of this file will be loaded into the scope of the object
+// <prefpane id="navigator_pane">!
+
+// platform integration
+const PFINT_NOT_DEFAULT = 0;
+const PFINT_DEFAULT = 1;
+const PFINT_PENDING = 2;
+
+
+// put "global" definitions here for easy reference
+var gDefaultHomePage = "";
+var gHomePagePrefPeak = 0;
+var gPreferences = null;
+
+
+// <preferences> access helper methods
+function GetHomePagePrefCount()
+{
+ return document.getElementById("browser.startup.homepage.count").value;
+}
+
+function SetHomePagePrefCount(aCount)
+{
+ document.getElementById("browser.startup.homepage.count").value = aCount;
+}
+
+function GetHomePagePrefName(aIndex)
+{
+ var prefname = "browser.startup.homepage";
+ if (aIndex > 0)
+ prefname += "." + aIndex;
+ return prefname;
+}
+
+function GetHomePagePref(aIndex)
+{
+ // return the <preference> at aIndex
+ return document.getElementById(GetHomePagePrefName(aIndex));
+}
+
+function AddHomePagePref(aIndex)
+{
+ // create new <preference> for aIndex
+ var pref = document.createElement("preference");
+ var prefname = GetHomePagePrefName(aIndex);
+ pref.setAttribute("id", prefname);
+ pref.setAttribute("name", prefname);
+ pref.setAttribute("type", "wstring");
+ gPreferences.appendChild(pref);
+ return pref;
+}
+
+// homepage group textbox helper methods
+function GetHomePageGroup()
+{
+ return document.getElementById("browserStartupHomepage").value;
+}
+
+function SetHomePageValue(aValue)
+{
+ document.getElementById("browserStartupHomepage").value = aValue;
+}
+
+// helper methods for reading current page URIs
+function GetMostRecentBrowser()
+{
+ var browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+ return browserWindow && browserWindow.getBrowser();
+}
+
+function GetCurrentPage()
+{
+ var tabbrowser = GetMostRecentBrowser();
+ return tabbrowser && tabbrowser.currentURI.spec || ""; // ensure string
+}
+
+function GetCurrentGroup()
+{
+ var uris = [];
+ var tabbrowser = GetMostRecentBrowser();
+ if (tabbrowser)
+ {
+ var browsers = tabbrowser.browsers;
+ var browsersLen = browsers.length;
+ for (var i = 0; i < browsersLen; ++i)
+ uris[i] = browsers[i].currentURI.spec;
+ }
+ return uris.join("\n");
+}
+
+// synchronize button states with current input
+function CanonifyURLList(aList)
+{
+ return (aList + "\n").replace(/\n+/g, "\n");
+}
+
+function UpdateHomePageButtons()
+{
+ var homePageGroup = CanonifyURLList(GetHomePageGroup());
+ var currentPage = CanonifyURLList(GetCurrentPage());
+ var currentGroup = CanonifyURLList(GetCurrentGroup());
+
+ // disable "current page" button if current page is already the homepage
+ var currentPageButton = document.getElementById("browserUseCurrent");
+ currentPageButton.disabled = (homePageGroup == currentPage) ||
+ (currentPage == "\n");
+
+ // disable "current group" button if current group already set or no group
+ var currentGroupButton = document.getElementById("browserUseCurrentGroup");
+ currentGroupButton.disabled = (homePageGroup == currentGroup) ||
+ (currentGroup == currentPage);
+
+ // disable "restore" button if homepage hasn't changed
+ var restoreButton = document.getElementById("browserUseDefault");
+ restoreButton.disabled = (homePageGroup == gDefaultHomePage);
+}
+
+function UpdateHomePagePrefs()
+{
+ // update the list of <preference>s to the current settings
+ var newCount = 1; // current number of homepages
+ var homePageGroup = CanonifyURLList(GetHomePageGroup()).split("\n");
+ GetHomePagePref(0).value = "about:blank"; // in case it's empty
+ if (homePageGroup[0])
+ {
+ // we have at least one homepage
+ // (the last index is always empty due to canonification)
+ newCount = homePageGroup.length - 1
+ for (var i = 0; i < newCount; ++i)
+ {
+ var pref = GetHomePagePref(i) || AddHomePagePref(i);
+ pref.value = homePageGroup[i];
+ }
+ }
+
+ // work around bug 410562:
+ // reset unneeded preferences on dialogaccept only
+
+ // update pref count watermark before setting new number of homepages
+ var alreadyRequested = (gHomePagePrefPeak > 0);
+ var oldCount = GetHomePagePrefCount();
+ if (gHomePagePrefPeak < oldCount)
+ gHomePagePrefPeak = oldCount;
+ SetHomePagePrefCount(newCount);
+
+ var needCleanup = (newCount < gHomePagePrefPeak);
+ if (document.documentElement.instantApply)
+ {
+ // throw away unneeded preferences now
+ if (needCleanup)
+ HomePagePrefCleanup();
+ }
+ else if (needCleanup != alreadyRequested)
+ {
+ // cleanup necessity changed
+ if (needCleanup)
+ {
+ // register OK handler for the capturing phase
+ window.addEventListener("dialogaccept", this.HomePagePrefCleanup, true);
+ }
+ else
+ {
+ // no cleanup necessary, remove OK handler
+ window.removeEventListener("dialogaccept", this.HomePagePrefCleanup, true);
+ }
+ }
+}
+
+function HomePagePrefCleanup()
+{
+ // remove the old user prefs values that we didn't overwrite
+ var count = GetHomePagePrefCount();
+ for (var j = count; j < gHomePagePrefPeak; ++j)
+ {
+ // clear <preference>
+ var pref = GetHomePagePref(j);
+ pref.valueFromPreferences = undefined;
+ pref.remove();
+ }
+ gHomePagePrefPeak = 0; // cleanup done
+}
+
+function UpdateHomePageListFromInput()
+{
+ UpdateHomePagePrefs();
+ UpdateHomePageButtons();
+}
+
+function UpdateHomePageList(aSingleURL)
+{
+ // write single URL into input box and set it as the list of homepages
+ SetHomePageValue(aSingleURL);
+ UpdateHomePageListFromInput();
+}
+
+function SelectFile()
+{
+ let fp = Cc["@mozilla.org/filepicker;1"]
+ .createInstance(Ci.nsIFilePicker);
+ let title = document.getElementById("bundle_prefutilities")
+ .getString("choosehomepage");
+ fp.init(window, title, Ci.nsIFilePicker.modeOpen);
+ fp.appendFilters(Ci.nsIFilePicker.filterAll |
+ Ci.nsIFilePicker.filterText |
+ Ci.nsIFilePicker.filterXML |
+ Ci.nsIFilePicker.filterHTML |
+ Ci.nsIFilePicker.filterImages);
+
+ fp.open(rv => {
+ if (rv == Ci.nsIFilePicker.returnOK && fp.fileURL.spec &&
+ fp.fileURL.spec.length > 0) {
+ UpdateHomePageList(fp.fileURL.spec);
+ }
+ });
+}
+
+function SetHomePageToCurrentPage()
+{
+ UpdateHomePageList(GetCurrentPage());
+}
+
+function SetHomePageToCurrentGroup()
+{
+ UpdateHomePageList(GetCurrentGroup());
+}
+
+function SetHomePageToDefaultPage()
+{
+ UpdateHomePageList(gDefaultHomePage);
+}
+
+function Startup()
+{
+ // homepage groups can have an arbitrary number of <preference>s,
+ // except for the default (0), thus we create them manually here
+ gPreferences = document.getElementById("navigator_preferences");
+ var count = GetHomePagePrefCount();
+ var homePageGroup = GetHomePagePref(0).value + "\n";
+ for (var i = 1; i < count; ++i)
+ homePageGroup += AddHomePagePref(i).value + "\n";
+ gDefaultHomePage = CanonifyURLList(GetHomePagePref(0).defaultValue);
+ SetHomePageValue(homePageGroup);
+ UpdateHomePageButtons();
+}
+
+function SwitchPage(aIndex)
+{
+ document.getElementById("behaviourDeck").selectedIndex = aIndex;
+}
+
+function WriteConcurrentTabs()
+{
+ var val = document.getElementById("maxConcurrentTabsGroup").value;
+ return val > 0 ? document.getElementById("maxConcurrentTabs").value : val;
+}
diff --git a/comm/suite/components/pref/content/pref-navigator.xul b/comm/suite/components/pref/content/pref-navigator.xul
new file mode 100644
index 0000000000..2b9888419f
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-navigator.xul
@@ -0,0 +1,188 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+ <!ENTITY % navigatorDTD SYSTEM "chrome://communicator/locale/pref/pref-navigator.dtd"> %navigatorDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="navigator_pane"
+ label="&pref.navigator.title;"
+ script="chrome://communicator/content/pref/pref-navigator.js">
+
+ <preferences id="navigator_preferences">
+ <preference id="browser.startup.page"
+ name="browser.startup.page"
+ type="int"/>
+ <preference id="browser.windows.loadOnNewWindow"
+ name="browser.windows.loadOnNewWindow"
+ type="int"/>
+ <preference id="browser.tabs.loadOnNewTab"
+ name="browser.tabs.loadOnNewTab"
+ type="int"/>
+ <preference id="browser.startup.homepage"
+ name="browser.startup.homepage"
+ type="wstring"/>
+ <preference id="browser.startup.homepage.count"
+ name="browser.startup.homepage.count"
+ type="int"/>
+ <preference id="browser.sessionstore.max_concurrent_tabs"
+ name="browser.sessionstore.max_concurrent_tabs"
+ type="int"/>
+ <preference id="browser.chrome.site_icons"
+ name="browser.chrome.site_icons"
+ type="bool"/>
+ <preference id="browser.chrome.favicons"
+ name="browser.chrome.favicons"
+ type="bool"/>
+ <preference id="pref.browser.homepage.disable_button.select_file"
+ name="pref.browser.homepage.disable_button.select_file"
+ type="bool"/>
+ <preference id="pref.browser.homepage.disable_button.current_page"
+ name="pref.browser.homepage.disable_button.current_page"
+ type="bool"/>
+ <preference id="pref.browser.homepage.disable_button.current_group"
+ name="pref.browser.homepage.disable_button.current_group"
+ type="bool"/>
+ <preference id="pref.browser.homepage.disable_button.default_page"
+ name="pref.browser.homepage.disable_button.default_page"
+ type="bool"/>
+ </preferences>
+
+ <hbox>
+ <!-- navigator startup / new window / new tab behaviour -->
+ <groupbox flex="1">
+ <caption align="center">
+ <label value="&navRadio.label;"
+ accesskey="&navRadio.accesskey;"
+ control="selectDisplayOn"/>
+ <menulist id="selectDisplayOn"
+ oncommand="SwitchPage(this.selectedIndex);">
+ <menupopup>
+ <menuitem label="&navStartPageMenu.label;"/>
+ <menuitem label="&newWinPageMenu.label;"/>
+ <menuitem label="&newTabPageMenu.label;"/>
+ </menupopup>
+ </menulist>
+ </caption>
+ <deck id="behaviourDeck" flex="1">
+ <radiogroup id="startupPage" preference="browser.startup.page">
+ <radio value="0"
+ label="&blankPageRadio.label;"
+ accesskey="&blankPageRadio.accesskey;"/>
+ <radio value="1"
+ label="&homePageRadio.label;"
+ accesskey="&homePageRadio.accesskey;"/>
+ <radio value="2"
+ label="&lastPageRadio.label;"
+ accesskey="&lastPageRadio.accesskey;"/>
+ <radio value="3"
+ label="&restoreSessionRadio.label;"
+ accesskey="&restoreSessionRadio.accesskey;"/>
+ </radiogroup>
+ <radiogroup id="newWinPage"
+ preference="browser.windows.loadOnNewWindow">
+ <radio value="0"
+ label="&blankPageRadio.label;"
+ accesskey="&blankPageRadio.accesskey;"/>
+ <radio value="1"
+ label="&homePageRadio.label;"
+ accesskey="&homePageRadio.accesskey;"/>
+ <radio value="2"
+ label="&lastPageRadio.label;"
+ accesskey="&lastPageRadio.accesskey;"/>
+ </radiogroup>
+ <radiogroup id="newTabPage" preference="browser.tabs.loadOnNewTab">
+ <radio value="0"
+ label="&blankPageRadio.label;"
+ accesskey="&blankPageRadio.accesskey;"/>
+ <radio value="1"
+ label="&homePageRadio.label;"
+ accesskey="&homePageRadio.accesskey;"/>
+ <radio value="2"
+ label="&lastPageRadio.label;"
+ accesskey="&lastPageRadio.accesskey;"/>
+ </radiogroup>
+ </deck>
+ </groupbox>
+
+ <!-- session restore background tabs -->
+ <groupbox flex="1">
+ <caption label="&restoreSessionIntro.label;"/>
+ <radiogroup id="maxConcurrentTabsGroup"
+ align="start"
+ preference="browser.sessionstore.max_concurrent_tabs"
+ onsyncfrompreference="var val = document.getElementById(this.getAttribute('preference')).value; return val > 0 ? 3 : val;"
+ onsynctopreference="return document.getElementById('navigator_pane').WriteConcurrentTabs();">
+ <radio value="-1"
+ label="&restoreImmediately.label;"
+ accesskey="&restoreImmediately.accesskey;"/>
+ <hbox align="center">
+ <radio id="restoreTabs"
+ value="3"
+ onclick="this.nextSibling.focus();"
+ label="&restoreTabs.label;"
+ accesskey="&restoreTabs.accesskey;"/>
+ <textbox id="maxConcurrentTabs"
+ type="number"
+ size="2"
+ min="1"
+ value="3"
+ aria-labelledby="restoreTabs maxConcurrentTabs restoreTabsAtATime"
+ preference="browser.sessionstore.max_concurrent_tabs"
+ onsyncfrompreference="var pref = document.getElementById(this.getAttribute('preference')); var val = pref.value; var valid = val > 0; this.disabled = pref.locked || !valid; return valid ? val : this.value;"
+ onsynctopreference="return document.getElementById('navigator_pane').WriteConcurrentTabs();"/>
+ <label id="restoreTabsAtATime" value="&restoreTabsAtATime.label;">
+ <observes element="maxConcurrentTabsGroup" attribute="disabled"/>
+ </label>
+ </hbox>
+ <radio value="0"
+ label="&restoreDeferred.label;"
+ accesskey="&restoreDeferred.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+ </hbox>
+
+ <groupbox id="siteIconPreferences">
+ <caption label="&siteIcons.label;"/>
+
+ <checkbox id="useSiteIcons"
+ label="&useSiteIcons.label;"
+ accesskey="&useSiteIcons.accesskey;"
+ preference="browser.chrome.site_icons"/>
+ <checkbox id="useFavIcons"
+ label="&useFavIcons.label;"
+ accesskey="&useFavIcons.accesskey;"
+ preference="browser.chrome.favicons"/>
+ </groupbox>
+
+ <!-- homepage specification -->
+ <description>&homePageIntro.label;</description>
+ <hbox>
+ <textbox id="browserStartupHomepage" class="uri-element" flex="1"
+ multiline="true" wrap="off" timeout="500"
+ oninput="UpdateHomePageListFromInput();"/>
+ <vbox>
+ <button label="&browseFile.label;" accesskey="&browseFile.accesskey;"
+ oncommand="SelectFile();"
+ id="browserChooseFile"
+ preference="pref.browser.homepage.disable_button.select_file"/>
+ <button label="&useCurrent.label;" accesskey="&useCurrent.accesskey;"
+ oncommand="SetHomePageToCurrentPage();"
+ id="browserUseCurrent"
+ preference="pref.browser.homepage.disable_button.current_page"/>
+ <button label="&useCurrentGroup.label;" accesskey="&useCurrentGroup.accesskey;"
+ oncommand="SetHomePageToCurrentGroup();"
+ id="browserUseCurrentGroup"
+ preference="pref.browser.homepage.disable_button.current_group"/>
+ <button label="&useDefault.label;" accesskey="&useDefault.accesskey;"
+ oncommand="SetHomePageToDefaultPage();"
+ id="browserUseDefault"
+ preference="pref.browser.homepage.disable_button.default_page"/>
+ </vbox>
+ </hbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-offlineapps.js b/comm/suite/components/pref/content/pref-offlineapps.js
new file mode 100644
index 0000000000..db7c44cb81
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-offlineapps.js
@@ -0,0 +1,178 @@
+/* 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 {DownloadUtils} = ChromeUtils.import("resource://gre/modules/DownloadUtils.jsm");
+var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+function Startup()
+{
+ OfflineAppsObserver.init();
+
+ let always = document.getElementById("offline-apps.allow_by_default").value;
+ UpdateNotifyBox(always);
+}
+
+var OfflineAppsObserver = {
+
+ init: function offlineAppsInit() {
+ this.update();
+ Services.obs.addObserver(this, "perm-changed");
+ window.addEventListener("unload", this);
+ },
+
+ update: function offlineAppsUpdate() {
+ UpdateActualCacheSize();
+ UpdateOfflineApps();
+ },
+
+ observe: function offlineAppsObserve(aSubject, aTopic, aData) {
+ if (aTopic == "perm-changed")
+ this.update();
+ },
+
+ handleEvent: function offlineAppsEvent(aEvent) {
+ if (aEvent.type == "unload") {
+ window.removeEventListener("unload", this);
+ Services.obs.removeObserver(this, "perm-changed");
+ }
+ }
+}
+
+function UpdateActualCacheSize()
+{
+ var visitor = {
+ onCacheStorageInfo: function(aEntryCount, aTotalSize)
+ {
+ let actualSizeLabel = document.getElementById("offlineAppSizeInfo");
+ let sizeStrings = DownloadUtils.convertByteUnits(aTotalSize);
+ let bundle = document.getElementById("bundle_prefutilities");
+ let sizeStr = bundle.getFormattedString("offlineAppSizeInfo",
+ sizeStrings);
+ actualSizeLabel.textContent = sizeStr;
+ },
+
+ onCacheEntryInfo: function(entryInfo)
+ {
+ },
+
+ onCacheEntryVisitCompleted: function()
+ {
+ }
+ };
+
+ Services.cache2.appCacheStorage(Services.loadContextInfo.default, null)
+ .asyncVisitStorage(visitor, false);
+}
+
+/**
+ * Clears the application cache.
+ */
+var callback = {
+ onCacheEntryDoomed: function(aResult) {
+ UpdateActualCacheSize();
+ UpdateOfflineApps();
+ }
+};
+
+function ClearOfflineAppCache()
+{
+ try {
+ Services.cache2.appCacheStorage(Services.loadContextInfo.default, null)
+ .asyncEvictStorage(callback);
+ } catch(ex) {}
+}
+
+function UpdateNotifyBox(aValue)
+{
+ EnableElementById("offlineNotifyAsk", !aValue);
+
+ // remove this once bug 934457 and bug 1024832 are fixed
+ document.getElementById("offlineNotifyPermissions").disabled = aValue;
+}
+
+function _getOfflineAppUsage(aPermission)
+{
+ var appCache = Cc["@mozilla.org/network/application-cache-service;1"]
+ .getService(Ci.nsIApplicationCacheService);
+ var groups = appCache.getGroups();
+
+ var usage = 0;
+ for (let i = 0; i < groups.length; i++) {
+ let uri = Services.io.newURI(groups[i]);
+ if (aPermission.matchesURI(uri, true))
+ usage += appCache.getActiveCache(groups[i]).usage;
+ }
+ return usage;
+}
+
+/**
+ * Updates the list of offline applications.
+ */
+function UpdateOfflineApps()
+{
+ var list = document.getElementById("offlineAppsList");
+ while (list.hasChildNodes())
+ list.lastChild.remove();
+
+ var bundle = document.getElementById("bundle_prefutilities");
+ var pm = Services.perms;
+ var enumerator = pm.enumerator;
+
+ while (enumerator.hasMoreElements()) {
+ let perm = enumerator.getNext()
+ .QueryInterface(Ci.nsIPermission);
+ if (perm.type != "offline-app" ||
+ perm.capability != pm.ALLOW_ACTION)
+ continue;
+
+ let usage = _getOfflineAppUsage(perm);
+ let row = document.createElement("listitem");
+ row.setAttribute("host", perm.principal.URI.host);
+ let converted = DownloadUtils.convertByteUnits(usage);
+ row.setAttribute("usage", bundle.getFormattedString("offlineAppUsage",
+ converted));
+ list.appendChild(row);
+ }
+}
+
+function OfflineAppSelected(aList)
+{
+ document.getElementById("offlineAppsListRemove")
+ .setAttribute("disabled", !aList.selectedItem);
+}
+
+function RemoveOfflineApp()
+{
+ var list = document.getElementById("offlineAppsList");
+ var item = list.selectedItem;
+ var host = item.getAttribute("host");
+
+ var flags = Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
+ Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1;
+
+ var bundle = document.getElementById("bundle_prefutilities");
+ var title = bundle.getString("offlineAppRemoveTitle");
+ var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [host]);
+ var confirm = bundle.getString("offlineAppRemoveConfirm");
+ if (Services.prompt.confirmEx(window, title, prompt, flags, confirm,
+ null, null, null, {}))
+ return;
+
+ // clear offline cache entries
+ var appCache = Cc["@mozilla.org/network/application-cache-service;1"]
+ .getService(Ci.nsIApplicationCacheService);
+ var groups = appCache.getGroups();
+ for (let i = 0; i < groups.length; i++) {
+ var uri = Services.io.newURI(groups[i]);
+ if (uri.asciiHost == host)
+ appCache.getActiveCache(groups[i]).discard();
+ }
+
+ // remove the permission
+ // Services.perms.remove(host, "offline-app");
+
+ UpdateOfflineApps();
+ OfflineAppSelected(list);
+ UpdateActualCacheSize();
+}
diff --git a/comm/suite/components/pref/content/pref-offlineapps.xul b/comm/suite/components/pref/content/pref-offlineapps.xul
new file mode 100644
index 0000000000..d12a26c808
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-offlineapps.xul
@@ -0,0 +1,81 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+ <!ENTITY % prefOfflineCacheDTD SYSTEM "chrome://communicator/locale/pref/pref-offlineapps.dtd">
+ %prefOfflineCacheDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="offlineapps_pane"
+ label="&pref.offlineapps.title;"
+ script="chrome://communicator/content/pref/pref-offlineapps.js">
+
+ <preferences>
+ <preference id="offline-apps.allow_by_default"
+ name="offline-apps.allow_by_default"
+ type="bool"
+ onchange="UpdateNotifyBox(this.value);"/>
+ <preference id="browser.offline-apps.notify"
+ name="browser.offline-apps.notify"
+ type="bool"/>
+ </preferences>
+
+ <groupbox id="offlineGroup" flex="1">
+ <caption label="&pref.offlineCache.caption;"/>
+
+ <hbox align="center">
+ <label id="offlineAppSizeInfo" flex="1"/>
+ <button id="clearOfflineAppCache"
+ icon="clear"
+ label="&clearOfflineAppCache.label;"
+ accesskey="&clearOfflineAppCache.accesskey;"
+ oncommand="ClearOfflineAppCache();"/>
+ </hbox>
+ <radiogroup id="offlineDefault"
+ preference="offline-apps.allow_by_default">
+ <radio id="offlineAlwaysAllow"
+ value="true"
+ label="&offlineAlwaysAllow.label;"
+ accesskey="&offlineAlwaysAllow.accesskey;"/>
+ <hbox align="center">
+ <radio id="offlineExplicit"
+ flex="1"
+ value="false"
+ label="&offlineExplicit.label;"
+ accesskey="&offlineExplicit.accesskey;"/>
+ <button id="offlineNotifyPermissions"
+ label="&offlineNotifyPermissions.label;"
+ accesskey="&offlineNotifyPermissions.accesskey;"
+ oncommand="toDataManager('|permissions');"/>
+ </hbox>
+ </radiogroup>
+ <checkbox id="offlineNotifyAsk"
+ class="indent"
+ label="&offlineNotifyAsk.label;"
+ accesskey="&offlineNotifyAsk.accesskey;"
+ preference="browser.offline-apps.notify"/>
+ <separator class="thin"/>
+ <hbox flex="1">
+ <vbox flex="1">
+ <label id="offlineAppsListLabel">&offlineAppsUsage.label;</label>
+ <listbox id="offlineAppsList"
+ flex="1"
+ aria-labelledby="offlineAppsListLabel"
+ onselect="OfflineAppSelected(this);">
+ </listbox>
+ </vbox>
+ <vbox pack="end">
+ <button id="offlineAppsListRemove"
+ disabled="true"
+ label="&offlineAppsListRemove.label;"
+ accesskey="&offlineAppsListRemove.accesskey;"
+ oncommand="RemoveOfflineApp();"/>
+ </vbox>
+ </hbox>
+ </groupbox>
+
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-popups.js b/comm/suite/components/pref/content/pref-popups.js
new file mode 100644
index 0000000000..dc8a2b42c2
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-popups.js
@@ -0,0 +1,95 @@
+/* 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/. */
+
+var gSoundUrlPref;
+
+function Startup()
+{
+ gSoundUrlPref = document.getElementById("privacy.popups.sound_url");
+
+ SetLists();
+
+ SetButtons();
+}
+
+function SetLists()
+{
+ const kPopupType = "popup";
+
+ var pref = document.getElementById("privacy.popups.remove_blacklist");
+ if (pref.value)
+ {
+ var enumerator = Services.perms.enumerator;
+ var uris = [];
+
+ while (enumerator.hasMoreElements())
+ {
+ var permission = enumerator.getNext();
+ if (permission instanceof Ci.nsIPermission)
+ {
+ if ((permission.type == kPopupType) &&
+ (permission.capability == Ci.nsIPermissionManager.DENY_ACTION))
+ uris.push(permission.principal.URI);
+ }
+ }
+
+ for (var i in uris)
+ Services.perms.remove(uris[i], kPopupType);
+
+ pref.value = false;
+ }
+
+ pref = document.getElementById("privacy.popups.prefill_whitelist");
+ if (pref.value)
+ {
+ try
+ {
+ var whitelist = document.getElementById("privacy.popups.default_whitelist").value;
+ var hosts = whitelist.split(",");
+
+ for (var i in hosts)
+ {
+ var host = "http://" + hosts[i];
+ var uri = Services.io.newURI(host);
+ Services.perms.add(uri, kPopupType, true);
+ }
+ }
+ catch (ex) {}
+
+ pref.value = false;
+ }
+}
+
+function SetButtons()
+{
+ var prefString = document.getElementById("popupPolicy")
+ .getAttribute("preference");
+ var enable = document.getElementById(prefString).value;
+ EnableElementById("exceptionsButton", enable, false);
+ EnableElementById("displayIcon", enable, false);
+ EnableElementById("displayPopupsNotification", enable, false);
+
+ var element = document.getElementById("playSound");
+ EnableElement(element, enable, false);
+
+ prefString = element.getAttribute("preference");
+ EnableSoundRadio(enable && document.getElementById(prefString).value);
+}
+
+function EnableSoundRadio(aSoundChecked)
+{
+ const kCustomSound = 1;
+
+ var element = document.getElementById("popupSoundType");
+ EnableElement(element, aSoundChecked, false);
+ var pref = document.getElementById(element.getAttribute("preference"));
+ EnableSoundUrl(aSoundChecked && (pref.value == kCustomSound));
+}
+
+function EnableSoundUrl(aCustomSelected)
+{
+ EnableElementById("playSoundUrl", aCustomSelected, false);
+ EnableElementById("selectSound", aCustomSelected, false);
+ EnableElementById("playSoundButton", aCustomSelected, false);
+}
diff --git a/comm/suite/components/pref/content/pref-popups.xul b/comm/suite/components/pref/content/pref-popups.xul
new file mode 100644
index 0000000000..78f7a75e57
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-popups.xul
@@ -0,0 +1,132 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+<!ENTITY % prefPopupsDTD SYSTEM "chrome://communicator/locale/pref/pref-popups.dtd">
+%prefPopupsDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="popups_pane"
+ label="&pref.popups.title;"
+ script="chrome://communicator/content/pref/pref-popups.js">
+ <preferences id="popups_preferences">
+ <preference id="dom.disable_open_during_load"
+ name="dom.disable_open_during_load"
+ type="bool"
+ onchange="SetButtons();"/>
+ <preference id="pref.advanced.popups.disable_button.view_popups"
+ name="pref.advanced.popups.disable_button.view_popups"
+ type="bool"/>
+ <preference id="privacy.popups.sound_enabled"
+ name="privacy.popups.sound_enabled"
+ type="bool"
+ onchange="EnableSoundRadio(this.value);"/>
+ <preference id="privacy.popups.sound_type"
+ name="privacy.popups.sound_type"
+ type="int"
+ onchange="EnableSoundUrl(this.value == 1);"/>
+ <preference id="privacy.popups.sound_url"
+ name="privacy.popups.sound_url"
+ type="string"
+ onchange="EnableElementById('previewSound', true, false);"/>
+ <preference id="pref.advanced.popups.disable_button.select_sound"
+ name="pref.advanced.popups.disable_button.select_sound"
+ type="bool"/>
+ <preference id="pref.advanced.popups.disable_button.preview_sound"
+ name="pref.advanced.popups.disable_button.preview_sound"
+ type="bool"/>
+ <preference id="privacy.popups.statusbar_icon_enabled"
+ name="privacy.popups.statusbar_icon_enabled"
+ type="bool"/>
+ <preference id="privacy.popups.showBrowserMessage"
+ name="privacy.popups.showBrowserMessage"
+ type="bool"/>
+ <preference id="privacy.popups.prefill_whitelist"
+ name="privacy.popups.prefill_whitelist"
+ type="bool"/>
+ <preference id="privacy.popups.remove_blacklist"
+ name="privacy.popups.remove_blacklist"
+ type="bool"/>
+ <preference id="privacy.popups.default_whitelist"
+ name="privacy.popups.default_whitelist"
+ type="string"/>
+ </preferences>
+
+ <groupbox id="popupsArea">
+ <caption label="&pref.popups.caption;"/>
+
+ <hbox>
+ <checkbox id="popupPolicy"
+ label="&popupBlock.label;"
+ accesskey="&popupBlock.accesskey;"
+ preference="dom.disable_open_during_load"/>
+ <spacer flex="1"/>
+ <button id="exceptionsButton"
+ label="&viewPermissions.label;"
+ accesskey="&viewPermissions.accesskey;"
+ preference="pref.advanced.popups.disable_button.view_popups"
+ oncommand="toDataManager('|permissions');"/>
+ </hbox>
+ <separator class="thin"/>
+ <description id="whenBlock">&whenBlock.description;</description>
+ <hbox>
+ <checkbox id="playSound"
+ label="&playSound.label;"
+ accesskey="&playSound.accesskey;"
+ preference="privacy.popups.sound_enabled"/>
+ </hbox>
+ <hbox class="indent">
+ <radiogroup id="popupSoundType"
+ preference="privacy.popups.sound_type"
+ aria-labelledby="playSound">
+ <radio id="popupSystemSound"
+ class="iconic"
+ value="0"
+ label="&systemSound.label;"
+ accesskey="&systemSound.accesskey;"/>
+ <radio id="popupCustomSound"
+ class="iconic"
+ value="1"
+ label="&customSound.label;"
+ accesskey="&customSound.accesskey;"/>
+ </radiogroup>
+ </hbox>
+ <hbox class="indent">
+ <filefield id="playSoundUrl"
+ flex="1"
+ preference="privacy.popups.sound_url"
+ preference-editable="true"
+ onsyncfrompreference="return WriteSoundField(this, document.getElementById('popups_pane').gSoundUrlPref.value);"
+ aria-labelledby="popupCustomSound"/>
+ <button id="selectSound"
+ label="&selectSound.label;"
+ accesskey="&selectSound.accesskey;"
+ preference="pref.advanced.popups.disable_button.select_sound"
+ oncommand="SelectSound(gSoundUrlPref);"/>
+ <button id="playSoundButton"
+ label="&playSoundButton.label;"
+ accesskey="&playSoundButton.accesskey;"
+ preference="pref.advanced.popups.disable_button.preview_sound"
+ oncommand="PlaySound(gSoundUrlPref.value, false);"/>
+ </hbox>
+ <hbox>
+ <checkbox id="displayIcon"
+ label="&displayIcon.label;"
+ accesskey="&displayIcon.accesskey;"
+ preference="privacy.popups.statusbar_icon_enabled"/>
+ </hbox>
+ <hbox>
+ <checkbox id="displayPopupsNotification"
+ label="&displayNotification.label;"
+ accesskey="&displayNotification.accesskey;"
+ preference="privacy.popups.showBrowserMessage"/>
+ </hbox>
+ <separator class="thin"/>
+ <description>&popupNote.description;</description>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-privatedata.js b/comm/suite/components/pref/content/pref-privatedata.js
new file mode 100644
index 0000000000..ba7305bc41
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-privatedata.js
@@ -0,0 +1,30 @@
+/* -*- Mode: Java; 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/. */
+
+function Startup() {
+ let pref = document.getElementById("privacy.sanitize.sanitizeOnShutdown");
+ updateClearOnShutdownBox(pref.valueFromPreferences);
+}
+
+/**
+ * Disable/enable clear on shutdown items in dialog depending on general pref
+ * to clear on shutdown.
+ */
+function updateClearOnShutdownBox(aDisable) {
+ let clearOnShutdownBox = document.getElementById("clearOnShutdownBox");
+ for (let childNode of clearOnShutdownBox.childNodes) {
+ childNode.disabled = !aDisable;
+ }
+}
+
+/**
+ * Displays a dialog from which individual parts of private data may be
+ * cleared.
+ */
+function clearPrivateDataNow() {
+ Cc["@mozilla.org/suite/suiteglue;1"]
+ .getService(Ci.nsISuiteGlue)
+ .sanitize(window);
+}
diff --git a/comm/suite/components/pref/content/pref-privatedata.xul b/comm/suite/components/pref/content/pref-privatedata.xul
new file mode 100644
index 0000000000..97e236def8
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-privatedata.xul
@@ -0,0 +1,181 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+ %brandDTD;
+ <!ENTITY % prefPrivateDataDTD SYSTEM "chrome://communicator/locale/pref/pref-privatedata.dtd">
+ %prefPrivateDataDTD;
+ <!ENTITY % prefSanitizeDTD SYSTEM "chrome://communicator/locale/sanitize.dtd">
+ %prefSanitizeDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="privatedata_pane" label="&pref.privatedata.title;"
+ script="chrome://communicator/content/pref/pref-privatedata.js">
+ <preferences id="privatedata_preferences">
+ <!-- Clear Private Data -->
+ <preference id="privacy.sanitize.sanitizeOnShutdown"
+ name="privacy.sanitize.sanitizeOnShutdown"
+ type="bool"
+ onchange="updateClearOnShutdownBox(this.value);"/>
+ <!-- Clear Private Data on shutdown -->
+ <preference id="privacy.clearOnShutdown.history"
+ name="privacy.clearOnShutdown.history"
+ type="bool"/>
+ <preference id="privacy.clearOnShutdown.urlbar"
+ name="privacy.clearOnShutdown.urlbar"
+ type="bool"/>
+ <preference id="privacy.clearOnShutdown.formdata"
+ name="privacy.clearOnShutdown.formdata"
+ type="bool"/>
+ <preference id="privacy.clearOnShutdown.passwords"
+ name="privacy.clearOnShutdown.passwords"
+ type="bool"/>
+ <preference id="privacy.clearOnShutdown.downloads"
+ name="privacy.clearOnShutdown.downloads"
+ type="bool"/>
+ <preference id="privacy.clearOnShutdown.cookies"
+ name="privacy.clearOnShutdown.cookies"
+ type="bool"/>
+ <preference id="privacy.clearOnShutdown.cache"
+ name="privacy.clearOnShutdown.cache"
+ type="bool"/>
+ <preference id="privacy.clearOnShutdown.offlineApps"
+ name="privacy.clearOnShutdown.offlineApps"
+ type="bool"/>
+ <preference id="privacy.clearOnShutdown.sessions"
+ name="privacy.clearOnShutdown.sessions"
+ type="bool"/>
+ <preference id="privacy.clearOnShutdown.siteSettings"
+ name="privacy.clearOnShutdown.siteSettings"
+ type="bool"/>
+
+ <!-- Clear Private Data manually -->
+ <preference id="privacy.cpd.history"
+ name="privacy.cpd.history"
+ type="bool"/>
+ <preference id="privacy.cpd.urlbar"
+ name="privacy.cpd.urlbar"
+ type="bool"/>
+ <preference id="privacy.cpd.formdata"
+ name="privacy.cpd.formdata"
+ type="bool"/>
+ <preference id="privacy.cpd.passwords"
+ name="privacy.cpd.passwords"
+ type="bool"/>
+ <preference id="privacy.cpd.downloads"
+ name="privacy.cpd.downloads"
+ type="bool"/>
+ <preference id="privacy.cpd.cookies"
+ name="privacy.cpd.cookies"
+ type="bool"/>
+ <preference id="privacy.cpd.cache"
+ name="privacy.cpd.cache"
+ type="bool"/>
+ <preference id="privacy.cpd.offlineApps"
+ name="privacy.cpd.offlineApps"
+ type="bool"/>
+ <preference id="privacy.cpd.sessions"
+ name="privacy.cpd.sessions"
+ type="bool"/>
+ <preference id="privacy.cpd.siteSettings"
+ name="privacy.cpd.siteSettings"
+ type="bool"/>
+ </preferences>
+
+ <!-- Clear Private Data -->
+ <groupbox id="clearPrivateDataGroup">
+ <caption label="&clearPrivateData.label;"/>
+ <button id="clearDataNow" icon="clear"
+ label="&clearDataDialog.label;"
+ accesskey="&clearDataDialog.accesskey;"
+ oncommand="clearPrivateDataNow();"/>
+ <separator class="thin" />
+ <hbox id="clearDataBox" align="center">
+ <checkbox id="alwaysClear" flex="1"
+ label="&alwaysClear.label;"
+ accesskey="&alwaysClear.accesskey;"
+ preference="privacy.sanitize.sanitizeOnShutdown"/>
+ </hbox>
+
+ <separator class="thin"/>
+
+ <label id="clearDataSettings"
+ value="&clearData.label;"/>
+
+ <hbox>
+ <groupbox id="clearCpdBox" flex="1">
+ <caption label="&clearData.cpd.label;"/>
+ <checkbox label="&itemHistory.label;"
+ accesskey="&itemHistory.accesskey;"
+ preference="privacy.cpd.history"/>
+ <checkbox label="&itemUrlBar.label;"
+ accesskey="&itemUrlBar.accesskey;"
+ preference="privacy.cpd.urlbar"/>
+ <checkbox label="&itemDownloads.label;"
+ accesskey="&itemDownloads.accesskey;"
+ preference="privacy.cpd.downloads"/>
+ <checkbox label="&itemFormSearchHistory.label;"
+ accesskey="&itemFormSearchHistory.accesskey;"
+ preference="privacy.cpd.formdata"/>
+ <checkbox label="&itemCache.label;"
+ accesskey="&itemCache.accesskey;"
+ preference="privacy.cpd.cache"/>
+ <checkbox label="&itemCookies.label;"
+ accesskey="&itemCookies.accesskey;"
+ preference="privacy.cpd.cookies"/>
+ <checkbox label="&itemOfflineApps.label;"
+ accesskey="&itemOfflineApps.accesskey;"
+ preference="privacy.cpd.offlineApps"/>
+ <checkbox label="&itemPasswords.label;"
+ accesskey="&itemPasswords.accesskey;"
+ preference="privacy.cpd.passwords"/>
+ <checkbox label="&itemSessions.label;"
+ accesskey="&itemSessions.accesskey;"
+ preference="privacy.cpd.sessions"/>
+ <checkbox label="&itemSitePreferences.label;"
+ accesskey="&itemSitePreferences.accesskey;"
+ preference="privacy.cpd.siteSettings"/>
+ </groupbox>
+
+ <groupbox id="clearOnShutdownBox" flex="1">
+ <caption label="&clearData.onShutdown.label;"/>
+ <checkbox label="&itemHistory.label;"
+ accesskey="&itemHistoryS.accesskey;"
+ preference="privacy.clearOnShutdown.history"/>
+ <checkbox label="&itemUrlBar.label;"
+ accesskey="&itemUrlBarS.accesskey;"
+ preference="privacy.clearOnShutdown.urlbar"/>
+ <checkbox label="&itemDownloads.label;"
+ accesskey="&itemDownloadsS.accesskey;"
+ preference="privacy.clearOnShutdown.downloads"/>
+ <checkbox label="&itemFormSearchHistory.label;"
+ accesskey="&itemFormSearchHistoryS.accesskey;"
+ preference="privacy.clearOnShutdown.formdata"/>
+ <checkbox label="&itemCache.label;"
+ accesskey="&itemCacheS.accesskey;"
+ preference="privacy.clearOnShutdown.cache"/>
+ <checkbox label="&itemCookies.label;"
+ accesskey="&itemCookiesS.accesskey;"
+ preference="privacy.clearOnShutdown.cookies"/>
+ <checkbox label="&itemOfflineApps.label;"
+ accesskey="&itemOfflineAppsS.accesskey;"
+ preference="privacy.clearOnShutdown.offlineApps"/>
+ <checkbox label="&itemPasswords.label;"
+ accesskey="&itemPasswordsS.accesskey;"
+ preference="privacy.clearOnShutdown.passwords"/>
+ <checkbox label="&itemSessions.label;"
+ accesskey="&itemSessionsS.accesskey;"
+ preference="privacy.clearOnShutdown.sessions"/>
+ <checkbox label="&itemSitePreferences.label;"
+ accesskey="&itemSitePreferencesS.accesskey;"
+ preference="privacy.clearOnShutdown.siteSettings"/>
+ </groupbox>
+ </hbox>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-proxies-advanced.xul b/comm/suite/components/pref/content/pref-proxies-advanced.xul
new file mode 100644
index 0000000000..69313f80e7
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-proxies-advanced.xul
@@ -0,0 +1,194 @@
+<?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://communicator/skin/" type="text/css"?>
+
+<!DOCTYPE prefwindow SYSTEM "chrome://communicator/locale/pref/pref-proxies-advanced.dtd" >
+
+<prefwindow xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="advancedProxyPreferences"
+ type="child"
+ onload="AdvancedInit();"
+ title="&pref.proxies.advanced.title;"
+ persist="screenX screenY">
+
+ <script src="chrome://communicator/content/pref/pref-proxies.js"/>
+ <script src="chrome://communicator/content/pref/preferences.js"/>
+
+ <prefpane helpTopic="nav-prefs-advanced-proxy-advanced"
+ helpURI="chrome://communicator/locale/help/suitehelp.rdf">
+ <preferences>
+ <preference id="network.proxy.http"
+ name="network.proxy.http"
+ type="string"
+ onchange="DoProxyHostCopy(this.value);"/>
+ <preference id="network.proxy.http_port"
+ name="network.proxy.http_port"
+ type="int"
+ onchange="DoProxyPortCopy(this.value);"/>
+ <preference id="network.proxy.ssl"
+ name="network.proxy.ssl"
+ type="string"/>
+ <preference id="network.proxy.ssl_port"
+ name="network.proxy.ssl_port"
+ type="int"/>
+ <preference id="network.proxy.ftp"
+ name="network.proxy.ftp"
+ type="string"/>
+ <preference id="network.proxy.ftp_port"
+ name="network.proxy.ftp_port"
+ type="int"/>
+ <preference id="network.proxy.share_proxy_settings"
+ name="network.proxy.share_proxy_settings"
+ type="bool"
+ onchange="DoProxyCopy(this.value);"/>
+ <preference id="network.proxy.socks"
+ name="network.proxy.socks"
+ type="string"/>
+ <preference id="network.proxy.socks_port"
+ name="network.proxy.socks_port"
+ type="int"/>
+ <preference id="network.proxy.socks_version"
+ name="network.proxy.socks_version"
+ type="int"/>
+ <preference id="network.proxy.socks_remote_dns"
+ name="network.proxy.socks_remote_dns"
+ type="bool"/>
+ </preferences>
+
+ <groupbox>
+ <caption label="&protocols.caption;"/>
+ <description style="width: 1px;">&protocols.description;</description>
+
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+
+ <rows>
+ <row>
+ <hbox align="center" pack="end">
+ <label value="&http.label;"
+ accesskey="&http.accesskey;"
+ control="networkProxyHTTP"/>
+ </hbox>
+ <hbox align="center">
+ <textbox id="networkProxyHTTP"
+ preference="network.proxy.http"
+ flex="1"
+ class="uri-element"/>
+ <label value="&port.label;"
+ accesskey="&HTTPPort.accesskey;"
+ control="networkProxyHTTP_Port"/>
+ <textbox id="networkProxyHTTP_Port"
+ preference="network.proxy.http_port"
+ type="number"
+ max="65535"
+ size="5"/>
+ </hbox>
+ </row>
+
+ <row>
+ <spacer/>
+ <hbox>
+ <checkbox id="networkProxyShareSettings"
+ label="&reuseProxy.label;"
+ accesskey="&reuseProxy.accesskey;"
+ preference="network.proxy.share_proxy_settings"/>
+ </hbox>
+ </row>
+
+ <row>
+ <hbox align="center" pack="end">
+ <label value="&ssl.label;"
+ accesskey="&ssl.accesskey;"
+ control="networkProxySSL"/>
+ </hbox>
+ <hbox align="center">
+ <textbox id="networkProxySSL"
+ preference="network.proxy.ssl"
+ flex="1"
+ class="uri-element"/>
+ <label value="&port.label;"
+ accesskey="&SSLPort.accesskey;"
+ control="networkProxySSL_Port"/>
+ <textbox id="networkProxySSL_Port"
+ preference="network.proxy.ssl_port"
+ type="number"
+ max="65535"
+ size="5"/>
+ </hbox>
+ </row>
+
+ <row>
+ <hbox align="center" pack="end">
+ <label value="&ftp.label;" accesskey="&ftp.accesskey;"
+ control="networkProxyFTP"/>
+ </hbox>
+ <hbox align="center">
+ <textbox id="networkProxyFTP"
+ preference="network.proxy.ftp"
+ flex="1"
+ class="uri-element"/>
+ <label value="&port.label;"
+ accesskey="&FTPPort.accesskey;"
+ control="networkProxyFTP_Port"/>
+ <textbox id="networkProxyFTP_Port"
+ preference="network.proxy.ftp_port"
+ type="number"
+ max="65535"
+ size="5"/>
+ </hbox>
+ </row>
+
+ </rows>
+ </grid>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&socks.caption;"/>
+ <description style="width: 1px;">&socks.description;</description>
+
+ <hbox align="center" pack="end">
+ <label value="&socks.label;"
+ accesskey="&socks.accesskey;"
+ control="networkProxySOCKS"/>
+ <textbox id="networkProxySOCKS"
+ preference="network.proxy.socks"
+ flex="1"
+ class="uri-element"/>
+ <label value="&port.label;"
+ accesskey="&SOCKSport.accesskey;"
+ control="networkProxySOCKS_Port"/>
+ <textbox id="networkProxySOCKS_Port"
+ type="number"
+ preference="network.proxy.socks_port"
+ max="65535"
+ size="5"/>
+ </hbox>
+
+ <radiogroup id="networkProxySOCKSVersion"
+ orient="horizontal"
+ preference="network.proxy.socks_version">
+ <radio id="networkProxySOCKSVersion4"
+ value="4"
+ label="&socks4.label;"
+ accesskey="&socks4.accesskey;"/>
+ <radio id="networkProxySOCKSVersion5"
+ value="5"
+ label="&socks5.label;"
+ accesskey="&socks5.accesskey;"/>
+ </radiogroup>
+
+ <hbox align="left">
+ <checkbox id="networkProxySOCKSRemoteDNS"
+ label="&socksRemoteDNS.label;"
+ accesskey="&socksRemoteDNS.accesskey;"
+ preference="network.proxy.socks_remote_dns"/>
+ </hbox>
+
+ </groupbox>
+ </prefpane>
+</prefwindow>
diff --git a/comm/suite/components/pref/content/pref-proxies.js b/comm/suite/components/pref/content/pref-proxies.js
new file mode 100644
index 0000000000..5120c3f5d0
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-proxies.js
@@ -0,0 +1,188 @@
+/* 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 kNoProxy = 0;
+const kManualProxy = 1;
+const kAutoConfigProxy = 2;
+const kObsoleteProxy = 3;
+const kAutoDiscoverProxy = 4;
+const kSystemProxy = 5;
+
+var gInstantApply;
+var gHTTP;
+var gHTTPPort;
+var gSSL;
+var gSSLPort;
+var gFTP;
+var gFTPPort;
+var gAutoURL;
+var gProxyType;
+var gShareSettings;
+
+// Only used by main prefwindow
+function Startup()
+{
+ InitCommonGlobals();
+ gAutoURL = document.getElementById("network.proxy.autoconfig_url");
+ gProxyType = document.getElementById("network.proxy.type");
+
+ // Check for system proxy settings class and unhide UI if present
+ if ("@mozilla.org/system-proxy-settings;1" in Cc)
+ document.getElementById("systemPref").hidden = false;
+
+ // Calculate a sane default for network.proxy.share_proxy_settings.
+ if (gShareSettings.value == null)
+ gShareSettings.value = DefaultForShareSettingsPref();
+
+ // The pref value 3 (kObsoleteProxy) for network.proxy.type is unused to
+ // maintain backwards compatibility. Treat 3 (kObsoleteProxy) equally to
+ // 0 (kNoProxy). See bug 115720.
+ if (gProxyType.value == kObsoleteProxy)
+ gProxyType.value = kNoProxy;
+
+ DoEnabling();
+}
+
+// Only used by child prefwindow
+function AdvancedInit()
+{
+ InitCommonGlobals();
+ DoProxyCopy(gShareSettings.value);
+}
+
+function InitCommonGlobals()
+{
+ gInstantApply = document.documentElement.instantApply;
+ gHTTP = document.getElementById("network.proxy.http");
+ gHTTPPort = document.getElementById("network.proxy.http_port");
+ gSSL = document.getElementById("network.proxy.ssl");
+ gSSLPort = document.getElementById("network.proxy.ssl_port");
+ gFTP = document.getElementById("network.proxy.ftp");
+ gFTPPort = document.getElementById("network.proxy.ftp_port");
+ gShareSettings = document.getElementById("network.proxy.share_proxy_settings");
+}
+
+// Returns true if all protocol specific proxies and all their
+// ports are set to the same value, false otherwise.
+function DefaultForShareSettingsPref()
+{
+ return gHTTP.value == gSSL.value &&
+ gHTTP.value == gFTP.value &&
+ gHTTPPort.value == gSSLPort.value &&
+ gHTTPPort.value == gFTPPort.value;
+}
+
+function DoEnabling()
+{
+ // convenience arrays
+ var manual = ["networkProxyHTTP", "networkProxyHTTP_Port",
+ "networkProxyNone", "advancedButton"];
+ var auto = ["networkProxyAutoconfigURL", "autoReload"];
+
+ switch (gProxyType.value)
+ {
+ case kNoProxy:
+ case kAutoDiscoverProxy:
+ case kSystemProxy:
+ Disable(manual);
+ Disable(auto);
+ break;
+ case kManualProxy:
+ Disable(auto);
+ if (!gProxyType.locked)
+ EnableUnlockedElements(manual, true);
+ break;
+ case kAutoConfigProxy:
+ default:
+ Disable(manual);
+ if (!gProxyType.locked)
+ {
+ EnableElementById("networkProxyAutoconfigURL", true, false);
+ EnableUnlockedButton(gAutoURL);
+ }
+ break;
+ }
+}
+
+function Disable(aElementIds)
+{
+ for (var i = 0; i < aElementIds.length; i++)
+ document.getElementById(aElementIds[i]).setAttribute("disabled", "true");
+}
+
+function EnableUnlockedElements(aElementIds, aEnable)
+{
+ for (var i = 0; i < aElementIds.length; i++)
+ EnableElementById(aElementIds[i], aEnable, false);
+}
+
+function EnableUnlockedButton(aElement)
+{
+ var enable = gInstantApply ||
+ (aElement.valueFromPreferences == aElement.value);
+ EnableElementById("autoReload", enable, false);
+}
+
+function ReloadPAC() {
+ // This reloads the PAC URL stored in preferences.
+ // When not in instant apply mode, the button that calls this gets
+ // disabled if the preference and what is showing in the UI differ.
+ Cc["@mozilla.org/network/protocol-proxy-service;1"]
+ .getService().reloadPAC();
+}
+
+function FixProxyURL(aURL)
+{
+ try
+ {
+ aURL.value =
+ Services.uriFixup.createFixupURI(aURL.value,
+ Ci.nsIURIFixup.FIXUP_FLAG_NONE).spec;
+ }
+ catch (e) {}
+
+ if (!gInstantApply)
+ EnableUnlockedButton(aURL);
+}
+
+function OpenAdvancedDialog()
+{
+ document.documentElement.openSubDialog("chrome://communicator/content/pref/pref-proxies-advanced.xul",
+ "AdvancedProxyPreferences", null);
+}
+
+function DoProxyCopy(aChecked)
+{
+ DoProxyHostCopy(gHTTP.value);
+ DoProxyPortCopy(gHTTPPort.value);
+ var nonshare = ["networkProxySSL", "networkProxySSL_Port",
+ "networkProxyFTP", "networkProxyFTP_Port"];
+ EnableUnlockedElements(nonshare, !aChecked);
+}
+
+function DoProxyHostCopy(aValue)
+{
+ if (!gShareSettings.value)
+ return;
+
+ gSSL.value = aValue;
+ gFTP.value = aValue;
+}
+
+function DoProxyPortCopy(aValue)
+{
+ if (!gShareSettings.value)
+ return;
+
+ gSSLPort.value = aValue;
+ gFTPPort.value = aValue;
+}
+
+function UpdateProxies()
+{
+ var noProxiesPref = document.getElementById("network.proxy.no_proxies_on");
+
+ noProxiesPref.value = noProxiesPref.value.replace(/[;, \n]+/g, ", ")
+ .replace(/^, |, $/g, "");
+}
diff --git a/comm/suite/components/pref/content/pref-proxies.xul b/comm/suite/components/pref/content/pref-proxies.xul
new file mode 100644
index 0000000000..acd1a1f053
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-proxies.xul
@@ -0,0 +1,156 @@
+<?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/. -->
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-proxies.dtd">
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="proxies_pane"
+ label="&pref.proxies.title;"
+ script="chrome://communicator/content/pref/pref-proxies.js">
+ <preferences id="proxies_preferences">
+ <preference id="network.proxy.type"
+ name="network.proxy.type"
+ type="int"
+ onchange="DoEnabling();"/>
+ <preference id="network.proxy.autoconfig_url"
+ name="network.proxy.autoconfig_url"
+ type="string"/>
+ <preference id="pref.advanced.proxies.disable_button.reload"
+ name="pref.advanced.proxies.disable_button.reload"
+ type="bool"/>
+ <preference id="network.proxy.http"
+ name="network.proxy.http"
+ type="string"
+ onchange="DoProxyHostCopy(this.value);"/>
+ <preference id="network.proxy.http_port"
+ name="network.proxy.http_port"
+ type="int"
+ onchange="DoProxyPortCopy(this.value);"/>
+ <preference id="pref.advanced.proxies.disable_button.advanced"
+ name="pref.advanced.proxies.disable_button.advanced"
+ type="bool"/>
+ <preference id="network.proxy.no_proxies_on"
+ name="network.proxy.no_proxies_on"
+ type="string"/>
+ <preference id="network.proxy.ssl"
+ name="network.proxy.ssl"
+ type="string"/>
+ <preference id="network.proxy.ssl_port"
+ name="network.proxy.ssl_port"
+ type="int"/>
+ <preference id="network.proxy.ftp"
+ name="network.proxy.ftp"
+ type="string"/>
+ <preference id="network.proxy.ftp_port"
+ name="network.proxy.ftp_port"
+ type="int"/>
+ <preference id="network.proxy.share_proxy_settings"
+ name="network.proxy.share_proxy_settings"
+ type="bool"/>
+ </preferences>
+
+ <description>&pref.proxies.desc;</description>
+ <groupbox>
+ <caption label="&proxyTitle.label;"/>
+ <radiogroup id="networkProxyType"
+ preference="network.proxy.type"
+ align="stretch">
+ <vbox align="start">
+ <radio value="0"
+ label="&directTypeRadio.label;"
+ accesskey="&directTypeRadio.accesskey;"/>
+ <radio value="4"
+ label="&wpadTypeRadio.label;"
+ accesskey="&wpadTypeRadio.accesskey;"/>
+ <radio value="5"
+ label="&systemTypeRadio.label;"
+ accesskey="&systemTypeRadio.accesskey;"
+ id="systemPref"
+ hidden="true"/>
+ <radio value="2"
+ label="&autoTypeRadio.label;"
+ accesskey="&autoTypeRadio.accesskey;"/>
+ </vbox>
+
+ <hbox class="indent" align="center">
+ <textbox id="networkProxyAutoconfigURL"
+ flex="1"
+ class="uri-element"
+ onchange="FixProxyURL(this);"
+ preference="network.proxy.autoconfig_url"/>
+ <button id="autoReload"
+ label="&reload.label;"
+ accesskey="&reload.accesskey;"
+ oncommand="ReloadPAC();"
+ preference="pref.advanced.proxies.disable_button.reload"/>
+ </hbox>
+
+ <vbox align="start">
+ <radio value="1"
+ label="&manualTypeRadio.label;"
+ accesskey="&manualTypeRadio.accesskey;"/>
+ </vbox>
+
+ <grid class="indent">
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+
+ <rows>
+ <row align="center">
+ <hbox align="center" pack="end">
+ <label value="&http.label;"
+ accesskey="&http.accesskey;"
+ control="networkProxyHTTP"/>
+ </hbox>
+ <textbox id="networkProxyHTTP"
+ preference="network.proxy.http"
+ class="uri-element"/>
+ </row>
+
+ <row>
+ <hbox align="center" pack="end">
+ <label value="&port.label;"
+ accesskey="&HTTPPort.accesskey;"
+ control="networkProxyHTTP_Port"/>
+ </hbox>
+ <hbox align="center">
+ <textbox id="networkProxyHTTP_Port"
+ preference="network.proxy.http_port"
+ type="number"
+ max="65535"
+ size="5"/>
+ <spacer flex="1"/>
+ <button id="advancedButton"
+ label="&advanced.label;"
+ accesskey="&advanced.accesskey;"
+ align="end"
+ oncommand="OpenAdvancedDialog();"
+ preference="pref.advanced.proxies.disable_button.advanced"/>
+ </hbox>
+ </row>
+
+ <row align="baseline">
+ <hbox align="center" pack="end">
+ <label value="&noproxy.label;"
+ accesskey="&noproxy.accesskey;"
+ control="networkProxyNone"/>
+ </hbox>
+ <textbox id="networkProxyNone"
+ multiline="true"
+ preference="network.proxy.no_proxies_on"
+ class="uri-element"
+ onchange="UpdateProxies();"/>
+ </row>
+ <row>
+ <spacer/>
+ <description control="networkProxyNone">&noproxyExplain.label;
+ </description>
+ </row>
+ </rows>
+ </grid>
+ </radiogroup>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-scripts.js b/comm/suite/components/pref/content/pref-scripts.js
new file mode 100644
index 0000000000..eb16b4d62f
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-scripts.js
@@ -0,0 +1,29 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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/. */
+
+function setDisableState(id, state) {
+ var component = document.getElementById(id);
+ var preference = component.getAttribute("preference");
+ var isLocked = document.getElementById(preference).locked;
+ component.disabled = isLocked || state;
+}
+
+function changeDisabledState(state) {
+ //Set the states of the groupbox children state based on the "javascript enabled" checkbox value
+ setDisableState("allowWindowMoveResize", state);
+ setDisableState("allowWindowStatusChange", state);
+ setDisableState("allowWindowFlip", state);
+ setDisableState("allowHideStatusBar", state);
+ setDisableState("allowContextmenuDisable", state);
+}
+
+function javascriptEnabledChange() {
+ var javascriptDisabled = !document.getElementById('javascript.enabled').value;
+ changeDisabledState(javascriptDisabled);
+}
+
+function Startup() {
+ javascriptEnabledChange();
+}
diff --git a/comm/suite/components/pref/content/pref-scripts.xul b/comm/suite/components/pref/content/pref-scripts.xul
new file mode 100644
index 0000000000..9018f29cc4
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-scripts.xul
@@ -0,0 +1,92 @@
+<?xml version="1.0"?><!-- -*- Mode: HTML -*- -->
+<!-- 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 overlay SYSTEM "chrome://communicator/locale/pref/pref-scripts.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="scripts_pane"
+ label="&pref.scripts2.title;"
+ script="chrome://communicator/content/pref/pref-scripts.js">
+
+ <preferences id="scripts_preferences">
+ <preference id="javascript.enabled"
+ name="javascript.enabled"
+ type="bool"
+ onchange="javascriptEnabledChange();"/>
+ <preference id="dom.disable_window_move_resize"
+ name="dom.disable_window_move_resize"
+ type="bool" inverted="true"/>
+ <preference id="dom.disable_window_flip"
+ name="dom.disable_window_flip"
+ type="bool" inverted="true"/>
+ <preference id="dom.disable_window_open_feature.status"
+ name="dom.disable_window_open_feature.status"
+ type="bool" inverted="true"/>
+ <preference id="dom.disable_window_status_change"
+ name="dom.disable_window_status_change"
+ type="bool" inverted="true"/>
+ <preference id="dom.event.contextmenu.enabled"
+ name="dom.event.contextmenu.enabled"
+ type="bool"/>
+ <preference id="browser.dom.window.dump.enabled"
+ name="browser.dom.window.dump.enabled"
+ type="bool"/>
+ <preference id="javascript.options.strict"
+ name="javascript.options.strict"
+ type="bool"/>
+ <preference id="javascript.options.showInConsole"
+ name="javascript.options.showInConsole"
+ type="bool"/>
+ </preferences>
+
+ <groupbox id="javascriptPreferences" flex="1">
+ <caption label="&enableJavaScript.label;"/>
+
+ <checkbox id="javascriptAllowNavigator"
+ label="&navigator.label;"
+ accesskey="&navigator.accesskey;"
+ preference="javascript.enabled"/>
+
+ <label control="AllowList"
+ class="indent"
+ value="&allowScripts.label;"
+ accesskey="&allowScripts.accesskey;"/>
+
+ <listbox id="AllowList" class="indent" flex="1">
+ <listitem type="checkbox" id="allowWindowMoveResize"
+ label="&allowWindowMoveResize.label;"
+ preference="dom.disable_window_move_resize"/>
+ <listitem type="checkbox" id="allowWindowFlip"
+ label="&allowWindowFlip.label;"
+ preference="dom.disable_window_flip"/>
+ <listitem type="checkbox" id="allowHideStatusBar"
+ label="&allowHideStatusBar.label;"
+ preference="dom.disable_window_open_feature.status"/>
+ <listitem type="checkbox" id="allowWindowStatusChange"
+ label="&allowWindowStatusChange.label;"
+ preference="dom.disable_window_status_change"/>
+ <listitem type="checkbox" id="allowContextmenuDisable"
+ label="&allowContextmenuDisable.label;"
+ preference="dom.event.contextmenu.enabled"/>
+ </listbox>
+ </groupbox>
+
+ <groupbox id="debugging">
+ <caption label="&debugging.label;"/>
+ <checkbox id="browserDOMWindowDumpEnabled"
+ label="&debugEnableDump.label;"
+ accesskey="&debugEnableDump.accesskey;"
+ preference="browser.dom.window.dump.enabled"/>
+ <checkbox id="javascriptOptionsStrict"
+ label="&debugStrictJavascript.label;"
+ accesskey="&debugStrictJavascript.accesskey;"
+ preference="javascript.options.strict"/>
+ <checkbox id="javascriptOptionsShowInConsole"
+ label="&debugConsoleJavascript.label;"
+ accesskey="&debugConsoleJavascript.accesskey;"
+ preference="javascript.options.showInConsole"/>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-search.js b/comm/suite/components/pref/content/pref-search.js
new file mode 100755
index 0000000000..8f17af63d2
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-search.js
@@ -0,0 +1,60 @@
+/* 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/. */
+
+var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+function Startup() {
+ MakeList();
+ SearchObserver.init();
+}
+
+var SearchObserver = {
+ init: function searchEngineListObserver_init() {
+ Services.obs.addObserver(this, "browser-search-engine-modified");
+ window.addEventListener("unload", this);
+ },
+
+ observe: function searchEngineListObj_observe(aEngine, aTopic, aVerb) {
+ if (aTopic != "browser-search-engine-modified")
+ return;
+ MakeList();
+ },
+
+ handleEvent: function searchEngineListEvent(aEvent) {
+ if (aEvent.type == "unload") {
+ window.removeEventListener("unload", this);
+ Services.obs.removeObserver(this, "browser-search-engine-modified");
+ }
+ }
+};
+
+function MakeList() {
+ var menulist = document.getElementById("engineList");
+ var currentEngineName = Services.search.currentEngine.name;
+
+ // Make sure the popup is empty.
+ menulist.removeAllItems();
+
+ var engines = Services.search.getVisibleEngines();
+ for (let engine of engines) {
+ let name = engine.name;
+ let menuitem = menulist.appendItem(name, name);
+ menuitem.setAttribute("class", "menuitem-iconic");
+ if (engine.iconURI)
+ menuitem.setAttribute("image", engine.iconURI.spec);
+ menuitem.engine = engine;
+ if (engine.name == currentEngineName) {
+ // Set selection to the current default engine.
+ menulist.selectedItem = menuitem;
+ }
+ }
+ // If the current engine isn't in the list any more, select the first item.
+ if (menulist.selectedIndex < 0)
+ menulist.selectedIndex = 0;
+}
+
+function UpdateDefaultEngine(selectedItem) {
+ Services.search.currentEngine = selectedItem.engine;
+ Services.obs.notifyObservers(null, "browser-search-engine-modified", "engine-current");
+}
diff --git a/comm/suite/components/pref/content/pref-search.xul b/comm/suite/components/pref/content/pref-search.xul
new file mode 100755
index 0000000000..e3eaa61701
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-search.xul
@@ -0,0 +1,50 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-search.dtd">
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="search_pane"
+ label="&pref.search.title;"
+ script="chrome://communicator/content/pref/pref-search.js">
+
+ <preferences id="search_preferences">
+ <preference id="browser.search.openintab"
+ name="browser.search.openintab"
+ type="bool"/>
+ <preference id="browser.search.opentabforcontextsearch"
+ name="browser.search.opentabforcontextsearch"
+ type="bool"/>
+ </preferences>
+
+ <groupbox>
+ <caption label="&legendHeader;"/>
+
+ <hbox align="center">
+ <label value="&defaultSearchEngine.label;"
+ accesskey="&defaultSearchEngine.accesskey;"
+ control="engineList"/>
+ <menulist id="engineList"
+ oncommand="UpdateDefaultEngine(this.selectedItem)"/>
+ </hbox>
+ <hbox pack="end">
+ <button id="managerButton"
+ label="&engineManager.label;"
+ oncommand="OpenSearchEngineManager();"/>
+ </hbox>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&searchResults.label;"/>
+ <checkbox id="openSearchTab"
+ label="&openInTab.label;"
+ accesskey="&openInTab.accesskey;"
+ preference="browser.search.openintab"/>
+ <checkbox id="openContextSearchTab"
+ label="&openContextSearchTab.label;"
+ accesskey="&openContextSearchTab.accesskey;"
+ preference="browser.search.opentabforcontextsearch"/>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-security.js b/comm/suite/components/pref/content/pref-security.js
new file mode 100644
index 0000000000..31dba56b7a
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-security.js
@@ -0,0 +1,15 @@
+/* -*- Mode: Java; 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/. */
+
+function Startup()
+{
+ var prefTrackProtect = document.getElementById("privacy.trackingprotection.enabled");
+ SetWarnTrackEnabled(prefTrackProtect.value);
+}
+
+function SetWarnTrackEnabled(aEnable)
+{
+ EnableElementById("warnTrackContent", aEnable, false);
+}
diff --git a/comm/suite/components/pref/content/pref-security.xul b/comm/suite/components/pref/content/pref-security.xul
new file mode 100644
index 0000000000..6823df7f9e
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-security.xul
@@ -0,0 +1,108 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+%brandDTD;
+<!ENTITY % prefSecurityDTD SYSTEM "chrome://communicator/locale/pref/pref-security.dtd">
+%prefSecurityDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="security_pane" label="&pref.security.title;"
+ script="chrome://communicator/content/pref/pref-security.js">
+ <preferences id="security_preferences">
+ <!-- User Tracking -->
+ <preference id="privacy.donottrackheader.enabled"
+ name="privacy.donottrackheader.enabled"
+ type="bool"/>
+ <preference id="privacy.trackingprotection.enabled"
+ name="privacy.trackingprotection.enabled"
+ type="bool"
+ onchange="SetWarnTrackEnabled(this.value);"/>
+ <preference id="privacy.warn_tracking_content"
+ name="privacy.warn_tracking_content"
+ type="bool"/>
+
+ <!-- Location Aware Browsing -->
+ <preference id="geo.enabled"
+ name="geo.enabled"
+ type="bool"/>
+
+ <!-- Safe Browsing -->
+ <preference id="browser.safebrowsing.malware.enabled"
+ name="browser.safebrowsing.malware.enabled"
+ type="bool"/>
+ <preference id="browser.safebrowsing.phishing.enabled"
+ name="browser.safebrowsing.phishing.enabled"
+ type="bool"/>
+
+ <preference id="accessibility.blockautorefresh"
+ name="accessibility.blockautorefresh"
+ type="bool"/>
+ </preferences>
+
+ <!-- User Tracking -->
+ <groupbox id="trackingGroup">
+ <caption label="&tracking.label;"/>
+
+ <description>&trackingIntro.label;</description>
+ <checkbox id="doNotTrack"
+ label="&doNotTrack.label;"
+ accesskey="&doNotTrack.accesskey;"
+ preference="privacy.donottrackheader.enabled"/>
+ <checkbox id="trackProtect"
+ label="&trackProtect.label;"
+ accesskey="&trackProtect.accesskey;"
+ preference="privacy.trackingprotection.enabled"/>
+ <checkbox id="warnTrackContent"
+ class="indent"
+ label="&warnTrackContent.label;"
+ accesskey="&warnTrackContent.accesskey;"
+ preference="privacy.warn_tracking_content"/>
+ </groupbox>
+
+ <!-- Location Aware Browsing -->
+ <groupbox id="geoLocationGroup">
+ <caption label="&geoLocation.label;"/>
+
+ <description>&geoIntro.label;</description>
+ <radiogroup id="geoSelection"
+ preference="geo.enabled">
+ <radio id="geoEnabled"
+ value="true"
+ label="&geoEnabled.label;"
+ accesskey="&geoEnabled.accesskey;"/>
+ <radio id="geoDisabled"
+ value="false"
+ label="&geoDisabled.label;"
+ accesskey="&geoDisabled.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+
+ <!-- Safe Browsing -->
+ <groupbox id="safeBrowsingGroup">
+ <caption label="&safeBrowsing.label;"/>
+
+ <description>&safeBrowsingIntro.label;</description>
+ <checkbox id="blockAttackSites"
+ label="&blockAttackSites.label;"
+ accesskey="&blockAttackSites.accesskey;"
+ preference="browser.safebrowsing.malware.enabled"/>
+ <checkbox id="blockWebForgeries"
+ label="&blockWebForgeries.label;"
+ accesskey="&blockWebForgeries.accesskey;"
+ preference="browser.safebrowsing.phishing.enabled"/>
+ </groupbox>
+
+ <vbox class="box-padded" align="start">
+ <checkbox id="blockAutoRefresh"
+ label="&blockAutoRefresh.label;"
+ accesskey="&blockAutoRefresh.accesskey;"
+ preference="accessibility.blockautorefresh"/>
+ </vbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-smartupdate.js b/comm/suite/components/pref/content/pref-smartupdate.js
new file mode 100644
index 0000000000..8e9712a936
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-smartupdate.js
@@ -0,0 +1,87 @@
+/* -*- Mode: Java; 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/. */
+
+var gCanCheckForUpdates;
+
+function Startup()
+{
+ var hasUpdater = "nsIApplicationUpdateService" in Ci;
+
+ if (hasUpdater)
+ {
+ var aus = Cc["@mozilla.org/updates/update-service;1"]
+ .getService(Ci.nsIApplicationUpdateService);
+ gCanCheckForUpdates = aus.canCheckForUpdates;
+
+ UpdateAddonsItems();
+ UpdateAppItems();
+ }
+ else
+ {
+ var appGroupBox = document.getElementById("appUpdatesGroupBox");
+ appGroupBox.hidden = true;
+ }
+}
+
+/*
+ * Preferences:
+ *
+ * app.update.enabled
+ * - boolean:
+ * - true if updates to the application are enabled, false otherwise
+ * extensions.update.enabled
+ * - boolean:
+ * - true if updates to extensions and themes are enabled, false otherwise
+ * app.update.auto
+ * - true if updates should be automatically downloaded and installed,
+ * false if the user should be asked what he wants to do when an
+ * update is available
+ */
+function UpdateAddonsItems()
+{
+ var addOnsCheck = !document.getElementById("xpinstall.enabled").value;
+
+ document.getElementById("addOnsUpdatesEnabled").disabled =
+ addOnsCheck ||
+ document.getElementById("extensions.update.enabled").locked;
+
+ document.getElementById("addOnsUpdateFrequency").disabled =
+ !document.getElementById("xpinstall.enabled").value ||
+ !document.getElementById("extensions.update.enabled").value ||
+ document.getElementById("extensions.update.interval").locked;
+
+ document.getElementById("allowedSitesLink").disabled =
+ addOnsCheck;
+
+ document.getElementById("addOnsModeAutoEnabled").disabled =
+ addOnsCheck ||
+ !document.getElementById("extensions.update.enabled").value ||
+ document.getElementById("extensions.update.enabled").locked;
+}
+
+function UpdateAppItems()
+{
+ var enabledPref = document.getElementById("app.update.enabled");
+
+ document.getElementById("appUpdatesEnabled").disabled =
+ !gCanCheckForUpdates || enabledPref.locked;
+
+ document.getElementById("appUpdateFrequency").disabled =
+ !enabledPref.value || !gCanCheckForUpdates ||
+ document.getElementById("app.update.interval").locked;
+
+ document.getElementById("appModeAutoEnabled").disabled =
+ !enabledPref.value || !gCanCheckForUpdates;
+}
+
+/**
+ * Displays the history of installed updates.
+ */
+function ShowUpdateHistory()
+{
+ Cc["@mozilla.org/updates/update-prompt;1"]
+ .createInstance(Ci.nsIUpdatePrompt)
+ .showUpdateHistory(window);
+}
diff --git a/comm/suite/components/pref/content/pref-smartupdate.xul b/comm/suite/components/pref/content/pref-smartupdate.xul
new file mode 100644
index 0000000000..a9b9546c31
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-smartupdate.xul
@@ -0,0 +1,139 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+%brandDTD;
+<!ENTITY % prefSmartUpdateDTD SYSTEM "chrome://communicator/locale/pref/pref-smartupdate.dtd">
+%prefSmartUpdateDTD;
+]>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="smartupdate_pane"
+ label="&pref.smartUpdate.title;"
+ script="chrome://communicator/content/pref/pref-smartupdate.js">
+
+ <preferences id="smartupdate_preferences">
+ <preference id="xpinstall.enabled"
+ name="xpinstall.enabled"
+ type="bool"
+ onchange="UpdateAddonsItems();"/>
+ <preference id="extensions.update.enabled"
+ name="extensions.update.enabled"
+ type="bool"
+ onchange="UpdateAddonsItems();"/>
+ <preference id="extensions.update.interval"
+ name="extensions.update.interval"
+ type="int"/>
+ <preference id="extensions.update.autoUpdateDefault"
+ name="extensions.update.autoUpdateDefault"
+ type="bool"/>
+ <preference id="extensions.getAddons.cache.enabled"
+ name="extensions.getAddons.cache.enabled"
+ type="bool"/>
+ <preference id="app.update.enabled"
+ name="app.update.enabled"
+ type="bool"
+ onchange="UpdateAppItems();"/>
+ <preference id="app.update.auto"
+ name="app.update.auto"
+ type="bool"
+ onchange="UpdateAppItems();"/>
+ <preference id="app.update.interval"
+ name="app.update.interval"
+ type="int"/>
+ <preference id="app.update.disable_button.showUpdateHistory"
+ name="app.update.disable_button.showUpdateHistory"
+ type="bool"/>
+ </preferences>
+
+ <groupbox>
+ <caption label="&addOnsTitle.label;"/>
+ <hbox align="center">
+ <checkbox id="XPInstallEnabled"
+ label="&addOnsAllow.label;"
+ flex="1"
+ accesskey="&addOnsAllow.accesskey;"
+ preference="xpinstall.enabled"/>
+ <label id="allowedSitesLink"
+ class="text-link"
+ value="&allowedSitesLink.label;"
+ onclick="toDataManager('|permissions');"/>
+ </hbox>
+ <hbox class="indent">
+ <checkbox id="addOnsUpdatesEnabled"
+ label="&autoAddOnsUpdates.label;"
+ accesskey="&autoAddOnsUpdates.accesskey;"
+ preference="extensions.update.enabled"/>
+ <radiogroup id="addOnsUpdateFrequency"
+ orient="horizontal"
+ preference="extensions.update.interval">
+ <radio id="addOnsFreqDaily"
+ label="&daily.label;"
+ accesskey="&addOnsDaily.accesskey;"
+ value="86400"/>
+ <radio id="addOnsFreqWeekly"
+ label="&weekly.label;"
+ accesskey="&addOnsWeekly.accesskey;"
+ value="604800"/>
+ </radiogroup>
+ </hbox>
+ <hbox class="indent">
+ <checkbox id="addOnsModeAutoEnabled"
+ class="indent"
+ label="&addOnsModeAutomatic.label;"
+ flex="1"
+ accesskey="&addOnsModeAutomatic.accesskey;"
+ preference="extensions.update.autoUpdateDefault"/>
+ </hbox>
+ <hbox align="center">
+ <checkbox id="enablePersonalized"
+ flex="1"
+ label="&enablePersonalized.label;"
+ accesskey="&enablePersonalized.accesskey;"
+ preference="extensions.getAddons.cache.enabled"/>
+ <label id="addonManagerLink"
+ class="text-link"
+ onclick="toEM('addons://list/extension');"
+ value="&addonManagerLink.label;"/>
+ </hbox>
+ </groupbox>
+
+ <groupbox id="appUpdatesGroupBox">
+ <caption label="&appUpdates.caption;"/>
+ <hbox>
+ <checkbox id="appUpdatesEnabled"
+ label="&autoAppUpdates.label;"
+ accesskey="&autoAppUpdates.accesskey;"
+ preference="app.update.enabled"/>
+ <radiogroup id="appUpdateFrequency"
+ orient="horizontal"
+ preference="app.update.interval">
+ <radio id="appFreqDaily"
+ label="&daily.label;"
+ accesskey="&appDaily.accesskey;"
+ value="86400"/>
+ <radio id="appFreqWeekly"
+ label="&weekly.label;"
+ accesskey="&appWeekly.accesskey;"
+ value="604800"/>
+ </radiogroup>
+ </hbox>
+ <checkbox id="appModeAutoEnabled"
+ class="indent"
+ label="&appModeAutomatic.label;"
+ flex="1"
+ accesskey="&appModeAutomatic.accesskey;"
+ preference="app.update.auto"/>
+ <hbox pack="end">
+ <button id="showUpdateHistory"
+ label="&updateHistoryButton.label;"
+ accesskey="&updateHistoryButton.accesskey;"
+ preference="app.update.disable_button.showUpdateHistory"
+ oncommand="ShowUpdateHistory();"/>
+ </hbox>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-spelling.js b/comm/suite/components/pref/content/pref-spelling.js
new file mode 100644
index 0000000000..6c214af3fc
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-spelling.js
@@ -0,0 +1,119 @@
+/* -*- Mode: Java; 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/. */
+
+var gDictCount = 0;
+var gLastSelectedLang;
+
+function Startup() {
+ if ("@mozilla.org/spellchecker;1" in Cc)
+ InitLanguageMenu();
+ else
+ {
+ document.getElementById("generalSpelling").hidden = true;
+ document.getElementById("mailSpelling").hidden = true;
+ document.getElementById("noSpellCheckLabel").hidden = false;
+ }
+}
+
+function InitLanguageMenu() {
+ var spellChecker = Cc["@mozilla.org/spellchecker/engine;1"]
+ .getService(Ci.mozISpellCheckingEngine);
+
+ // Get the list of dictionaries from the spellchecker.
+ var dictList = spellChecker.getDictionaryList();
+ var count = dictList.length;
+
+ // If dictionary count hasn't changed then no need to update the menu.
+ if (gDictCount == count)
+ return;
+
+ // Store current dictionary count.
+ gDictCount = count;
+
+ // Load the string bundles that will help us map
+ // RFC 1766 strings to UI strings.
+
+ // Load the language string bundle.
+ var languageBundle = document.getElementById("languageNamesBundle");
+ var regionBundle = null;
+ // If we have a language string bundle, load the region string bundle.
+ if (languageBundle)
+ regionBundle = document.getElementById("regionNamesBundle");
+
+ var menuStr2;
+ var isoStrArray;
+ var langId;
+ var langLabel;
+
+ for (let i = 0; i < count; i++) {
+ try {
+ langId = dictList[i];
+ isoStrArray = dictList[i].split(/[-_]/);
+
+ if (languageBundle && isoStrArray[0])
+ langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
+
+ if (regionBundle && langLabel && isoStrArray.length > 1 && isoStrArray[1]) {
+ menuStr2 = regionBundle.getString(isoStrArray[1].toLowerCase());
+ if (menuStr2)
+ langLabel += "/" + menuStr2;
+ }
+
+ if (langLabel && isoStrArray.length > 2 && isoStrArray[2])
+ langLabel += " (" + isoStrArray[2] + ")";
+
+ if (!langLabel)
+ langLabel = langId;
+ } catch (ex) {
+ // getString throws an exception when a key is not found in the
+ // bundle. In that case, just use the original dictList string.
+ langLabel = langId;
+ }
+ dictList[i] = [langLabel, langId];
+ }
+
+ // sort by locale-aware collation
+ dictList.sort(
+ function compareFn(a, b) {
+ return a[0].localeCompare(b[0]);
+ }
+ );
+
+ var languageMenuList = document.getElementById("languageMenuList");
+ // Remove any languages from the list.
+ var languageMenuPopup = languageMenuList.menupopup;
+ while (languageMenuPopup.firstChild.localName != "menuseparator")
+ languageMenuPopup.firstChild.remove();
+
+ var curLang = languageMenuList.value;
+ var defaultItem = null;
+
+ for (let i = 0; i < count; i++) {
+ let item = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem");
+ item.setAttribute("label", dictList[i][0]);
+ item.setAttribute("value", dictList[i][1]);
+ let beforeItem = gDialog.LanguageMenulist.getItemAtIndex(i);
+ languageMenuPopup.insertBefore(item, beforeItem);
+
+ if (curLang && dictList[i][1] == curLang)
+ defaultItem = item;
+ }
+
+ // Now make sure the correct item in the menu list is selected.
+ if (defaultItem) {
+ languageMenuList.selectedItem = defaultItem;
+ gLastSelectedLang = defaultItem;
+ }
+}
+
+function SelectLanguage(aTarget) {
+ if (aTarget.value != "more-cmd")
+ gLastSelectedLang = aTarget;
+ else {
+ openDictionaryList();
+ if (gLastSelectedLang)
+ document.getElementById("languageMenuList").selectedItem = gLastSelectedLang;
+ }
+}
diff --git a/comm/suite/components/pref/content/pref-spelling.xul b/comm/suite/components/pref/content/pref-spelling.xul
new file mode 100644
index 0000000000..93fa605fb5
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-spelling.xul
@@ -0,0 +1,80 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-spelling.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <prefpane id="spelling_pane"
+ label="&prefSpelling.title;"
+ script="chrome://communicator/content/pref/pref-spelling.js">
+
+ <preferences id="spelling_preferences">
+ <preference id="mail.SpellCheckBeforeSend"
+ name="mail.SpellCheckBeforeSend"
+ type="bool"/>
+ <preference id="mail.spellcheck.inline"
+ name="mail.spellcheck.inline"
+ type="bool"/>
+ <preference id="spellchecker.dictionary"
+ name="spellchecker.dictionary"
+ type="string"
+ onchange="SelectLanguage(event.target)"/>
+ <preference id="layout.spellcheckDefault"
+ name="layout.spellcheckDefault"
+ type="int"/>
+ </preferences>
+
+ <label id="noSpellCheckLabel"
+ value="&noSpellCheckAvailable.label;"
+ hidden="true"/>
+
+ <groupbox id="generalSpelling" align="start">
+ <caption label="&generalSpelling.label;"/>
+ <hbox align="center" pack="start">
+ <label value="&languagePopup.label;"
+ accesskey="&languagePopup.accessKey;"
+ control="languageMenuList"/>
+ <menulist id="languageMenuList"
+ preference="spellchecker.dictionary">
+ <menupopup onpopupshowing="InitLanguageMenu();">
+ <!-- dynamic content populated by JS -->
+ <menuseparator/>
+ <menuitem value="more-cmd" label="&moreDictionaries.label;"/>
+ </menupopup>
+ </menulist>
+ <spring flex="1"/>
+ </hbox>
+ <separator class="thin"/>
+ <hbox align="center">
+ <label value="&checkSpellingWhenTyping.label;"
+ accesskey="&checkSpellingWhenTyping.accesskey;"
+ control="spellcheckDefault"/>
+ <menulist id="spellcheckDefault"
+ preference="layout.spellcheckDefault">
+ <menupopup>
+ <menuitem value="0" label="&dontCheckSpelling.label;"/>
+ <menuitem value="1" label="&multilineCheckSpelling.label;"/>
+ <menuitem value="2" label="&alwaysCheckSpelling.label;"/>
+ </menupopup>
+ </menulist>
+ </hbox>
+ </groupbox>
+
+ <groupbox id="mailSpelling" align="start">
+ <caption label="&spellForMailAndNews.label;"/>
+ <vbox align="start">
+ <checkbox id="spellCheckBeforeSend"
+ label="&checkSpellingBeforeSend.label;"
+ accesskey="&checkSpellingBeforeSend.accesskey;"
+ preference="mail.SpellCheckBeforeSend"/>
+ <checkbox id="inlineSpellCheck"
+ label="&spellCheckInline.label;"
+ accesskey="&spellCheckInline.accesskey;"
+ preference="mail.spellcheck.inline"/>
+ </vbox>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-sync.js b/comm/suite/components/pref/content/pref-sync.js
new file mode 100644
index 0000000000..06d1825a70
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-sync.js
@@ -0,0 +1,143 @@
+/* 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 {Weave} = ChromeUtils.import("resource://services-sync/main.js");
+
+const PAGE_NO_ACCOUNT = 0;
+const PAGE_HAS_ACCOUNT = 1;
+const PAGE_NEEDS_UPDATE = 2;
+
+var gSyncPane = {
+ get page() {
+ return document.getElementById("weavePrefsDeck").selectedIndex;
+ },
+
+ set page(val) {
+ document.getElementById("weavePrefsDeck").selectedIndex = val;
+ },
+
+ get _usingCustomServer() {
+ return Weave.Svc.Prefs.isSet("serverURL");
+ },
+
+ needsUpdate: function () {
+ this.page = PAGE_NEEDS_UPDATE;
+ let label = document.getElementById("loginError");
+ label.value = Weave.Utils.getErrorString(Weave.Status.login);
+ label.className = "error";
+ },
+
+ topics: [ "weave:service:ready",
+ "weave:service:login:error",
+ "weave:service:login:finish",
+ "weave:service:start-over",
+ "weave:service:setup-complete",
+ "weave:service:logout:finish"],
+
+ init: function () {
+ for (var topic of this.topics)
+ Services.obs.addObserver(this, topic);
+
+ window.addEventListener("unload", this);
+
+ var xps = Cc["@mozilla.org/weave/service;1"]
+ .getService().wrappedJSObject;
+ if (xps.ready)
+ this.observe(null, "weave:service:ready", null);
+ else
+ xps.ensureLoaded();
+ },
+
+ handleEvent: function (aEvent) {
+ window.removeEventListener("unload", this);
+
+ for (var topic of this.topics)
+ Services.obs.removeObserver(this, topic);
+ },
+
+ observe: function (aSubject, aTopic, aData) {
+ if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED ||
+ Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
+ this.page = PAGE_NO_ACCOUNT;
+ } else if (Weave.Status.login == Weave.LOGIN_FAILED_INVALID_PASSPHRASE ||
+ Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) {
+ this.needsUpdate();
+ } else {
+ this.page = PAGE_HAS_ACCOUNT;
+ document.getElementById("accountName").value = Weave.Service.identity.account;
+ document.getElementById("syncComputerName").value = Weave.Service.clientsEngine.localName;
+ document.getElementById("tosPP").hidden = this._usingCustomServer;
+ }
+ },
+
+ startOver: function (showDialog) {
+ if (showDialog) {
+ let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING +
+ Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL;
+ let prefutilitiesBundle = document.getElementById("bundle_prefutilities");
+ let buttonChoice =
+ Services.prompt.confirmEx(window,
+ prefutilitiesBundle.getString("syncUnlink.title"),
+ prefutilitiesBundle.getString("syncUnlink.label"),
+ flags,
+ prefutilitiesBundle.getString("syncUnlinkConfirm.label"),
+ null, null, null, {});
+
+ // If the user selects cancel, just bail
+ if (buttonChoice == 1)
+ return;
+ }
+
+ Weave.Service.startOver();
+ this.updateWeavePrefs();
+ },
+
+ updatePass: function () {
+ if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED)
+ gSyncUtils.changePassword();
+ else
+ gSyncUtils.updatePassphrase();
+ },
+
+ resetPass: function () {
+ if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED)
+ gSyncUtils.resetPassword();
+ else
+ gSyncUtils.resetPassphrase();
+ },
+
+ openSetup: function (resetSync) {
+ var win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
+ if (win)
+ win.focus();
+ else {
+ window.openDialog("chrome://communicator/content/sync/syncSetup.xul",
+ "weaveSetup", "centerscreen,chrome,resizable=no", resetSync);
+ }
+ },
+
+ openQuotaDialog: function () {
+ let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
+ if (win)
+ win.focus();
+ else
+ window.openDialog("chrome://communicator/content/sync/syncQuota.xul", "",
+ "centerscreen,chrome,dialog,modal");
+ },
+
+ openAddDevice: function () {
+ if (!Weave.Utils.ensureMPUnlocked())
+ return;
+ let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
+ if (win)
+ win.focus();
+ else
+ window.openDialog("chrome://communicator/content/sync/syncAddDevice.xul",
+ "syncAddDevice", "centerscreen,chrome,resizable=no");
+ },
+
+ resetSync: function () {
+ this.openSetup(true);
+ }
+};
diff --git a/comm/suite/components/pref/content/pref-sync.xul b/comm/suite/components/pref/content/pref-sync.xul
new file mode 100644
index 0000000000..4163c0de70
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-sync.xul
@@ -0,0 +1,158 @@
+<?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/. -->
+
+<!DOCTYPE overlay [
+<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+<!ENTITY % syncBrandDTD SYSTEM "chrome://communicator/locale/sync/syncBrand.dtd">
+<!ENTITY % syncDTD SYSTEM "chrome://communicator/locale/pref/pref-sync.dtd">
+%brandDTD;
+%syncBrandDTD;
+%syncDTD;
+]>
+
+<overlay id="SyncPaneOverlay"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml">
+
+ <prefpane id="sync_pane"
+ helpTopic="sync_prefs"
+ onpaneload="gSyncPane.init();">
+
+ <preferences>
+ <preference id="engine.addons" name="services.sync.engine.addons" type="bool"/>
+ <preference id="engine.bookmarks" name="services.sync.engine.bookmarks" type="bool"/>
+ <preference id="engine.history" name="services.sync.engine.history" type="bool"/>
+ <preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/>
+ <preference id="engine.prefs" name="services.sync.engine.prefs" type="bool"/>
+ <preference id="engine.tabs" name="services.sync.engine.tabs" type="bool"/>
+ </preferences>
+
+ <script src="chrome://communicator/content/pref/pref-sync.js"/>
+ <script src="chrome://communicator/content/sync/syncUtils.js"/>
+
+ <deck id="weavePrefsDeck">
+ <vbox id="noAccount" align="center">
+ <spacer flex="1"/>
+ <description id="syncDesc" flex="1">
+ &weaveDesc.label;
+ </description>
+ <button id="setupButton"
+ label="&setupButton.label;"
+ accesskey="&setupButton.accesskey;"
+ oncommand="gSyncPane.openSetup();"/>
+ <separator/>
+ <spacer flex="3"/>
+ </vbox>
+ <vbox id="hasAccount">
+ <groupbox>
+ <caption label="&accountGroupboxCaption.label;"/>
+ <hbox align="center">
+ <label value="&accountName.label;" control="accountName"/>
+ <textbox id="accountName" flex="1" readonly="true"/>
+ <button type="menu"
+ label="&manageAccount.label;"
+ accesskey="&manageAccount.accesskey;">
+ <menupopup>
+ <menuitem label="&viewQuota.label;"
+ accesskey="&viewQuota.accesskey;"
+ oncommand="gSyncPane.openQuotaDialog();"/>
+ <menuseparator/>
+ <menuitem label="&changePassword.label;"
+ accesskey="&changePassword.accesskey;"
+ oncommand="gSyncUtils.changePassword();"/>
+ <menuitem label="&myRecoveryKey.label;"
+ accesskey="&myRecoveryKey.accesskey;"
+ oncommand="gSyncUtils.resetPassphrase();"/>
+ <menuseparator/>
+ <menuitem label="&resetSync.label;"
+ accesskey="&resetSync.accesskey;"
+ oncommand="gSyncPane.resetSync();"/>
+ <menuitem label="&unlinkDevice.label;"
+ accesskey="&unlinkDevice.accesskey;"
+ oncommand="gSyncPane.startOver(true);"/>
+ <menuseparator/>
+ <menuitem label="&addDevice.label;"
+ accesskey="&addDevice.accesskey;"
+ oncommand="gSyncPane.openAddDevice();"/>
+ </menupopup>
+ </button>
+ </hbox>
+ <vbox>
+ <label value="&syncMy2.label;"/>
+ <listbox id="syncEnginesList" flex="1">
+ <listitem type="checkbox"
+ label="&engine.addons.label;"
+ accesskey="&engine.addons.accesskey;"
+ preference="engine.addons"/>
+ <listitem type="checkbox"
+ label="&engine.bookmarks.label;"
+ accesskey="&engine.bookmarks.accesskey;"
+ preference="engine.bookmarks"/>
+ <listitem type="checkbox"
+ label="&engine.history.label;"
+ accesskey="&engine.history.accesskey;"
+ preference="engine.history"/>
+ <listitem type="checkbox"
+ label="&engine.passwords.label;"
+ accesskey="&engine.passwords.accesskey;"
+ preference="engine.passwords"/>
+ <listitem type="checkbox"
+ label="&engine.prefs.label;"
+ accesskey="&engine.prefs.accesskey;"
+ preference="engine.prefs"/>
+ <listitem type="checkbox"
+ label="&engine.tabs.label;"
+ accesskey="&engine.tabs.accesskey;"
+ preference="engine.tabs"/>
+ </listbox>
+ </vbox>
+ </groupbox>
+ <groupbox>
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="&syncComputerName.label;"
+ accesskey="&syncComputerName.accesskey;"
+ control="syncComputerName"/>
+ <textbox id="syncComputerName"
+ onchange="gSyncUtils.changeName(this);"/>
+ </row>
+ </rows>
+ </grid>
+ </groupbox>
+ <hbox id="tosPP" pack="center">
+ <label class="text-link"
+ onclick="event.stopPropagation(); gSyncUtils.openToS();"
+ value="&prefs.tosLink.label;"/>
+ <label class="text-link"
+ onclick="event.stopPropagation(); gSyncUtils.openPrivacyPolicy();"
+ value="&prefs.ppLink.label;"/>
+ </hbox>
+ </vbox>
+ <vbox id="needsUpdate" align="center" pack="center">
+ <hbox>
+ <label id="loginError" value=""/>
+ <button label="&updatePass.label;"
+ accesskey="&updatePass.accesskey;"
+ oncommand="gSyncPane.updatePass(); return false;"
+ id="updatePassButton"/>
+ <button label="&resetPass.label;"
+ accesskey="&resetPass.accesskey;"
+ oncommand="gSyncPane.resetPass(); return false;"
+ id="resetPassButton"/>
+ </hbox>
+ <button label="&unlinkDevice.label;"
+ accesskey="&unlinkDevice.accesskey;"
+ oncommand="gSyncPane.startOver(true); return false;"
+ id="unlinkDeviceButton"/>
+ </vbox>
+ </deck>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/pref-tabs.xul b/comm/suite/components/pref/content/pref-tabs.xul
new file mode 100644
index 0000000000..24361fba85
--- /dev/null
+++ b/comm/suite/components/pref/content/pref-tabs.xul
@@ -0,0 +1,113 @@
+<?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/. -->
+
+<!DOCTYPE overlay SYSTEM "chrome://communicator/locale/pref/pref-tabs.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <prefpane id="tabs_pane"
+ label="&tabHeader.label;">
+
+ <preferences id="tabs_preferences">
+ <preference id="browser.tabs.autoHide"
+ name="browser.tabs.autoHide"
+ type="bool"/>
+ <preference id="browser.tabs.loadInBackground"
+ name="browser.tabs.loadInBackground"
+ type="bool"
+ inverted="true"/>
+ <preference id="browser.tabs.loadDivertedInBackground"
+ name="browser.tabs.loadDivertedInBackground"
+ type="bool"
+ inverted="true"/>
+ <preference id="browser.tabs.avoidBrowserFocus"
+ name="browser.tabs.avoidBrowserFocus"
+ type="bool"
+ inverted="true"/>
+ <preference id="browser.tabs.warnOnClose"
+ name="browser.tabs.warnOnClose"
+ type="bool"/>
+ <preference id="browser.tabs.insertRelatedAfterCurrent"
+ name="browser.tabs.insertRelatedAfterCurrent"
+ type="bool"/>
+ <preference id="browser.tabs.opentabfor.middleclick"
+ name="browser.tabs.opentabfor.middleclick"
+ type="bool"/>
+ <preference id="browser.tabs.opentabfor.urlbar"
+ name="browser.tabs.opentabfor.urlbar"
+ type="bool"/>
+ <preference id="suite.manager.dataman.openAsDialog"
+ name="suite.manager.dataman.openAsDialog"
+ inverted="true"
+ type="bool"/>
+ <preference id="suite.manager.addons.openAsDialog"
+ name="suite.manager.addons.openAsDialog"
+ inverted="true"
+ type="bool"/>
+ </preferences>
+
+ <groupbox id="generalTabPreferences" align="start">
+ <caption label="&tabDisplay.label;"/>
+ <checkbox id="tabStrip"
+ label="&autoHide.label;"
+ accesskey="&autoHide.accesskey2;"
+ preference="browser.tabs.autoHide"/>
+ <checkbox id="tabBackground"
+ label="&background.label;"
+ accesskey="&background.accesskey;"
+ preference="browser.tabs.loadInBackground"/>
+ <checkbox id="tabDivertedBackground"
+ label="&diverted.label;"
+ accesskey="&diverted.accesskey;"
+ preference="browser.tabs.loadDivertedInBackground"/>
+ <checkbox id="tabAvoidBrowserFocus"
+ label="&browserFocus.label;"
+ accesskey="&browserFocus.accesskey;"
+ preference="browser.tabs.avoidBrowserFocus"/>
+ <checkbox id="tabWarnOnClose"
+ label="&warnOnClose.label;"
+ accesskey="&warnOnClose.accesskey;"
+ preference="browser.tabs.warnOnClose"/>
+ <checkbox id="tabRelatedAfterCurrent"
+ label="&relatedAfterCurrent.label;"
+ accesskey="&relatedAfterCurrent.accesskey;"
+ preference="browser.tabs.insertRelatedAfterCurrent"/>
+ </groupbox>
+
+ <groupbox id="useTabPreferences" align="start">
+ <caption label="&openTabs.label;"/>
+ <checkbox id="middleClick"
+#ifndef XP_MACOSX
+ label="&middleClick.label;"
+ accesskey="&middleClick.accesskey;"
+#else
+ label="&middleClickMac.label;"
+ accesskey="&middleClickMac.accesskey;"
+#endif
+ preference="browser.tabs.opentabfor.middleclick"/>
+ <checkbox id="urlBar"
+#ifndef XP_MACOSX
+ label="&urlbar.label;"
+ accesskey="&urlbar.accesskey;"
+#else
+ label="&urlbarMac.label;"
+ accesskey="&urlbarMac.accesskey;"
+#endif
+ preference="browser.tabs.opentabfor.urlbar"/>
+ </groupbox>
+
+ <groupbox id="useManagersPreferences" align="start">
+ <caption label="&openManagers.label;"/>
+ <checkbox id="openDataManager"
+ label="&openDataManager.label;"
+ accesskey="&openDataManager.accesskey;"
+ preference="suite.manager.dataman.openAsDialog"/>
+ <checkbox id="openAddOnsManager"
+ label="&openAddOnsManager.label;"
+ accesskey="&openAddOnsManager.accesskey;"
+ preference="suite.manager.addons.openAsDialog"/>
+ </groupbox>
+ </prefpane>
+</overlay>
diff --git a/comm/suite/components/pref/content/preferences.js b/comm/suite/components/pref/content/preferences.js
new file mode 100644
index 0000000000..091a3904fc
--- /dev/null
+++ b/comm/suite/components/pref/content/preferences.js
@@ -0,0 +1,99 @@
+/* -*- Mode: Java; 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/. */
+
+// The content of this file is loaded into the scope of the
+// prefwindow and will be available to all prefpanes!
+
+const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+
+function OnLoad()
+{
+ // Make sure that the preferences window fits the screen.
+ let dialog = document.documentElement;
+ let curHeight = dialog.scrollHeight;
+ let curWidth = dialog.scrollWidth;
+
+ // Leave some space for desktop toolbar and window decoration.
+ let maxHeight = window.screen.availHeight - 48;
+ let maxWidth = window.screen.availWidth - 24;
+
+ // Trigger overflow situation within 40px for bug 868495 expansions.
+ let setHeight = curHeight > maxHeight - 40 ? maxHeight : curHeight;
+ let setWidth = curWidth > maxWidth ? maxWidth : curWidth;
+
+ if (setHeight == curHeight && setWidth == curWidth)
+ dialog.setAttribute("overflow", "visible");
+
+ window.innerHeight = setHeight;
+ window.innerWidth = setWidth;
+}
+
+function EnableElementById(aElementId, aEnable, aFocus)
+{
+ EnableElement(document.getElementById(aElementId), aEnable, aFocus);
+}
+
+function EnableElement(aElement, aEnable, aFocus)
+{
+ let pref = document.getElementById(aElement.getAttribute("preference"));
+ let enabled = aEnable && !pref.locked;
+
+ aElement.disabled = !enabled;
+
+ if (enabled && aFocus)
+ aElement.focus();
+}
+
+function WriteSoundField(aField, aValue)
+{
+ var file = GetFileFromString(aValue);
+ if (file)
+ {
+ aField.file = file;
+ aField.label = (AppConstants.platform == "macosx") ? file.leafName : file.path;
+ }
+}
+
+function SelectSound(aSoundUrlPref)
+{
+ var soundUrlPref = aSoundUrlPref;
+ let fp = Cc["@mozilla.org/filepicker;1"]
+ .createInstance(Ci.nsIFilePicker);
+ var prefutilitiesBundle = document.getElementById("bundle_prefutilities");
+ fp.init(window, prefutilitiesBundle.getString("choosesound"),
+ Ci.nsIFilePicker.modeOpen);
+
+ let file = GetFileFromString(soundUrlPref.value);
+ if (file && file.parent && file.parent.exists())
+ fp.displayDirectory = file.parent;
+
+ let filterExts = "*.wav; *.wave";
+ // On Mac, allow AIFF and CAF files too.
+ if (AppConstants.platform == "macosx") {
+ filterExts += "; *.aif; *.aiff; *.caf";
+ }
+ fp.appendFilter(prefutilitiesBundle.getString("SoundFiles"), filterExts);
+ fp.appendFilters(Ci.nsIFilePicker.filterAll);
+ fp.open(rv => {
+ if (rv == Ci.nsIFilePicker.returnOK && fp.fileURL.spec &&
+ fp.fileURL.spec.length > 0) {
+ soundUrlPref.value = fp.fileURL.spec;
+ }
+ });
+}
+
+function PlaySound(aValue, aMail)
+{
+ const nsISound = Ci.nsISound;
+ var sound = Cc["@mozilla.org/sound;1"]
+ .createInstance(nsISound);
+
+ if (aValue)
+ sound.play(Services.io.newURI(aValue));
+ else if (aMail && (AppConstants.platform != "macosx"))
+ sound.playEventSound(nsISound.EVENT_NEW_MAIL_RECEIVED);
+ else
+ sound.beep();
+}
diff --git a/comm/suite/components/pref/content/preferences.xul b/comm/suite/components/pref/content/preferences.xul
new file mode 100644
index 0000000000..787d086af5
--- /dev/null
+++ b/comm/suite/components/pref/content/preferences.xul
@@ -0,0 +1,264 @@
+<?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 type="text/css" href="chrome://communicator/skin/"?>
+<?xml-stylesheet type="text/css" href="chrome://communicator/content/communicator.css"?>
+<?xml-stylesheet type="text/css" href="chrome://communicator/content/pref/prefpanels.css"?>
+<?xml-stylesheet type="text/css" href="chrome://communicator/skin/prefpanels.css"?>
+<?xml-stylesheet type="text/css" href="chrome://communicator/skin/preferences.css"?>
+
+<!DOCTYPE prefwindow SYSTEM "chrome://communicator/locale/pref/preferences.dtd">
+
+<prefwindow id="prefDialog"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&prefWindow.title;"
+#ifndef XP_WIN
+#ifndef XP_MACOSX
+ style="&prefWindow.size;"
+#else
+ style="&prefWindowMac2.size;"
+#endif
+#else
+ style="&prefWindowWin2.size;"
+#endif
+ overflow="auto"
+ onload="OnLoad();"
+ windowtype="mozilla:preferences"
+ buttons="accept,cancel,help"
+ autopanes="true">
+
+ <script src="chrome://communicator/content/pref/preferences.js"/>
+ <!-- Used by pref-smartupdate, pref-privatedata, pref-cookies, pref-images, pref-popups and pref-passwords, as well as pref-sync (gSyncUtils.*open* -> openUILinkIn) -->
+ <script src="chrome://communicator/content/utilityOverlay.js"/>
+ <script src="chrome://communicator/content/tasksOverlay.js"/>
+
+ <stringbundleset id="prefBundleset">
+ <stringbundle id="bundle_prefutilities"
+ src="chrome://communicator/locale/pref/prefutilities.properties"/>
+ <stringbundle id="languageNamesBundle"
+ src="chrome://global/locale/languageNames.properties"/>
+ <stringbundle id="regionNamesBundle"
+ src="chrome://global/locale/regionNames.properties"/>
+ </stringbundleset>
+
+ <tree id="prefsTree"
+ style="width: 13em;"
+ seltype="single"
+ hidecolumnpicker="true"
+ hidden="true"
+ flex="1">
+ <treecols>
+ <treecol id="categoryCol"
+ label="&categoryHeader;"
+ primary="true"
+ flex="1"/>
+ </treecols>
+
+ <treechildren id="prefsPanelChildren">
+ <!-- Appearance items -->
+ <treeitem container="true"
+ id="appearanceItem"
+ label="&appear.label;"
+ prefpane="appearance_pane"
+ helpTopic="appearance_pref"
+ url="chrome://communicator/content/pref/pref-appearance.xul">
+ <treechildren id="appearanceChildren">
+ <treeitem id="contentItem"
+ label="&content.label;"
+ prefpane="content_pane"
+ helpTopic="appearance_pref_content"
+ url="chrome://communicator/content/pref/pref-content.xul"/>
+ <treeitem id="fontsItem"
+ label="&fonts.label;"
+ prefpane="fonts_pane"
+ helpTopic="appearance_pref_fonts"
+ url="chrome://communicator/content/pref/pref-fonts.xul"/>
+ <treeitem id="colorsItem"
+ label="&colors.label;"
+ prefpane="colors_pane"
+ helpTopic="appearance_pref_colors"
+ url="chrome://communicator/content/pref/pref-colors.xul"/>
+ <treeitem id="mediaItem"
+ label="&media.label;"
+ prefpane="media_pane"
+ helpTopic="appearance_pref_media"
+ url="chrome://communicator/content/pref/pref-media.xul"/>
+ <treeitem id="spellingItem"
+ label="&spellingPane.label;"
+ prefpane="spelling_pane"
+ helpTopic="appearance_pref_spelling"
+ url="chrome://communicator/content/pref/pref-spelling.xul"/>
+ </treechildren>
+ </treeitem>
+
+ <!-- Browser items -->
+ <treeitem container="true"
+ id="navigatorItem"
+ label="&navigator.label;"
+ prefpane="navigator_pane"
+ helpTopic="navigator_pref_navigator"
+ url="chrome://communicator/content/pref/pref-navigator.xul">
+ <treechildren id="navigatorChildren">
+ <treeitem id="historyItem"
+ label="&history.label;"
+ prefpane="history_pane"
+ helpTopic="navigator_pref_history"
+ url="chrome://communicator/content/pref/pref-history.xul"/>
+ <treeitem id="languagesItem"
+ label="&languages.label;"
+ prefpane="languages_pane"
+ helpTopic="navigator_pref_languages"
+ url="chrome://communicator/content/pref/pref-languages.xul"/>
+ <treeitem id="applicationsItem"
+ label="&applications.label;"
+ prefpane="applications_pane"
+ helpTopic="navigator_pref_helper_applications"
+ url="chrome://communicator/content/pref/pref-applications.xul"/>
+ <treeitem id="locationBarItem"
+ label="&locationBar.label;"
+ prefpane="locationBar_pane"
+ helpTopic="navigator_pref_location_bar"
+ url="chrome://communicator/content/pref/pref-locationbar.xul"/>
+ <treeitem id="searchItem"
+ label="&search.label;"
+ prefpane="search_pane"
+ helpTopic="navigator_pref_internet_searching"
+ url="chrome://communicator/content/pref/pref-search.xul"/>
+ <treeitem id="tabsItem"
+ label="&tabWindows.label;"
+ prefpane="tabs_pane"
+ helpTopic="navigator_pref_tabbed_browsing"
+ url="chrome://communicator/content/pref/pref-tabs.xul"/>
+ <treeitem id="linksItem"
+ label="&links.label;"
+ prefpane="links_pane"
+ helpTopic="navigator_pref_link_behavior"
+ url="chrome://communicator/content/pref/pref-links.xul"/>
+ <treeitem id="downloadItem"
+ label="&download.label;"
+ prefpane="download_pane"
+ helpTopic="navigator_pref_downloads"
+ url="chrome://communicator/content/pref/pref-download.xul"/>
+ </treechildren>
+ </treeitem>
+
+ <!-- Privacy & Security items -->
+ <treeitem container="true"
+ id="securityItem"
+ prefpane="security_pane"
+ label="&security.label;"
+ helpTopic="sec_gen"
+ url="chrome://communicator/content/pref/pref-security.xul">
+ <treechildren id="securityChildren">
+ <treeitem id="privatedataItem"
+ label="&privatedata.label;"
+ prefpane="privatedata_pane"
+ helpTopic="privatedata_prefs"
+ url="chrome://communicator/content/pref/pref-privatedata.xul"/>
+ <treeitem id="cookiesItem"
+ label="&cookies.label;"
+ prefpane="cookies_pane"
+ helpTopic="cookies_prefs"
+ url="chrome://communicator/content/pref/pref-cookies.xul"/>
+ <treeitem id="imagesItem"
+ label="&images.label;"
+ prefpane="images_pane"
+ helpTopic="images_prefs"
+ url="chrome://communicator/content/pref/pref-images.xul"/>
+ <treeitem id="popupsItem"
+ label="&popups.label;"
+ prefpane="popups_pane"
+ helpTopic="pop_up_blocking_prefs"
+ url="chrome://communicator/content/pref/pref-popups.xul"/>
+ <treeitem id="passwordsItem"
+ label="&passwords.label;"
+ prefpane="passwords_pane"
+ url="chrome://pippki/content/pref-passwords.xul"
+ helpTopic="passwords_prefs"/>
+ <treeitem id="sslItem"
+ label="&ssltls.label;"
+ prefpane="ssl_pane"
+ url="chrome://pippki/content/pref-ssl.xul"
+ helpTopic="ssl_prefs"/>
+ <treeitem id="certItem"
+ label="&certs.label;"
+ prefpane="certs_pane"
+ url="chrome://pippki/content/pref-certs.xul"
+ helpTopic="certs_prefs"/>
+ </treechildren>
+ </treeitem>
+
+ <!-- Sync
+ <treeitem id="syncItem"
+ label="&sync.label;"
+ prefpane="sync_pane"
+ url="chrome://communicator/content/pref/pref-sync.xul"
+ helpTopic="sync_prefs"/> -->
+
+ <!-- Advanced items -->
+ <treeitem container="true"
+ id="advancedItem"
+ label="&advance.label;"
+ prefpane="advanced_pane"
+ helpTopic="advanced_pref_advanced"
+ url="chrome://communicator/content/pref/pref-advanced.xul">
+ <treechildren id="advancedChildren">
+ <treeitem id="scriptsItem"
+ label="&scriptsAndWindows2.label;"
+ prefpane="scripts_pane"
+ helpTopic="advanced_pref_scripts"
+ url="chrome://communicator/content/pref/pref-scripts.xul"/>
+ <treeitem id="keynavItem"
+ label="&keynav.label;"
+ prefpane="keynav_pane"
+ helpTopic="advanced_pref_keyboard_nav"
+ url="chrome://communicator/content/pref/pref-keynav.xul"/>
+ <treeitem id="findasyoutypeItem"
+ label="&findAsYouType.label;"
+ prefpane="findasyoutype_pane"
+ helpTopic="advanced_pref_find_as_you_type"
+ url="chrome://communicator/content/pref/pref-findasyoutype.xul"/>
+ <treeitem id="cacheItem"
+ label="&cache.label;"
+ prefpane="cache_pane"
+ helpTopic="advanced_pref_cache"
+ url="chrome://communicator/content/pref/pref-cache.xul"/>
+ <treeitem id="offlineAppsItem"
+ label="&offlineApps.label;"
+ prefpane="offlineapps_pane"
+ helpTopic="advanced_pref_offlineapps"
+ url="chrome://communicator/content/pref/pref-offlineapps.xul"/>
+ <treeitem id="proxiesItem"
+ label="&proxies.label;"
+ prefpane="proxies_pane"
+ helpTopic="advanced_pref_proxies"
+ url="chrome://communicator/content/pref/pref-proxies.xul"/>
+ <treeitem id="httpItem"
+ label="&httpnetworking.label;"
+ prefpane="http_pane"
+ helpTopic="advanced_http_networking"
+ url="chrome://communicator/content/pref/pref-http.xul"/>
+ <treeitem id="smartupdateItem"
+ label="&smart.label;"
+ prefpane="smartupdate_pane"
+ helpTopic="advanced_pref_installation"
+ url="chrome://communicator/content/pref/pref-smartupdate.xul"/>
+ <treeitem id="mousewheelItem"
+ label="&mousewheel.label;"
+ prefpane="mousewheel_pane"
+ helpTopic="advanced_pref_mouse_wheel"
+ url="chrome://communicator/content/pref/pref-mousewheel.xul"/>
+ <treeitem id="debuggingItem"
+ label="&debugging.label;"
+ prefpane="debugging_pane"
+ helpTopic="advanced_pref_debugging"
+ url="chrome://communicator/content/pref/pref-debugging.xul"/>
+ </treechildren>
+ </treeitem>
+ </treechildren>
+ </tree>
+
+</prefwindow>
diff --git a/comm/suite/components/pref/content/prefpanels.css b/comm/suite/components/pref/content/prefpanels.css
new file mode 100755
index 0000000000..c38509d590
--- /dev/null
+++ b/comm/suite/components/pref/content/prefpanels.css
@@ -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/. */
+
+#handlersView > listitem {
+ -moz-binding: url("chrome://communicator/content/pref/prefpanels.xml#handler");
+}
+
+.listcell-iconic.handler-action[selected="true"] {
+ -moz-binding: url("chrome://communicator/content/pref/prefpanels.xml#handler-action-selected");
+}
+
+#offlineAppsList > listitem {
+ -moz-binding: url("chrome://communicator/content/pref/prefpanels.xml#offlineapp");
+}
+
+/*
+ * Font dialog menulist fixes
+ */
+#defaultFontType,
+#serif,
+#sans-serif,
+#monospace {
+ min-width: 30ch;
+}
+
+/*
+ * Calendar Event/Tasks menulist fix
+ */
+
+#defaults-itemtype-menulist {
+ min-width: 20ch;
+}
diff --git a/comm/suite/components/pref/content/prefpanels.xml b/comm/suite/components/pref/content/prefpanels.xml
new file mode 100644
index 0000000000..347eac9755
--- /dev/null
+++ b/comm/suite/components/pref/content/prefpanels.xml
@@ -0,0 +1,59 @@
+<?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/. -->
+
+<!DOCTYPE bindings [
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+ %brandDTD;
+ <!ENTITY % applicationsDTD SYSTEM "chrome://communicator/locale/pref/pref-applications.dtd">
+ %applicationsDTD;
+]>
+
+<bindings id="handlerBindings"
+ xmlns="http://www.mozilla.org/xbl"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:xbl="http://www.mozilla.org/xbl">
+
+ <binding id="handler" extends="chrome://global/content/bindings/listbox.xml#listitem">
+ <implementation>
+ <constructor>
+ this.doCommand();
+ </constructor>
+ <property name="type" readonly="true">
+ <getter>
+ return this.getAttribute("type");
+ </getter>
+ </property>
+ </implementation>
+ <content>
+ <xul:listcell class="listcell-iconic handler-type" align="center" crop="end"
+ xbl:inherits="tooltiptext=typeDescription,label=typeDescription,image=typeIcon,typeClass"/>
+ <xul:listcell anonid="action-cell" class="listcell-iconic handler-action" align="center" crop="end"
+ xbl:inherits="tooltiptext=actionDescription,label=actionDescription,image=actionIcon,appHandlerIcon,selected"/>
+ </content>
+ </binding>
+
+ <binding id="handler-action-selected" extends="chrome://global/content/bindings/listbox.xml#listcell">
+ <content>
+ <xul:menulist anonid="action-menu" class="actionsMenu" flex="1" crop="end" selectedIndex="1">
+ <xul:menupopup/>
+ </xul:menulist>
+ </content>
+
+ <implementation>
+ <constructor>
+ this.doCommand();
+ </constructor>
+ </implementation>
+ </binding>
+
+ <binding id="offlineapp" extends="chrome://global/content/bindings/listbox.xml#listitem">
+ <content>
+ <xul:listcell xbl:inherits="label=host"/>
+ <xul:listcell xbl:inherits="label=usage"/>
+ </content>
+ </binding>
+
+</bindings>