diff options
Diffstat (limited to 'browser/components/preferences/in-content')
23 files changed, 0 insertions, 8932 deletions
diff --git a/browser/components/preferences/in-content/advanced.js b/browser/components/preferences/in-content/advanced.js deleted file mode 100644 index 5f9458eee..000000000 --- a/browser/components/preferences/in-content/advanced.js +++ /dev/null @@ -1,767 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Load DownloadUtils module for convertByteUnits -Components.utils.import("resource://gre/modules/DownloadUtils.jsm"); -Components.utils.import("resource://gre/modules/LoadContextInfo.jsm"); -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); - -const PREF_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled"; - -var gAdvancedPane = { - _inited: false, - - /** - * Brings the appropriate tab to the front and initializes various bits of UI. - */ - init: function () - { - function setEventListener(aId, aEventType, aCallback) - { - document.getElementById(aId) - .addEventListener(aEventType, aCallback.bind(gAdvancedPane)); - } - - this._inited = true; - var advancedPrefs = document.getElementById("advancedPrefs"); - - var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex"); - if (preference.value !== null) - advancedPrefs.selectedIndex = preference.value; - - if (AppConstants.MOZ_UPDATER) { - let onUnload = function () { - window.removeEventListener("unload", onUnload, false); - Services.prefs.removeObserver("app.update.", this); - }.bind(this); - window.addEventListener("unload", onUnload, false); - Services.prefs.addObserver("app.update.", this, false); - this.updateReadPrefs(); - } - this.updateOfflineApps(); - this.initTelemetry(); - if (AppConstants.MOZ_TELEMETRY_REPORTING) { - this.initSubmitHealthReport(); - } - this.updateOnScreenKeyboardVisibility(); - this.updateCacheSizeInputField(); - this.updateActualCacheSize(); - this.updateActualAppCacheSize(); - - setEventListener("layers.acceleration.disabled", "change", - gAdvancedPane.updateHardwareAcceleration); - setEventListener("advancedPrefs", "select", - gAdvancedPane.tabSelectionChanged); - if (AppConstants.MOZ_TELEMETRY_REPORTING) { - setEventListener("submitHealthReportBox", "command", - gAdvancedPane.updateSubmitHealthReport); - } - - setEventListener("connectionSettings", "command", - gAdvancedPane.showConnections); - setEventListener("clearCacheButton", "command", - gAdvancedPane.clearCache); - setEventListener("clearOfflineAppCacheButton", "command", - gAdvancedPane.clearOfflineAppCache); - setEventListener("offlineNotifyExceptions", "command", - gAdvancedPane.showOfflineExceptions); - setEventListener("offlineAppsList", "select", - gAdvancedPane.offlineAppSelected); - let bundlePrefs = document.getElementById("bundlePreferences"); - document.getElementById("offlineAppsList") - .style.height = bundlePrefs.getString("offlineAppsList.height"); - setEventListener("offlineAppsListRemove", "command", - gAdvancedPane.removeOfflineApp); - if (AppConstants.MOZ_UPDATER) { - setEventListener("updateRadioGroup", "command", - gAdvancedPane.updateWritePrefs); - setEventListener("showUpdateHistory", "command", - gAdvancedPane.showUpdates); - } - setEventListener("viewCertificatesButton", "command", - gAdvancedPane.showCertificates); - setEventListener("viewSecurityDevicesButton", "command", - gAdvancedPane.showSecurityDevices); - setEventListener("cacheSize", "change", - gAdvancedPane.updateCacheSizePref); - - if (AppConstants.MOZ_WIDGET_GTK) { - // GTK tabbox' allow the scroll wheel to change the selected tab, - // but we don't want this behavior for the in-content preferences. - let tabsElement = document.getElementById("tabsElement"); - tabsElement.addEventListener("DOMMouseScroll", event => { - event.stopPropagation(); - }, true); - } - }, - - /** - * Stores the identity of the current tab in preferences so that the selected - * tab can be persisted between openings of the preferences window. - */ - tabSelectionChanged: function () - { - if (!this._inited) - return; - var advancedPrefs = document.getElementById("advancedPrefs"); - var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex"); - - // tabSelectionChanged gets called twice due to the selectedIndex being set - // by both the selectedItem and selectedPanel callstacks. This guard is used - // to prevent double-counting in Telemetry. - if (preference.valueFromPreferences != advancedPrefs.selectedIndex) { - Services.telemetry - .getHistogramById("FX_PREFERENCES_CATEGORY_OPENED") - .add(telemetryBucketForCategory("advanced")); - } - - preference.valueFromPreferences = advancedPrefs.selectedIndex; - }, - - // GENERAL TAB - - /* - * Preferences: - * - * accessibility.browsewithcaret - * - true enables keyboard navigation and selection within web pages using a - * visible caret, false uses normal keyboard navigation with no caret - * accessibility.typeaheadfind - * - when set to true, typing outside text areas and input boxes will - * automatically start searching for what's typed within the current - * document; when set to false, no search action happens - * ui.osk.enabled - * - when set to true, subject to other conditions, we may sometimes invoke - * an on-screen keyboard when a text input is focused. - * (Currently Windows-only, and depending on prefs, may be Windows-8-only) - * general.autoScroll - * - when set to true, clicking the scroll wheel on the mouse activates a - * mouse mode where moving the mouse down scrolls the document downward with - * speed correlated with the distance of the cursor from the original - * position at which the click occurred (and likewise with movement upward); - * if false, this behavior is disabled - * general.smoothScroll - * - set to true to enable finer page scrolling than line-by-line on page-up, - * page-down, and other such page movements - * layout.spellcheckDefault - * - an integer: - * 0 disables spellchecking - * 1 enables spellchecking, but only for multiline text fields - * 2 enables spellchecking for all text fields - */ - - /** - * Stores the original value of the spellchecking preference to enable proper - * restoration if unchanged (since we're mapping a tristate onto a checkbox). - */ - _storedSpellCheck: 0, - - /** - * Returns true if any spellchecking is enabled and false otherwise, caching - * the current value to enable proper pref restoration if the checkbox is - * never changed. - */ - readCheckSpelling: function () - { - var pref = document.getElementById("layout.spellcheckDefault"); - this._storedSpellCheck = pref.value; - - return (pref.value != 0); - }, - - /** - * Returns the value of the spellchecking preference represented by UI, - * preserving the preference's "hidden" value if the preference is - * unchanged and represents a value not strictly allowed in UI. - */ - writeCheckSpelling: function () - { - var checkbox = document.getElementById("checkSpelling"); - if (checkbox.checked) { - if (this._storedSpellCheck == 2) { - return 2; - } - return 1; - } - return 0; - }, - - /** - * security.OCSP.enabled is an integer value for legacy reasons. - * A value of 1 means OCSP is enabled. Any other value means it is disabled. - */ - readEnableOCSP: function () - { - var preference = document.getElementById("security.OCSP.enabled"); - // This is the case if the preference is the default value. - if (preference.value === undefined) { - return true; - } - return preference.value == 1; - }, - - /** - * See documentation for readEnableOCSP. - */ - writeEnableOCSP: function () - { - var checkbox = document.getElementById("enableOCSP"); - return checkbox.checked ? 1 : 0; - }, - - /** - * When the user toggles the layers.acceleration.disabled pref, - * sync its new value to the gfx.direct2d.disabled pref too. - */ - updateHardwareAcceleration: function() - { - if (AppConstants.platform = "win") { - var fromPref = document.getElementById("layers.acceleration.disabled"); - var toPref = document.getElementById("gfx.direct2d.disabled"); - toPref.value = fromPref.value; - } - }, - - // DATA CHOICES TAB - - /** - * Set up or hide the Learn More links for various data collection options - */ - _setupLearnMoreLink: function (pref, element) { - // set up the Learn More link with the correct URL - let url = Services.prefs.getCharPref(pref); - let el = document.getElementById(element); - - if (url) { - el.setAttribute("href", url); - } else { - el.setAttribute("hidden", "true"); - } - }, - - /** - * - */ - initSubmitCrashes: function () - { - this._setupLearnMoreLink("toolkit.crashreporter.infoURL", - "crashReporterLearnMore"); - }, - - /** - * The preference/checkbox is configured in XUL. - * - * In all cases, set up the Learn More link sanely. - */ - initTelemetry: function () - { - if (AppConstants.MOZ_TELEMETRY_REPORTING) { - this._setupLearnMoreLink("toolkit.telemetry.infoURL", "telemetryLearnMore"); - } - }, - - /** - * Set the status of the telemetry controls based on the input argument. - * @param {Boolean} aEnabled False disables the controls, true enables them. - */ - setTelemetrySectionEnabled: function (aEnabled) - { - if (AppConstants.MOZ_TELEMETRY_REPORTING) { - // If FHR is disabled, additional data sharing should be disabled as well. - let disabled = !aEnabled; - document.getElementById("submitTelemetryBox").disabled = disabled; - if (disabled) { - // If we disable FHR, untick the telemetry checkbox. - Services.prefs.setBoolPref("toolkit.telemetry.enabled", false); - } - document.getElementById("telemetryDataDesc").disabled = disabled; - } - }, - - /** - * Initialize the health report service reference and checkbox. - */ - initSubmitHealthReport: function () { - if (AppConstants.MOZ_TELEMETRY_REPORTING) { - this._setupLearnMoreLink("datareporting.healthreport.infoURL", "FHRLearnMore"); - - let checkbox = document.getElementById("submitHealthReportBox"); - - if (Services.prefs.prefIsLocked(PREF_UPLOAD_ENABLED)) { - checkbox.setAttribute("disabled", "true"); - return; - } - - checkbox.checked = Services.prefs.getBoolPref(PREF_UPLOAD_ENABLED); - this.setTelemetrySectionEnabled(checkbox.checked); - } - }, - - /** - * Update the health report preference with state from checkbox. - */ - updateSubmitHealthReport: function () { - if (AppConstants.MOZ_TELEMETRY_REPORTING) { - let checkbox = document.getElementById("submitHealthReportBox"); - Services.prefs.setBoolPref(PREF_UPLOAD_ENABLED, checkbox.checked); - this.setTelemetrySectionEnabled(checkbox.checked); - } - }, - - updateOnScreenKeyboardVisibility() { - if (AppConstants.platform == "win") { - let minVersion = Services.prefs.getBoolPref("ui.osk.require_win10") ? 10 : 6.2; - if (Services.vc.compare(Services.sysinfo.getProperty("version"), minVersion) >= 0) { - document.getElementById("useOnScreenKeyboard").hidden = false; - } - } - }, - - // NETWORK TAB - - /* - * Preferences: - * - * browser.cache.disk.capacity - * - the size of the browser cache in KB - * - Only used if browser.cache.disk.smart_size.enabled is disabled - */ - - /** - * Displays a dialog in which proxy settings may be changed. - */ - showConnections: function () - { - gSubDialog.open("chrome://browser/content/preferences/connection.xul"); - }, - - // Retrieves the amount of space currently used by disk cache - updateActualCacheSize: function () - { - var actualSizeLabel = document.getElementById("actualDiskCacheSize"); - var prefStrBundle = document.getElementById("bundlePreferences"); - - // Needs to root the observer since cache service keeps only a weak reference. - this.observer = { - onNetworkCacheDiskConsumption: function(consumption) { - var size = DownloadUtils.convertByteUnits(consumption); - // The XBL binding for the string bundle may have been destroyed if - // the page was closed before this callback was executed. - if (!prefStrBundle.getFormattedString) { - return; - } - actualSizeLabel.value = prefStrBundle.getFormattedString("actualDiskCacheSize", size); - }, - - QueryInterface: XPCOMUtils.generateQI([ - Components.interfaces.nsICacheStorageConsumptionObserver, - Components.interfaces.nsISupportsWeakReference - ]) - }; - - actualSizeLabel.value = prefStrBundle.getString("actualDiskCacheSizeCalculated"); - - try { - var cacheService = - Components.classes["@mozilla.org/netwerk/cache-storage-service;1"] - .getService(Components.interfaces.nsICacheStorageService); - cacheService.asyncGetDiskConsumption(this.observer); - } catch (e) {} - }, - - // Retrieves the amount of space currently used by offline cache - updateActualAppCacheSize: function () - { - var visitor = { - onCacheStorageInfo: function (aEntryCount, aConsumption, aCapacity, aDiskDirectory) - { - var actualSizeLabel = document.getElementById("actualAppCacheSize"); - var sizeStrings = DownloadUtils.convertByteUnits(aConsumption); - var prefStrBundle = document.getElementById("bundlePreferences"); - // The XBL binding for the string bundle may have been destroyed if - // the page was closed before this callback was executed. - if (!prefStrBundle.getFormattedString) { - return; - } - var sizeStr = prefStrBundle.getFormattedString("actualAppCacheSize", sizeStrings); - actualSizeLabel.value = sizeStr; - } - }; - - try { - var cacheService = - Components.classes["@mozilla.org/netwerk/cache-storage-service;1"] - .getService(Components.interfaces.nsICacheStorageService); - var storage = cacheService.appCacheStorage(LoadContextInfo.default, null); - storage.asyncVisitStorage(visitor, false); - } catch (e) {} - }, - - updateCacheSizeUI: function (smartSizeEnabled) - { - document.getElementById("useCacheBefore").disabled = smartSizeEnabled; - document.getElementById("cacheSize").disabled = smartSizeEnabled; - document.getElementById("useCacheAfter").disabled = smartSizeEnabled; - }, - - readSmartSizeEnabled: function () - { - // The smart_size.enabled preference element is inverted="true", so its - // value is the opposite of the actual pref value - var disabled = document.getElementById("browser.cache.disk.smart_size.enabled").value; - this.updateCacheSizeUI(!disabled); - }, - - /** - * Converts the cache size from units of KB to units of MB and stores it in - * the textbox element. - */ - updateCacheSizeInputField() - { - let cacheSizeElem = document.getElementById("cacheSize"); - let cachePref = document.getElementById("browser.cache.disk.capacity"); - cacheSizeElem.value = cachePref.value / 1024; - if (cachePref.locked) - cacheSizeElem.disabled = true; - }, - - /** - * Updates the cache size preference once user enters a new value. - * We intentionally do not set preference="browser.cache.disk.capacity" - * onto the textbox directly, as that would update the pref at each keypress - * not only after the final value is entered. - */ - updateCacheSizePref() - { - let cacheSizeElem = document.getElementById("cacheSize"); - let cachePref = document.getElementById("browser.cache.disk.capacity"); - // Converts the cache size as specified in UI (in MB) to KB. - let intValue = parseInt(cacheSizeElem.value, 10); - cachePref.value = isNaN(intValue) ? 0 : intValue * 1024; - }, - - /** - * Clears the cache. - */ - clearCache: function () - { - try { - var cache = Components.classes["@mozilla.org/netwerk/cache-storage-service;1"] - .getService(Components.interfaces.nsICacheStorageService); - cache.clear(); - } catch (ex) {} - this.updateActualCacheSize(); - }, - - /** - * Clears the application cache. - */ - clearOfflineAppCache: function () - { - Components.utils.import("resource:///modules/offlineAppCache.jsm"); - OfflineAppCacheHelper.clear(); - - this.updateActualAppCacheSize(); - this.updateOfflineApps(); - }, - - readOfflineNotify: function() - { - var pref = document.getElementById("browser.offline-apps.notify"); - var button = document.getElementById("offlineNotifyExceptions"); - button.disabled = !pref.value; - return pref.value; - }, - - showOfflineExceptions: function() - { - var bundlePreferences = document.getElementById("bundlePreferences"); - var params = { blockVisible : false, - sessionVisible : false, - allowVisible : false, - prefilledHost : "", - permissionType : "offline-app", - manageCapability : Components.interfaces.nsIPermissionManager.DENY_ACTION, - windowTitle : bundlePreferences.getString("offlinepermissionstitle"), - introText : bundlePreferences.getString("offlinepermissionstext") }; - gSubDialog.open("chrome://browser/content/preferences/permissions.xul", - null, params); - }, - - // XXX: duplicated in browser.js - _getOfflineAppUsage(perm, groups) { - let cacheService = Cc["@mozilla.org/network/application-cache-service;1"]. - getService(Ci.nsIApplicationCacheService); - if (!groups) { - try { - groups = cacheService.getGroups(); - } catch (ex) { - return 0; - } - } - - let usage = 0; - for (let group of groups) { - let uri = Services.io.newURI(group, null, null); - if (perm.matchesURI(uri, true)) { - let cache = cacheService.getActiveCache(group); - usage += cache.usage; - } - } - - return usage; - }, - - /** - * Updates the list of offline applications - */ - updateOfflineApps: function () - { - var pm = Components.classes["@mozilla.org/permissionmanager;1"] - .getService(Components.interfaces.nsIPermissionManager); - - var list = document.getElementById("offlineAppsList"); - while (list.firstChild) { - list.removeChild(list.firstChild); - } - - var groups; - try { - var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"]. - getService(Components.interfaces.nsIApplicationCacheService); - groups = cacheService.getGroups(); - } catch (e) { - return; - } - - var bundle = document.getElementById("bundlePreferences"); - - var enumerator = pm.enumerator; - while (enumerator.hasMoreElements()) { - var perm = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission); - if (perm.type == "offline-app" && - perm.capability != Components.interfaces.nsIPermissionManager.DEFAULT_ACTION && - perm.capability != Components.interfaces.nsIPermissionManager.DENY_ACTION) { - var row = document.createElement("listitem"); - row.id = ""; - row.className = "offlineapp"; - row.setAttribute("origin", perm.principal.origin); - var converted = DownloadUtils. - convertByteUnits(this._getOfflineAppUsage(perm, groups)); - row.setAttribute("usage", - bundle.getFormattedString("offlineAppUsage", - converted)); - list.appendChild(row); - } - } - }, - - offlineAppSelected: function() - { - var removeButton = document.getElementById("offlineAppsListRemove"); - var list = document.getElementById("offlineAppsList"); - if (list.selectedItem) { - removeButton.setAttribute("disabled", "false"); - } else { - removeButton.setAttribute("disabled", "true"); - } - }, - - removeOfflineApp: function() - { - var list = document.getElementById("offlineAppsList"); - var item = list.selectedItem; - var origin = item.getAttribute("origin"); - var principal = Services.scriptSecurityManager.createCodebasePrincipalFromOrigin(origin); - - var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] - .getService(Components.interfaces.nsIPromptService); - var flags = prompts.BUTTON_TITLE_IS_STRING * prompts.BUTTON_POS_0 + - prompts.BUTTON_TITLE_CANCEL * prompts.BUTTON_POS_1; - - var bundle = document.getElementById("bundlePreferences"); - var title = bundle.getString("offlineAppRemoveTitle"); - var prompt = bundle.getFormattedString("offlineAppRemovePrompt", [principal.URI.prePath]); - var confirm = bundle.getString("offlineAppRemoveConfirm"); - var result = prompts.confirmEx(window, title, prompt, flags, confirm, - null, null, null, {}); - if (result != 0) - return; - - // get the permission - var pm = Components.classes["@mozilla.org/permissionmanager;1"] - .getService(Components.interfaces.nsIPermissionManager); - var perm = pm.getPermissionObject(principal, "offline-app", true); - if (perm) { - // clear offline cache entries - try { - var cacheService = Components.classes["@mozilla.org/network/application-cache-service;1"]. - getService(Components.interfaces.nsIApplicationCacheService); - var groups = cacheService.getGroups(); - for (var i = 0; i < groups.length; i++) { - var uri = Services.io.newURI(groups[i], null, null); - if (perm.matchesURI(uri, true)) { - var cache = cacheService.getActiveCache(groups[i]); - cache.discard(); - } - } - } catch (e) {} - - pm.removePermission(perm); - } - list.removeChild(item); - gAdvancedPane.offlineAppSelected(); - this.updateActualAppCacheSize(); - }, - - // UPDATE TAB - - /* - * Preferences: - * - * app.update.enabled - * - true if updates to the application are enabled, false otherwise - * app.update.auto - * - true if updates should be automatically downloaded and installed and - * false if the user should be asked what he wants to do when an update is - * available - * extensions.update.enabled - * - true if updates to extensions and themes are enabled, false otherwise - * browser.search.update - * - true if updates to search engines are enabled, false otherwise - */ - - /** - * Selects the item of the radiogroup based on the pref values and locked - * states. - * - * UI state matrix for update preference conditions - * - * UI Components: Preferences - * Radiogroup i = app.update.enabled - * ii = app.update.auto - * - * Disabled states: - * Element pref value locked disabled - * radiogroup i t/f f false - * i t/f *t* *true* - * ii t/f f false - * ii t/f *t* *true* - */ - updateReadPrefs: function () - { - if (AppConstants.MOZ_UPDATER) { - var enabledPref = document.getElementById("app.update.enabled"); - var autoPref = document.getElementById("app.update.auto"); - var radiogroup = document.getElementById("updateRadioGroup"); - - if (!enabledPref.value) // Don't care for autoPref.value in this case. - radiogroup.value="manual"; // 3. Never check for updates. - else if (autoPref.value) // enabledPref.value && autoPref.value - radiogroup.value="auto"; // 1. Automatically install updates - else // enabledPref.value && !autoPref.value - radiogroup.value="checkOnly"; // 2. Check, but let me choose - - var canCheck = Components.classes["@mozilla.org/updates/update-service;1"]. - getService(Components.interfaces.nsIApplicationUpdateService). - canCheckForUpdates; - // canCheck is false if the enabledPref is false and locked, - // or the binary platform or OS version is not known. - // A locked pref is sufficient to disable the radiogroup. - radiogroup.disabled = !canCheck || enabledPref.locked || autoPref.locked; - - if (AppConstants.MOZ_MAINTENANCE_SERVICE) { - // Check to see if the maintenance service is installed. - // If it is don't show the preference at all. - var installed; - try { - var wrk = Components.classes["@mozilla.org/windows-registry-key;1"] - .createInstance(Components.interfaces.nsIWindowsRegKey); - wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE, - "SOFTWARE\\Mozilla\\MaintenanceService", - wrk.ACCESS_READ | wrk.WOW64_64); - installed = wrk.readIntValue("Installed"); - wrk.close(); - } catch (e) { - } - if (installed != 1) { - document.getElementById("useService").hidden = true; - } - } - } - }, - - /** - * Sets the pref values based on the selected item of the radiogroup. - */ - updateWritePrefs: function () - { - if (AppConstants.MOZ_UPDATER) { - var enabledPref = document.getElementById("app.update.enabled"); - var autoPref = document.getElementById("app.update.auto"); - var radiogroup = document.getElementById("updateRadioGroup"); - switch (radiogroup.value) { - case "auto": // 1. Automatically install updates for Desktop only - enabledPref.value = true; - autoPref.value = true; - break; - case "checkOnly": // 2. Check, but let me choose - enabledPref.value = true; - autoPref.value = false; - break; - case "manual": // 3. Never check for updates. - enabledPref.value = false; - autoPref.value = false; - } - } - }, - - /** - * Displays the history of installed updates. - */ - showUpdates: function () - { - gSubDialog.open("chrome://mozapps/content/update/history.xul"); - }, - - // ENCRYPTION TAB - - /* - * Preferences: - * - * security.default_personal_cert - * - a string: - * "Select Automatically" select a certificate automatically when a site - * requests one - * "Ask Every Time" present a dialog to the user so he can select - * the certificate to use on a site which - * requests one - */ - - /** - * Displays the user's certificates and associated options. - */ - showCertificates: function () - { - gSubDialog.open("chrome://pippki/content/certManager.xul"); - }, - - /** - * Displays a dialog from which the user can manage his security devices. - */ - showSecurityDevices: function () - { - gSubDialog.open("chrome://pippki/content/device_manager.xul"); - }, - - observe: function (aSubject, aTopic, aData) { - if (AppConstants.MOZ_UPDATER) { - switch (aTopic) { - case "nsPref:changed": - this.updateReadPrefs(); - break; - } - } - }, -}; diff --git a/browser/components/preferences/in-content/advanced.xul b/browser/components/preferences/in-content/advanced.xul deleted file mode 100644 index 4973f8e09..000000000 --- a/browser/components/preferences/in-content/advanced.xul +++ /dev/null @@ -1,398 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<!-- Advanced panel --> - -<script type="application/javascript" - src="chrome://browser/content/preferences/in-content/advanced.js"/> - -<preferences id="advancedPreferences" hidden="true" data-category="paneAdvanced"> - <preference id="browser.preferences.advanced.selectedTabIndex" - name="browser.preferences.advanced.selectedTabIndex" - type="int"/> - - <!-- General tab --> - <preference id="accessibility.browsewithcaret" - name="accessibility.browsewithcaret" - type="bool"/> - <preference id="accessibility.typeaheadfind" - name="accessibility.typeaheadfind" - type="bool"/> - <preference id="accessibility.blockautorefresh" - name="accessibility.blockautorefresh" - type="bool"/> -#ifdef XP_WIN - <preference id="ui.osk.enabled" - name="ui.osk.enabled" - type="bool"/> -#endif - - <preference id="general.autoScroll" - name="general.autoScroll" - type="bool"/> - <preference id="general.smoothScroll" - name="general.smoothScroll" - type="bool"/> - <preference id="layers.acceleration.disabled" - name="layers.acceleration.disabled" - type="bool" - inverted="true"/> -#ifdef XP_WIN - <preference id="gfx.direct2d.disabled" - name="gfx.direct2d.disabled" - type="bool" - inverted="true"/> -#endif - <preference id="layout.spellcheckDefault" - name="layout.spellcheckDefault" - type="int"/> - -#ifdef MOZ_TELEMETRY_REPORTING - <preference id="toolkit.telemetry.enabled" - name="toolkit.telemetry.enabled" - type="bool"/> -#endif - - <!-- Network tab --> - <preference id="browser.cache.disk.capacity" - name="browser.cache.disk.capacity" - type="int"/> - <preference id="browser.offline-apps.notify" - name="browser.offline-apps.notify" - type="bool"/> - - <preference id="browser.cache.disk.smart_size.enabled" - name="browser.cache.disk.smart_size.enabled" - inverted="true" - type="bool"/> - - <!-- Update tab --> -#ifdef MOZ_UPDATER - <preference id="app.update.enabled" - name="app.update.enabled" - type="bool"/> - <preference id="app.update.auto" - name="app.update.auto" - type="bool"/> - - <preference id="app.update.disable_button.showUpdateHistory" - name="app.update.disable_button.showUpdateHistory" - type="bool"/> - -#ifdef MOZ_MAINTENANCE_SERVICE - <preference id="app.update.service.enabled" - name="app.update.service.enabled" - type="bool"/> -#endif -#endif - - <preference id="browser.search.update" - name="browser.search.update" - type="bool"/> - - <!-- Certificates tab --> - <preference id="security.default_personal_cert" - name="security.default_personal_cert" - type="string"/> - - <preference id="security.disable_button.openCertManager" - name="security.disable_button.openCertManager" - type="bool"/> - - <preference id="security.disable_button.openDeviceManager" - name="security.disable_button.openDeviceManager" - type="bool"/> - - <preference id="security.OCSP.enabled" - name="security.OCSP.enabled" - type="int"/> -</preferences> - -#ifdef HAVE_SHELL_SERVICE - <stringbundle id="bundleShell" src="chrome://browser/locale/shellservice.properties"/> - <stringbundle id="bundleBrand" src="chrome://branding/locale/brand.properties"/> -#endif - <stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/> - -<hbox id="header-advanced" - class="header" - hidden="true" - data-category="paneAdvanced"> - <label class="header-name" flex="1">&paneAdvanced.title;</label> - <html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a> -</hbox> - -<tabbox id="advancedPrefs" - handleCtrlTab="false" - handleCtrlPageUpDown="false" - flex="1" - data-category="paneAdvanced" - hidden="true"> - - <tabs id="tabsElement"> - <tab id="generalTab" label="&generalTab.label;"/> -#ifdef MOZ_DATA_REPORTING - <tab id="dataChoicesTab" label="&dataChoicesTab.label;"/> -#endif - <tab id="networkTab" label="&networkTab.label;"/> - <tab id="updateTab" label="&updateTab.label;"/> - <tab id="encryptionTab" label="&certificateTab.label;"/> - </tabs> - - <tabpanels flex="1"> - - <!-- General --> - <tabpanel id="generalPanel" orient="vertical"> - <!-- Accessibility --> - <groupbox id="accessibilityGroup" align="start"> - <caption><label>&accessibility.label;</label></caption> - -#ifdef XP_WIN - <checkbox id="useOnScreenKeyboard" - hidden="true" - label="&useOnScreenKeyboard.label;" - accesskey="&useOnScreenKeyboard.accesskey;" - preference="ui.osk.enabled"/> -#endif - <checkbox id="useCursorNavigation" - label="&useCursorNavigation.label;" - accesskey="&useCursorNavigation.accesskey;" - preference="accessibility.browsewithcaret"/> - <checkbox id="searchStartTyping" - label="&searchStartTyping.label;" - accesskey="&searchStartTyping.accesskey;" - preference="accessibility.typeaheadfind"/> - <checkbox id="blockAutoRefresh" - label="&blockAutoRefresh.label;" - accesskey="&blockAutoRefresh.accesskey;" - preference="accessibility.blockautorefresh"/> - </groupbox> - <!-- Browsing --> - <groupbox id="browsingGroup" align="start"> - <caption><label>&browsing.label;</label></caption> - - <checkbox id="useAutoScroll" - label="&useAutoScroll.label;" - accesskey="&useAutoScroll.accesskey;" - preference="general.autoScroll"/> - <checkbox id="useSmoothScrolling" - label="&useSmoothScrolling.label;" - accesskey="&useSmoothScrolling.accesskey;" - preference="general.smoothScroll"/> - <checkbox id="allowHWAccel" - label="&allowHWAccel.label;" - accesskey="&allowHWAccel.accesskey;" - preference="layers.acceleration.disabled"/> - <checkbox id="checkSpelling" - label="&checkSpelling.label;" - accesskey="&checkSpelling.accesskey;" - onsyncfrompreference="return gAdvancedPane.readCheckSpelling();" - onsynctopreference="return gAdvancedPane.writeCheckSpelling();" - preference="layout.spellcheckDefault"/> - </groupbox> - </tabpanel> -#ifdef MOZ_DATA_REPORTING - <!-- Data Choices --> - <tabpanel id="dataChoicesPanel" orient="vertical"> -#ifdef MOZ_TELEMETRY_REPORTING - <groupbox> - <caption> - <checkbox id="submitHealthReportBox" label="&enableHealthReport.label;" - accesskey="&enableHealthReport.accesskey;"/> - </caption> - <vbox> - <hbox class="indent"> - <label flex="1">&healthReportDesc.label;</label> - <spacer flex="10"/> - <label id="FHRLearnMore" - class="text-link">&healthReportLearnMore.label;</label> - </hbox> - <hbox class="indent"> - <groupbox flex="1"> - <caption> - <checkbox id="submitTelemetryBox" preference="toolkit.telemetry.enabled" - label="&enableTelemetryData.label;" - accesskey="&enableTelemetryData.accesskey;"/> - </caption> - <hbox class="indent"> - <label id="telemetryDataDesc" flex="1">&telemetryDesc.label;</label> - <spacer flex="10"/> - <label id="telemetryLearnMore" - class="text-link">&telemetryLearnMore.label;</label> - </hbox> - </groupbox> - </hbox> - </vbox> - </groupbox> -#endif - </tabpanel> -#endif - - <!-- Network --> - <tabpanel id="networkPanel" orient="vertical"> - - <!-- Connection --> - <groupbox id="connectionGroup"> - <caption><label>&connection.label;</label></caption> - - <hbox align="center"> - <description flex="1" control="connectionSettings">&connectionDesc.label;</description> - <button id="connectionSettings" icon="network" label="&connectionSettings.label;" - accesskey="&connectionSettings.accesskey;"/> - </hbox> - </groupbox> - - <!-- Cache --> - <groupbox id="cacheGroup"> - <caption><label>&httpCache.label;</label></caption> - - <hbox align="center"> - <label id="actualDiskCacheSize" flex="1"/> - <button id="clearCacheButton" icon="clear" - label="&clearCacheNow.label;" accesskey="&clearCacheNow.accesskey;"/> - </hbox> - <hbox> - <checkbox preference="browser.cache.disk.smart_size.enabled" - id="allowSmartSize" - onsyncfrompreference="return gAdvancedPane.readSmartSizeEnabled();" - label="&overrideSmartCacheSize.label;" - accesskey="&overrideSmartCacheSize.accesskey;"/> - </hbox> - <hbox align="center" class="indent"> - <label id="useCacheBefore" control="cacheSize" - accesskey="&limitCacheSizeBefore.accesskey;"> - &limitCacheSizeBefore.label; - </label> - <textbox id="cacheSize" type="number" size="4" max="1024" - aria-labelledby="useCacheBefore cacheSize useCacheAfter"/> - <label id="useCacheAfter" flex="1">&limitCacheSizeAfter.label;</label> - </hbox> - </groupbox> - - <!-- Offline apps --> - <groupbox id="offlineGroup"> - <caption><label>&offlineStorage2.label;</label></caption> - - <hbox align="center"> - <label id="actualAppCacheSize" flex="1"/> - <button id="clearOfflineAppCacheButton" icon="clear" - label="&clearOfflineAppCacheNow.label;" accesskey="&clearOfflineAppCacheNow.accesskey;"/> - </hbox> - <hbox align="center"> - <checkbox id="offlineNotify" - label="&offlineNotify.label;" accesskey="&offlineNotify.accesskey;" - preference="browser.offline-apps.notify" - onsyncfrompreference="return gAdvancedPane.readOfflineNotify();"/> - <spacer flex="1"/> - <button id="offlineNotifyExceptions" - label="&offlineNotifyExceptions.label;" - accesskey="&offlineNotifyExceptions.accesskey;"/> - </hbox> - <hbox> - <vbox flex="1"> - <label id="offlineAppsListLabel">&offlineAppsList2.label;</label> - <listbox id="offlineAppsList" - flex="1" - aria-labelledby="offlineAppsListLabel"> - </listbox> - </vbox> - <vbox pack="end"> - <button id="offlineAppsListRemove" - disabled="true" - label="&offlineAppsListRemove.label;" - accesskey="&offlineAppsListRemove.accesskey;"/> - </vbox> - </hbox> - </groupbox> - </tabpanel> - - <!-- Update --> - <tabpanel id="updatePanel" orient="vertical"> -#ifdef MOZ_UPDATER - <groupbox id="updateApp" align="start"> - <caption><label>&updateApp.label;</label></caption> - <radiogroup id="updateRadioGroup" align="start"> - <radio id="autoDesktop" - value="auto" - label="&updateAuto1.label;" - accesskey="&updateAuto1.accesskey;"/> - <radio value="checkOnly" - label="&updateCheck.label;" - accesskey="&updateCheck.accesskey;"/> - <radio value="manual" - label="&updateManual.label;" - accesskey="&updateManual.accesskey;"/> - </radiogroup> - <separator class="thin"/> - <hbox> - <button id="showUpdateHistory" - label="&updateHistory.label;" - accesskey="&updateHistory.accesskey;" - preference="app.update.disable_button.showUpdateHistory"/> - </hbox> - -#ifdef MOZ_MAINTENANCE_SERVICE - <checkbox id="useService" - label="&useService.label;" - accesskey="&useService.accesskey;" - preference="app.update.service.enabled"/> -#endif - </groupbox> -#endif - <groupbox id="updateOthers" align="start"> - <caption><label>&updateOthers.label;</label></caption> - <checkbox id="enableSearchUpdate" - label="&enableSearchUpdate.label;" - accesskey="&enableSearchUpdate.accesskey;" - preference="browser.search.update"/> - </groupbox> - </tabpanel> - - <!-- Certificates --> - <tabpanel id="encryptionPanel" orient="vertical"> - <groupbox id="certSelection" align="start"> - <caption><label>&certSelection.label;</label></caption> - <description id="CertSelectionDesc" control="certSelection">&certSelection.description;</description> - - <!-- - The values on these radio buttons may look like l12y issues, but - they're not - this preference uses *those strings* as its values. - I KID YOU NOT. - --> - <radiogroup id="certSelection" - preftype="string" - preference="security.default_personal_cert" - aria-labelledby="CertSelectionDesc"> - <radio label="&certs.auto;" - accesskey="&certs.auto.accesskey;" - value="Select Automatically"/> - <radio label="&certs.ask;" - accesskey="&certs.ask.accesskey;" - value="Ask Every Time"/> - </radiogroup> - </groupbox> - <separator/> - <checkbox id="enableOCSP" - label="&enableOCSP.label;" - accesskey="&enableOCSP.accesskey;" - onsyncfrompreference="return gAdvancedPane.readEnableOCSP();" - onsynctopreference="return gAdvancedPane.writeEnableOCSP();" - preference="security.OCSP.enabled"/> - <separator/> - <hbox> - <button id="viewCertificatesButton" - flex="1" - label="&viewCerts.label;" - accesskey="&viewCerts.accesskey;" - preference="security.disable_button.openCertManager"/> - <button id="viewSecurityDevicesButton" - flex="1" - label="&viewSecurityDevices.label;" - accesskey="&viewSecurityDevices.accesskey;" - preference="security.disable_button.openDeviceManager"/> - <hbox flex="10"/> - </hbox> - </tabpanel> - </tabpanels> -</tabbox> diff --git a/browser/components/preferences/in-content/applications.js b/browser/components/preferences/in-content/applications.js deleted file mode 100644 index 6f2989657..000000000 --- a/browser/components/preferences/in-content/applications.js +++ /dev/null @@ -1,1900 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -// Constants & Enumeration Values - -Components.utils.import('resource://gre/modules/Services.jsm'); -Components.utils.import('resource://gre/modules/AppConstants.jsm'); -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"; -const TYPE_PDF = "application/pdf"; - -const PREF_PDFJS_DISABLED = "pdfjs.disabled"; -const TOPIC_PDFJS_HANDLER_CHANGED = "pdfjs:handlerChanged"; - -const PREF_DISABLED_PLUGIN_TYPES = "plugin.disable_full_page_plugin_for_types"; - -// Preferences that affect which entries to show in the list. -const PREF_SHOW_PLUGINS_IN_LIST = "browser.download.show_plugins_in_list"; -const PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS = - "browser.download.hide_plugins_without_extensions"; - -/* - * Preferences where we store handling information about the feed type. - * - * browser.feeds.handler - * - "bookmarks", "reader" (clarified further using the .default preference), - * or "ask" -- indicates the default handler being used to process feeds; - * "bookmarks" is obsolete; to specify that the handler is bookmarks, - * set browser.feeds.handler.default to "bookmarks"; - * - * browser.feeds.handler.default - * - "bookmarks", "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 - * - nsILocalFile, 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. -// But since nsIHandlerInfo doesn't support plugins, there's no value -// identifying the "use plugin" action, so we use this constant instead. -const kActionUsePlugin = 5; - -const ICON_URL_APP = AppConstants.platform == "linux" ? - "moz-icon://dummy.exe?size=16" : - "chrome://browser/skin/preferences/application.png"; - -// For CSS. Can be one of "ask", "save", "plugin" or "feed". If absent, the icon URL -// was set by us to a custom handler icon and CSS should not try to override it. -const APP_ICON_ATTR_NAME = "appHandlerIcon"; - -// Utilities - -function getFileDisplayName(file) { - if (AppConstants.platform == "win") { - if (file instanceof Ci.nsILocalFileWin) { - try { - return file.getVersionInfoField("FileDescription"); - } catch (e) {} - } - } - if (AppConstants.platform == "macosx") { - if (file instanceof Ci.nsILocalFileMac) { - try { - return file.bundleDisplayName; - } catch (e) {} - } - } - return file.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 plugins and 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, - - - // Convenience Utils - - _handlerSvc: Cc["@mozilla.org/uriloader/handler-service;1"]. - getService(Ci.nsIHandlerService), - - _prefSvc: Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefBranch), - - _categoryMgr: Cc["@mozilla.org/categorymanager;1"]. - getService(Ci.nsICategoryManager), - - element: function(aID) { - return document.getElementById(aID); - }, - - - // nsIHandlerInfo - - // The MIME type or protocol scheme. - _type: null, - get type() { - return this._type; - }, - - get description() { - if (this.wrappedHandlerInfo.description) - return this.wrappedHandlerInfo.description; - - if (this.primaryExtension) { - var extension = this.primaryExtension.toUpperCase(); - return this.element("bundlePreferences").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: function(aNewHandler) { - var possibleApps = this.possibleApplicationHandlers.enumerate(); - while (possibleApps.hasMoreElements()) { - if (possibleApps.getNext().equals(aNewHandler)) - return; - } - this.possibleApplicationHandlers.appendElement(aNewHandler, false); - }, - - removePossibleApplicationHandler: function(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 we have an enabled plugin, then the action is to use that plugin. - if (this.pluginName && !this.isDisabledPluginType) - return kActionUsePlugin; - - // 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)) { - if (this.wrappedHandlerInfo.hasDefaultHandler) - return Ci.nsIHandlerInfo.useSystemDefault; - return Ci.nsIHandlerInfo.saveToDisk; - } - - return this.wrappedHandlerInfo.preferredAction; - }, - - set preferredAction(aNewValue) { - // If the action is to use the plugin, - // we must set the preferred action to "save to disk". - // But only if it's not currently the preferred action. - if ((aNewValue == kActionUsePlugin) && - (this.preferredAction != Ci.nsIHandlerInfo.saveToDisk)) { - aNewValue = Ci.nsIHandlerInfo.saveToDisk; - } - - // We don't modify the preferred action if the new action is to use a plugin - // because handler info objects don't understand our custom "use plugin" - // value. Also, leaving it untouched means that we can automatically revert - // to the old setting if the user ever removes the plugin. - - if (aNewValue != kActionUsePlugin) - this.wrappedHandlerInfo.preferredAction = aNewValue; - }, - - get alwaysAskBeforeHandling() { - // If this type is handled only by a plugin, we can't trust the value - // in the handler info object, since it'll be a default based on the absence - // of any user configuration, and the default in that case is to always ask, - // even though we never ask for content handled by a plugin, so special case - // plugin-handled types by returning false here. - if (this.pluginName && this.handledOnlyByPlugin) - return false; - - // 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. - // - // XXX Plugin objects contain an array of MimeType objects with "suffixes" - // properties; if this object has an associated plugin, shouldn't we check - // those properties for an extension? - get primaryExtension() { - try { - if (this.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo && - this.wrappedHandlerInfo.primaryExtension) - return this.wrappedHandlerInfo.primaryExtension - } catch (ex) {} - - return null; - }, - - - // Plugin Handling - - // A plugin that can handle this type, if any. - // - // Note: just because we have one doesn't mean it *will* handle the type. - // That depends on whether or not the type is in the list of types for which - // plugin handling is disabled. - plugin: null, - - // Whether or not this type is only handled by a plugin or is also handled - // by some user-configured action as specified in the handler info object. - // - // Note: we can't just check if there's a handler info object for this type, - // because OS and user configuration is mixed up in the handler info object, - // so we always need to retrieve it for the OS info and can't tell whether - // it represents only OS-default information or user-configured information. - // - // FIXME: once handler info records are broken up into OS-provided records - // and user-configured records, stop using this boolean flag and simply - // check for the presence of a user-configured record to determine whether - // or not this type is only handled by a plugin. Filed as bug 395142. - handledOnlyByPlugin: undefined, - - get isDisabledPluginType() { - return this._getDisabledPluginTypes().indexOf(this.type) != -1; - }, - - _getDisabledPluginTypes: function() { - var types = ""; - - if (this._prefSvc.prefHasUserValue(PREF_DISABLED_PLUGIN_TYPES)) - types = this._prefSvc.getCharPref(PREF_DISABLED_PLUGIN_TYPES); - - // Only split if the string isn't empty so we don't end up with an array - // containing a single empty string. - if (types != "") - return types.split(","); - - return []; - }, - - disablePluginType: function() { - var disabledPluginTypes = this._getDisabledPluginTypes(); - - if (disabledPluginTypes.indexOf(this.type) == -1) - disabledPluginTypes.push(this.type); - - this._prefSvc.setCharPref(PREF_DISABLED_PLUGIN_TYPES, - disabledPluginTypes.join(",")); - - // Update the category manager so existing browser windows update. - this._categoryMgr.deleteCategoryEntry("Gecko-Content-Viewers", - this.type, - false); - }, - - enablePluginType: function() { - var disabledPluginTypes = this._getDisabledPluginTypes(); - - var type = this.type; - disabledPluginTypes = disabledPluginTypes.filter(v => v != type); - - this._prefSvc.setCharPref(PREF_DISABLED_PLUGIN_TYPES, - disabledPluginTypes.join(",")); - - // Update the category manager so existing browser windows update. - this._categoryMgr. - addCategoryEntry("Gecko-Content-Viewers", - this.type, - "@mozilla.org/content/plugin/document-loader-factory;1", - false, - true); - }, - - - // Storage - - store: function() { - this._handlerSvc.store(this.wrappedHandlerInfo); - }, - - - // Icons - - get smallIcon() { - return this._getIcon(16); - }, - - _getIcon: function(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; - - // FIXME: consider returning some generic icon when we can't get a URL for - // one (for example in the case of protocol schemes). Filed as bug 395141. - return null; - } - -}; - - -// 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, - - // Convenience Utils - - _converterSvc: - Cc["@mozilla.org/embeddor.implemented/web-content-handler-registrar;1"]. - getService(Ci.nsIWebContentConverterService), - - _shellSvc: AppConstants.HAVE_SHELL_SERVICE ? getShellService() : null, - - // nsIHandlerInfo - - get description() { - return this.element("bundlePreferences").getString(this._appPrefLabel); - }, - - get preferredApplicationHandler() { - switch (this.element(this._prefSelectedReader).value) { - case "client": - var file = this.element(this._prefSelectedApp).value; - if (file) - return getLocalHandlerApp(file); - - return null; - - case "web": - var uri = this.element(this._prefSelectedWeb).value; - if (!uri) - return null; - return this._converterSvc.getWebContentHandlerByURI(this.type, uri); - - case "bookmarks": - default: - // When the pref is set to bookmarks, 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) { - this.element(this._prefSelectedApp).value = aNewValue.executable; - this.element(this._prefSelectedReader).value = "client"; - } - else if (aNewValue instanceof Ci.nsIWebContentHandlerInfo) { - this.element(this._prefSelectedWeb).value = aNewValue.uri; - this.element(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, Live Bookmarks, 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. - this._converterSvc.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 and nsIArray::enumerate. - this._possibleApplicationHandlers = { - _inner: [], - _removed: [], - - QueryInterface: function(aIID) { - if (aIID.equals(Ci.nsIMutableArray) || - aIID.equals(Ci.nsIArray) || - aIID.equals(Ci.nsISupports)) - return this; - - throw Cr.NS_ERROR_NO_INTERFACE; - }, - - get length() { - return this._inner.length; - }, - - enumerate: function() { - return new ArrayEnumerator(this._inner); - }, - - appendElement: function(aHandlerApp, aWeak) { - 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 = this.element(this._prefSelectedApp).value; - if (preferredAppFile) { - let preferredApp = getLocalHandlerApp(preferredAppFile); - let defaultApp = this._defaultApplicationHandler; - if (!defaultApp || !defaultApp.equals(preferredApp)) - this._possibleApplicationHandlers.appendElement(preferredApp, false); - } - - // Add the registered web handlers. There can be any number of these. - var webHandlers = this._converterSvc.getContentHandlers(this.type); - for (let webHandler of webHandlers) - this._possibleApplicationHandlers.appendElement(webHandler, false); - - return this._possibleApplicationHandlers; - }, - - __defaultApplicationHandler: undefined, - get _defaultApplicationHandler() { - if (typeof this.__defaultApplicationHandler != "undefined") - return this.__defaultApplicationHandler; - - var defaultFeedReader = null; - if (AppConstants.HAVE_SHELL_SERVICE) { - try { - defaultFeedReader = this._shellSvc.defaultFeedReader; - } - catch (ex) { - // no default reader or _shellSvc is null - } - } - - 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() { - if (AppConstants.HAVE_SHELL_SERVICE) { - try { - if (this._shellSvc.defaultFeedReader) - return true; - } - catch (ex) { - // no default reader or _shellSvc is null - } - } - - 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 (this.element(this._prefSelectedAction).value) { - - case "bookmarks": - return Ci.nsIHandlerInfo.handleInternally; - - 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": - default: - return Ci.nsIHandlerInfo.handleInternally; - } - }, - - set preferredAction(aNewValue) { - switch (aNewValue) { - - case Ci.nsIHandlerInfo.handleInternally: - this.element(this._prefSelectedReader).value = "bookmarks"; - break; - - case Ci.nsIHandlerInfo.useHelperApp: - this.element(this._prefSelectedAction).value = "reader"; - // The controller has already set preferredApplicationHandler - // to the new helper app. - break; - - case Ci.nsIHandlerInfo.useSystemDefault: - this.element(this._prefSelectedAction).value = "reader"; - this.preferredApplicationHandler = this._defaultApplicationHandler; - break; - } - }, - - get alwaysAskBeforeHandling() { - return this.element(this._prefSelectedAction).value == "ask"; - }, - - set alwaysAskBeforeHandling(aNewValue) { - if (aNewValue == true) - this.element(this._prefSelectedAction).value = "ask"; - else - this.element(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 - - get primaryExtension() { - return "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: function() { - for (let app of this._possibleApplicationHandlers._removed) { - if (app instanceof Ci.nsILocalHandlerApp) { - let pref = this.element(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); - this._converterSvc.removeContentHandler(app.contentType, app.uri); - } - } - this._possibleApplicationHandlers._removed = []; - }, - - - // Icons - - get smallIcon() { - return this._smallIcon; - } - -}; - -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, - _smallIcon: "chrome://browser/skin/feeds/feedIcon16.png", - _appPrefLabel: "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, - _smallIcon: "chrome://browser/skin/feeds/videoFeedIcon16.png", - _appPrefLabel: "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, - _smallIcon: "chrome://browser/skin/feeds/audioFeedIcon16.png", - _appPrefLabel: "audioPodcastFeed" -} - -/** - * InternalHandlerInfoWrapper provides a basic mechanism to create an internal - * mime type handler that can be enabled/disabled in the applications preference - * menu. - */ -function InternalHandlerInfoWrapper(aMIMEType) { - var mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); - var handlerInfo = mimeSvc.getFromTypeAndExtension(aMIMEType, null); - - HandlerInfoWrapper.call(this, aMIMEType, handlerInfo); -} - -InternalHandlerInfoWrapper.prototype = { - __proto__: HandlerInfoWrapper.prototype, - - // Override store so we so we can notify any code listening for registration - // or unregistration of this handler. - store: function() { - HandlerInfoWrapper.prototype.store.call(this); - Services.obs.notifyObservers(null, this._handlerChanged, null); - }, - - get enabled() { - throw Cr.NS_ERROR_NOT_IMPLEMENTED; - }, - - get description() { - return this.element("bundlePreferences").getString(this._appPrefLabel); - } -}; - -var pdfHandlerInfo = { - __proto__: new InternalHandlerInfoWrapper(TYPE_PDF), - _handlerChanged: TOPIC_PDFJS_HANDLER_CHANGED, - _appPrefLabel: "portableDocumentFormat", - get enabled() { - return !Services.prefs.getBoolPref(PREF_PDFJS_DISABLED); - }, -}; - - -// 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, - - _prefSvc : Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefBranch), - - _mimeSvc : Cc["@mozilla.org/mime;1"]. - getService(Ci.nsIMIMEService), - - _helperAppSvc : Cc["@mozilla.org/uriloader/external-helper-app-service;1"]. - getService(Ci.nsIExternalHelperAppService), - - _handlerSvc : Cc["@mozilla.org/uriloader/handler-service;1"]. - getService(Ci.nsIHandlerService), - - _ioSvc : Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService), - - - // Initialization & Destruction - - init: function() { - function setEventListener(aId, aEventType, aCallback) - { - document.getElementById(aId) - .addEventListener(aEventType, aCallback.bind(gApplicationsPane)); - } - - // Initialize shortcuts to some commonly accessed elements & values. - this._brandShortName = - document.getElementById("bundleBrand").getString("brandShortName"); - this._prefsBundle = document.getElementById("bundlePreferences"); - 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. - this._prefSvc.addObserver(PREF_SHOW_PLUGINS_IN_LIST, this, false); - this._prefSvc.addObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this, false); - this._prefSvc.addObserver(PREF_FEED_SELECTED_APP, this, false); - this._prefSvc.addObserver(PREF_FEED_SELECTED_WEB, this, false); - this._prefSvc.addObserver(PREF_FEED_SELECTED_ACTION, this, false); - this._prefSvc.addObserver(PREF_FEED_SELECTED_READER, this, false); - - this._prefSvc.addObserver(PREF_VIDEO_FEED_SELECTED_APP, this, false); - this._prefSvc.addObserver(PREF_VIDEO_FEED_SELECTED_WEB, this, false); - this._prefSvc.addObserver(PREF_VIDEO_FEED_SELECTED_ACTION, this, false); - this._prefSvc.addObserver(PREF_VIDEO_FEED_SELECTED_READER, this, false); - - this._prefSvc.addObserver(PREF_AUDIO_FEED_SELECTED_APP, this, false); - this._prefSvc.addObserver(PREF_AUDIO_FEED_SELECTED_WEB, this, false); - this._prefSvc.addObserver(PREF_AUDIO_FEED_SELECTED_ACTION, this, false); - this._prefSvc.addObserver(PREF_AUDIO_FEED_SELECTED_READER, this, false); - - - setEventListener("focusSearch1", "command", gApplicationsPane.focusFilterBox); - setEventListener("focusSearch2", "command", gApplicationsPane.focusFilterBox); - setEventListener("filter", "command", gApplicationsPane.filter); - setEventListener("handlersView", "select", - gApplicationsPane.onSelectionChanged); - setEventListener("typeColumn", "click", gApplicationsPane.sort); - setEventListener("actionColumn", "click", gApplicationsPane.sort); - - // Listen for window unload so we can remove our preference observers. - window.addEventListener("unload", this, false); - - // 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. - // XXX should we be using the XUL sort service instead? - 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"); - } - else - this._sortColumn = document.getElementById("typeColumn"); - - // Load the data and build the list of handlers. - // By doing this in a timeout, we let the preferences dialog resize itself - // to an appropriate size before we add a bunch of items to the list. - // Otherwise, if there are many items, and the Applications prefpane - // is the one that gets displayed when the user first opens the dialog, - // the dialog might stretch too much in an attempt to fit them all in. - // XXX Shouldn't we perhaps just set a max-height on the richlistbox? - var _delayedPaneLoad = function(self) { - self._loadData(); - self._rebuildVisibleTypes(); - self._sortVisibleTypes(); - self._rebuildView(); - - // Notify observers that the UI is now ready - Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService). - notifyObservers(window, "app-handler-pane-loaded", null); - } - setTimeout(_delayedPaneLoad, 0, this); - }, - - destroy: function() { - window.removeEventListener("unload", this, false); - this._prefSvc.removeObserver(PREF_SHOW_PLUGINS_IN_LIST, this); - this._prefSvc.removeObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this); - this._prefSvc.removeObserver(PREF_FEED_SELECTED_APP, this); - this._prefSvc.removeObserver(PREF_FEED_SELECTED_WEB, this); - this._prefSvc.removeObserver(PREF_FEED_SELECTED_ACTION, this); - this._prefSvc.removeObserver(PREF_FEED_SELECTED_READER, this); - - this._prefSvc.removeObserver(PREF_VIDEO_FEED_SELECTED_APP, this); - this._prefSvc.removeObserver(PREF_VIDEO_FEED_SELECTED_WEB, this); - this._prefSvc.removeObserver(PREF_VIDEO_FEED_SELECTED_ACTION, this); - this._prefSvc.removeObserver(PREF_VIDEO_FEED_SELECTED_READER, this); - - this._prefSvc.removeObserver(PREF_AUDIO_FEED_SELECTED_APP, this); - this._prefSvc.removeObserver(PREF_AUDIO_FEED_SELECTED_WEB, this); - this._prefSvc.removeObserver(PREF_AUDIO_FEED_SELECTED_ACTION, this); - this._prefSvc.removeObserver(PREF_AUDIO_FEED_SELECTED_READER, this); - }, - - - // nsISupports - - QueryInterface: function(aIID) { - if (aIID.equals(Ci.nsIObserver) || - aIID.equals(Ci.nsIDOMEventListener || - aIID.equals(Ci.nsISupports))) - return this; - - throw Cr.NS_ERROR_NO_INTERFACE; - }, - - - // nsIObserver - - observe: function (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) { - // These two prefs alter the list of visible types, so we have to rebuild - // that list when they change. - if (aData == PREF_SHOW_PLUGINS_IN_LIST || - aData == PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS) { - this._rebuildVisibleTypes(); - this._sortVisibleTypes(); - } - - // All the prefs we observe can affect what we display, so we rebuild - // the view when any of them changes. - this._rebuildView(); - } - }, - - - // nsIDOMEventListener - - handleEvent: function(aEvent) { - if (aEvent.type == "unload") { - this.destroy(); - } - }, - - - // Composed Model Construction - - _loadData: function() { - this._loadFeedHandler(); - this._loadInternalHandlers(); - this._loadPluginHandlers(); - this._loadApplicationHandlers(); - }, - - _loadFeedHandler: function() { - this._handledTypes[TYPE_MAYBE_FEED] = feedHandlerInfo; - feedHandlerInfo.handledOnlyByPlugin = false; - - this._handledTypes[TYPE_MAYBE_VIDEO_FEED] = videoFeedHandlerInfo; - videoFeedHandlerInfo.handledOnlyByPlugin = false; - - this._handledTypes[TYPE_MAYBE_AUDIO_FEED] = audioFeedHandlerInfo; - audioFeedHandlerInfo.handledOnlyByPlugin = false; - }, - - /** - * Load higher level internal handlers so they can be turned on/off in the - * applications menu. - */ - _loadInternalHandlers: function() { - var internalHandlers = [pdfHandlerInfo]; - for (let internalHandler of internalHandlers) { - if (internalHandler.enabled) { - this._handledTypes[internalHandler.type] = internalHandler; - } - } - }, - - /** - * Load the set of handlers defined by plugins. - * - * Note: if there's more than one plugin for a given MIME type, we assume - * the last one is the one that the application will use. That may not be - * correct, but it's how we've been doing it for years. - * - * Perhaps we should instead query navigator.mimeTypes for the set of types - * supported by the application and then get the plugin from each MIME type's - * enabledPlugin property. But if there's a plugin for a type, we need - * to know about it even if it isn't enabled, since we're going to give - * the user an option to enable it. - * - * Also note that enabledPlugin does not get updated when - * plugin.disable_full_page_plugin_for_types changes, so even if we could use - * enabledPlugin to get the plugin that would be used, we'd still need to - * check the pref ourselves to find out if it's enabled. - */ - _loadPluginHandlers: function() { - "use strict"; - - let mimeTypes = navigator.mimeTypes; - - for (let mimeType of mimeTypes) { - let handlerInfoWrapper; - if (mimeType.type in this._handledTypes) { - handlerInfoWrapper = this._handledTypes[mimeType.type]; - } else { - let wrappedHandlerInfo = - this._mimeSvc.getFromTypeAndExtension(mimeType.type, null); - handlerInfoWrapper = new HandlerInfoWrapper(mimeType.type, wrappedHandlerInfo); - handlerInfoWrapper.handledOnlyByPlugin = true; - this._handledTypes[mimeType.type] = handlerInfoWrapper; - } - handlerInfoWrapper.pluginName = mimeType.enabledPlugin.name; - } - }, - - /** - * Load the set of handlers defined by the application datastore. - */ - _loadApplicationHandlers: function() { - var wrappedHandlerInfos = this._handlerSvc.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; - } - - handlerInfoWrapper.handledOnlyByPlugin = false; - } - }, - - - // View Construction - - _rebuildVisibleTypes: function() { - // Reset the list of visible types and the visible type description counts. - this._visibleTypes = []; - this._visibleTypeDescriptionCount = {}; - - // Get the preferences that help determine what types to show. - var showPlugins = this._prefSvc.getBoolPref(PREF_SHOW_PLUGINS_IN_LIST); - var hidePluginsWithoutExtensions = - this._prefSvc.getBoolPref(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS); - - for (let type in this._handledTypes) { - let handlerInfo = this._handledTypes[type]; - - // Hide plugins without associated extensions if so prefed so we don't - // show a whole bunch of obscure types handled by plugins on Mac. - // Note: though protocol types don't have extensions, we still show them; - // the pref is only meant to be applied to MIME types, since plugins are - // only associated with MIME types. - // FIXME: should we also check the "suffixes" property of the plugin? - // Filed as bug 395135. - if (hidePluginsWithoutExtensions && handlerInfo.handledOnlyByPlugin && - handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo && - !handlerInfo.primaryExtension) - continue; - - // Hide types handled only by plugins if so prefed. - if (handlerInfo.handledOnlyByPlugin && !showPlugins) - continue; - - // 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: function() { - // Clear the list of entries. - while (this._list.childNodes.length > 1) - this._list.removeChild(this._list.lastChild); - - 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("richlistitem"); - item.setAttribute("type", visibleType.type); - item.setAttribute("typeDescription", this._describeType(visibleType)); - if (visibleType.smallIcon) - item.setAttribute("typeIcon", visibleType.smallIcon); - item.setAttribute("actionDescription", - this._describePreferredAction(visibleType)); - - if (!this._setIconClassForPreferredAction(visibleType, item)) { - item.setAttribute("actionIcon", - this._getIconURLForPreferredAction(visibleType)); - } - - this._list.appendChild(item); - } - - this._selectLastSelectedType(); - }, - - _matchesFilter: function(aType) { - var filterValue = this._filter.value.toLowerCase(); - return this._describeType(aType).toLowerCase().indexOf(filterValue) != -1 || - this._describePreferredAction(aType).toLowerCase().indexOf(filterValue) != -1; - }, - - /** - * 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: function(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: function(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"); - } - - switch (aHandlerInfo.preferredAction) { - case Ci.nsIHandlerInfo.saveToDisk: - return this._prefsBundle.getString("saveFile"); - - case Ci.nsIHandlerInfo.useHelperApp: - var preferredApp = aHandlerInfo.preferredApplicationHandler; - var name; - if (preferredApp instanceof Ci.nsILocalHandlerApp) - name = getFileDisplayName(preferredApp.executable); - else - name = preferredApp.name; - return this._prefsBundle.getFormattedString("useApp", [name]); - - case Ci.nsIHandlerInfo.handleInternally: - // For the feed type, handleInternally means live bookmarks. - if (isFeedType(aHandlerInfo.type)) { - return this._prefsBundle.getFormattedString("addLiveBookmarksInApp", - [this._brandShortName]); - } - - if (aHandlerInfo instanceof InternalHandlerInfoWrapper) { - return this._prefsBundle.getFormattedString("previewInApp", - [this._brandShortName]); - } - - // For other types, handleInternally looks like either useHelperApp - // or useSystemDefault depending on whether or not there's a preferred - // handler app. - if (this.isValidHandlerApp(aHandlerInfo.preferredApplicationHandler)) - return aHandlerInfo.preferredApplicationHandler.name; - - return 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]); - - case kActionUsePlugin: - return this._prefsBundle.getFormattedString("usePluginIn", - [aHandlerInfo.pluginName, - this._brandShortName]); - default: - throw new Error(`Unexpected preferredAction: ${aHandlerInfo.preferredAction}`); - } - }, - - _selectLastSelectedType: function() { - // If the list is disabled by the pref.downloads.disable_button.edit_actions - // preference being locked, then don't select the type, as that would cause - // it to appear selected, with a different background and an actions menu - // that makes it seem like you can choose an action for the type. - if (this._list.disabled) - return; - - var lastSelectedType = this._list.getAttribute("lastSelectedType"); - if (!lastSelectedType) - return; - - var item = this._list.getElementsByAttribute("type", lastSelectedType)[0]; - if (!item) - return; - - this._list.selectedItem = item; - }, - - /** - * 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: function(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; - - return false; - }, - - _isValidHandlerExecutable: function(aExecutable) { - let leafName; - if (AppConstants.platform == "win") { - leafName = `${AppConstants.MOZ_APP_NAME}.exe`; - } else if (AppConstants.platform == "macosx") { - leafName = AppConstants.MOZ_MACBUNDLE_NAME; - } else { - leafName = `${AppConstants.MOZ_APP_NAME}-bin`; - } - return aExecutable && - aExecutable.exists() && - aExecutable.isExecutable() && -// XXXben - we need to compare this with the running instance executable -// just don't know how to do that via script... -// XXXmano TBD: can probably add this to nsIShellService - aExecutable.leafName != leafName; - }, - - /** - * Rebuild the actions menu for the selected entry. Gets called by - * the richlistitem constructor when an entry in the list gets selected. - */ - rebuildActionsMenu: function() { - var typeItem = this._list.selectedItem; - var handlerInfo = this._handledTypes[typeItem.type]; - var menu = - document.getAnonymousElementByAttribute(typeItem, "class", "actionsMenu"); - var menuPopup = menu.menupopup; - - // Clear out existing items. - while (menuPopup.hasChildNodes()) - menuPopup.removeChild(menuPopup.lastChild); - - // Add the "Preview in Firefox" option for optional internal handlers. - if (handlerInfo instanceof InternalHandlerInfoWrapper) { - let internalMenuItem = document.createElement("menuitem"); - internalMenuItem.setAttribute("action", Ci.nsIHandlerInfo.handleInternally); - let label = this._prefsBundle.getFormattedString("previewInApp", - [this._brandShortName]); - internalMenuItem.setAttribute("label", label); - internalMenuItem.setAttribute("tooltiptext", label); - internalMenuItem.setAttribute(APP_ICON_ATTR_NAME, "ask"); - menuPopup.appendChild(internalMenuItem); - } - - { - var askMenuItem = document.createElement("menuitem"); - askMenuItem.setAttribute("action", 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(APP_ICON_ATTR_NAME, "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)) { - var saveMenuItem = document.createElement("menuitem"); - saveMenuItem.setAttribute("action", Ci.nsIHandlerInfo.saveToDisk); - let label = this._prefsBundle.getString("saveFile"); - saveMenuItem.setAttribute("label", label); - saveMenuItem.setAttribute("tooltiptext", label); - saveMenuItem.setAttribute(APP_ICON_ATTR_NAME, "save"); - menuPopup.appendChild(saveMenuItem); - } - - // If this is the feed type, add a Live Bookmarks item. - if (isFeedType(handlerInfo.type)) { - let internalMenuItem = document.createElement("menuitem"); - internalMenuItem.setAttribute("action", Ci.nsIHandlerInfo.handleInternally); - let label = this._prefsBundle.getFormattedString("addLiveBookmarksInApp", - [this._brandShortName]); - internalMenuItem.setAttribute("label", label); - internalMenuItem.setAttribute("tooltiptext", label); - internalMenuItem.setAttribute(APP_ICON_ATTR_NAME, "feed"); - menuPopup.appendChild(internalMenuItem); - } - - // Add a separator to distinguish these items from the helper app items - // that follow them. - let menuItem = document.createElement("menuseparator"); - menuPopup.appendChild(menuItem); - - // Create a menu item for the OS default application, if any. - if (handlerInfo.hasDefaultHandler) { - var defaultMenuItem = document.createElement("menuitem"); - defaultMenuItem.setAttribute("action", Ci.nsIHandlerInfo.useSystemDefault); - let label = this._prefsBundle.getFormattedString("useDefault", - [handlerInfo.defaultDescription]); - defaultMenuItem.setAttribute("label", label); - defaultMenuItem.setAttribute("tooltiptext", handlerInfo.defaultDescription); - defaultMenuItem.setAttribute("image", this._getIconURLForSystemDefault(handlerInfo)); - - 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("action", 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); - menuItem.setAttribute("image", this._getIconURLForHandlerApp(possibleApp)); - - // 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); - } - - // Create a menu item for the plugin. - if (handlerInfo.pluginName) { - var pluginMenuItem = document.createElement("menuitem"); - pluginMenuItem.setAttribute("action", kActionUsePlugin); - let label = this._prefsBundle.getFormattedString("usePluginIn", - [handlerInfo.pluginName, - this._brandShortName]); - pluginMenuItem.setAttribute("label", label); - pluginMenuItem.setAttribute("tooltiptext", label); - pluginMenuItem.setAttribute(APP_ICON_ATTR_NAME, "plugin"); - menuPopup.appendChild(pluginMenuItem); - } - - // 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 = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService) - .getTypeFromExtension("exe"); - canOpenWithOtherApp = handlerInfo.type != executableType; - } - if (canOpenWithOtherApp) - { - let menuItem = document.createElement("menuitem"); - menuItem.className = "choose-app-item"; - menuItem.addEventListener("command", function(e) { - gApplicationsPane.chooseApp(e); - }); - 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.className = "manage-app-item"; - menuItem.addEventListener("command", function(e) { - gApplicationsPane.manageApp(e); - }); - 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.selectedItem = askMenuItem; - else switch (handlerInfo.preferredAction) { - case Ci.nsIHandlerInfo.handleInternally: - menu.selectedItem = internalMenuItem; - break; - case Ci.nsIHandlerInfo.useSystemDefault: - menu.selectedItem = defaultMenuItem; - break; - case Ci.nsIHandlerInfo.useHelperApp: - if (preferredApp) - menu.selectedItem = - possibleAppMenuItems.filter(v => v.handlerApp.equals(preferredApp))[0]; - break; - case kActionUsePlugin: - menu.selectedItem = pluginMenuItem; - break; - case Ci.nsIHandlerInfo.saveToDisk: - menu.selectedItem = saveMenuItem; - break; - } - }, - - - // Sorting & Filtering - - _sortColumn: null, - - /** - * Sort the list when the user clicks on a column header. - */ - sort: function (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: function() { - 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(); - }, - - /** - * Filter the list when the user enters a filter term into the filter field. - */ - filter: function() { - this._rebuildView(); - }, - - focusFilterBox: function() { - this._filter.focus(); - this._filter.select(); - }, - - - // Changes - - onSelectAction: function(aActionItem) { - this._storingAction = true; - - try { - this._storeAction(aActionItem); - } - finally { - this._storingAction = false; - } - }, - - _storeAction: function(aActionItem) { - var typeItem = this._list.selectedItem; - var handlerInfo = this._handledTypes[typeItem.type]; - - let action = parseInt(aActionItem.getAttribute("action")); - - // Set the plugin state if we're enabling or disabling a plugin. - if (action == kActionUsePlugin) - handlerInfo.enablePluginType(); - else if (handlerInfo.pluginName && !handlerInfo.isDisabledPluginType) - handlerInfo.disablePluginType(); - - // 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 "always ask" flag. - if (action == Ci.nsIHandlerInfo.alwaysAsk) - handlerInfo.alwaysAskBeforeHandling = true; - else - handlerInfo.alwaysAskBeforeHandling = false; - - // Set the preferred action. - handlerInfo.preferredAction = action; - - handlerInfo.store(); - - // Make sure the handler info object is flagged to indicate that there is - // now some user configuration for the type. - handlerInfo.handledOnlyByPlugin = false; - - // Update the action label and image to reflect the new preferred action. - typeItem.setAttribute("actionDescription", - this._describePreferredAction(handlerInfo)); - if (!this._setIconClassForPreferredAction(handlerInfo, typeItem)) { - typeItem.setAttribute("actionIcon", - this._getIconURLForPreferredAction(handlerInfo)); - } - }, - - manageApp: function(aEvent) { - // Don't let the normal "on select action" handler get this event, - // as we handle it specially ourselves. - aEvent.stopPropagation(); - - var typeItem = this._list.selectedItem; - var handlerInfo = this._handledTypes[typeItem.type]; - - let onComplete = () => { - // 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 richlistitem too. Will be visible when selecting another row - typeItem.setAttribute("actionDescription", - this._describePreferredAction(handlerInfo)); - if (!this._setIconClassForPreferredAction(handlerInfo, typeItem)) { - typeItem.setAttribute("actionIcon", - this._getIconURLForPreferredAction(handlerInfo)); - } - }; - - gSubDialog.open("chrome://browser/content/preferences/applicationManager.xul", - "resizable=no", handlerInfo, onComplete); - - }, - - chooseApp: function(aEvent) { - // Don't let the normal "on select action" handler get this event, - // as we handle it specially ourselves. - aEvent.stopPropagation(); - - var handlerApp; - let chooseAppCallback = function(aHandlerApp) { - // 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 (aHandlerApp) { - let typeItem = this._list.selectedItem; - let actionsMenu = - document.getAnonymousElementByAttribute(typeItem, "class", "actionsMenu"); - let menuItems = actionsMenu.menupopup.childNodes; - for (let i = 0; i < menuItems.length; i++) { - let menuItem = menuItems[i]; - if (menuItem.handlerApp && menuItem.handlerApp.equals(aHandlerApp)) { - actionsMenu.selectedIndex = i; - this.onSelectAction(menuItem); - break; - } - } - } - }.bind(this); - - if (AppConstants.platform == "win") { - var params = {}; - var handlerInfo = this._handledTypes[this._list.selectedItem.type]; - - if (isFeedType(handlerInfo.type)) { - // MIME info will be null, create a temp object. - params.mimeInfo = this._mimeSvc.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; - - let onAppSelected = () => { - if (this.isValidHandlerApp(params.handlerApp)) { - handlerApp = params.handlerApp; - - // Add the app to the type's list of possible handlers. - handlerInfo.addPossibleApplicationHandler(handlerApp); - } - - chooseAppCallback(handlerApp); - }; - - gSubDialog.open("chrome://global/content/appPicker.xul", - null, params, onAppSelected); - } else { - let winTitle = this._prefsBundle.getString("fpTitleChooseApp"); - let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - let fpCallback = function fpCallback_done(aResult) { - if (aResult == Ci.nsIFilePicker.returnOK && fp.file && - this._isValidHandlerExecutable(fp.file)) { - handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]. - createInstance(Ci.nsILocalHandlerApp); - handlerApp.name = getFileDisplayName(fp.file); - handlerApp.executable = fp.file; - - // Add the app to the type's list of possible handlers. - let handlerInfo = this._handledTypes[this._list.selectedItem.type]; - handlerInfo.addPossibleApplicationHandler(handlerApp); - - chooseAppCallback(handlerApp); - } - }.bind(this); - - // 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.init(window, winTitle, Ci.nsIFilePicker.modeOpen); - fp.appendFilters(Ci.nsIFilePicker.filterApps); - fp.open(fpCallback); - } - }, - - // Mark which item in the list was last selected so we can reselect it - // when we rebuild the list or when the user returns to the prefpane. - onSelectionChanged: function() { - if (this._list.selectedItem) - this._list.setAttribute("lastSelectedType", - this._list.selectedItem.getAttribute("type")); - }, - - _setIconClassForPreferredAction: function(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(APP_ICON_ATTR_NAME, "ask"); - return true; - } - - switch (aHandlerInfo.preferredAction) { - case Ci.nsIHandlerInfo.saveToDisk: - aElement.setAttribute(APP_ICON_ATTR_NAME, "save"); - return true; - - case Ci.nsIHandlerInfo.handleInternally: - if (isFeedType(aHandlerInfo.type)) { - aElement.setAttribute(APP_ICON_ATTR_NAME, "feed"); - return true; - } else if (aHandlerInfo instanceof InternalHandlerInfoWrapper) { - aElement.setAttribute(APP_ICON_ATTR_NAME, "ask"); - return true; - } - break; - - case kActionUsePlugin: - aElement.setAttribute(APP_ICON_ATTR_NAME, "plugin"); - return true; - } - aElement.removeAttribute(APP_ICON_ATTR_NAME); - return false; - }, - - _getIconURLForPreferredAction: function(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); - // Explicit fall-through - - // This should never happen, but if preferredAction is set to some weird - // value, then fall back to the generic application icon. - default: - return ICON_URL_APP; - } - }, - - _getIconURLForHandlerApp: function(aHandlerApp) { - if (aHandlerApp instanceof Ci.nsILocalHandlerApp) - return this._getIconURLForFile(aHandlerApp.executable); - - 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: function(aFile) { - var fph = this._ioSvc.getProtocolHandler("file"). - QueryInterface(Ci.nsIFileProtocolHandler); - var urlSpec = fph.getURLSpecFromFile(aFile); - - return "moz-icon://" + urlSpec + "?size=16"; - }, - - _getIconURLForWebApp: function(aWebAppURITemplate) { - var uri = this._ioSvc.newURI(aWebAppURITemplate, null, null); - - // Unfortunately we can't use the favicon service to get the favicon, - // because the service looks in the annotations table for a record with - // the exact URL we give it, and users won't have such records for URLs - // they don't visit, and users won't visit the web app's URL template, - // they'll only visit URLs derived from that template (i.e. with %s - // in the template replaced by the URL of the content being handled). - - if (/^https?$/.test(uri.scheme) && this._prefSvc.getBoolPref("browser.chrome.favicons")) - return uri.prePath + "/favicon.ico"; - - return ""; - }, - - _getIconURLForSystemDefault: function(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 ICON_URL_APP; - } - -}; diff --git a/browser/components/preferences/in-content/applications.xul b/browser/components/preferences/in-content/applications.xul deleted file mode 100644 index 1d4723493..000000000 --- a/browser/components/preferences/in-content/applications.xul +++ /dev/null @@ -1,95 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<!-- Applications panel --> - -<script type="application/javascript" - src="chrome://browser/content/preferences/in-content/applications.js"/> - -<preferences id="feedsPreferences" hidden="true" data-category="paneApplications"> - <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"/> -</preferences> - -<keyset data-category="paneApplications"> - <!-- Ctrl+f/k focus the search box in the Applications pane. - These <key>s have oncommand attributes because of bug 371900. --> - <key key="&focusSearch1.key;" modifiers="accel" id="focusSearch1" oncommand=";"/> - <key key="&focusSearch2.key;" modifiers="accel" id="focusSearch2" oncommand=";"/> -</keyset> - -<hbox id="header-applications" - class="header" - hidden="true" - data-category="paneApplications"> - <label class="header-name" flex="1">&paneApplications.title;</label> - <html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a> -</hbox> - -<vbox id="applicationsContent" - data-category="paneApplications" - hidden="true" - flex="1"> - <hbox> - <textbox id="filter" flex="1" - type="search" - placeholder="&filter.emptytext;" - aria-controls="handlersView"/> - </hbox> - - <separator class="thin"/> - - <richlistbox id="handlersView" orient="vertical" persist="lastSelectedType" - preference="pref.downloads.disable_button.edit_actions" - flex="1"> - <listheader equalsize="always"> - <treecol id="typeColumn" label="&typeColumn.label;" value="type" - accesskey="&typeColumn.accesskey;" persist="sortDirection" - flex="1" sortDirection="ascending"/> - <treecol id="actionColumn" label="&actionColumn2.label;" value="action" - accesskey="&actionColumn2.accesskey;" persist="sortDirection" - flex="1"/> - </listheader> - </richlistbox> -</vbox> diff --git a/browser/components/preferences/in-content/containers.js b/browser/components/preferences/in-content/containers.js deleted file mode 100644 index 758e45fff..000000000 --- a/browser/components/preferences/in-content/containers.js +++ /dev/null @@ -1,73 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -Components.utils.import("resource://gre/modules/AppConstants.jsm"); -Components.utils.import("resource://gre/modules/ContextualIdentityService.jsm"); - -const containersBundle = Services.strings.createBundle("chrome://browser/locale/preferences/containers.properties"); - -const defaultContainerIcon = "fingerprint"; -const defaultContainerColor = "blue"; - -let gContainersPane = { - - init() { - this._list = document.getElementById("containersView"); - - document.getElementById("backContainersLink").addEventListener("click", function () { - gotoPref("privacy"); - }); - - this._rebuildView(); - }, - - _rebuildView() { - const containers = ContextualIdentityService.getIdentities(); - while (this._list.firstChild) { - this._list.firstChild.remove(); - } - for (let container of containers) { - let item = document.createElement("richlistitem"); - item.setAttribute("containerName", ContextualIdentityService.getUserContextLabel(container.userContextId)); - item.setAttribute("containerIcon", container.icon); - item.setAttribute("containerColor", container.color); - item.setAttribute("userContextId", container.userContextId); - - this._list.appendChild(item); - } - }, - - onRemoveClick(button) { - let userContextId = button.getAttribute("value"); - ContextualIdentityService.remove(userContextId); - this._rebuildView(); - }, - onPeferenceClick(button) { - this.openPreferenceDialog(button.getAttribute("value")); - }, - - onAddButtonClick(button) { - this.openPreferenceDialog(null); - }, - - openPreferenceDialog(userContextId) { - let identity = { - name: "", - icon: defaultContainerIcon, - color: defaultContainerColor - }; - let title; - if (userContextId) { - identity = ContextualIdentityService.getIdentityFromId(userContextId); - // This is required to get the translation string from defaults - identity.name = ContextualIdentityService.getUserContextLabel(identity.userContextId); - title = containersBundle.formatStringFromName("containers.updateContainerTitle", [identity.name], 1); - } - - const params = { userContextId, identity, windowTitle: title }; - gSubDialog.open("chrome://browser/content/preferences/containers.xul", - null, params); - } - -}; diff --git a/browser/components/preferences/in-content/containers.xul b/browser/components/preferences/in-content/containers.xul deleted file mode 100644 index e83bac1c3..000000000 --- a/browser/components/preferences/in-content/containers.xul +++ /dev/null @@ -1,54 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<!-- Containers panel --> - -<script type="application/javascript" - src="chrome://browser/content/preferences/in-content/containers.js"/> - -<preferences id="containerPreferences" hidden="true" data-category="paneContainer"> - <!-- Containers --> - <preference id="privacy.userContext.enabled" - name="privacy.userContext.enabled" - type="bool"/> - -</preferences> - -<hbox hidden="true" - class="container-header-links" - data-category="paneContainers"> - <label class="text-link" id="backContainersLink" value="&backLink.label;" /> -</hbox> - -<hbox id="header-containers" - class="header" - hidden="true" - data-category="paneContainers"> - <label class="header-name" flex="1">&paneContainers.title;</label> - <button class="help-button" - aria-label="&helpButton.label;"/> -</hbox> - -<!-- Containers --> -<groupbox id="browserContainersGroup" data-category="paneContainers" hidden="true"> - <vbox id="browserContainersbox"> - - <richlistbox id="containersView" orient="vertical" persist="lastSelectedType" - flex="1"> - <listheader equalsize="always"> - <treecol id="typeColumn" label="&label.label;" value="type" - persist="sortDirection" - flex="1" sortDirection="ascending"/> - <treecol id="actionColumn" value="action" - persist="sortDirection" - flex="1"/> - </listheader> - </richlistbox> - </vbox> - <vbox> - <hbox flex="1"> - <button onclick="gContainersPane.onAddButtonClick();" accesskey="&addButton.accesskey;" label="&addButton.label;"/> - </hbox> - </vbox> -</groupbox> diff --git a/browser/components/preferences/in-content/content.js b/browser/components/preferences/in-content/content.js deleted file mode 100644 index a957b1dd5..000000000 --- a/browser/components/preferences/in-content/content.js +++ /dev/null @@ -1,296 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -XPCOMUtils.defineLazyGetter(this, "AlertsServiceDND", function () { - try { - let alertsService = Cc["@mozilla.org/alerts-service;1"] - .getService(Ci.nsIAlertsService) - .QueryInterface(Ci.nsIAlertsDoNotDisturb); - // This will throw if manualDoNotDisturb isn't implemented. - alertsService.manualDoNotDisturb; - return alertsService; - } catch (ex) { - return undefined; - } -}); - -var gContentPane = { - init: function () - { - function setEventListener(aId, aEventType, aCallback) - { - document.getElementById(aId) - .addEventListener(aEventType, aCallback.bind(gContentPane)); - } - - // Initializes the fonts dropdowns displayed in this pane. - this._rebuildFonts(); - var menulist = document.getElementById("defaultFont"); - if (menulist.selectedIndex == -1) { - menulist.value = FontBuilder.readFontSelection(menulist); - } - - // Show translation preferences if we may: - const prefName = "browser.translation.ui.show"; - if (Services.prefs.getBoolPref(prefName)) { - let row = document.getElementById("translationBox"); - row.removeAttribute("hidden"); - // Showing attribution only for Bing Translator. - Components.utils.import("resource:///modules/translation/Translation.jsm"); - if (Translation.translationEngine == "bing") { - document.getElementById("bingAttribution").removeAttribute("hidden"); - } - } - - if (AlertsServiceDND) { - let notificationsDoNotDisturbRow = - document.getElementById("notificationsDoNotDisturbRow"); - notificationsDoNotDisturbRow.removeAttribute("hidden"); - if (AlertsServiceDND.manualDoNotDisturb) { - let notificationsDoNotDisturb = - document.getElementById("notificationsDoNotDisturb"); - notificationsDoNotDisturb.setAttribute("checked", true); - } - } - - setEventListener("font.language.group", "change", - gContentPane._rebuildFonts); - setEventListener("notificationsPolicyButton", "command", - gContentPane.showNotificationExceptions); - setEventListener("popupPolicyButton", "command", - gContentPane.showPopupExceptions); - setEventListener("advancedFonts", "command", - gContentPane.configureFonts); - setEventListener("colors", "command", - gContentPane.configureColors); - setEventListener("chooseLanguage", "command", - gContentPane.showLanguages); - setEventListener("translationAttributionImage", "click", - gContentPane.openTranslationProviderAttribution); - setEventListener("translateButton", "command", - gContentPane.showTranslationExceptions); - setEventListener("notificationsDoNotDisturb", "command", - gContentPane.toggleDoNotDisturbNotifications); - - let notificationInfoURL = - Services.urlFormatter.formatURLPref("app.support.baseURL") + "push"; - document.getElementById("notificationsPolicyLearnMore").setAttribute("href", - notificationInfoURL); - -#ifdef MOZ_EME - let drmInfoURL = - Services.urlFormatter.formatURLPref("app.support.baseURL") + "drm-content"; - document.getElementById("playDRMContentLink").setAttribute("href", drmInfoURL); - let emeUIEnabled = Services.prefs.getBoolPref("browser.eme.ui.enabled"); - // Force-disable/hide on WinXP: - if (navigator.platform.toLowerCase().startsWith("win")) { - emeUIEnabled = emeUIEnabled && parseFloat(Services.sysinfo.get("version")) >= 6; - } - if (!emeUIEnabled) { - // Don't want to rely on .hidden for the toplevel groupbox because - // of the pane hiding/showing code potentially interfering: - document.getElementById("drmGroup").setAttribute("style", "display: none !important"); - } -#endif - }, - - // UTILITY FUNCTIONS - - /** - * Utility function to enable/disable the button specified by aButtonID based - * on the value of the Boolean preference specified by aPreferenceID. - */ - updateButtons: function (aButtonID, aPreferenceID) - { - var button = document.getElementById(aButtonID); - var preference = document.getElementById(aPreferenceID); - button.disabled = preference.value != true; - return undefined; - }, - - // BEGIN UI CODE - - /* - * Preferences: - * - * dom.disable_open_during_load - * - true if popups are blocked by default, false otherwise - */ - - // NOTIFICATIONS - - /** - * Displays the notifications exceptions dialog where specific site notification - * preferences can be set. - */ - showNotificationExceptions() - { - let bundlePreferences = document.getElementById("bundlePreferences"); - let params = { permissionType: "desktop-notification" }; - params.windowTitle = bundlePreferences.getString("notificationspermissionstitle"); - params.introText = bundlePreferences.getString("notificationspermissionstext4"); - - gSubDialog.open("chrome://browser/content/preferences/permissions.xul", - "resizable=yes", params); - - try { - Services.telemetry - .getHistogramById("WEB_NOTIFICATION_EXCEPTIONS_OPENED").add(); - } catch (e) {} - }, - - - // POP-UPS - - /** - * Displays the popup exceptions dialog where specific site popup preferences - * can be set. - */ - showPopupExceptions: function () - { - var bundlePreferences = document.getElementById("bundlePreferences"); - var params = { blockVisible: false, sessionVisible: false, allowVisible: true, - prefilledHost: "", permissionType: "popup" } - params.windowTitle = bundlePreferences.getString("popuppermissionstitle"); - params.introText = bundlePreferences.getString("popuppermissionstext"); - - gSubDialog.open("chrome://browser/content/preferences/permissions.xul", - "resizable=yes", params); - }, - - // FONTS - - /** - * Populates the default font list in UI. - */ - _rebuildFonts: function () - { - var preferences = document.getElementById("contentPreferences"); - // Ensure preferences are "visible" to ensure bindings work. - preferences.hidden = false; - // Force flush: - preferences.clientHeight; - var langGroupPref = document.getElementById("font.language.group"); - this._selectDefaultLanguageGroup(langGroupPref.value, - this._readDefaultFontTypeForLanguage(langGroupPref.value) == "serif"); - }, - - /** - * - */ - _selectDefaultLanguageGroup: function (aLanguageGroup, aIsSerif) - { - const kFontNameFmtSerif = "font.name.serif.%LANG%"; - const kFontNameFmtSansSerif = "font.name.sans-serif.%LANG%"; - const kFontNameListFmtSerif = "font.name-list.serif.%LANG%"; - const kFontNameListFmtSansSerif = "font.name-list.sans-serif.%LANG%"; - const kFontSizeFmtVariable = "font.size.variable.%LANG%"; - - var preferences = document.getElementById("contentPreferences"); - var prefs = [{ format : aIsSerif ? kFontNameFmtSerif : kFontNameFmtSansSerif, - type : "fontname", - element : "defaultFont", - fonttype : aIsSerif ? "serif" : "sans-serif" }, - { format : aIsSerif ? kFontNameListFmtSerif : kFontNameListFmtSansSerif, - type : "unichar", - element : null, - fonttype : aIsSerif ? "serif" : "sans-serif" }, - { format : kFontSizeFmtVariable, - type : "int", - element : "defaultFontSize", - fonttype : null }]; - for (var i = 0; i < prefs.length; ++i) { - var preference = document.getElementById(prefs[i].format.replace(/%LANG%/, aLanguageGroup)); - if (!preference) { - preference = document.createElement("preference"); - var name = prefs[i].format.replace(/%LANG%/, aLanguageGroup); - 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) { - element.setAttribute("preference", preference.id); - - if (prefs[i].fonttype) - FontBuilder.buildFontList(aLanguageGroup, prefs[i].fonttype, element); - - preference.setElementValue(element); - } - } - }, - - /** - * Returns the type of the current default font for the language denoted by - * aLanguageGroup. - */ - _readDefaultFontTypeForLanguage: function (aLanguageGroup) - { - const kDefaultFontType = "font.default.%LANG%"; - var defaultFontTypePref = kDefaultFontType.replace(/%LANG%/, aLanguageGroup); - var preference = document.getElementById(defaultFontTypePref); - if (!preference) { - preference = document.createElement("preference"); - preference.id = defaultFontTypePref; - preference.setAttribute("name", defaultFontTypePref); - preference.setAttribute("type", "string"); - preference.setAttribute("onchange", "gContentPane._rebuildFonts();"); - document.getElementById("contentPreferences").appendChild(preference); - } - return preference.value; - }, - - /** - * Displays the fonts dialog, where web page font names and sizes can be - * configured. - */ - configureFonts: function () - { - gSubDialog.open("chrome://browser/content/preferences/fonts.xul", "resizable=no"); - }, - - /** - * Displays the colors dialog, where default web page/link/etc. colors can be - * configured. - */ - configureColors: function () - { - gSubDialog.open("chrome://browser/content/preferences/colors.xul", "resizable=no"); - }, - - // LANGUAGES - - /** - * Shows a dialog in which the preferred language for web content may be set. - */ - showLanguages: function () - { - gSubDialog.open("chrome://browser/content/preferences/languages.xul"); - }, - - /** - * Displays the translation exceptions dialog where specific site and language - * translation preferences can be set. - */ - showTranslationExceptions: function () - { - gSubDialog.open("chrome://browser/content/preferences/translation.xul"); - }, - - openTranslationProviderAttribution: function () - { - Components.utils.import("resource:///modules/translation/Translation.jsm"); - Translation.openProviderAttribution(); - }, - - toggleDoNotDisturbNotifications: function (event) - { - AlertsServiceDND.manualDoNotDisturb = event.target.checked; - }, -}; diff --git a/browser/components/preferences/in-content/content.xul b/browser/components/preferences/in-content/content.xul deleted file mode 100644 index 9434cba62..000000000 --- a/browser/components/preferences/in-content/content.xul +++ /dev/null @@ -1,213 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<!-- Content panel --> - -<preferences id="contentPreferences" hidden="true" data-category="paneContent"> - -#ifdef MOZ_EME - <!-- DRM content --> - <preference id="media.eme.enabled" - name="media.eme.enabled" - type="bool"/> -#endif - - <!-- Popups --> - <preference id="dom.disable_open_during_load" - name="dom.disable_open_during_load" - type="bool"/> - - <!-- Fonts --> - <preference id="font.language.group" - name="font.language.group" - type="wstring"/> - - <!-- Languages --> - <preference id="browser.translation.detectLanguage" - name="browser.translation.detectLanguage" - type="bool"/> -</preferences> - -<script type="application/javascript" - src="chrome://mozapps/content/preferences/fontbuilder.js"/> -<script type="application/javascript" - src="chrome://browser/content/preferences/in-content/content.js"/> - -<hbox id="header-content" - class="header" - hidden="true" - data-category="paneContent"> - <label class="header-name" flex="1">&paneContent.title;</label> - <html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a> -</hbox> - -#ifdef MOZ_EME -<groupbox id="drmGroup" data-category="paneContent" hidden="true"> - <caption><label>&drmContent.label;</label></caption> - <grid id="contentGrid2"> - <columns> - <column flex="1"/> - <column/> - </columns> - <rows id="contentRows-2"> - <row id="playDRMContentRow"> - <vbox align="start"> - <checkbox id="playDRMContent" preference="media.eme.enabled" - label="&playDRMContent.label;" accesskey="&playDRMContent.accesskey;"/> - </vbox> - <hbox pack="end" align="center"> - <label id="playDRMContentLink" class="text-link" value="&playDRMContent.learnMore.label;"/> - </hbox> - </row> - </rows> - </grid> -</groupbox> -#endif - -<groupbox id="notificationsGroup" data-category="paneContent" hidden="true"> - <caption><label>¬ificationsPolicy.label;</label></caption> - <grid> - <columns> - <column flex="1"/> - <column/> - </columns> - <rows> - <row id="notificationsPolicyRow" align="center"> - <hbox align="start"> - <label id="notificationsPolicy">¬ificationsPolicyDesc3.label;</label> - <label id="notificationsPolicyLearnMore" - class="text-link" - value="¬ificationsPolicyLearnMore.label;"/> - </hbox> - <hbox pack="end"> - <button id="notificationsPolicyButton" label="¬ificationsPolicyButton.label;" - accesskey="¬ificationsPolicyButton.accesskey;"/> - </hbox> - </row> - <row id="notificationsDoNotDisturbRow" hidden="true"> - <vbox align="start"> - <checkbox id="notificationsDoNotDisturb" label="¬ificationsDoNotDisturb.label;" - accesskey="¬ificationsDoNotDisturb.accesskey;"/> - <label id="notificationsDoNotDisturbDetails" - class="indent" - value="¬ificationsDoNotDisturbDetails.value;"/> - </vbox> - </row> - </rows> - </grid> -</groupbox> - -<groupbox id="miscGroup" data-category="paneContent" hidden="true"> - <caption><label>&popups.label;</label></caption> - <grid id="contentGrid"> - <columns> - <column flex="1"/> - <column/> - </columns> - <rows id="contentRows-1"> - <row id="popupPolicyRow"> - <vbox align="start"> - <checkbox id="popupPolicy" preference="dom.disable_open_during_load" - label="&blockPopups.label;" accesskey="&blockPopups.accesskey;" - onsyncfrompreference="return gContentPane.updateButtons('popupPolicyButton', - 'dom.disable_open_during_load');"/> - </vbox> - <hbox pack="end"> - <button id="popupPolicyButton" label="&popupExceptions.label;" - accesskey="&popupExceptions.accesskey;"/> - </hbox> - </row> - </rows> - </grid> -</groupbox> - -<!-- Fonts and Colors --> -<groupbox id="fontsGroup" data-category="paneContent" hidden="true"> - <caption><label>&fontsAndColors.label;</label></caption> - - <grid id="fontsGrid"> - <columns> - <column flex="1"/> - <column/> - </columns> - <rows id="fontsRows"> - <row id="fontRow"> - <hbox align="center"> - <label control="defaultFont" accesskey="&defaultFont.accesskey;">&defaultFont.label;</label> - <menulist id="defaultFont" delayprefsave="true"/> - <label id="defaultFontSizeLabel" control="defaultFontSize" accesskey="&defaultSize.accesskey;">&defaultSize.label;</label> - <menulist id="defaultFontSize" delayprefsave="true"> - <menupopup> - <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> - </hbox> - <button id="advancedFonts" icon="select-font" - label="&advancedFonts.label;" - accesskey="&advancedFonts.accesskey;"/> - </row> - <row id="colorsRow"> - <hbox/> - <button id="colors" icon="select-color" - label="&colors.label;" - accesskey="&colors.accesskey;"/> - </row> - </rows> - </grid> -</groupbox> - -<!-- Languages --> -<groupbox id="languagesGroup" data-category="paneContent" hidden="true"> - <caption><label>&languages.label;</label></caption> - - <hbox id="languagesBox" align="center"> - <description flex="1" control="chooseLanguage">&chooseLanguage.label;</description> - <button id="chooseLanguage" - label="&chooseButton.label;" - accesskey="&chooseButton.accesskey;"/> - </hbox> - - <hbox id="translationBox" hidden="true"> - <hbox align="center" flex="1"> - <checkbox id="translate" preference="browser.translation.detectLanguage" - label="&translateWebPages.label;." accesskey="&translateWebPages.accesskey;" - onsyncfrompreference="return gContentPane.updateButtons('translateButton', - 'browser.translation.detectLanguage');"/> - <hbox id="bingAttribution" hidden="true"> - <label>&translation.options.attribution.beforeLogo;</label> - <separator orient="vertical" class="thin"/> - <image id="translationAttributionImage" aria-label="Microsoft Translator" - src="chrome://browser/content/microsoft-translator-attribution.png"/> - <separator orient="vertical" class="thin"/> - <label>&translation.options.attribution.afterLogo;</label> - </hbox> - </hbox> - <button id="translateButton" label="&translateExceptions.label;" - accesskey="&translateExceptions.accesskey;"/> - </hbox> -</groupbox> diff --git a/browser/components/preferences/in-content/jar.mn b/browser/components/preferences/in-content/jar.mn deleted file mode 100644 index 130bf8549..000000000 --- a/browser/components/preferences/in-content/jar.mn +++ /dev/null @@ -1,18 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -browser.jar: - content/browser/preferences/in-content/preferences.js -* content/browser/preferences/in-content/preferences.xul - content/browser/preferences/in-content/subdialogs.js - - content/browser/preferences/in-content/main.js - content/browser/preferences/in-content/privacy.js - content/browser/preferences/in-content/containers.js - content/browser/preferences/in-content/advanced.js - content/browser/preferences/in-content/applications.js -* content/browser/preferences/in-content/content.js - content/browser/preferences/in-content/sync.js -* content/browser/preferences/in-content/security.js - content/browser/preferences/in-content/search.js diff --git a/browser/components/preferences/in-content/main.js b/browser/components/preferences/in-content/main.js deleted file mode 100644 index bac771bec..000000000 --- a/browser/components/preferences/in-content/main.js +++ /dev/null @@ -1,667 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -Components.utils.import("resource://gre/modules/Downloads.jsm"); -Components.utils.import("resource://gre/modules/FileUtils.jsm"); -Components.utils.import("resource://gre/modules/Task.jsm"); -Components.utils.import("resource:///modules/ShellService.jsm"); -Components.utils.import("resource:///modules/TransientPrefs.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); - -var gMainPane = { - /** - * Initialization of this. - */ - init: function () - { - function setEventListener(aId, aEventType, aCallback) - { - document.getElementById(aId) - .addEventListener(aEventType, aCallback.bind(gMainPane)); - } - - if (AppConstants.HAVE_SHELL_SERVICE) { - this.updateSetDefaultBrowser(); - if (AppConstants.platform == "win") { - // In Windows 8 we launch the control panel since it's the only - // way to get all file type association prefs. So we don't know - // when the user will select the default. We refresh here periodically - // in case the default changes. On other Windows OS's defaults can also - // be set while the prefs are open. - window.setInterval(this.updateSetDefaultBrowser.bind(this), 1000); - } - } - - // set up the "use current page" label-changing listener - this._updateUseCurrentButton(); - window.addEventListener("focus", this._updateUseCurrentButton.bind(this), false); - - this.updateBrowserStartupLastSession(); - - if (AppConstants.platform == "win") { - // Functionality for "Show tabs in taskbar" on Windows 7 and up. - try { - let sysInfo = Cc["@mozilla.org/system-info;1"]. - getService(Ci.nsIPropertyBag2); - let ver = parseFloat(sysInfo.getProperty("version")); - let showTabsInTaskbar = document.getElementById("showTabsInTaskbar"); - showTabsInTaskbar.hidden = ver < 6.1; - } catch (ex) {} - } - - // The "closing multiple tabs" and "opening multiple tabs might slow down - // &brandShortName;" warnings provide options for not showing these - // warnings again. When the user disabled them, we provide checkboxes to - // re-enable the warnings. - if (!TransientPrefs.prefShouldBeVisible("browser.tabs.warnOnClose")) - document.getElementById("warnCloseMultiple").hidden = true; - if (!TransientPrefs.prefShouldBeVisible("browser.tabs.warnOnOpen")) - document.getElementById("warnOpenMany").hidden = true; - - setEventListener("browser.privatebrowsing.autostart", "change", - gMainPane.updateBrowserStartupLastSession); - setEventListener("browser.download.dir", "change", - gMainPane.displayDownloadDirPref); - if (AppConstants.HAVE_SHELL_SERVICE) { - setEventListener("setDefaultButton", "command", - gMainPane.setDefaultBrowser); - } - setEventListener("useCurrent", "command", - gMainPane.setHomePageToCurrent); - setEventListener("useBookmark", "command", - gMainPane.setHomePageToBookmark); - setEventListener("restoreDefaultHomePage", "command", - gMainPane.restoreDefaultHomePage); - setEventListener("chooseFolder", "command", - gMainPane.chooseFolder); - - if (AppConstants.MOZ_DEV_EDITION) { - let uAppData = OS.Constants.Path.userApplicationDataDir; - let ignoreSeparateProfile = OS.Path.join(uAppData, "ignore-dev-edition-profile"); - - setEventListener("separateProfileMode", "command", gMainPane.separateProfileModeChange); - let separateProfileModeCheckbox = document.getElementById("separateProfileMode"); - setEventListener("getStarted", "click", gMainPane.onGetStarted); - - OS.File.stat(ignoreSeparateProfile).then(() => separateProfileModeCheckbox.checked = false, - () => separateProfileModeCheckbox.checked = true); - } - - // Notify observers that the UI is now ready - Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService) - .notifyObservers(window, "main-pane-loaded", null); - }, - - enableE10SChange: function () - { - // **STUB** - }, - - separateProfileModeChange: function () - { - if (AppConstants.MOZ_DEV_EDITION) { - function quitApp() { - Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestartNotSameProfile); - } - function revertCheckbox(error) { - separateProfileModeCheckbox.checked = !separateProfileModeCheckbox.checked; - if (error) { - Cu.reportError("Failed to toggle separate profile mode: " + error); - } - } - function createOrRemoveSpecialDevEditionFile(onSuccess) { - let uAppData = OS.Constants.Path.userApplicationDataDir; - let ignoreSeparateProfile = OS.Path.join(uAppData, "ignore-dev-edition-profile"); - - if (separateProfileModeCheckbox.checked) { - OS.File.remove(ignoreSeparateProfile).then(onSuccess, revertCheckbox); - } else { - OS.File.writeAtomic(ignoreSeparateProfile, new Uint8Array()).then(onSuccess, revertCheckbox); - } - } - - let separateProfileModeCheckbox = document.getElementById("separateProfileMode"); - let button_index = confirmRestartPrompt(separateProfileModeCheckbox.checked, - 0, false, true); - switch (button_index) { - case CONFIRM_RESTART_PROMPT_CANCEL: - revertCheckbox(); - return; - case CONFIRM_RESTART_PROMPT_RESTART_NOW: - const Cc = Components.classes, Ci = Components.interfaces; - let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] - .createInstance(Ci.nsISupportsPRBool); - Services.obs.notifyObservers(cancelQuit, "quit-application-requested", - "restart"); - if (!cancelQuit.data) { - createOrRemoveSpecialDevEditionFile(quitApp); - return; - } - - // Revert the checkbox in case we didn't quit - revertCheckbox(); - return; - case CONFIRM_RESTART_PROMPT_RESTART_LATER: - createOrRemoveSpecialDevEditionFile(); - return; - } - } - }, - - onGetStarted: function (aEvent) { - if (AppConstants.MOZ_DEV_EDITION) { - const Cc = Components.classes, Ci = Components.interfaces; - let wm = Cc["@mozilla.org/appshell/window-mediator;1"] - .getService(Ci.nsIWindowMediator); - let win = wm.getMostRecentWindow("navigator:browser"); - - if (win) { - let accountsTab = win.gBrowser.addTab("about:accounts?action=signin&entrypoint=dev-edition-setup"); - win.gBrowser.selectedTab = accountsTab; - } - } - }, - - // HOME PAGE - - /* - * Preferences: - * - * browser.startup.homepage - * - the user's home page, as a string; if the home page is a set of tabs, - * this will be those URLs separated by the pipe character "|" - * browser.startup.page - * - what page(s) to show when the user starts the application, as an integer: - * - * 0: a blank page - * 1: the home page (as set by the browser.startup.homepage pref) - * 2: the last page the user visited (DEPRECATED) - * 3: windows and tabs from the last session (a.k.a. session restore) - * - * The deprecated option is not exposed in UI; however, if the user has it - * selected and doesn't change the UI for this preference, the deprecated - * option is preserved. - */ - - syncFromHomePref: function () - { - let homePref = document.getElementById("browser.startup.homepage"); - - // If the pref is set to about:home or about:newtab, set the value to "" - // to show the placeholder text (about:home title) rather than - // exposing those URLs to users. - let defaultBranch = Services.prefs.getDefaultBranch(""); - let defaultValue = defaultBranch.getComplexValue("browser.startup.homepage", - Ci.nsIPrefLocalizedString).data; - let currentValue = homePref.value.toLowerCase(); - if (currentValue == "about:home" || - (currentValue == defaultValue && currentValue == "about:newtab")) { - return ""; - } - - // If the pref is actually "", show about:blank. The actual home page - // loading code treats them the same, and we don't want the placeholder text - // to be shown. - if (homePref.value == "") - return "about:blank"; - - // Otherwise, show the actual pref value. - return undefined; - }, - - syncToHomePref: function (value) - { - // If the value is "", use about:home. - if (value == "") - return "about:home"; - - // Otherwise, use the actual textbox value. - return undefined; - }, - - /** - * Sets the home page to the current displayed page (or frontmost tab, if the - * most recent browser window contains multiple tabs), updating preference - * window UI to reflect this. - */ - setHomePageToCurrent: function () - { - let homePage = document.getElementById("browser.startup.homepage"); - let tabs = this._getTabsForHomePage(); - function getTabURI(t) { - return t.linkedBrowser.currentURI.spec; - } - - // FIXME Bug 244192: using dangerous "|" joiner! - if (tabs.length) - homePage.value = tabs.map(getTabURI).join("|"); - }, - - /** - * Displays a dialog in which the user can select a bookmark to use as home - * page. If the user selects a bookmark, that bookmark's name is displayed in - * UI and the bookmark's address is stored to the home page preference. - */ - setHomePageToBookmark: function () - { - var rv = { urls: null, names: null }; - gSubDialog.open("chrome://browser/content/preferences/selectBookmark.xul", - "resizable=yes, modal=yes", rv, - this._setHomePageToBookmarkClosed.bind(this, rv)); - }, - - _setHomePageToBookmarkClosed: function(rv, aEvent) { - if (aEvent.detail.button != "accept") - return; - if (rv.urls && rv.names) { - var homePage = document.getElementById("browser.startup.homepage"); - - // XXX still using dangerous "|" joiner! - homePage.value = rv.urls.join("|"); - } - }, - - /** - * Switches the "Use Current Page" button between its singular and plural - * forms. - */ - _updateUseCurrentButton: function () { - let useCurrent = document.getElementById("useCurrent"); - - - let tabs = this._getTabsForHomePage(); - - if (tabs.length > 1) - useCurrent.label = useCurrent.getAttribute("label2"); - else - useCurrent.label = useCurrent.getAttribute("label1"); - - // In this case, the button's disabled state is set by preferences.xml. - let prefName = "pref.browser.homepage.disable_button.current_page"; - if (document.getElementById(prefName).locked) - return; - - useCurrent.disabled = !tabs.length - }, - - _getTabsForHomePage: function () - { - var win; - var tabs = []; - - const Cc = Components.classes, Ci = Components.interfaces; - var wm = Cc["@mozilla.org/appshell/window-mediator;1"] - .getService(Ci.nsIWindowMediator); - win = wm.getMostRecentWindow("navigator:browser"); - - if (win && win.document.documentElement - .getAttribute("windowtype") == "navigator:browser") { - // We should only include visible & non-pinned tabs - - tabs = win.gBrowser.visibleTabs.slice(win.gBrowser._numPinnedTabs); - tabs = tabs.filter(this.isNotAboutPreferences); - } - - return tabs; - }, - - /** - * Check to see if a tab is not about:preferences - */ - isNotAboutPreferences: function (aElement, aIndex, aArray) - { - return !aElement.linkedBrowser.currentURI.spec.startsWith("about:preferences"); - }, - - /** - * Restores the default home page as the user's home page. - */ - restoreDefaultHomePage: function () - { - var homePage = document.getElementById("browser.startup.homepage"); - homePage.value = homePage.defaultValue; - }, - - // DOWNLOADS - - /* - * Preferences: - * - * browser.download.useDownloadDir - bool - * True - Save files directly to the folder configured via the - * browser.download.folderList preference. - * False - Always ask the user where to save a file and default to - * browser.download.lastDir when displaying a folder picker dialog. - * browser.download.dir - local file handle - * A local folder the user may have selected for downloaded files to be - * saved. Migration of other browser settings may also set this path. - * This folder is enabled when folderList equals 2. - * browser.download.lastDir - local file handle - * May contain the last folder path accessed when the user browsed - * via the file save-as dialog. (see contentAreaUtils.js) - * browser.download.folderList - int - * Indicates the location users wish to save downloaded files too. - * It is also used to display special file labels when the default - * download location is either the Desktop or the Downloads folder. - * Values: - * 0 - The desktop is the default download location. - * 1 - The system's downloads folder is the default download location. - * 2 - The default download location is elsewhere as specified in - * browser.download.dir. - * browser.download.downloadDir - * deprecated. - * browser.download.defaultFolder - * deprecated. - */ - - /** - * Enables/disables the folder field and Browse button based on whether a - * default download directory is being used. - */ - readUseDownloadDir: function () - { - var downloadFolder = document.getElementById("downloadFolder"); - var chooseFolder = document.getElementById("chooseFolder"); - var preference = document.getElementById("browser.download.useDownloadDir"); - downloadFolder.disabled = !preference.value || preference.locked; - chooseFolder.disabled = !preference.value || preference.locked; - - // don't override the preference's value in UI - return undefined; - }, - - /** - * 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. - */ - chooseFolder() - { - return this.chooseFolderTask().catch(Components.utils.reportError); - }, - chooseFolderTask: Task.async(function* () - { - let bundlePreferences = document.getElementById("bundlePreferences"); - let title = bundlePreferences.getString("chooseDownloadFolderTitle"); - let folderListPref = document.getElementById("browser.download.folderList"); - let currentDirPref = yield this._indexToFolder(folderListPref.value); - let defDownloads = yield this._indexToFolder(1); - let fp = Components.classes["@mozilla.org/filepicker;1"]. - createInstance(Components.interfaces.nsIFilePicker); - - fp.init(window, title, Components.interfaces.nsIFilePicker.modeGetFolder); - fp.appendFilters(Components.interfaces.nsIFilePicker.filterAll); - // First try to open what's currently configured - if (currentDirPref && currentDirPref.exists()) { - fp.displayDirectory = currentDirPref; - } // Try the system's download dir - else if (defDownloads && defDownloads.exists()) { - fp.displayDirectory = defDownloads; - } // Fall back to Desktop - else { - fp.displayDirectory = yield this._indexToFolder(0); - } - - let result = yield new Promise(resolve => fp.open(resolve)); - if (result != Components.interfaces.nsIFilePicker.returnOK) { - return; - } - - let downloadDirPref = document.getElementById("browser.download.dir"); - downloadDirPref.value = fp.file; - folderListPref.value = yield this._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. - */ - displayDownloadDirPref() - { - this.displayDownloadDirPrefTask().catch(Components.utils.reportError); - - // don't override the preference's value in UI - return undefined; - }, - - displayDownloadDirPrefTask: Task.async(function* () - { - var folderListPref = document.getElementById("browser.download.folderList"); - var bundlePreferences = document.getElementById("bundlePreferences"); - var downloadFolder = document.getElementById("downloadFolder"); - var currentDirPref = document.getElementById("browser.download.dir"); - - // Used in defining the correct path to the folder icon. - var ios = Components.classes["@mozilla.org/network/io-service;1"] - .getService(Components.interfaces.nsIIOService); - var fph = ios.getProtocolHandler("file") - .QueryInterface(Components.interfaces.nsIFileProtocolHandler); - var iconUrlSpec; - - // Display a 'pretty' label or the path in the UI. - if (folderListPref.value == 2) { - // Custom path selected and is configured - downloadFolder.label = this._getDisplayNameOfFile(currentDirPref.value); - iconUrlSpec = fph.getURLSpecFromFile(currentDirPref.value); - } else if (folderListPref.value == 1) { - // 'Downloads' - // In 1.5, this pointed to a folder we created called 'My Downloads' - // and was available as an option in the 1.5 drop down. On XP this - // was in My Documents, on OSX it was in User Docs. In 2.0, we did - // away with the drop down option, although the special label was - // still supported for the folder if it existed. Because it was - // not exposed it was rarely used. - // With 3.0, a new desktop folder - 'Downloads' was introduced for - // platforms and versions that don't support a default system downloads - // folder. See nsDownloadManager for details. - downloadFolder.label = bundlePreferences.getString("downloadsFolderName"); - iconUrlSpec = fph.getURLSpecFromFile(yield this._indexToFolder(1)); - } else { - // 'Desktop' - downloadFolder.label = bundlePreferences.getString("desktopFolderName"); - iconUrlSpec = fph.getURLSpecFromFile(yield this._getDownloadsFolder("Desktop")); - } - downloadFolder.image = "moz-icon://" + iconUrlSpec + "?size=16"; - }), - - /** - * Returns the textual path of a folder in readable form. - */ - _getDisplayNameOfFile: function (aFolder) - { - // TODO: would like to add support for 'Downloads on Macintosh HD' - // for OS X users. - return aFolder ? aFolder.path : ""; - }, - - /** - * 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" - */ - _getDownloadsFolder: Task.async(function* (aFolder) - { - switch (aFolder) { - case "Desktop": - var fileLoc = Components.classes["@mozilla.org/file/directory_service;1"] - .getService(Components.interfaces.nsIProperties); - return fileLoc.get("Desk", Components.interfaces.nsILocalFile); - case "Downloads": - let downloadsDir = yield 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 - * 0 if aFolder is the Desktop or is unspecified, - * 1 if aFolder is the Downloads folder, - * 2 otherwise - */ - _folderToIndex: Task.async(function* (aFolder) - { - if (!aFolder || aFolder.equals(yield this._getDownloadsFolder("Desktop"))) - return 0; - else if (aFolder.equals(yield this._getDownloadsFolder("Downloads"))) - return 1; - return 2; - }), - - /** - * Converts an integer into the corresponding folder. - * - * @param aIndex - * an integer - * @returns the Desktop folder if aIndex == 0, - * the Downloads folder if aIndex == 1, - * the folder stored in browser.download.dir - */ - _indexToFolder: Task.async(function* (aIndex) - { - switch (aIndex) { - case 0: - return yield this._getDownloadsFolder("Desktop"); - case 1: - return yield this._getDownloadsFolder("Downloads"); - } - var currentDirPref = document.getElementById("browser.download.dir"); - return currentDirPref.value; - }), - - /** - * Hide/show the "Show my windows and tabs from last time" option based - * on the value of the browser.privatebrowsing.autostart pref. - */ - updateBrowserStartupLastSession: function() - { - let pbAutoStartPref = document.getElementById("browser.privatebrowsing.autostart"); - let startupPref = document.getElementById("browser.startup.page"); - let menu = document.getElementById("browserStartupPage"); - let option = document.getElementById("browserStartupLastSession"); - if (pbAutoStartPref.value) { - option.setAttribute("disabled", "true"); - if (option.selected) { - menu.selectedItem = document.getElementById("browserStartupHomePage"); - } - } else { - option.removeAttribute("disabled"); - startupPref.updateElements(); // select the correct index in the startup menulist - } - }, - - // TABS - - /* - * Preferences: - * - * browser.link.open_newwindow - int - * Determines where links targeting new windows should open. - * Values: - * 1 - Open in the current window or tab. - * 2 - Open in a new window. - * 3 - Open in a new tab in the most recent window. - * browser.tabs.loadInBackground - bool - * True - Whether browser should switch to a new tab opened from a link. - * browser.tabs.warnOnClose - bool - * True - If when closing a window with multiple tabs the user is warned and - * allowed to cancel the action, false to just close the window. - * browser.tabs.warnOnOpen - bool - * True - Whether the user should be warned when trying to open a lot of - * tabs at once (e.g. a large folder of bookmarks), allowing to - * cancel the action. - * browser.taskbar.previews.enable - bool - * True - Tabs are to be shown in Windows 7 taskbar. - * False - Only the window is to be shown in Windows 7 taskbar. - */ - - /** - * Determines where a link which opens a new window will open. - * - * @returns |true| if such links should be opened in new tabs - */ - readLinkTarget: function() { - var openNewWindow = document.getElementById("browser.link.open_newwindow"); - return openNewWindow.value != 2; - }, - - /** - * Determines where a link which opens a new window will open. - * - * @returns 2 if such links should be opened in new windows, - * 3 if such links should be opened in new tabs - */ - writeLinkTarget: function() { - var linkTargeting = document.getElementById("linkTargeting"); - return linkTargeting.checked ? 3 : 2; - }, - /* - * Preferences: - * - * browser.shell.checkDefault - * - true if a default-browser check (and prompt to make it so if necessary) - * occurs at startup, false otherwise - */ - - /** - * Show button for setting browser as default browser or information that - * browser is already the default browser. - */ - updateSetDefaultBrowser: function() - { - if (AppConstants.HAVE_SHELL_SERVICE) { - let shellSvc = getShellService(); - let defaultBrowserBox = document.getElementById("defaultBrowserBox"); - if (!shellSvc) { - defaultBrowserBox.hidden = true; - return; - } - let setDefaultPane = document.getElementById("setDefaultPane"); - let isDefault = shellSvc.isDefaultBrowser(false, true); - setDefaultPane.selectedIndex = isDefault ? 1 : 0; - let alwaysCheck = document.getElementById("alwaysCheckDefault"); - alwaysCheck.disabled = alwaysCheck.disabled || - isDefault && alwaysCheck.checked; - } - }, - - /** - * Set browser as the operating system default browser. - */ - setDefaultBrowser: function() - { - if (AppConstants.HAVE_SHELL_SERVICE) { - let alwaysCheckPref = document.getElementById("browser.shell.checkDefaultBrowser"); - alwaysCheckPref.value = true; - - let shellSvc = getShellService(); - if (!shellSvc) - return; - try { - shellSvc.setDefaultBrowser(true, false); - } catch (ex) { - Cu.reportError(ex); - return; - } - - let selectedIndex = shellSvc.isDefaultBrowser(false, true) ? 1 : 0; - document.getElementById("setDefaultPane").selectedIndex = selectedIndex; - } - }, -}; diff --git a/browser/components/preferences/in-content/main.xul b/browser/components/preferences/in-content/main.xul deleted file mode 100644 index 8eca11877..000000000 --- a/browser/components/preferences/in-content/main.xul +++ /dev/null @@ -1,284 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<!-- General panel --> - -<script type="application/javascript" - src="chrome://browser/content/preferences/in-content/main.js"/> - -<preferences id="mainPreferences" hidden="true" data-category="paneGeneral"> - - <!-- Startup --> - <preference id="browser.startup.page" - name="browser.startup.page" - type="int"/> - <preference id="browser.startup.homepage" - name="browser.startup.homepage" - type="wstring"/> - -#ifdef HAVE_SHELL_SERVICE - <preference id="browser.shell.checkDefaultBrowser" - name="browser.shell.checkDefaultBrowser" - type="bool"/> - - <preference id="pref.general.disable_button.default_browser" - name="pref.general.disable_button.default_browser" - type="bool"/> -#endif - - <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.bookmark_page" - name="pref.browser.homepage.disable_button.bookmark_page" - type="bool"/> - <preference id="pref.browser.homepage.disable_button.restore_default" - name="pref.browser.homepage.disable_button.restore_default" - type="bool"/> - - <preference id="browser.privatebrowsing.autostart" - name="browser.privatebrowsing.autostart" - type="bool"/> - - <!-- Downloads --> - <preference id="browser.download.useDownloadDir" - name="browser.download.useDownloadDir" - type="bool"/> - - <preference id="browser.download.folderList" - name="browser.download.folderList" - type="int"/> - <preference id="browser.download.dir" - name="browser.download.dir" - type="file"/> - <!-- Tab preferences - Preferences: - - browser.link.open_newwindow - 1 opens such links in the most recent window or tab, - 2 opens such links in a new window, - 3 opens such links in a new tab - browser.tabs.loadInBackground - - true if display should switch to a new tab which has been opened from a - link, false if display shouldn't switch - browser.tabs.warnOnClose - - true if when closing a window with multiple tabs the user is warned and - allowed to cancel the action, false to just close the window - browser.tabs.warnOnOpen - - true if the user should be warned if he attempts to open a lot of tabs at - once (e.g. a large folder of bookmarks), false otherwise - browser.taskbar.previews.enable - - true if tabs are to be shown in the Windows 7 taskbar - --> - - <preference id="browser.link.open_newwindow" - name="browser.link.open_newwindow" - type="int"/> - <preference id="browser.tabs.loadInBackground" - name="browser.tabs.loadInBackground" - type="bool" - inverted="true"/> - <preference id="browser.tabs.warnOnClose" - name="browser.tabs.warnOnClose" - type="bool"/> - <preference id="browser.tabs.warnOnOpen" - name="browser.tabs.warnOnOpen" - type="bool"/> - <preference id="browser.sessionstore.restore_on_demand" - name="browser.sessionstore.restore_on_demand" - type="bool"/> -#ifdef XP_WIN - <preference id="browser.taskbar.previews.enable" - name="browser.taskbar.previews.enable" - type="bool"/> -#endif - <preference id="browser.ctrlTab.previews" - name="browser.ctrlTab.previews" - type="bool"/> -</preferences> - -<hbox id="header-general" - class="header" - hidden="true" - data-category="paneGeneral"> - <label class="header-name" flex="1">&paneGeneral.title;</label> - <html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a> -</hbox> - -<!-- Startup --> -<groupbox id="startupGroup" - data-category="paneGeneral" - hidden="true"> - <caption><label>&startup.label;</label></caption> - -#ifdef MOZ_DEV_EDITION - <vbox id="separateProfileBox"> - <checkbox id="separateProfileMode" - label="&separateProfileMode.label;"/> - <hbox align="center" class="indent"> - <label id="useFirefoxSync">&useFirefoxSync.label;</label> - <label id="getStarted" class="text-link">&getStarted.label;</label> - </hbox> - </vbox> -#endif - -#ifdef HAVE_SHELL_SERVICE - <vbox id="defaultBrowserBox"> - <hbox align="center"> - <checkbox id="alwaysCheckDefault" preference="browser.shell.checkDefaultBrowser" - label="&alwaysCheckDefault2.label;" accesskey="&alwaysCheckDefault2.accesskey;"/> - </hbox> - <deck id="setDefaultPane"> - <hbox align="center" class="indent"> - <label id="isNotDefaultLabel" flex="1">&isNotDefault.label;</label> - <button id="setDefaultButton" - label="&setAsMyDefaultBrowser2.label;" accesskey="&setAsMyDefaultBrowser2.accesskey;" - preference="pref.general.disable_button.default_browser"/> - </hbox> - <hbox align="center" class="indent"> - <label id="isDefaultLabel" flex="1">&isDefault.label;</label> - </hbox> - </deck> - <separator class="thin"/> - </vbox> -#endif - - <html:table id="startupTable"> - <html:tr> - <html:td class="label-cell"> - <label accesskey="&startupPage.accesskey;" - control="browserStartupPage">&startupPage.label;</label> - </html:td> - <html:td class="content-cell"> - <menulist id="browserStartupPage" - class="content-cell-item" - preference="browser.startup.page"> - <menupopup> - <menuitem label="&startupHomePage.label;" - value="1" - id="browserStartupHomePage"/> - <menuitem label="&startupBlankPage.label;" - value="0" - id="browserStartupBlank"/> - <menuitem label="&startupLastSession.label;" - value="3" - id="browserStartupLastSession"/> - </menupopup> - </menulist> - </html:td> - </html:tr> - <html:tr> - <html:td class="label-cell"> - <label accesskey="&homepage.accesskey;" - control="browserHomePage">&homepage.label;</label> - </html:td> - <html:td class="content-cell"> - <textbox id="browserHomePage" - class="padded uri-element content-cell-item" - type="autocomplete" - autocompletesearch="unifiedcomplete" - onsyncfrompreference="return gMainPane.syncFromHomePref();" - onsynctopreference="return gMainPane.syncToHomePref(this.value);" - placeholder="&abouthome.pageTitle;" - preference="browser.startup.homepage"/> - </html:td> - </html:tr> - <html:tr> - <html:td class="label-cell" /> - <html:td class="content-cell homepage-buttons"> - <button id="useCurrent" - class="content-cell-item" - label="" - accesskey="&useCurrentPage.accesskey;" - label1="&useCurrentPage.label;" - label2="&useMultiple.label;" - preference="pref.browser.homepage.disable_button.current_page"/> - <button id="useBookmark" - class="content-cell-item" - label="&chooseBookmark.label;" - accesskey="&chooseBookmark.accesskey;" - preference="pref.browser.homepage.disable_button.bookmark_page"/> - <button id="restoreDefaultHomePage" - class="content-cell-item" - label="&restoreDefault.label;" - accesskey="&restoreDefault.accesskey;" - preference="pref.browser.homepage.disable_button.restore_default"/> - </html:td> - </html:tr> - </html:table> -</groupbox> - -<!-- Downloads --> -<groupbox id="downloadsGroup" - data-category="paneGeneral" - hidden="true"> - <caption><label>&downloads.label;</label></caption> - - <radiogroup id="saveWhere" - preference="browser.download.useDownloadDir" - onsyncfrompreference="return gMainPane.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.folderList" - preference-editable="true" - aria-labelledby="saveTo" - onsyncfrompreference="return gMainPane.displayDownloadDirPref();"/> - <button id="chooseFolder" -#ifdef XP_MACOSX - accesskey="&chooseFolderMac.accesskey;" - label="&chooseFolderMac.label;" -#else - accesskey="&chooseFolderWin.accesskey;" - label="&chooseFolderWin.label;" -#endif - /> - </hbox> - <hbox> - <radio id="alwaysAsk" - value="false" - label="&alwaysAsk.label;" - accesskey="&alwaysAsk.accesskey;"/> - </hbox> - </radiogroup> -</groupbox> - -<!-- Tab preferences --> -<groupbox data-category="paneGeneral" - hidden="true" align="start"> - <caption><label>&tabsGroup.label;</label></caption> - - <checkbox id="ctrlTabRecentlyUsedOrder" label="&ctrlTabRecentlyUsedOrder.label;" - accesskey="&ctrlTabRecentlyUsedOrder.accesskey;" - preference="browser.ctrlTab.previews"/> - - <checkbox id="linkTargeting" label="&newWindowsAsTabs.label;" - accesskey="&newWindowsAsTabs.accesskey;" - preference="browser.link.open_newwindow" - onsyncfrompreference="return gMainPane.readLinkTarget();" - onsynctopreference="return gMainPane.writeLinkTarget();"/> - - <checkbox id="warnCloseMultiple" label="&warnCloseMultipleTabs.label;" - accesskey="&warnCloseMultipleTabs.accesskey;" - preference="browser.tabs.warnOnClose"/> - - <checkbox id="warnOpenMany" label="&warnOpenManyTabs.label;" - accesskey="&warnOpenManyTabs.accesskey;" - preference="browser.tabs.warnOnOpen"/> - - <checkbox id="switchToNewTabs" label="&switchToNewTabs.label;" - accesskey="&switchToNewTabs.accesskey;" - preference="browser.tabs.loadInBackground"/> - -#ifdef XP_WIN - <checkbox id="showTabsInTaskbar" label="&showTabsInTaskbar.label;" - accesskey="&showTabsInTaskbar.accesskey;" - preference="browser.taskbar.previews.enable"/> -#endif -</groupbox> diff --git a/browser/components/preferences/in-content/moz.build b/browser/components/preferences/in-content/moz.build deleted file mode 100644 index 08a75bcf7..000000000 --- a/browser/components/preferences/in-content/moz.build +++ /dev/null @@ -1,13 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'): - DEFINES[var] = CONFIG[var] - -if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'): - DEFINES['HAVE_SHELL_SERVICE'] = 1 - -JAR_MANIFESTS += ['jar.mn'] diff --git a/browser/components/preferences/in-content/preferences.js b/browser/components/preferences/in-content/preferences.js deleted file mode 100644 index e18ab4b04..000000000 --- a/browser/components/preferences/in-content/preferences.js +++ /dev/null @@ -1,315 +0,0 @@ -/* - This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this file, - - You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// Import globals from the files imported by the .xul files. -/* import-globals-from subdialogs.js */ -/* import-globals-from advanced.js */ -/* import-globals-from main.js */ -/* import-globals-from search.js */ -/* import-globals-from content.js */ -/* import-globals-from privacy.js */ -/* import-globals-from applications.js */ -/* import-globals-from security.js */ -/* import-globals-from sync.js */ -/* import-globals-from ../../../base/content/utilityOverlay.js */ - -"use strict"; - -var Cc = Components.classes; -var Ci = Components.interfaces; -var Cu = Components.utils; -var Cr = Components.results; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/AppConstants.jsm"); - -var gLastHash = ""; - -var gCategoryInits = new Map(); -function init_category_if_required(category) { - let categoryInfo = gCategoryInits.get(category); - if (!categoryInfo) { - throw "Unknown in-content prefs category! Can't init " + category; - } - if (categoryInfo.inited) { - return; - } - categoryInfo.init(); -} - -function register_module(categoryName, categoryObject) { - gCategoryInits.set(categoryName, { - inited: false, - init: function() { - categoryObject.init(); - this.inited = true; - } - }); -} - -addEventListener("DOMContentLoaded", function onLoad() { - removeEventListener("DOMContentLoaded", onLoad); - init_all(); -}); - -function init_all() { - document.documentElement.instantApply = true; - - gSubDialog.init(); - register_module("paneGeneral", gMainPane); - register_module("paneSearch", gSearchPane); - register_module("panePrivacy", gPrivacyPane); - register_module("paneContainers", gContainersPane); - register_module("paneAdvanced", gAdvancedPane); - register_module("paneApplications", gApplicationsPane); - register_module("paneContent", gContentPane); - register_module("paneSync", gSyncPane); - register_module("paneSecurity", gSecurityPane); - - let categories = document.getElementById("categories"); - categories.addEventListener("select", event => gotoPref(event.target.value)); - - document.documentElement.addEventListener("keydown", function(event) { - if (event.keyCode == KeyEvent.DOM_VK_TAB) { - categories.setAttribute("keyboard-navigation", "true"); - } - }); - categories.addEventListener("mousedown", function() { - this.removeAttribute("keyboard-navigation"); - }); - - window.addEventListener("hashchange", onHashChange); - gotoPref(); - - init_dynamic_padding(); - - var initFinished = new CustomEvent("Initialized", { - 'bubbles': true, - 'cancelable': true - }); - document.dispatchEvent(initFinished); - - categories = categories.querySelectorAll("richlistitem.category"); - for (let category of categories) { - let name = internalPrefCategoryNameToFriendlyName(category.value); - let helpSelector = `#header-${name} > .help-button`; - let helpButton = document.querySelector(helpSelector); - helpButton.setAttribute("href", getHelpLinkURL(category.getAttribute("helpTopic"))); - } - - // Wait until initialization of all preferences are complete before - // notifying observers that the UI is now ready. - Services.obs.notifyObservers(window, "advanced-pane-loaded", null); -} - -// Make the space above the categories list shrink on low window heights -function init_dynamic_padding() { - let categories = document.getElementById("categories"); - let catPadding = Number.parseInt(getComputedStyle(categories) - .getPropertyValue('padding-top')); - let fullHeight = categories.lastElementChild.getBoundingClientRect().bottom; - let mediaRule = ` - @media (max-height: ${fullHeight}px) { - #categories { - padding-top: calc(100vh - ${fullHeight - catPadding}px); - } - } - `; - let mediaStyle = document.createElementNS('http://www.w3.org/1999/xhtml', 'html:style'); - mediaStyle.setAttribute('type', 'text/css'); - mediaStyle.appendChild(document.createCDATASection(mediaRule)); - document.documentElement.appendChild(mediaStyle); -} - -function telemetryBucketForCategory(category) { - switch (category) { - case "general": - case "search": - case "content": - case "applications": - case "privacy": - case "security": - case "sync": - return category; - case "advanced": - let advancedPaneTabs = document.getElementById("advancedPrefs"); - switch (advancedPaneTabs.selectedTab.id) { - case "generalTab": - return "advancedGeneral"; - case "dataChoicesTab": - return "advancedDataChoices"; - case "networkTab": - return "advancedNetwork"; - case "updateTab": - return "advancedUpdates"; - case "encryptionTab": - return "advancedCerts"; - } - // fall-through for unknown. - default: - return "unknown"; - } -} - -function onHashChange() { - gotoPref(); -} - -function gotoPref(aCategory) { - let categories = document.getElementById("categories"); - const kDefaultCategoryInternalName = categories.firstElementChild.value; - let hash = document.location.hash; - let category = aCategory || hash.substr(1) || kDefaultCategoryInternalName; - category = friendlyPrefCategoryNameToInternalName(category); - - // Updating the hash (below) or changing the selected category - // will re-enter gotoPref. - if (gLastHash == category) - return; - let item = categories.querySelector(".category[value=" + category + "]"); - if (!item) { - category = kDefaultCategoryInternalName; - item = categories.querySelector(".category[value=" + category + "]"); - } - - try { - init_category_if_required(category); - } catch (ex) { - Cu.reportError("Error initializing preference category " + category + ": " + ex); - throw ex; - } - - let friendlyName = internalPrefCategoryNameToFriendlyName(category); - if (gLastHash || category != kDefaultCategoryInternalName) { - document.location.hash = friendlyName; - } - // Need to set the gLastHash before setting categories.selectedItem since - // the categories 'select' event will re-enter the gotoPref codepath. - gLastHash = category; - categories.selectedItem = item; - window.history.replaceState(category, document.title); - search(category, "data-category"); - let mainContent = document.querySelector(".main-content"); - mainContent.scrollTop = 0; - - Services.telemetry - .getHistogramById("FX_PREFERENCES_CATEGORY_OPENED") - .add(telemetryBucketForCategory(friendlyName)); -} - -function search(aQuery, aAttribute) { - let mainPrefPane = document.getElementById("mainPrefPane"); - let elements = mainPrefPane.children; - for (let element of elements) { - let attributeValue = element.getAttribute(aAttribute); - element.hidden = (attributeValue != aQuery); - } - - let keysets = mainPrefPane.getElementsByTagName("keyset"); - for (let element of keysets) { - let attributeValue = element.getAttribute(aAttribute); - if (attributeValue == aQuery) - element.removeAttribute("disabled"); - else - element.setAttribute("disabled", true); - } -} - -function helpButtonCommand() { - let pane = history.state; - let categories = document.getElementById("categories"); - let helpTopic = categories.querySelector(".category[value=" + pane + "]") - .getAttribute("helpTopic"); - openHelpLink(helpTopic); -} - -function friendlyPrefCategoryNameToInternalName(aName) { - if (aName.startsWith("pane")) - return aName; - return "pane" + aName.substring(0, 1).toUpperCase() + aName.substr(1); -} - -// This function is duplicated inside of utilityOverlay.js's openPreferences. -function internalPrefCategoryNameToFriendlyName(aName) { - return (aName || "").replace(/^pane./, function(toReplace) { return toReplace[4].toLowerCase(); }); -} - -// Put up a confirm dialog with "ok to restart", "revert without restarting" -// and "restart later" buttons and returns the index of the button chosen. -// We can choose not to display the "restart later", or "revert" buttons, -// altough the later still lets us revert by using the escape key. -// -// The constants are useful to interpret the return value of the function. -const CONFIRM_RESTART_PROMPT_RESTART_NOW = 0; -const CONFIRM_RESTART_PROMPT_CANCEL = 1; -const CONFIRM_RESTART_PROMPT_RESTART_LATER = 2; -function confirmRestartPrompt(aRestartToEnable, aDefaultButtonIndex, - aWantRevertAsCancelButton, - aWantRestartLaterButton) { - let brandName = document.getElementById("bundleBrand").getString("brandShortName"); - let bundle = document.getElementById("bundlePreferences"); - let msg = bundle.getFormattedString(aRestartToEnable ? - "featureEnableRequiresRestart" : - "featureDisableRequiresRestart", - [brandName]); - let title = bundle.getFormattedString("shouldRestartTitle", [brandName]); - let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService); - - // Set up the first (index 0) button: - let button0Text = bundle.getFormattedString("okToRestartButton", [brandName]); - let buttonFlags = (Services.prompt.BUTTON_POS_0 * - Services.prompt.BUTTON_TITLE_IS_STRING); - - - // Set up the second (index 1) button: - let button1Text = null; - if (aWantRevertAsCancelButton) { - button1Text = bundle.getString("revertNoRestartButton"); - buttonFlags += (Services.prompt.BUTTON_POS_1 * - Services.prompt.BUTTON_TITLE_IS_STRING); - } else { - buttonFlags += (Services.prompt.BUTTON_POS_1 * - Services.prompt.BUTTON_TITLE_CANCEL); - } - - // Set up the third (index 2) button: - let button2Text = null; - if (aWantRestartLaterButton) { - button2Text = bundle.getString("restartLater"); - buttonFlags += (Services.prompt.BUTTON_POS_2 * - Services.prompt.BUTTON_TITLE_IS_STRING); - } - - switch (aDefaultButtonIndex) { - case 0: - buttonFlags += Services.prompt.BUTTON_POS_0_DEFAULT; - break; - case 1: - buttonFlags += Services.prompt.BUTTON_POS_1_DEFAULT; - break; - case 2: - buttonFlags += Services.prompt.BUTTON_POS_2_DEFAULT; - break; - default: - break; - } - - let buttonIndex = prompts.confirmEx(window, title, msg, buttonFlags, - button0Text, button1Text, button2Text, - null, {}); - - // If we have the second confirmation dialog for restart, see if the user - // cancels out at that point. - if (buttonIndex == CONFIRM_RESTART_PROMPT_RESTART_NOW) { - let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] - .createInstance(Ci.nsISupportsPRBool); - Services.obs.notifyObservers(cancelQuit, "quit-application-requested", - "restart"); - if (cancelQuit.data) { - buttonIndex = CONFIRM_RESTART_PROMPT_CANCEL; - } - } - return buttonIndex; -} diff --git a/browser/components/preferences/in-content/preferences.xul b/browser/components/preferences/in-content/preferences.xul deleted file mode 100644 index 7ec7ef119..000000000 --- a/browser/components/preferences/in-content/preferences.xul +++ /dev/null @@ -1,216 +0,0 @@ -<?xml version="1.0"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this file, - - You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<?xml-stylesheet href="chrome://global/skin/global.css"?> - -<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?> -<?xml-stylesheet href="chrome://global/skin/in-content/common.css"?> -<?xml-stylesheet - href="chrome://browser/skin/preferences/in-content/preferences.css"?> -<?xml-stylesheet - href="chrome://browser/content/preferences/handlers.css"?> -<?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?> -<?xml-stylesheet href="chrome://browser/skin/preferences/in-content/search.css"?> -<?xml-stylesheet href="chrome://browser/skin/preferences/in-content/containers.css"?> - -<!DOCTYPE page [ -<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> -<!ENTITY % globalPreferencesDTD SYSTEM "chrome://global/locale/preferences.dtd"> -<!ENTITY % preferencesDTD SYSTEM - "chrome://browser/locale/preferences/preferences.dtd"> -<!ENTITY % privacyDTD SYSTEM "chrome://browser/locale/preferences/privacy.dtd"> -<!ENTITY % tabsDTD SYSTEM "chrome://browser/locale/preferences/tabs.dtd"> -<!ENTITY % searchDTD SYSTEM "chrome://browser/locale/preferences/search.dtd"> -<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> -<!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd"> -<!ENTITY % securityDTD SYSTEM - "chrome://browser/locale/preferences/security.dtd"> -<!ENTITY % containersDTD SYSTEM - "chrome://browser/locale/preferences/containers.dtd"> -<!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd"> -<!ENTITY % mainDTD SYSTEM "chrome://browser/locale/preferences/main.dtd"> -<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd"> -<!ENTITY % contentDTD SYSTEM "chrome://browser/locale/preferences/content.dtd"> -<!ENTITY % applicationsDTD SYSTEM - "chrome://browser/locale/preferences/applications.dtd"> -<!ENTITY % advancedDTD SYSTEM - "chrome://browser/locale/preferences/advanced.dtd"> -%brandDTD; -%globalPreferencesDTD; -%preferencesDTD; -%privacyDTD; -%tabsDTD; -%searchDTD; -%syncBrandDTD; -%syncDTD; -%securityDTD; -%containersDTD; -%sanitizeDTD; -%mainDTD; -%aboutHomeDTD; -%contentDTD; -%applicationsDTD; -%advancedDTD; -]> - -<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - disablefastfind="true" - title="&prefWindow.title;"> - - <html:link rel="shortcut icon" - href="chrome://browser/skin/preferences/in-content/favicon.ico"/> - - <script type="application/javascript" - src="chrome://browser/content/utilityOverlay.js"/> - <script type="application/javascript" - src="chrome://browser/content/preferences/in-content/preferences.js"/> - <script src="chrome://browser/content/preferences/in-content/subdialogs.js"/> - - <stringbundle id="bundleBrand" - src="chrome://branding/locale/brand.properties"/> - <stringbundle id="bundlePreferences" - src="chrome://browser/locale/preferences/preferences.properties"/> - - <stringbundleset id="appManagerBundleset"> - <stringbundle id="appManagerBundle" - src="chrome://browser/locale/preferences/applicationManager.properties"/> - </stringbundleset> - - <stack flex="1"> - <hbox flex="1"> - - <!-- category list --> - <richlistbox id="categories"> - <richlistitem id="category-general" - class="category" - value="paneGeneral" - helpTopic="prefs-main" - tooltiptext="&paneGeneral.title;" - align="center"> - <image class="category-icon"/> - <label class="category-name" flex="1">&paneGeneral.title;</label> - </richlistitem> - - <richlistitem id="category-search" - class="category" - value="paneSearch" - helpTopic="prefs-search" - tooltiptext="&paneSearch.title;" - align="center"> - <image class="category-icon"/> - <label class="category-name" flex="1">&paneSearch.title;</label> - </richlistitem> - - <richlistitem id="category-content" - class="category" - value="paneContent" - helpTopic="prefs-content" - tooltiptext="&paneContent.title;" - align="center"> - <image class="category-icon"/> - <label class="category-name" flex="1">&paneContent.title;</label> - </richlistitem> - - <richlistitem id="category-application" - class="category" - value="paneApplications" - helpTopic="prefs-applications" - tooltiptext="&paneApplications.title;" - align="center"> - <image class="category-icon"/> - <label class="category-name" flex="1">&paneApplications.title;</label> - </richlistitem> - - <richlistitem id="category-privacy" - class="category" - value="panePrivacy" - helpTopic="prefs-privacy" - tooltiptext="&panePrivacy.title;" - align="center"> - <image class="category-icon"/> - <label class="category-name" flex="1">&panePrivacy.title;</label> - </richlistitem> - - <richlistitem id="category-containers" - class="category" - value="paneContainers" - helpTopic="prefs-containers" - hidden="true"/> - - <richlistitem id="category-security" - class="category" - value="paneSecurity" - helpTopic="prefs-security" - tooltiptext="&paneSecurity.title;" - align="center"> - <image class="category-icon"/> - <label class="category-name" flex="1">&paneSecurity.title;</label> - </richlistitem> - - <richlistitem id="category-sync" - class="category" - value="paneSync" - helpTopic="prefs-weave" - tooltiptext="&paneSync.title;" - align="center"> - <image class="category-icon"/> - <label class="category-name" flex="1">&paneSync.title;</label> - </richlistitem> - - <richlistitem id="category-advanced" - class="category" - value="paneAdvanced" - helpTopic="prefs-advanced-general" - tooltiptext="&paneAdvanced.title;" - align="center"> - <image class="category-icon"/> - <label class="category-name" flex="1">&paneAdvanced.title;</label> - </richlistitem> - </richlistbox> - - <keyset> - <!-- Disable the findbar because it doesn't work properly. - Remove this keyset once bug 1094240 ("disablefastfind" attribute - broken in e10s mode) is fixed. --> - <key key="&focusSearch1.key;" modifiers="accel" id="focusSearch1" oncommand=";"/> - </keyset> - - <vbox class="main-content" flex="1"> - <prefpane id="mainPrefPane"> -#include main.xul -#include search.xul -#include privacy.xul -#include containers.xul -#include advanced.xul -#include applications.xul -#include content.xul -#include security.xul -#include sync.xul - </prefpane> - </vbox> - - </hbox> - - <vbox id="dialogOverlay" align="center" pack="center"> - <groupbox id="dialogBox" - orient="vertical" - pack="end" - role="dialog" - aria-labelledby="dialogTitle"> - <caption flex="1" align="center"> - <label id="dialogTitle" flex="1"></label> - <button id="dialogClose" - class="close-icon" - aria-label="&preferencesCloseButton.label;"/> - </caption> - <browser id="dialogFrame" - name="dialogFrame" - autoscroll="false" - disablehistory="true"/> - </groupbox> - </vbox> - </stack> -</page> diff --git a/browser/components/preferences/in-content/privacy.js b/browser/components/preferences/in-content/privacy.js deleted file mode 100644 index 7dfc7de5a..000000000 --- a/browser/components/preferences/in-content/privacy.js +++ /dev/null @@ -1,712 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -Components.utils.import("resource://gre/modules/AppConstants.jsm"); -Components.utils.import("resource://gre/modules/PluralForm.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService", - "resource://gre/modules/ContextualIdentityService.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", - "resource://gre/modules/PluralForm.jsm"); - -var gPrivacyPane = { - - /** - * Whether the use has selected the auto-start private browsing mode in the UI. - */ - _autoStartPrivateBrowsing: false, - - /** - * Whether the prompt to restart Firefox should appear when changing the autostart pref. - */ - _shouldPromptForRestart: true, - - /** - * Show the Tracking Protection UI depending on the - * privacy.trackingprotection.ui.enabled pref, and linkify its Learn More link - */ - _initTrackingProtection: function () { - if (!Services.prefs.getBoolPref("privacy.trackingprotection.ui.enabled")) { - return; - } - - let link = document.getElementById("trackingProtectionLearnMore"); - let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "tracking-protection"; - link.setAttribute("href", url); - - this.trackingProtectionReadPrefs(); - - document.getElementById("trackingprotectionbox").hidden = false; - document.getElementById("trackingprotectionpbmbox").hidden = true; - }, - - /** - * Linkify the Learn More link of the Private Browsing Mode Tracking - * Protection UI. - */ - _initTrackingProtectionPBM: function () { - let link = document.getElementById("trackingProtectionPBMLearnMore"); - let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "tracking-protection-pbm"; - link.setAttribute("href", url); - }, - - /** - * Initialize autocomplete to ensure prefs are in sync. - */ - _initAutocomplete: function () { - Components.classes["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"] - .getService(Components.interfaces.mozIPlacesAutoComplete); - }, - - /** - * Show the Containers UI depending on the privacy.userContext.ui.enabled pref. - */ - _initBrowserContainers: function () { - if (!Services.prefs.getBoolPref("privacy.userContext.ui.enabled")) { - return; - } - - let link = document.getElementById("browserContainersLearnMore"); - link.href = Services.urlFormatter.formatURLPref("app.support.baseURL") + "containers"; - - document.getElementById("browserContainersbox").hidden = false; - - document.getElementById("browserContainersCheckbox").checked = - Services.prefs.getBoolPref("privacy.userContext.enabled"); - }, - - _checkBrowserContainers: function(event) { - let checkbox = document.getElementById("browserContainersCheckbox"); - if (checkbox.checked) { - Services.prefs.setBoolPref("privacy.userContext.enabled", true); - return; - } - - let count = ContextualIdentityService.countContainerTabs(); - if (count == 0) { - Services.prefs.setBoolPref("privacy.userContext.enabled", false); - return; - } - - let bundlePreferences = document.getElementById("bundlePreferences"); - - let title = bundlePreferences.getString("disableContainersAlertTitle"); - let message = PluralForm.get(count, bundlePreferences.getString("disableContainersMsg")) - .replace("#S", count) - let okButton = PluralForm.get(count, bundlePreferences.getString("disableContainersOkButton")) - .replace("#S", count) - let cancelButton = bundlePreferences.getString("disableContainersButton2"); - - let buttonFlags = (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_0) + - (Ci.nsIPrompt.BUTTON_TITLE_IS_STRING * Ci.nsIPrompt.BUTTON_POS_1); - - let rv = Services.prompt.confirmEx(window, title, message, buttonFlags, - okButton, cancelButton, null, null, {}); - if (rv == 0) { - ContextualIdentityService.closeAllContainerTabs(); - Services.prefs.setBoolPref("privacy.userContext.enabled", false); - return; - } - - checkbox.checked = true; - }, - - /** - * Sets up the UI for the number of days of history to keep, and updates the - * label of the "Clear Now..." button. - */ - init: function () - { - function setEventListener(aId, aEventType, aCallback) - { - document.getElementById(aId) - .addEventListener(aEventType, aCallback.bind(gPrivacyPane)); - } - - this._updateSanitizeSettingsButton(); - this.initializeHistoryMode(); - this.updateHistoryModePane(); - this.updatePrivacyMicroControls(); - this.initAutoStartPrivateBrowsingReverter(); - this._initTrackingProtection(); - this._initTrackingProtectionPBM(); - this._initAutocomplete(); - this._initBrowserContainers(); - - setEventListener("privacy.sanitize.sanitizeOnShutdown", "change", - gPrivacyPane._updateSanitizeSettingsButton); - setEventListener("browser.privatebrowsing.autostart", "change", - gPrivacyPane.updatePrivacyMicroControls); - setEventListener("historyMode", "command", function () { - gPrivacyPane.updateHistoryModePane(); - gPrivacyPane.updateHistoryModePrefs(); - gPrivacyPane.updatePrivacyMicroControls(); - gPrivacyPane.updateAutostart(); - }); - setEventListener("historyRememberClear", "click", function () { - gPrivacyPane.clearPrivateDataNow(false); - return false; - }); - setEventListener("historyRememberCookies", "click", function () { - gPrivacyPane.showCookies(); - return false; - }); - setEventListener("historyDontRememberClear", "click", function () { - gPrivacyPane.clearPrivateDataNow(true); - return false; - }); - setEventListener("doNotTrackSettings", "click", function () { - gPrivacyPane.showDoNotTrackSettings(); - return false; - }); - setEventListener("privateBrowsingAutoStart", "command", - gPrivacyPane.updateAutostart); - setEventListener("cookieExceptions", "command", - gPrivacyPane.showCookieExceptions); - setEventListener("showCookiesButton", "command", - gPrivacyPane.showCookies); - setEventListener("clearDataSettings", "command", - gPrivacyPane.showClearPrivateDataSettings); - setEventListener("trackingProtectionRadioGroup", "command", - gPrivacyPane.trackingProtectionWritePrefs); - setEventListener("trackingProtectionExceptions", "command", - gPrivacyPane.showTrackingProtectionExceptions); - setEventListener("changeBlockList", "command", - gPrivacyPane.showBlockLists); - setEventListener("changeBlockListPBM", "command", - gPrivacyPane.showBlockLists); - setEventListener("browserContainersCheckbox", "command", - gPrivacyPane._checkBrowserContainers); - setEventListener("browserContainersSettings", "command", - gPrivacyPane.showContainerSettings); - }, - - // TRACKING PROTECTION MODE - - /** - * Selects the right item of the Tracking Protection radiogroup. - */ - trackingProtectionReadPrefs() { - let enabledPref = document.getElementById("privacy.trackingprotection.enabled"); - let pbmPref = document.getElementById("privacy.trackingprotection.pbmode.enabled"); - let radiogroup = document.getElementById("trackingProtectionRadioGroup"); - - // Global enable takes precedence over enabled in Private Browsing. - if (enabledPref.value) { - radiogroup.value = "always"; - } else if (pbmPref.value) { - radiogroup.value = "private"; - } else { - radiogroup.value = "never"; - } - }, - - /** - * Sets the pref values based on the selected item of the radiogroup. - */ - trackingProtectionWritePrefs() { - let enabledPref = document.getElementById("privacy.trackingprotection.enabled"); - let pbmPref = document.getElementById("privacy.trackingprotection.pbmode.enabled"); - let radiogroup = document.getElementById("trackingProtectionRadioGroup"); - - switch (radiogroup.value) { - case "always": - enabledPref.value = true; - pbmPref.value = true; - break; - case "private": - enabledPref.value = false; - pbmPref.value = true; - break; - case "never": - enabledPref.value = false; - pbmPref.value = false; - break; - } - }, - - // HISTORY MODE - - /** - * The list of preferences which affect the initial history mode settings. - * If the auto start private browsing mode pref is active, the initial - * history mode would be set to "Don't remember anything". - * If ALL of these preferences are set to the values that correspond - * to keeping some part of history, and the auto-start - * private browsing mode is not active, the initial history mode would be - * set to "Remember everything". - * Otherwise, the initial history mode would be set to "Custom". - * - * Extensions adding their own preferences can set values here if needed. - */ - prefsForKeepingHistory: { - "places.history.enabled": true, // History is enabled - "browser.formfill.enable": true, // Form information is saved - "network.cookie.cookieBehavior": 0, // All cookies are enabled - "network.cookie.lifetimePolicy": 0, // Cookies use supplied lifetime - "privacy.sanitize.sanitizeOnShutdown": false, // Private date is NOT cleared on shutdown - }, - - /** - * The list of control IDs which are dependent on the auto-start private - * browsing setting, such that in "Custom" mode they would be disabled if - * the auto-start private browsing checkbox is checked, and enabled otherwise. - * - * Extensions adding their own controls can append their IDs to this array if needed. - */ - dependentControls: [ - "rememberHistory", - "rememberForms", - "keepUntil", - "keepCookiesUntil", - "alwaysClear", - "clearDataSettings" - ], - - /** - * Check whether preferences values are set to keep history - * - * @param aPrefs an array of pref names to check for - * @returns boolean true if all of the prefs are set to keep history, - * false otherwise - */ - _checkHistoryValues: function(aPrefs) { - for (let pref of Object.keys(aPrefs)) { - if (document.getElementById(pref).value != aPrefs[pref]) - return false; - } - return true; - }, - - /** - * Initialize the history mode menulist based on the privacy preferences - */ - initializeHistoryMode: function PPP_initializeHistoryMode() - { - let mode; - let getVal = aPref => document.getElementById(aPref).value; - - if (this._checkHistoryValues(this.prefsForKeepingHistory)) { - if (getVal("browser.privatebrowsing.autostart")) - mode = "dontremember"; - else - mode = "remember"; - } - else - mode = "custom"; - - document.getElementById("historyMode").value = mode; - }, - - /** - * Update the selected pane based on the history mode menulist - */ - updateHistoryModePane: function PPP_updateHistoryModePane() - { - let selectedIndex = -1; - switch (document.getElementById("historyMode").value) { - case "remember": - selectedIndex = 0; - break; - case "dontremember": - selectedIndex = 1; - break; - case "custom": - selectedIndex = 2; - break; - } - document.getElementById("historyPane").selectedIndex = selectedIndex; - }, - - /** - * Update the private browsing auto-start pref and the history mode - * micro-management prefs based on the history mode menulist - */ - updateHistoryModePrefs: function PPP_updateHistoryModePrefs() - { - let pref = document.getElementById("browser.privatebrowsing.autostart"); - switch (document.getElementById("historyMode").value) { - case "remember": - if (pref.value) - pref.value = false; - - // select the remember history option if needed - let rememberHistoryCheckbox = document.getElementById("rememberHistory"); - if (!rememberHistoryCheckbox.checked) - rememberHistoryCheckbox.checked = true; - - // select the remember forms history option - document.getElementById("browser.formfill.enable").value = true; - - // select the allow cookies option - document.getElementById("network.cookie.cookieBehavior").value = 0; - // select the cookie lifetime policy option - document.getElementById("network.cookie.lifetimePolicy").value = 0; - - // select the clear on close option - document.getElementById("privacy.sanitize.sanitizeOnShutdown").value = false; - break; - case "dontremember": - if (!pref.value) - pref.value = true; - break; - } - }, - - /** - * Update the privacy micro-management controls based on the - * value of the private browsing auto-start checkbox. - */ - updatePrivacyMicroControls: function PPP_updatePrivacyMicroControls() - { - if (document.getElementById("historyMode").value == "custom") { - let disabled = this._autoStartPrivateBrowsing = - document.getElementById("privateBrowsingAutoStart").checked; - this.dependentControls.forEach(function (aElement) { - let control = document.getElementById(aElement); - let preferenceId = control.getAttribute("preference"); - if (!preferenceId) { - let dependentControlId = control.getAttribute("control"); - if (dependentControlId) { - let dependentControl = document.getElementById(dependentControlId); - preferenceId = dependentControl.getAttribute("preference"); - } - } - - let preference = preferenceId ? document.getElementById(preferenceId) : {}; - control.disabled = disabled || preference.locked; - }); - - // adjust the cookie controls status - this.readAcceptCookies(); - let lifetimePolicy = document.getElementById("network.cookie.lifetimePolicy").value; - if (lifetimePolicy != Ci.nsICookieService.ACCEPT_NORMALLY && - lifetimePolicy != Ci.nsICookieService.ACCEPT_SESSION && - lifetimePolicy != Ci.nsICookieService.ACCEPT_FOR_N_DAYS) { - lifetimePolicy = Ci.nsICookieService.ACCEPT_NORMALLY; - } - document.getElementById("keepCookiesUntil").value = disabled ? 2 : lifetimePolicy; - - // adjust the checked state of the sanitizeOnShutdown checkbox - document.getElementById("alwaysClear").checked = disabled ? false : - document.getElementById("privacy.sanitize.sanitizeOnShutdown").value; - - // adjust the checked state of the remember history checkboxes - document.getElementById("rememberHistory").checked = disabled ? false : - document.getElementById("places.history.enabled").value; - document.getElementById("rememberForms").checked = disabled ? false : - document.getElementById("browser.formfill.enable").value; - - if (!disabled) { - // adjust the Settings button for sanitizeOnShutdown - this._updateSanitizeSettingsButton(); - } - } - }, - - // PRIVATE BROWSING - - /** - * Initialize the starting state for the auto-start private browsing mode pref reverter. - */ - initAutoStartPrivateBrowsingReverter: function PPP_initAutoStartPrivateBrowsingReverter() - { - let mode = document.getElementById("historyMode"); - let autoStart = document.getElementById("privateBrowsingAutoStart"); - this._lastMode = mode.selectedIndex; - this._lastCheckState = autoStart.hasAttribute('checked'); - }, - - _lastMode: null, - _lastCheckState: null, - updateAutostart: function PPP_updateAutostart() { - let mode = document.getElementById("historyMode"); - let autoStart = document.getElementById("privateBrowsingAutoStart"); - let pref = document.getElementById("browser.privatebrowsing.autostart"); - if ((mode.value == "custom" && this._lastCheckState == autoStart.checked) || - (mode.value == "remember" && !this._lastCheckState) || - (mode.value == "dontremember" && this._lastCheckState)) { - // These are all no-op changes, so we don't need to prompt. - this._lastMode = mode.selectedIndex; - this._lastCheckState = autoStart.hasAttribute('checked'); - return; - } - - if (!this._shouldPromptForRestart) { - // We're performing a revert. Just let it happen. - return; - } - - let buttonIndex = confirmRestartPrompt(autoStart.checked, 1, - true, false); - if (buttonIndex == CONFIRM_RESTART_PROMPT_RESTART_NOW) { - pref.value = autoStart.hasAttribute('checked'); - let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"] - .getService(Ci.nsIAppStartup); - appStartup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); - return; - } - - this._shouldPromptForRestart = false; - - if (this._lastCheckState) { - autoStart.checked = "checked"; - } else { - autoStart.removeAttribute('checked'); - } - pref.value = autoStart.hasAttribute('checked'); - mode.selectedIndex = this._lastMode; - mode.doCommand(); - - this._shouldPromptForRestart = true; - }, - - /** - * Displays fine-grained, per-site preferences for tracking protection. - */ - showTrackingProtectionExceptions() { - let bundlePreferences = document.getElementById("bundlePreferences"); - let params = { - permissionType: "trackingprotection", - hideStatusColumn: true, - windowTitle: bundlePreferences.getString("trackingprotectionpermissionstitle"), - introText: bundlePreferences.getString("trackingprotectionpermissionstext"), - }; - gSubDialog.open("chrome://browser/content/preferences/permissions.xul", - null, params); - }, - - /** - * Displays container panel for customising and adding containers. - */ - showContainerSettings() { - gotoPref("containers"); - }, - - /** - * Displays the available block lists for tracking protection. - */ - showBlockLists: function () - { - var bundlePreferences = document.getElementById("bundlePreferences"); - let brandName = document.getElementById("bundleBrand") - .getString("brandShortName"); - var params = { brandShortName: brandName, - windowTitle: bundlePreferences.getString("blockliststitle"), - introText: bundlePreferences.getString("blockliststext") }; - gSubDialog.open("chrome://browser/content/preferences/blocklists.xul", - null, params); - }, - - /** - * Displays the Do Not Track settings dialog. - */ - showDoNotTrackSettings() { - gSubDialog.open("chrome://browser/content/preferences/donottrack.xul", - "resizable=no"); - }, - - // HISTORY - - /* - * Preferences: - * - * places.history.enabled - * - whether history is enabled or not - * browser.formfill.enable - * - true if entries in forms and the search bar should be saved, false - * otherwise - */ - - // COOKIES - - /* - * Preferences: - * - * network.cookie.cookieBehavior - * - determines how the browser should handle cookies: - * 0 means enable all cookies - * 1 means reject all third party cookies - * 2 means disable all cookies - * 3 means reject third party cookies unless at least one is already set for the eTLD - * see netwerk/cookie/src/nsCookieService.cpp for details - * network.cookie.lifetimePolicy - * - determines how long cookies are stored: - * 0 means keep cookies until they expire - * 2 means keep cookies until the browser is closed - */ - - /** - * Reads the network.cookie.cookieBehavior preference value and - * enables/disables the rest of the cookie UI accordingly, returning true - * if cookies are enabled. - */ - readAcceptCookies: function () - { - var pref = document.getElementById("network.cookie.cookieBehavior"); - var acceptThirdPartyLabel = document.getElementById("acceptThirdPartyLabel"); - var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu"); - var keepUntil = document.getElementById("keepUntil"); - var menu = document.getElementById("keepCookiesUntil"); - - // enable the rest of the UI for anything other than "disable all cookies" - var acceptCookies = (pref.value != 2); - - acceptThirdPartyLabel.disabled = acceptThirdPartyMenu.disabled = !acceptCookies; - keepUntil.disabled = menu.disabled = this._autoStartPrivateBrowsing || !acceptCookies; - - return acceptCookies; - }, - - /** - * Enables/disables the "keep until" label and menulist in response to the - * "accept cookies" checkbox being checked or unchecked. - */ - writeAcceptCookies: function () - { - var accept = document.getElementById("acceptCookies"); - var acceptThirdPartyMenu = document.getElementById("acceptThirdPartyMenu"); - - // if we're enabling cookies, automatically select 'accept third party always' - if (accept.checked) - acceptThirdPartyMenu.selectedIndex = 0; - - return accept.checked ? 0 : 2; - }, - - /** - * Converts between network.cookie.cookieBehavior and the third-party cookie UI - */ - readAcceptThirdPartyCookies: function () - { - var pref = document.getElementById("network.cookie.cookieBehavior"); - switch (pref.value) - { - case 0: - return "always"; - case 1: - return "never"; - case 2: - return "never"; - case 3: - return "visited"; - default: - return undefined; - } - }, - - writeAcceptThirdPartyCookies: function () - { - var accept = document.getElementById("acceptThirdPartyMenu").selectedItem; - switch (accept.value) - { - case "always": - return 0; - case "visited": - return 3; - case "never": - return 1; - default: - return undefined; - } - }, - - /** - * Displays fine-grained, per-site preferences for cookies. - */ - showCookieExceptions: function () - { - var bundlePreferences = document.getElementById("bundlePreferences"); - var params = { blockVisible : true, - sessionVisible : true, - allowVisible : true, - prefilledHost : "", - permissionType : "cookie", - windowTitle : bundlePreferences.getString("cookiepermissionstitle"), - introText : bundlePreferences.getString("cookiepermissionstext") }; - gSubDialog.open("chrome://browser/content/preferences/permissions.xul", - null, params); - }, - - /** - * Displays all the user's cookies in a dialog. - */ - showCookies: function (aCategory) - { - gSubDialog.open("chrome://browser/content/preferences/cookies.xul"); - }, - - // CLEAR PRIVATE DATA - - /* - * Preferences: - * - * privacy.sanitize.sanitizeOnShutdown - * - true if the user's private data is cleared on startup according to the - * Clear Private Data settings, false otherwise - */ - - /** - * Displays the Clear Private Data settings dialog. - */ - showClearPrivateDataSettings: function () - { - gSubDialog.open("chrome://browser/content/preferences/sanitize.xul", "resizable=no"); - }, - - - /** - * Displays a dialog from which individual parts of private data may be - * cleared. - */ - clearPrivateDataNow: function (aClearEverything) { - var ts = document.getElementById("privacy.sanitize.timeSpan"); - var timeSpanOrig = ts.value; - - if (aClearEverything) { - ts.value = 0; - } - - gSubDialog.open("chrome://browser/content/sanitize.xul", "resizable=no", null, () => { - // reset the timeSpan pref - if (aClearEverything) { - ts.value = timeSpanOrig; - } - - Services.obs.notifyObservers(null, "clear-private-data", null); - }); - }, - - /** - * Enables or disables the "Settings..." button depending - * on the privacy.sanitize.sanitizeOnShutdown preference value - */ - _updateSanitizeSettingsButton: function () { - var settingsButton = document.getElementById("clearDataSettings"); - var sanitizeOnShutdownPref = document.getElementById("privacy.sanitize.sanitizeOnShutdown"); - - settingsButton.disabled = !sanitizeOnShutdownPref.value; - }, - - // CONTAINERS - - /* - * preferences: - * - * privacy.userContext.enabled - * - true if containers is enabled - */ - - /** - * Enables/disables the Settings button used to configure containers - */ - readBrowserContainersCheckbox: function () - { - var pref = document.getElementById("privacy.userContext.enabled"); - var settings = document.getElementById("browserContainersSettings"); - - settings.disabled = !pref.value; - } - -}; diff --git a/browser/components/preferences/in-content/privacy.xul b/browser/components/preferences/in-content/privacy.xul deleted file mode 100644 index 6ac6c88a4..000000000 --- a/browser/components/preferences/in-content/privacy.xul +++ /dev/null @@ -1,308 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<!-- Privacy panel --> - -<script type="application/javascript" - src="chrome://browser/content/preferences/in-content/privacy.js"/> - -<preferences id="privacyPreferences" hidden="true" data-category="panePrivacy"> - - <!-- Tracking --> - <preference id="privacy.trackingprotection.enabled" - name="privacy.trackingprotection.enabled" - type="bool"/> - <preference id="privacy.trackingprotection.pbmode.enabled" - name="privacy.trackingprotection.pbmode.enabled" - type="bool"/> - - <!-- XXX button prefs --> - <preference id="pref.privacy.disable_button.cookie_exceptions" - name="pref.privacy.disable_button.cookie_exceptions" - type="bool"/> - <preference id="pref.privacy.disable_button.view_cookies" - name="pref.privacy.disable_button.view_cookies" - type="bool"/> - <preference id="pref.privacy.disable_button.change_blocklist" - name="pref.privacy.disable_button.change_blocklist" - type="bool"/> - <preference id="pref.privacy.disable_button.tracking_protection_exceptions" - name="pref.privacy.disable_button.tracking_protection_exceptions" - type="bool"/> - - <!-- Location Bar --> - <preference id="browser.urlbar.autocomplete.enabled" - name="browser.urlbar.autocomplete.enabled" - type="bool"/> - <preference id="browser.urlbar.suggest.bookmark" - name="browser.urlbar.suggest.bookmark" - type="bool"/> - <preference id="browser.urlbar.suggest.history" - name="browser.urlbar.suggest.history" - type="bool"/> - <preference id="browser.urlbar.suggest.openpage" - name="browser.urlbar.suggest.openpage" - type="bool"/> - - <!-- History --> - <preference id="places.history.enabled" - name="places.history.enabled" - type="bool"/> - <preference id="browser.formfill.enable" - name="browser.formfill.enable" - type="bool"/> - <!-- Cookies --> - <preference id="network.cookie.cookieBehavior" - name="network.cookie.cookieBehavior" - type="int"/> - <preference id="network.cookie.lifetimePolicy" - name="network.cookie.lifetimePolicy" - type="int"/> - <preference id="network.cookie.blockFutureCookies" - name="network.cookie.blockFutureCookies" - type="bool"/> - <!-- Clear Private Data --> - <preference id="privacy.sanitize.sanitizeOnShutdown" - name="privacy.sanitize.sanitizeOnShutdown" - type="bool"/> - <preference id="privacy.sanitize.timeSpan" - name="privacy.sanitize.timeSpan" - type="int"/> - <!-- Private Browsing --> - <preference id="browser.privatebrowsing.autostart" - name="browser.privatebrowsing.autostart" - type="bool"/> -</preferences> - -<hbox id="header-privacy" - class="header" - hidden="true" - data-category="panePrivacy"> - <label class="header-name" flex="1">&panePrivacy.title;</label> - <html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a> -</hbox> - -<!-- Tracking --> -<groupbox id="trackingGroup" data-category="panePrivacy" hidden="true"> - <vbox id="trackingprotectionbox" hidden="true"> - <hbox align="start"> - <vbox> - <caption><label>&trackingProtectionHeader.label; - <label id="trackingProtectionLearnMore" class="text-link" - value="&trackingProtectionLearnMore.label;"/> - </label></caption> - <radiogroup id="trackingProtectionRadioGroup"> - <radio value="always" - label="&trackingProtectionAlways.label;" - accesskey="&trackingProtectionAlways.accesskey;"/> - <radio value="private" - label="&trackingProtectionPrivate.label;" - accesskey="&trackingProtectionPrivate.accesskey;"/> - <radio value="never" - label="&trackingProtectionNever.label;" - accesskey="&trackingProtectionNever.accesskey;"/> - </radiogroup> - </vbox> - <spacer flex="1" /> - <vbox> - <button id="trackingProtectionExceptions" - label="&trackingProtectionExceptions.label;" - accesskey="&trackingProtectionExceptions.accesskey;" - preference="pref.privacy.disable_button.tracking_protection_exceptions"/> - <button id="changeBlockList" - label="&changeBlockList.label;" - accesskey="&changeBlockList.accesskey;" - preference="pref.privacy.disable_button.change_blocklist"/> - </vbox> - </hbox> - </vbox> - <vbox id="trackingprotectionpbmbox"> - <caption><label>&tracking.label;</label></caption> - <hbox align="center"> - <checkbox id="trackingProtectionPBM" - preference="privacy.trackingprotection.pbmode.enabled" - accesskey="&trackingProtectionPBM5.accesskey;" - label="&trackingProtectionPBM5.label;" /> - <label id="trackingProtectionPBMLearnMore" - class="text-link" - value="&trackingProtectionPBMLearnMore.label;"/> - <spacer flex="1" /> - <button id="changeBlockListPBM" - label="&changeBlockList.label;" accesskey="&changeBlockList.accesskey;" - preference="pref.privacy.disable_button.change_blocklist"/> - </hbox> - </vbox> - <vbox> - <description>&doNotTrack.pre.label;<label - class="text-link" id="doNotTrackSettings" - >&doNotTrack.settings.label;</label>&doNotTrack.post.label;</description> - </vbox> -</groupbox> - -<!-- History --> -<groupbox id="historyGroup" data-category="panePrivacy" hidden="true"> - <caption><label>&history.label;</label></caption> - <hbox align="center"> - <label id="historyModeLabel" - control="historyMode" - accesskey="&historyHeader.pre.accesskey;">&historyHeader.pre.label; - </label> - <menulist id="historyMode"> - <menupopup> - <menuitem label="&historyHeader.remember.label;" value="remember"/> - <menuitem label="&historyHeader.dontremember.label;" value="dontremember"/> - <menuitem label="&historyHeader.custom.label;" value="custom"/> - </menupopup> - </menulist> - <label>&historyHeader.post.label;</label> - </hbox> - <deck id="historyPane"> - <vbox id="historyRememberPane"> - <hbox align="center" flex="1"> - <vbox flex="1"> - <description>&rememberDescription.label;</description> - <separator class="thin"/> - <description>&rememberActions.pre.label;<label - class="text-link" id="historyRememberClear" - >&rememberActions.clearHistory.label;</label>&rememberActions.middle.label;<label - class="text-link" id="historyRememberCookies" - >&rememberActions.removeCookies.label;</label>&rememberActions.post.label;</description> - </vbox> - </hbox> - </vbox> - <vbox id="historyDontRememberPane"> - <hbox align="center" flex="1"> - <vbox flex="1"> - <description>&dontrememberDescription.label;</description> - <separator class="thin"/> - <description>&dontrememberActions.pre.label;<label - class="text-link" id="historyDontRememberClear" - >&dontrememberActions.clearHistory.label;</label>&dontrememberActions.post.label;</description> - </vbox> - </hbox> - </vbox> - <vbox id="historyCustomPane"> - <separator class="thin"/> - <vbox> - <vbox align="start"> - <checkbox id="privateBrowsingAutoStart" - label="&privateBrowsingPermanent2.label;" - accesskey="&privateBrowsingPermanent2.accesskey;" - preference="browser.privatebrowsing.autostart"/> - </vbox> - <vbox class="indent"> - <vbox align="start"> - <checkbox id="rememberHistory" - label="&rememberHistory2.label;" - accesskey="&rememberHistory2.accesskey;" - preference="places.history.enabled"/> - <checkbox id="rememberForms" - label="&rememberSearchForm.label;" - accesskey="&rememberSearchForm.accesskey;" - preference="browser.formfill.enable"/> - </vbox> - <hbox id="cookiesBox"> - <checkbox id="acceptCookies" label="&acceptCookies.label;" - preference="network.cookie.cookieBehavior" - accesskey="&acceptCookies.accesskey;" - onsyncfrompreference="return gPrivacyPane.readAcceptCookies();" - onsynctopreference="return gPrivacyPane.writeAcceptCookies();"/> - <spacer flex="1" /> - <button id="cookieExceptions" - label="&cookieExceptions.label;" accesskey="&cookieExceptions.accesskey;" - preference="pref.privacy.disable_button.cookie_exceptions"/> - </hbox> - <hbox id="acceptThirdPartyRow" - class="indent" - align="center"> - <label id="acceptThirdPartyLabel" control="acceptThirdPartyMenu" - accesskey="&acceptThirdParty.pre.accesskey;">&acceptThirdParty.pre.label;</label> - <menulist id="acceptThirdPartyMenu" preference="network.cookie.cookieBehavior" - onsyncfrompreference="return gPrivacyPane.readAcceptThirdPartyCookies();" - onsynctopreference="return gPrivacyPane.writeAcceptThirdPartyCookies();"> - <menupopup> - <menuitem label="&acceptThirdParty.always.label;" value="always"/> - <menuitem label="&acceptThirdParty.visited.label;" value="visited"/> - <menuitem label="&acceptThirdParty.never.label;" value="never"/> - </menupopup> - </menulist> - </hbox> - <hbox id="keepRow" - class="indent" - align="center"> - <label id="keepUntil" - control="keepCookiesUntil" - accesskey="&keepUntil.accesskey;">&keepUntil.label;</label> - <menulist id="keepCookiesUntil" - preference="network.cookie.lifetimePolicy"> - <menupopup> - <menuitem label="&expire.label;" value="0"/> - <menuitem label="&close.label;" value="2"/> - </menupopup> - </menulist> - <spacer flex="1"/> - <button id="showCookiesButton" - label="&showCookies.label;" accesskey="&showCookies.accesskey;" - preference="pref.privacy.disable_button.view_cookies"/> - </hbox> - <hbox id="clearDataBox" - align="center"> - <checkbox id="alwaysClear" - preference="privacy.sanitize.sanitizeOnShutdown" - label="&clearOnClose.label;" - accesskey="&clearOnClose.accesskey;"/> - <spacer flex="1"/> - <button id="clearDataSettings" label="&clearOnCloseSettings.label;" - accesskey="&clearOnCloseSettings.accesskey;"/> - </hbox> - </vbox> - </vbox> - </vbox> - </deck> -</groupbox> - -<!-- Location Bar --> -<groupbox id="locationBarGroup" - data-category="panePrivacy" - hidden="true"> - <caption><label>&locationBar.label;</label></caption> - <label id="locationBarSuggestionLabel">&locbar.suggest.label;</label> - <checkbox id="historySuggestion" label="&locbar.history.label;" - accesskey="&locbar.history.accesskey;" - preference="browser.urlbar.suggest.history"/> - <checkbox id="bookmarkSuggestion" label="&locbar.bookmarks.label;" - accesskey="&locbar.bookmarks.accesskey;" - preference="browser.urlbar.suggest.bookmark"/> - <checkbox id="openpageSuggestion" label="&locbar.openpage.label;" - accesskey="&locbar.openpage.accesskey;" - preference="browser.urlbar.suggest.openpage"/> - <label class="text-link" onclick="gotoPref('search')"> - &suggestionSettings.label; - </label> -</groupbox> - -<!-- Containers --> -<groupbox id="browserContainersGroup" data-category="panePrivacy" hidden="true"> - <vbox id="browserContainersbox" hidden="true"> - <caption><label>&browserContainersHeader.label; - <label id="browserContainersLearnMore" class="text-link" - value="&browserContainersLearnMore.label;"/> - </label></caption> - <hbox align="start"> - <vbox> - <checkbox id="browserContainersCheckbox" - label="&browserContainersEnabled.label;" - accesskey="&browserContainersEnabled.accesskey;" - preference="privacy.userContext.enabled" - onsyncfrompreference="return gPrivacyPane.readBrowserContainersCheckbox();"/> - </vbox> - <spacer flex="1"/> - <vbox> - <button id="browserContainersSettings" - label="&browserContainersSettings.label;" - accesskey="&browserContainersSettings.accesskey;"/> - </vbox> - </hbox> - </vbox> -</groupbox> diff --git a/browser/components/preferences/in-content/search.js b/browser/components/preferences/in-content/search.js deleted file mode 100644 index 55aa2c18c..000000000 --- a/browser/components/preferences/in-content/search.js +++ /dev/null @@ -1,604 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", - "resource://gre/modules/PlacesUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Task", - "resource://gre/modules/Task.jsm"); - -const ENGINE_FLAVOR = "text/x-moz-search-engine"; - -var gEngineView = null; - -var gSearchPane = { - - /** - * Initialize autocomplete to ensure prefs are in sync. - */ - _initAutocomplete: function () { - Components.classes["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"] - .getService(Components.interfaces.mozIPlacesAutoComplete); - }, - - init: function () - { - gEngineView = new EngineView(new EngineStore()); - document.getElementById("engineList").view = gEngineView; - this.buildDefaultEngineDropDown(); - - let addEnginesLink = document.getElementById("addEngines"); - let searchEnginesURL = Services.wm.getMostRecentWindow('navigator:browser') - .BrowserSearch.searchEnginesURL; - addEnginesLink.setAttribute("href", searchEnginesURL); - - window.addEventListener("click", this, false); - window.addEventListener("command", this, false); - window.addEventListener("dragstart", this, false); - window.addEventListener("keypress", this, false); - window.addEventListener("select", this, false); - window.addEventListener("blur", this, true); - - Services.obs.addObserver(this, "browser-search-engine-modified", false); - window.addEventListener("unload", () => { - Services.obs.removeObserver(this, "browser-search-engine-modified", false); - }); - - this._initAutocomplete(); - - let suggestsPref = - document.getElementById("browser.search.suggest.enabled"); - suggestsPref.addEventListener("change", () => { - this.updateSuggestsCheckbox(); - }); - this.updateSuggestsCheckbox(); - }, - - updateSuggestsCheckbox() { - let suggestsPref = - document.getElementById("browser.search.suggest.enabled"); - let permanentPB = - Services.prefs.getBoolPref("browser.privatebrowsing.autostart"); - let urlbarSuggests = document.getElementById("urlBarSuggestion"); - urlbarSuggests.disabled = !suggestsPref.value || permanentPB; - - let urlbarSuggestsPref = - document.getElementById("browser.urlbar.suggest.searches"); - urlbarSuggests.checked = urlbarSuggestsPref.value; - if (urlbarSuggests.disabled) { - urlbarSuggests.checked = false; - } - - let permanentPBLabel = - document.getElementById("urlBarSuggestionPermanentPBLabel"); - permanentPBLabel.hidden = urlbarSuggests.hidden || !permanentPB; - }, - - buildDefaultEngineDropDown: function() { - // This is called each time something affects the list of engines. - let list = document.getElementById("defaultEngine"); - // Set selection to the current default engine. - let currentEngine = Services.search.currentEngine.name; - - // If the current engine isn't in the list any more, select the first item. - let engines = gEngineView._engineStore._engines; - if (!engines.some(e => e.name == currentEngine)) - currentEngine = engines[0].name; - - // Now clean-up and rebuild the list. - list.removeAllItems(); - gEngineView._engineStore._engines.forEach(e => { - let item = list.appendItem(e.name); - item.setAttribute("class", "menuitem-iconic searchengine-menuitem menuitem-with-favicon"); - if (e.iconURI) { - item.setAttribute("image", e.iconURI.spec); - } - item.engine = e; - if (e.name == currentEngine) - list.selectedItem = item; - }); - }, - - handleEvent: function(aEvent) { - switch (aEvent.type) { - case "click": - if (aEvent.target.id != "engineChildren" && - !aEvent.target.classList.contains("searchEngineAction")) { - let engineList = document.getElementById("engineList"); - // We don't want to toggle off selection while editing keyword - // so proceed only when the input field is hidden. - // We need to check that engineList.view is defined here - // because the "click" event listener is on <window> and the - // view might have been destroyed if the pane has been navigated - // away from. - if (engineList.inputField.hidden && engineList.view) { - let selection = engineList.view.selection; - if (selection.count > 0) { - selection.toggleSelect(selection.currentIndex); - } - engineList.blur(); - } - } - break; - case "command": - switch (aEvent.target.id) { - case "": - if (aEvent.target.parentNode && - aEvent.target.parentNode.parentNode && - aEvent.target.parentNode.parentNode.id == "defaultEngine") { - gSearchPane.setDefaultEngine(); - } - break; - case "restoreDefaultSearchEngines": - gSearchPane.onRestoreDefaults(); - break; - case "removeEngineButton": - Services.search.removeEngine(gEngineView.selectedEngine.originalEngine); - break; - } - break; - case "dragstart": - if (aEvent.target.id == "engineChildren") { - onDragEngineStart(aEvent); - } - break; - case "keypress": - if (aEvent.target.id == "engineList") { - gSearchPane.onTreeKeyPress(aEvent); - } - break; - case "select": - if (aEvent.target.id == "engineList") { - gSearchPane.onTreeSelect(); - } - break; - case "blur": - if (aEvent.target.id == "engineList" && - aEvent.target.inputField == document.getBindingParent(aEvent.originalTarget)) { - gSearchPane.onInputBlur(); - } - break; - } - }, - - observe: function(aEngine, aTopic, aVerb) { - if (aTopic == "browser-search-engine-modified") { - aEngine.QueryInterface(Components.interfaces.nsISearchEngine); - switch (aVerb) { - case "engine-added": - gEngineView._engineStore.addEngine(aEngine); - gEngineView.rowCountChanged(gEngineView.lastIndex, 1); - gSearchPane.buildDefaultEngineDropDown(); - break; - case "engine-changed": - gEngineView._engineStore.reloadIcons(); - gEngineView.invalidate(); - break; - case "engine-removed": - gSearchPane.remove(aEngine); - break; - case "engine-current": - // If the user is going through the drop down using up/down keys, the - // dropdown may still be open (eg. on Windows) when engine-current is - // fired, so rebuilding the list unconditionally would get in the way. - let selectedEngine = - document.getElementById("defaultEngine").selectedItem.engine; - if (selectedEngine.name != aEngine.name) - gSearchPane.buildDefaultEngineDropDown(); - break; - case "engine-default": - // Not relevant - break; - } - } - }, - - onInputBlur: function(aEvent) { - let tree = document.getElementById("engineList"); - if (!tree.hasAttribute("editing")) - return; - - // Accept input unless discarded. - let accept = aEvent.charCode != KeyEvent.DOM_VK_ESCAPE; - tree.stopEditing(accept); - }, - - onTreeSelect: function() { - document.getElementById("removeEngineButton").disabled = - !gEngineView.isEngineSelectedAndRemovable(); - }, - - onTreeKeyPress: function(aEvent) { - let index = gEngineView.selectedIndex; - let tree = document.getElementById("engineList"); - if (tree.hasAttribute("editing")) - return; - - if (aEvent.charCode == KeyEvent.DOM_VK_SPACE) { - // Space toggles the checkbox. - let newValue = !gEngineView._engineStore.engines[index].shown; - gEngineView.setCellValue(index, tree.columns.getFirstColumn(), - newValue.toString()); - // Prevent page from scrolling on the space key. - aEvent.preventDefault(); - } - else { - let isMac = Services.appinfo.OS == "Darwin"; - if ((isMac && aEvent.keyCode == KeyEvent.DOM_VK_RETURN) || - (!isMac && aEvent.keyCode == KeyEvent.DOM_VK_F2)) { - tree.startEditing(index, tree.columns.getLastColumn()); - } else if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE || - (isMac && aEvent.shiftKey && - aEvent.keyCode == KeyEvent.DOM_VK_BACK_SPACE && - gEngineView.isEngineSelectedAndRemovable())) { - // Delete and Shift+Backspace (Mac) removes selected engine. - Services.search.removeEngine(gEngineView.selectedEngine.originalEngine); - } - } - }, - - onRestoreDefaults: function() { - let num = gEngineView._engineStore.restoreDefaultEngines(); - gEngineView.rowCountChanged(0, num); - gEngineView.invalidate(); - }, - - showRestoreDefaults: function(aEnable) { - document.getElementById("restoreDefaultSearchEngines").disabled = !aEnable; - }, - - remove: function(aEngine) { - let index = gEngineView._engineStore.removeEngine(aEngine); - gEngineView.rowCountChanged(index, -1); - gEngineView.invalidate(); - gEngineView.selection.select(Math.min(index, gEngineView.lastIndex)); - gEngineView.ensureRowIsVisible(gEngineView.currentIndex); - document.getElementById("engineList").focus(); - }, - - editKeyword: Task.async(function* (aEngine, aNewKeyword) { - let keyword = aNewKeyword.trim(); - if (keyword) { - let eduplicate = false; - let dupName = ""; - - // Check for duplicates in Places keywords. - let bduplicate = !!(yield PlacesUtils.keywords.fetch(keyword)); - - // Check for duplicates in changes we haven't committed yet - let engines = gEngineView._engineStore.engines; - for (let engine of engines) { - if (engine.alias == keyword && - engine.name != aEngine.name) { - eduplicate = true; - dupName = engine.name; - break; - } - } - - // Notify the user if they have chosen an existing engine/bookmark keyword - if (eduplicate || bduplicate) { - let strings = document.getElementById("engineManagerBundle"); - let dtitle = strings.getString("duplicateTitle"); - let bmsg = strings.getString("duplicateBookmarkMsg"); - let emsg = strings.getFormattedString("duplicateEngineMsg", [dupName]); - - Services.prompt.alert(window, dtitle, eduplicate ? emsg : bmsg); - return false; - } - } - - gEngineView._engineStore.changeEngine(aEngine, "alias", keyword); - gEngineView.invalidate(); - return true; - }), - - saveOneClickEnginesList: function () { - let hiddenList = []; - for (let engine of gEngineView._engineStore.engines) { - if (!engine.shown) - hiddenList.push(engine.name); - } - document.getElementById("browser.search.hiddenOneOffs").value = - hiddenList.join(","); - }, - - setDefaultEngine: function () { - Services.search.currentEngine = - document.getElementById("defaultEngine").selectedItem.engine; - } -}; - -function onDragEngineStart(event) { - var selectedIndex = gEngineView.selectedIndex; - var tree = document.getElementById("engineList"); - var row = { }, col = { }, child = { }; - tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, child); - if (selectedIndex >= 0 && !gEngineView.isCheckBox(row.value, col.value)) { - event.dataTransfer.setData(ENGINE_FLAVOR, selectedIndex.toString()); - event.dataTransfer.effectAllowed = "move"; - } -} - - -function EngineStore() { - let pref = document.getElementById("browser.search.hiddenOneOffs").value; - this.hiddenList = pref ? pref.split(",") : []; - - this._engines = Services.search.getVisibleEngines().map(this._cloneEngine, this); - this._defaultEngines = Services.search.getDefaultEngines().map(this._cloneEngine, this); - - // check if we need to disable the restore defaults button - var someHidden = this._defaultEngines.some(e => e.hidden); - gSearchPane.showRestoreDefaults(someHidden); -} -EngineStore.prototype = { - _engines: null, - _defaultEngines: null, - - get engines() { - return this._engines; - }, - set engines(val) { - this._engines = val; - return val; - }, - - _getIndexForEngine: function ES_getIndexForEngine(aEngine) { - return this._engines.indexOf(aEngine); - }, - - _getEngineByName: function ES_getEngineByName(aName) { - return this._engines.find(engine => engine.name == aName); - }, - - _cloneEngine: function ES_cloneEngine(aEngine) { - var clonedObj={}; - for (var i in aEngine) - clonedObj[i] = aEngine[i]; - clonedObj.originalEngine = aEngine; - clonedObj.shown = this.hiddenList.indexOf(clonedObj.name) == -1; - return clonedObj; - }, - - // Callback for Array's some(). A thisObj must be passed to some() - _isSameEngine: function ES_isSameEngine(aEngineClone) { - return aEngineClone.originalEngine == this.originalEngine; - }, - - addEngine: function ES_addEngine(aEngine) { - this._engines.push(this._cloneEngine(aEngine)); - }, - - moveEngine: function ES_moveEngine(aEngine, aNewIndex) { - if (aNewIndex < 0 || aNewIndex > this._engines.length - 1) - throw new Error("ES_moveEngine: invalid aNewIndex!"); - var index = this._getIndexForEngine(aEngine); - if (index == -1) - throw new Error("ES_moveEngine: invalid engine?"); - - if (index == aNewIndex) - return; // nothing to do - - // Move the engine in our internal store - var removedEngine = this._engines.splice(index, 1)[0]; - this._engines.splice(aNewIndex, 0, removedEngine); - - Services.search.moveEngine(aEngine.originalEngine, aNewIndex); - }, - - removeEngine: function ES_removeEngine(aEngine) { - if (this._engines.length == 1) { - throw new Error("Cannot remove last engine!"); - } - - let engineName = aEngine.name; - let index = this._engines.findIndex(element => element.name == engineName); - - if (index == -1) - throw new Error("invalid engine?"); - - let removedEngine = this._engines.splice(index, 1)[0]; - - if (this._defaultEngines.some(this._isSameEngine, removedEngine)) - gSearchPane.showRestoreDefaults(true); - gSearchPane.buildDefaultEngineDropDown(); - return index; - }, - - restoreDefaultEngines: function ES_restoreDefaultEngines() { - var added = 0; - - for (var i = 0; i < this._defaultEngines.length; ++i) { - var e = this._defaultEngines[i]; - - // If the engine is already in the list, just move it. - if (this._engines.some(this._isSameEngine, e)) { - this.moveEngine(this._getEngineByName(e.name), i); - } else { - // Otherwise, add it back to our internal store - - // The search service removes the alias when an engine is hidden, - // so clear any alias we may have cached before unhiding the engine. - e.alias = ""; - - this._engines.splice(i, 0, e); - let engine = e.originalEngine; - engine.hidden = false; - Services.search.moveEngine(engine, i); - added++; - } - } - Services.search.resetToOriginalDefaultEngine(); - gSearchPane.showRestoreDefaults(false); - gSearchPane.buildDefaultEngineDropDown(); - return added; - }, - - changeEngine: function ES_changeEngine(aEngine, aProp, aNewValue) { - var index = this._getIndexForEngine(aEngine); - if (index == -1) - throw new Error("invalid engine?"); - - this._engines[index][aProp] = aNewValue; - aEngine.originalEngine[aProp] = aNewValue; - }, - - reloadIcons: function ES_reloadIcons() { - this._engines.forEach(function (e) { - e.uri = e.originalEngine.uri; - }); - } -}; - -function EngineView(aEngineStore) { - this._engineStore = aEngineStore; -} -EngineView.prototype = { - _engineStore: null, - tree: null, - - get lastIndex() { - return this.rowCount - 1; - }, - get selectedIndex() { - var seln = this.selection; - if (seln.getRangeCount() > 0) { - var min = {}; - seln.getRangeAt(0, min, {}); - return min.value; - } - return -1; - }, - get selectedEngine() { - return this._engineStore.engines[this.selectedIndex]; - }, - - // Helpers - rowCountChanged: function (index, count) { - this.tree.rowCountChanged(index, count); - }, - - invalidate: function () { - this.tree.invalidate(); - }, - - ensureRowIsVisible: function (index) { - this.tree.ensureRowIsVisible(index); - }, - - getSourceIndexFromDrag: function (dataTransfer) { - return parseInt(dataTransfer.getData(ENGINE_FLAVOR)); - }, - - isCheckBox: function(index, column) { - return column.id == "engineShown"; - }, - - isEngineSelectedAndRemovable: function() { - return this.selectedIndex != -1 && this.lastIndex != 0; - }, - - // nsITreeView - get rowCount() { - return this._engineStore.engines.length; - }, - - getImageSrc: function(index, column) { - if (column.id == "engineName") { - if (this._engineStore.engines[index].iconURI) - return this._engineStore.engines[index].iconURI.spec; - - if (window.devicePixelRatio > 1) - return "chrome://browser/skin/search-engine-placeholder@2x.png"; - return "chrome://browser/skin/search-engine-placeholder.png"; - } - - return ""; - }, - - getCellText: function(index, column) { - if (column.id == "engineName") - return this._engineStore.engines[index].name; - else if (column.id == "engineKeyword") - return this._engineStore.engines[index].alias; - return ""; - }, - - setTree: function(tree) { - this.tree = tree; - }, - - canDrop: function(targetIndex, orientation, dataTransfer) { - var sourceIndex = this.getSourceIndexFromDrag(dataTransfer); - return (sourceIndex != -1 && - sourceIndex != targetIndex && - sourceIndex != targetIndex + orientation); - }, - - drop: function(dropIndex, orientation, dataTransfer) { - var sourceIndex = this.getSourceIndexFromDrag(dataTransfer); - var sourceEngine = this._engineStore.engines[sourceIndex]; - - const nsITreeView = Components.interfaces.nsITreeView; - if (dropIndex > sourceIndex) { - if (orientation == nsITreeView.DROP_BEFORE) - dropIndex--; - } else if (orientation == nsITreeView.DROP_AFTER) { - dropIndex++; - } - - this._engineStore.moveEngine(sourceEngine, dropIndex); - gSearchPane.showRestoreDefaults(true); - gSearchPane.buildDefaultEngineDropDown(); - - // Redraw, and adjust selection - this.invalidate(); - this.selection.select(dropIndex); - }, - - selection: null, - getRowProperties: function(index) { return ""; }, - getCellProperties: function(index, column) { return ""; }, - getColumnProperties: function(column) { return ""; }, - isContainer: function(index) { return false; }, - isContainerOpen: function(index) { return false; }, - isContainerEmpty: function(index) { return false; }, - isSeparator: function(index) { return false; }, - isSorted: function(index) { return false; }, - getParentIndex: function(index) { return -1; }, - hasNextSibling: function(parentIndex, index) { return false; }, - getLevel: function(index) { return 0; }, - getProgressMode: function(index, column) { }, - getCellValue: function(index, column) { - if (column.id == "engineShown") - return this._engineStore.engines[index].shown; - return undefined; - }, - toggleOpenState: function(index) { }, - cycleHeader: function(column) { }, - selectionChanged: function() { }, - cycleCell: function(row, column) { }, - isEditable: function(index, column) { return column.id != "engineName"; }, - isSelectable: function(index, column) { return false; }, - setCellValue: function(index, column, value) { - if (column.id == "engineShown") { - this._engineStore.engines[index].shown = value == "true"; - gEngineView.invalidate(); - gSearchPane.saveOneClickEnginesList(); - } - }, - setCellText: function(index, column, value) { - if (column.id == "engineKeyword") { - gSearchPane.editKeyword(this._engineStore.engines[index], value) - .then(valid => { - if (!valid) - document.getElementById("engineList").startEditing(index, column); - }); - } - }, - performAction: function(action) { }, - performActionOnRow: function(action, index) { }, - performActionOnCell: function(action, index, column) { } -}; diff --git a/browser/components/preferences/in-content/search.xul b/browser/components/preferences/in-content/search.xul deleted file mode 100644 index 95c7acd85..000000000 --- a/browser/components/preferences/in-content/search.xul +++ /dev/null @@ -1,86 +0,0 @@ - <preferences id="searchPreferences" hidden="true" data-category="paneSearch"> - - <preference id="browser.search.suggest.enabled" - name="browser.search.suggest.enabled" - type="bool"/> - - <preference id="browser.urlbar.suggest.searches" - name="browser.urlbar.suggest.searches" - type="bool"/> - - <preference id="browser.search.hiddenOneOffs" - name="browser.search.hiddenOneOffs" - type="unichar"/> - - </preferences> - - <script type="application/javascript" - src="chrome://browser/content/preferences/in-content/search.js"/> - - <stringbundle id="engineManagerBundle" src="chrome://browser/locale/engineManager.properties"/> - - <hbox id="header-search" - class="header" - hidden="true" - data-category="paneSearch"> - <label class="header-name" flex="1">&paneSearch.title;</label> - <html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a> - </hbox> - - <!-- Default Search Engine --> - <groupbox id="defaultEngineGroup" align="start" data-category="paneSearch"> - <caption label="&defaultSearchEngine.label;"/> - <label>&chooseYourDefaultSearchEngine.label;</label> - <menulist id="defaultEngine"> - <menupopup/> - </menulist> - <checkbox id="suggestionsInSearchFieldsCheckbox" - label="&provideSearchSuggestions.label;" - accesskey="&provideSearchSuggestions.accesskey;" - preference="browser.search.suggest.enabled"/> - <vbox class="indent"> - <checkbox id="urlBarSuggestion" label="&showURLBarSuggestions.label;" - accesskey="&showURLBarSuggestions.accesskey;" - preference="browser.urlbar.suggest.searches"/> - <hbox id="urlBarSuggestionPermanentPBLabel" - align="center" class="indent"> - <label flex="1">&urlBarSuggestionsPermanentPB.label;</label> - </hbox> - </vbox> - </groupbox> - - <groupbox id="oneClickSearchProvidersGroup" data-category="paneSearch"> - <caption label="&oneClickSearchEngines.label;"/> - <label>&chooseWhichOneToDisplay.label;</label> - - <tree id="engineList" flex="1" rows="8" hidecolumnpicker="true" editable="true" - seltype="single"> - <treechildren id="engineChildren" flex="1"/> - <treecols> - <treecol id="engineShown" type="checkbox" editable="true" sortable="false"/> - <treecol id="engineName" flex="4" label="&engineNameColumn.label;" sortable="false"/> - <treecol id="engineKeyword" flex="1" label="&engineKeywordColumn.label;" editable="true" - sortable="false"/> - </treecols> - </tree> - - <hbox> - <button id="restoreDefaultSearchEngines" - label="&restoreDefaultSearchEngines.label;" - accesskey="&restoreDefaultSearchEngines.accesskey;" - /> - <spacer flex="1"/> - <button id="removeEngineButton" - class="searchEngineAction" - label="&removeEngine.label;" - accesskey="&removeEngine.accesskey;" - disabled="true" - /> - </hbox> - - <separator class="thin"/> - - <hbox id="addEnginesBox" pack="start"> - <label id="addEngines" class="text-link" value="&addMoreSearchEngines.label;"/> - </hbox> - </groupbox> diff --git a/browser/components/preferences/in-content/security.js b/browser/components/preferences/in-content/security.js deleted file mode 100644 index 37a187f9c..000000000 --- a/browser/components/preferences/in-content/security.js +++ /dev/null @@ -1,306 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper", - "resource://gre/modules/LoginHelper.jsm"); - -Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); - -var gSecurityPane = { - _pane: null, - - /** - * Initializes master password UI. - */ - init: function () - { - function setEventListener(aId, aEventType, aCallback) - { - document.getElementById(aId) - .addEventListener(aEventType, aCallback.bind(gSecurityPane)); - } - - this._pane = document.getElementById("paneSecurity"); - this._initMasterPasswordUI(); -#ifdef MOZ_SAFE_BROWSING - this._initSafeBrowsing(); -#endif - - setEventListener("addonExceptions", "command", - gSecurityPane.showAddonExceptions); - setEventListener("passwordExceptions", "command", - gSecurityPane.showPasswordExceptions); - setEventListener("useMasterPassword", "command", - gSecurityPane.updateMasterPasswordButton); - setEventListener("changeMasterPassword", "command", - gSecurityPane.changeMasterPassword); - setEventListener("showPasswords", "command", - gSecurityPane.showPasswords); - }, - - // ADD-ONS - - /* - * Preferences: - * - * xpinstall.whitelist.required - * - true if a site must be added to a site whitelist before extensions - * provided by the site may be installed from it, false if the extension - * may be directly installed after a confirmation dialog - */ - - /** - * Enables/disables the add-ons Exceptions button depending on whether - * or not add-on installation warnings are displayed. - */ - readWarnAddonInstall: function () - { - var warn = document.getElementById("xpinstall.whitelist.required"); - var exceptions = document.getElementById("addonExceptions"); - - exceptions.disabled = !warn.value; - - // don't override the preference value - return undefined; - }, - - /** - * Displays the exceptions lists for add-on installation warnings. - */ - showAddonExceptions: function () - { - var bundlePrefs = document.getElementById("bundlePreferences"); - - var params = this._addonParams; - if (!params.windowTitle || !params.introText) { - params.windowTitle = bundlePrefs.getString("addons_permissions_title"); - params.introText = bundlePrefs.getString("addonspermissionstext"); - } - - gSubDialog.open("chrome://browser/content/preferences/permissions.xul", - null, params); - }, - - /** - * Parameters for the add-on install permissions dialog. - */ - _addonParams: - { - blockVisible: false, - sessionVisible: false, - allowVisible: true, - prefilledHost: "", - permissionType: "install" - }, - - // PASSWORDS - - /* - * Preferences: - * - * signon.rememberSignons - * - true if passwords are remembered, false otherwise - */ - - /** - * Enables/disables the Exceptions button used to configure sites where - * passwords are never saved. When browser is set to start in Private - * Browsing mode, the "Remember passwords" UI is useless, so we disable it. - */ - readSavePasswords: function () - { - var pref = document.getElementById("signon.rememberSignons"); - var excepts = document.getElementById("passwordExceptions"); - - if (PrivateBrowsingUtils.permanentPrivateBrowsing) { - document.getElementById("savePasswords").disabled = true; - excepts.disabled = true; - return false; - } - excepts.disabled = !pref.value; - // don't override pref value in UI - return undefined; - }, - - /** - * Displays a dialog in which the user can view and modify the list of sites - * where passwords are never saved. - */ - showPasswordExceptions: function () - { - var bundlePrefs = document.getElementById("bundlePreferences"); - var params = { - blockVisible: true, - sessionVisible: false, - allowVisible: false, - hideStatusColumn: true, - prefilledHost: "", - permissionType: "login-saving", - windowTitle: bundlePrefs.getString("savedLoginsExceptions_title"), - introText: bundlePrefs.getString("savedLoginsExceptions_desc") - }; - - gSubDialog.open("chrome://browser/content/preferences/permissions.xul", - null, params); - }, - - /** - * Initializes master password UI: the "use master password" checkbox, selects - * the master password button to show, and enables/disables it as necessary. - * The master password is controlled by various bits of NSS functionality, so - * the UI for it can't be controlled by the normal preference bindings. - */ - _initMasterPasswordUI: function () - { - var noMP = !LoginHelper.isMasterPasswordSet(); - - var button = document.getElementById("changeMasterPassword"); - button.disabled = noMP; - - var checkbox = document.getElementById("useMasterPassword"); - checkbox.checked = !noMP; - }, - -#ifdef MOZ_SAFE_BROWSING - _initSafeBrowsing() { - let enableSafeBrowsing = document.getElementById("enableSafeBrowsing"); - let blockDownloads = document.getElementById("blockDownloads"); - let blockUncommonUnwanted = document.getElementById("blockUncommonUnwanted"); - - let safeBrowsingPhishingPref = document.getElementById("browser.safebrowsing.phishing.enabled"); - let safeBrowsingMalwarePref = document.getElementById("browser.safebrowsing.malware.enabled"); - - let blockDownloadsPref = document.getElementById("browser.safebrowsing.downloads.enabled"); - let malwareTable = document.getElementById("urlclassifier.malwareTable"); - - let blockUnwantedPref = document.getElementById("browser.safebrowsing.downloads.remote.block_potentially_unwanted"); - let blockUncommonPref = document.getElementById("browser.safebrowsing.downloads.remote.block_uncommon"); - - enableSafeBrowsing.addEventListener("command", function() { - safeBrowsingPhishingPref.value = enableSafeBrowsing.checked; - safeBrowsingMalwarePref.value = enableSafeBrowsing.checked; - - if (enableSafeBrowsing.checked) { - blockDownloads.removeAttribute("disabled"); - if (blockDownloads.checked) { - blockUncommonUnwanted.removeAttribute("disabled"); - } - } else { - blockDownloads.setAttribute("disabled", "true"); - blockUncommonUnwanted.setAttribute("disabled", "true"); - } - }); - - blockDownloads.addEventListener("command", function() { - blockDownloadsPref.value = blockDownloads.checked; - if (blockDownloads.checked) { - blockUncommonUnwanted.removeAttribute("disabled"); - } else { - blockUncommonUnwanted.setAttribute("disabled", "true"); - } - }); - - blockUncommonUnwanted.addEventListener("command", function() { - blockUnwantedPref.value = blockUncommonUnwanted.checked; - blockUncommonPref.value = blockUncommonUnwanted.checked; - - let malware = malwareTable.value - .split(",") - .filter(x => x !== "goog-unwanted-shavar" && x !== "test-unwanted-simple"); - - if (blockUncommonUnwanted.checked) { - malware.push("goog-unwanted-shavar"); - malware.push("test-unwanted-simple"); - } - - // sort alphabetically to keep the pref consistent - malware.sort(); - - malwareTable.value = malware.join(","); - }); - - // set initial values - - enableSafeBrowsing.checked = safeBrowsingPhishingPref.value && safeBrowsingMalwarePref.value; - if (!enableSafeBrowsing.checked) { - blockDownloads.setAttribute("disabled", "true"); - blockUncommonUnwanted.setAttribute("disabled", "true"); - } - - blockDownloads.checked = blockDownloadsPref.value; - if (!blockDownloadsPref.value) { - blockUncommonUnwanted.setAttribute("disabled", "true"); - } - - blockUncommonUnwanted.checked = blockUnwantedPref.value && blockUncommonPref.value; - }, -#endif - - /** - * Enables/disables the master password button depending on the state of the - * "use master password" checkbox, and prompts for master password removal if - * one is set. - */ - updateMasterPasswordButton: function () - { - var checkbox = document.getElementById("useMasterPassword"); - var button = document.getElementById("changeMasterPassword"); - button.disabled = !checkbox.checked; - - // unchecking the checkbox should try to immediately remove the master - // password, because it's impossible to non-destructively remove the master - // password used to encrypt all the passwords without providing it (by - // design), and it would be extremely odd to pop up that dialog when the - // user closes the prefwindow and saves his settings - if (!checkbox.checked) - this._removeMasterPassword(); - else - this.changeMasterPassword(); - - this._initMasterPasswordUI(); - }, - - /** - * Displays the "remove master password" dialog to allow the user to remove - * the current master password. When the dialog is dismissed, master password - * UI is automatically updated. - */ - _removeMasterPassword: function () - { - var secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]. - getService(Ci.nsIPKCS11ModuleDB); - if (secmodDB.isFIPSEnabled) { - var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"]. - getService(Ci.nsIPromptService); - var bundle = document.getElementById("bundlePreferences"); - promptService.alert(window, - bundle.getString("pw_change_failed_title"), - bundle.getString("pw_change2empty_in_fips_mode")); - this._initMasterPasswordUI(); - } - else { - gSubDialog.open("chrome://mozapps/content/preferences/removemp.xul", - null, null, this._initMasterPasswordUI.bind(this)); - } - }, - - /** - * Displays a dialog in which the master password may be changed. - */ - changeMasterPassword: function () - { - gSubDialog.open("chrome://mozapps/content/preferences/changemp.xul", - "resizable=no", null, this._initMasterPasswordUI.bind(this)); - }, - - /** - * Shows the sites where the user has saved passwords and the associated login - * information. - */ - showPasswords: function () - { - gSubDialog.open("chrome://passwordmgr/content/passwordManager.xul"); - } - -}; diff --git a/browser/components/preferences/in-content/security.xul b/browser/components/preferences/in-content/security.xul deleted file mode 100644 index 33e1471bd..000000000 --- a/browser/components/preferences/in-content/security.xul +++ /dev/null @@ -1,141 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<!-- Security panel --> - -<script type="application/javascript" - src="chrome://browser/content/preferences/in-content/security.js"/> - -<preferences id="securityPreferences" hidden="true" data-category="paneSecurity"> - <!-- XXX buttons --> - <preference id="pref.privacy.disable_button.view_passwords" - name="pref.privacy.disable_button.view_passwords" - type="bool"/> - <preference id="pref.privacy.disable_button.view_passwords_exceptions" - name="pref.privacy.disable_button.view_passwords_exceptions" - type="bool"/> - - <!-- Add-ons --> - <preference id="xpinstall.whitelist.required" - name="xpinstall.whitelist.required" - type="bool"/> - -#ifdef MOZ_SAFE_BROWSING - <!-- Malware, phishing --> - <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="browser.safebrowsing.downloads.enabled" - name="browser.safebrowsing.downloads.enabled" - type="bool"/> - - <preference id="urlclassifier.malwareTable" - name="urlclassifier.malwareTable" - type="string"/> - - <preference id="browser.safebrowsing.downloads.remote.block_potentially_unwanted" - name="browser.safebrowsing.downloads.remote.block_potentially_unwanted" - type="bool"/> - <preference id="browser.safebrowsing.downloads.remote.block_uncommon" - name="browser.safebrowsing.downloads.remote.block_uncommon" - type="bool"/> -#endif - - <!-- Passwords --> - <preference id="signon.rememberSignons" name="signon.rememberSignons" type="bool"/> - <preference id="signon.autofillForms" name="signon.autofillForms" type="bool"/> - -</preferences> - -<hbox id="header-security" - class="header" - hidden="true" - data-category="paneSecurity"> - <label class="header-name" flex="1">&paneSecurity.title;</label> - <html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a> -</hbox> - -<!-- addons --> -<groupbox id="addonsPhishingGroup" data-category="paneSecurity" hidden="true"> - <caption><label>&general.label;</label></caption> - - <hbox id="addonInstallBox"> - <checkbox id="warnAddonInstall" - label="&warnAddonInstall.label;" - accesskey="&warnAddonInstall.accesskey;" - preference="xpinstall.whitelist.required" - onsyncfrompreference="return gSecurityPane.readWarnAddonInstall();"/> - <spacer flex="1"/> - <button id="addonExceptions" - label="&addonExceptions.label;" - accesskey="&addonExceptions.accesskey;"/> - </hbox> - -#ifdef MOZ_SAFE_BROWSING -<!-- Safebrowsing (phishing) UI --> - <separator class="thin"/> - <vbox align="start"> - <checkbox id="enableSafeBrowsing" - label="&enableSafeBrowsing.label;" - accesskey="&enableSafeBrowsing.accesskey;" /> - <vbox class="indent"> - <checkbox id="blockDownloads" - label="&blockDownloads.label;" - accesskey="&blockDownloads.accesskey;" /> - <checkbox id="blockUncommonUnwanted" - label="&blockUncommonUnwanted.label;" - accesskey="&blockUncommonUnwanted.accesskey;" /> - </vbox> - </vbox> -#endif -</groupbox> - -<!-- Passwords --> -<groupbox id="passwordsGroup" orient="vertical" data-category="paneSecurity" hidden="true"> - <caption><label>&logins.label;</label></caption> - - <hbox id="savePasswordsBox"> - <checkbox id="savePasswords" - label="&rememberLogins.label;" accesskey="&rememberLogins.accesskey;" - preference="signon.rememberSignons" - onsyncfrompreference="return gSecurityPane.readSavePasswords();"/> - <spacer flex="1"/> - <button id="passwordExceptions" - label="&passwordExceptions.label;" - accesskey="&passwordExceptions.accesskey;" - preference="pref.privacy.disable_button.view_passwords_exceptions"/> - </hbox> - <checkbox id="autofillPasswords" flex="1" - label="&autofillPasswords.label;" accesskey="&autofillPasswords.accesskey;" - preference="signon.autofillForms"/> - <grid id="passwordGrid"> - <columns> - <column flex="1"/> - <column/> - </columns> - <rows id="passwordRows"> - <row id="masterPasswordRow"> - <hbox id="masterPasswordBox"> - <checkbox id="useMasterPassword" - label="&useMasterPassword.label;" - accesskey="&useMasterPassword.accesskey;"/> - <spacer flex="1"/> - </hbox> - <button id="changeMasterPassword" - label="&changeMasterPassword.label;" - accesskey="&changeMasterPassword.accesskey;"/> - </row> - <row id="showPasswordRow"> - <hbox id="showPasswordsBox"/> - <button id="showPasswords" - label="&savedLogins.label;" accesskey="&savedLogins.accesskey;" - preference="pref.privacy.disable_button.view_passwords"/> - </row> - </rows> - </grid> -</groupbox> diff --git a/browser/components/preferences/in-content/subdialogs.js b/browser/components/preferences/in-content/subdialogs.js deleted file mode 100644 index bb8d0048f..000000000 --- a/browser/components/preferences/in-content/subdialogs.js +++ /dev/null @@ -1,434 +0,0 @@ -/* - This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this file, - - You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -var gSubDialog = { - _closingCallback: null, - _closingEvent: null, - _isClosing: false, - _frame: null, - _overlay: null, - _box: null, - _injectedStyleSheets: [ - "chrome://browser/skin/preferences/preferences.css", - "chrome://global/skin/in-content/common.css", - "chrome://browser/skin/preferences/in-content/preferences.css", - "chrome://browser/skin/preferences/in-content/dialog.css", - ], - _resizeObserver: null, - - init: function() { - this._frame = document.getElementById("dialogFrame"); - this._overlay = document.getElementById("dialogOverlay"); - this._box = document.getElementById("dialogBox"); - this._closeButton = document.getElementById("dialogClose"); - }, - - updateTitle: function(aEvent) { - if (aEvent.target != gSubDialog._frame.contentDocument) - return; - document.getElementById("dialogTitle").textContent = gSubDialog._frame.contentDocument.title; - }, - - injectXMLStylesheet: function(aStylesheetURL) { - let contentStylesheet = this._frame.contentDocument.createProcessingInstruction( - 'xml-stylesheet', - 'href="' + aStylesheetURL + '" type="text/css"' - ); - this._frame.contentDocument.insertBefore(contentStylesheet, - this._frame.contentDocument.documentElement); - }, - - open: function(aURL, aFeatures = null, aParams = null, aClosingCallback = null) { - // If we're already open/opening on this URL, do nothing. - if (this._openedURL == aURL && !this._isClosing) { - return; - } - // If we're open on some (other) URL or we're closing, open when closing has finished. - if (this._openedURL || this._isClosing) { - if (!this._isClosing) { - this.close(); - } - let args = Array.from(arguments); - this._closingPromise.then(() => { - this.open.apply(this, args); - }); - return; - } - this._addDialogEventListeners(); - - let features = (aFeatures ? aFeatures + "," : "") + "resizable,dialog=no,centerscreen"; - let dialog = window.openDialog(aURL, "dialogFrame", features, aParams); - if (aClosingCallback) { - this._closingCallback = aClosingCallback.bind(dialog); - } - - this._closingEvent = null; - this._isClosing = false; - this._openedURL = aURL; - - features = features.replace(/,/g, "&"); - let featureParams = new URLSearchParams(features.toLowerCase()); - this._box.setAttribute("resizable", featureParams.has("resizable") && - featureParams.get("resizable") != "no" && - featureParams.get("resizable") != "0"); - }, - - close: function(aEvent = null) { - if (this._isClosing) { - return; - } - this._isClosing = true; - this._closingPromise = new Promise(resolve => { - this._resolveClosePromise = resolve; - }); - - if (this._closingCallback) { - try { - this._closingCallback.call(null, aEvent); - } catch (ex) { - Cu.reportError(ex); - } - this._closingCallback = null; - } - - this._removeDialogEventListeners(); - - this._overlay.style.visibility = ""; - // Clear the sizing inline styles. - this._frame.removeAttribute("style"); - // Clear the sizing attributes - this._box.removeAttribute("width"); - this._box.removeAttribute("height"); - this._box.style.removeProperty("min-height"); - this._box.style.removeProperty("min-width"); - - setTimeout(() => { - // Unload the dialog after the event listeners run so that the load of about:blank isn't - // cancelled by the ESC <key>. - let onBlankLoad = e => { - if (this._frame.contentWindow.location.href == "about:blank") { - this._frame.removeEventListener("load", onBlankLoad); - // We're now officially done closing, so update the state to reflect that. - delete this._openedURL; - this._isClosing = false; - this._resolveClosePromise(); - } - }; - this._frame.addEventListener("load", onBlankLoad); - this._frame.loadURI("about:blank"); - }, 0); - }, - - handleEvent: function(aEvent) { - switch (aEvent.type) { - case "command": - this._frame.contentWindow.close(); - break; - case "dialogclosing": - this._onDialogClosing(aEvent); - break; - case "DOMTitleChanged": - this.updateTitle(aEvent); - break; - case "DOMFrameContentLoaded": - this._onContentLoaded(aEvent); - break; - case "load": - this._onLoad(aEvent); - break; - case "unload": - this._onUnload(aEvent); - break; - case "keydown": - this._onKeyDown(aEvent); - break; - case "focus": - this._onParentWinFocus(aEvent); - break; - } - }, - - /* Private methods */ - - _onUnload: function(aEvent) { - if (aEvent.target.location.href == this._openedURL) { - this._frame.contentWindow.close(); - } - }, - - _onContentLoaded: function(aEvent) { - if (aEvent.target != this._frame || aEvent.target.contentWindow.location == "about:blank") { - return; - } - - for (let styleSheetURL of this._injectedStyleSheets) { - this.injectXMLStylesheet(styleSheetURL); - } - - // Provide the ability for the dialog to know that it is being loaded "in-content". - this._frame.contentDocument.documentElement.setAttribute("subdialog", "true"); - - this._frame.contentWindow.addEventListener("dialogclosing", this); - - let oldResizeBy = this._frame.contentWindow.resizeBy; - this._frame.contentWindow.resizeBy = function(resizeByWidth, resizeByHeight) { - // Only handle resizeByHeight currently. - let frameHeight = gSubDialog._frame.clientHeight; - let boxMinHeight = parseFloat(getComputedStyle(gSubDialog._box).minHeight, 10); - - gSubDialog._frame.style.height = (frameHeight + resizeByHeight) + "px"; - gSubDialog._box.style.minHeight = (boxMinHeight + resizeByHeight) + "px"; - - oldResizeBy.call(gSubDialog._frame.contentWindow, resizeByWidth, resizeByHeight); - }; - - // Make window.close calls work like dialog closing. - let oldClose = this._frame.contentWindow.close; - this._frame.contentWindow.close = function() { - var closingEvent = gSubDialog._closingEvent; - if (!closingEvent) { - closingEvent = new CustomEvent("dialogclosing", { - bubbles: true, - detail: { button: null }, - }); - - gSubDialog._frame.contentWindow.dispatchEvent(closingEvent); - } - - gSubDialog.close(closingEvent); - oldClose.call(gSubDialog._frame.contentWindow); - }; - - // XXX: Hack to make focus during the dialog's load functions work. Make the element visible - // sooner in DOMContentLoaded but mostly invisible instead of changing visibility just before - // the dialog's load event. - this._overlay.style.visibility = "visible"; - this._overlay.style.opacity = "0.01"; - }, - - _onLoad: function(aEvent) { - if (aEvent.target.contentWindow.location == "about:blank") { - return; - } - - // Do this on load to wait for the CSS to load and apply before calculating the size. - let docEl = this._frame.contentDocument.documentElement; - - let groupBoxTitle = document.getAnonymousElementByAttribute(this._box, "class", "groupbox-title"); - let groupBoxTitleHeight = groupBoxTitle.clientHeight + - parseFloat(getComputedStyle(groupBoxTitle).borderBottomWidth); - - let groupBoxBody = document.getAnonymousElementByAttribute(this._box, "class", "groupbox-body"); - // These are deduced from styles which we don't change, so it's safe to get them now: - let boxVerticalPadding = 2 * parseFloat(getComputedStyle(groupBoxBody).paddingTop); - let boxHorizontalPadding = 2 * parseFloat(getComputedStyle(groupBoxBody).paddingLeft); - let boxHorizontalBorder = 2 * parseFloat(getComputedStyle(this._box).borderLeftWidth); - let boxVerticalBorder = 2 * parseFloat(getComputedStyle(this._box).borderTopWidth); - - // The difference between the frame and box shouldn't change, either: - let boxRect = this._box.getBoundingClientRect(); - let frameRect = this._frame.getBoundingClientRect(); - let frameSizeDifference = (frameRect.top - boxRect.top) + (boxRect.bottom - frameRect.bottom); - - // Then determine and set a bunch of width stuff: - let frameMinWidth = docEl.style.width || docEl.scrollWidth + "px"; - let frameWidth = docEl.getAttribute("width") ? docEl.getAttribute("width") + "px" : - frameMinWidth; - this._frame.style.width = frameWidth; - this._box.style.minWidth = "calc(" + - (boxHorizontalBorder + boxHorizontalPadding) + - "px + " + frameMinWidth + ")"; - - // Now do the same but for the height. We need to do this afterwards because otherwise - // XUL assumes we'll optimize for height and gives us "wrong" values which then are no - // longer correct after we set the width: - let frameMinHeight = docEl.style.height || docEl.scrollHeight + "px"; - let frameHeight = docEl.getAttribute("height") ? docEl.getAttribute("height") + "px" : - frameMinHeight; - - // Now check if the frame height we calculated is possible at this window size, - // accounting for titlebar, padding/border and some spacing. - let maxHeight = window.innerHeight - frameSizeDifference - 30; - // Do this with a frame height in pixels... - let comparisonFrameHeight; - if (frameHeight.endsWith("em")) { - let fontSize = parseFloat(getComputedStyle(this._frame).fontSize); - comparisonFrameHeight = parseFloat(frameHeight, 10) * fontSize; - } else if (frameHeight.endsWith("px")) { - comparisonFrameHeight = parseFloat(frameHeight, 10); - } else { - Cu.reportError("This dialog (" + this._frame.contentWindow.location.href + ") " + - "set a height in non-px-non-em units ('" + frameHeight + "'), " + - "which is likely to lead to bad sizing in in-content preferences. " + - "Please consider changing this."); - comparisonFrameHeight = parseFloat(frameHeight); - } - - if (comparisonFrameHeight > maxHeight) { - // If the height is bigger than that of the window, we should let the contents scroll: - frameHeight = maxHeight + "px"; - frameMinHeight = maxHeight + "px"; - let containers = this._frame.contentDocument.querySelectorAll('.largeDialogContainer'); - for (let container of containers) { - container.classList.add("doScroll"); - } - } - - this._frame.style.height = frameHeight; - this._box.style.minHeight = "calc(" + - (boxVerticalBorder + groupBoxTitleHeight + boxVerticalPadding) + - "px + " + frameMinHeight + ")"; - - this._overlay.style.visibility = "visible"; - this._overlay.style.opacity = ""; // XXX: focus hack continued from _onContentLoaded - - if (this._box.getAttribute("resizable") == "true") { - this._resizeObserver = new MutationObserver(this._onResize); - this._resizeObserver.observe(this._box, {attributes: true}); - } - - this._trapFocus(); - }, - - _onResize: function(mutations) { - let frame = gSubDialog._frame; - // The width and height styles are needed for the initial - // layout of the frame, but afterward they need to be removed - // or their presence will restrict the contents of the <browser> - // from resizing to a smaller size. - frame.style.removeProperty("width"); - frame.style.removeProperty("height"); - - let docEl = frame.contentDocument.documentElement; - let persistedAttributes = docEl.getAttribute("persist"); - if (!persistedAttributes || - (!persistedAttributes.includes("width") && - !persistedAttributes.includes("height"))) { - return; - } - - for (let mutation of mutations) { - if (mutation.attributeName == "width") { - docEl.setAttribute("width", docEl.scrollWidth); - } else if (mutation.attributeName == "height") { - docEl.setAttribute("height", docEl.scrollHeight); - } - } - }, - - _onDialogClosing: function(aEvent) { - this._frame.contentWindow.removeEventListener("dialogclosing", this); - this._closingEvent = aEvent; - }, - - _onKeyDown: function(aEvent) { - if (aEvent.currentTarget == window && aEvent.keyCode == aEvent.DOM_VK_ESCAPE && - !aEvent.defaultPrevented) { - this.close(aEvent); - return; - } - if (aEvent.keyCode != aEvent.DOM_VK_TAB || - aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey) { - return; - } - - let fm = Services.focus; - - function isLastFocusableElement(el) { - // XXXgijs unfortunately there is no way to get the last focusable element without asking - // the focus manager to move focus to it. - let rv = el == fm.moveFocus(gSubDialog._frame.contentWindow, null, fm.MOVEFOCUS_LAST, 0); - fm.setFocus(el, 0); - return rv; - } - - let forward = !aEvent.shiftKey; - // check if focus is leaving the frame (incl. the close button): - if ((aEvent.target == this._closeButton && !forward) || - (isLastFocusableElement(aEvent.originalTarget) && forward)) { - aEvent.preventDefault(); - aEvent.stopImmediatePropagation(); - let parentWin = this._getBrowser().ownerGlobal; - if (forward) { - fm.moveFocus(parentWin, null, fm.MOVEFOCUS_FIRST, fm.FLAG_BYKEY); - } else { - // Somehow, moving back 'past' the opening doc is not trivial. Cheat by doing it in 2 steps: - fm.moveFocus(window, null, fm.MOVEFOCUS_ROOT, fm.FLAG_BYKEY); - fm.moveFocus(parentWin, null, fm.MOVEFOCUS_BACKWARD, fm.FLAG_BYKEY); - } - } - }, - - _onParentWinFocus: function(aEvent) { - // Explicitly check for the focus target of |window| to avoid triggering this when the window - // is refocused - if (aEvent.target != this._closeButton && aEvent.target != window) { - this._closeButton.focus(); - } - }, - - _addDialogEventListeners: function() { - // Make the close button work. - this._closeButton.addEventListener("command", this); - - // DOMTitleChanged isn't fired on the frame, only on the chromeEventHandler - let chromeBrowser = this._getBrowser(); - chromeBrowser.addEventListener("DOMTitleChanged", this, true); - - // Similarly DOMFrameContentLoaded only fires on the top window - window.addEventListener("DOMFrameContentLoaded", this, true); - - // Wait for the stylesheets injected during DOMContentLoaded to load before showing the dialog - // otherwise there is a flicker of the stylesheet applying. - this._frame.addEventListener("load", this); - - chromeBrowser.addEventListener("unload", this, true); - // Ensure we get <esc> keypresses even if nothing in the subdialog is focusable - // (happens on OS X when only text inputs and lists are focusable, and - // the subdialog only has checkboxes/radiobuttons/buttons) - window.addEventListener("keydown", this, true); - }, - - _removeDialogEventListeners: function() { - let chromeBrowser = this._getBrowser(); - chromeBrowser.removeEventListener("DOMTitleChanged", this, true); - chromeBrowser.removeEventListener("unload", this, true); - - this._closeButton.removeEventListener("command", this); - - window.removeEventListener("DOMFrameContentLoaded", this, true); - this._frame.removeEventListener("load", this); - this._frame.contentWindow.removeEventListener("dialogclosing", this); - window.removeEventListener("keydown", this, true); - if (this._resizeObserver) { - this._resizeObserver.disconnect(); - this._resizeObserver = null; - } - this._untrapFocus(); - }, - - _trapFocus: function() { - let fm = Services.focus; - fm.moveFocus(this._frame.contentWindow, null, fm.MOVEFOCUS_FIRST, 0); - this._frame.contentDocument.addEventListener("keydown", this, true); - this._closeButton.addEventListener("keydown", this); - - window.addEventListener("focus", this, true); - }, - - _untrapFocus: function() { - this._frame.contentDocument.removeEventListener("keydown", this, true); - this._closeButton.removeEventListener("keydown", this); - window.removeEventListener("focus", this); - }, - - _getBrowser: function() { - return window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell) - .chromeEventHandler; - }, -}; diff --git a/browser/components/preferences/in-content/sync.js b/browser/components/preferences/in-content/sync.js deleted file mode 100644 index 27f7cd48c..000000000 --- a/browser/components/preferences/in-content/sync.js +++ /dev/null @@ -1,673 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -Components.utils.import("resource://services-sync/main.js"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () { - return Components.utils.import("resource://gre/modules/FxAccountsCommon.js", {}); -}); - -XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", - "resource://gre/modules/FxAccounts.jsm"); - -const PAGE_NO_ACCOUNT = 0; -const PAGE_HAS_ACCOUNT = 1; -const PAGE_NEEDS_UPDATE = 2; -const FXA_PAGE_LOGGED_OUT = 3; -const FXA_PAGE_LOGGED_IN = 4; - -// Indexes into the "login status" deck. -// We are in a successful verified state - everything should work! -const FXA_LOGIN_VERIFIED = 0; -// We have logged in to an unverified account. -const FXA_LOGIN_UNVERIFIED = 1; -// We are logged in locally, but the server rejected our credentials. -const FXA_LOGIN_FAILED = 2; - -var gSyncPane = { - prefArray: ["engine.bookmarks", "engine.passwords", "engine.prefs", - "engine.tabs", "engine.history"], - - 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.textContent = Weave.Utils.getErrorString(Weave.Status.login); - label.className = "error"; - }, - - init: function () { - this._setupEventListeners(); - - // If the Service hasn't finished initializing, wait for it. - let xps = Components.classes["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; - - if (xps.ready) { - this._init(); - return; - } - - // it may take some time before we can determine what provider to use - // and the state of that provider, so show the "please wait" page. - this._showLoadPage(xps); - - let onUnload = function () { - window.removeEventListener("unload", onUnload, false); - try { - Services.obs.removeObserver(onReady, "weave:service:ready"); - } catch (e) {} - }; - - let onReady = function () { - Services.obs.removeObserver(onReady, "weave:service:ready"); - window.removeEventListener("unload", onUnload, false); - this._init(); - }.bind(this); - - Services.obs.addObserver(onReady, "weave:service:ready", false); - window.addEventListener("unload", onUnload, false); - - xps.ensureLoaded(); - }, - - _showLoadPage: function (xps) { - let username; - try { - username = Services.prefs.getCharPref("services.sync.username"); - } catch (e) {} - if (!username) { - this.page = FXA_PAGE_LOGGED_OUT; - } else if (xps.fxAccountsEnabled) { - // Use cached values while we wait for the up-to-date values - let cachedComputerName; - try { - cachedComputerName = Services.prefs.getCharPref("services.sync.client.name"); - } - catch (e) { - cachedComputerName = ""; - } - document.getElementById("fxaEmailAddress1").textContent = username; - this._populateComputerName(cachedComputerName); - this.page = FXA_PAGE_LOGGED_IN; - } else { // Old Sync - this.page = PAGE_HAS_ACCOUNT; - } - }, - - _init: function () { - let topics = ["weave:service:login:error", - "weave:service:login:finish", - "weave:service:start-over:finish", - "weave:service:setup-complete", - "weave:service:logout:finish", - FxAccountsCommon.ONVERIFIED_NOTIFICATION, - FxAccountsCommon.ONLOGIN_NOTIFICATION, - FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION, - ]; - // Add the observers now and remove them on unload - // XXXzpao This should use Services.obs.* but Weave's Obs does nice handling - // of `this`. Fix in a followup. (bug 583347) - topics.forEach(function (topic) { - Weave.Svc.Obs.add(topic, this.updateWeavePrefs, this); - }, this); - - window.addEventListener("unload", function() { - topics.forEach(function (topic) { - Weave.Svc.Obs.remove(topic, this.updateWeavePrefs, this); - }, gSyncPane); - }, false); - - XPCOMUtils.defineLazyGetter(this, '_stringBundle', () => { - return Services.strings.createBundle("chrome://browser/locale/preferences/preferences.properties"); - }); - - XPCOMUtils.defineLazyGetter(this, '_accountsStringBundle', () => { - return Services.strings.createBundle("chrome://browser/locale/accounts.properties"); - }); - - let url = Services.prefs.getCharPref("identity.mobilepromo.android") + "sync-preferences"; - document.getElementById("fxaMobilePromo-android").setAttribute("href", url); - document.getElementById("fxaMobilePromo-android-hasFxaAccount").setAttribute("href", url); - url = Services.prefs.getCharPref("identity.mobilepromo.ios") + "sync-preferences"; - document.getElementById("fxaMobilePromo-ios").setAttribute("href", url); - document.getElementById("fxaMobilePromo-ios-hasFxaAccount").setAttribute("href", url); - - document.getElementById("tosPP-small-ToS").setAttribute("href", gSyncUtils.tosURL); - document.getElementById("tosPP-normal-ToS").setAttribute("href", gSyncUtils.tosURL); - document.getElementById("tosPP-small-PP").setAttribute("href", gSyncUtils.privacyPolicyURL); - document.getElementById("tosPP-normal-PP").setAttribute("href", gSyncUtils.privacyPolicyURL); - - fxAccounts.promiseAccountsManageURI(this._getEntryPoint()).then(url => { - document.getElementById("verifiedManage").setAttribute("href", url); - }); - - this.updateWeavePrefs(); - - this._initProfileImageUI(); - }, - - _toggleComputerNameControls: function(editMode) { - let textbox = document.getElementById("fxaSyncComputerName"); - textbox.disabled = !editMode; - document.getElementById("fxaChangeDeviceName").hidden = editMode; - document.getElementById("fxaCancelChangeDeviceName").hidden = !editMode; - document.getElementById("fxaSaveChangeDeviceName").hidden = !editMode; - }, - - _focusComputerNameTextbox: function() { - let textbox = document.getElementById("fxaSyncComputerName"); - let valLength = textbox.value.length; - textbox.focus(); - textbox.setSelectionRange(valLength, valLength); - }, - - _blurComputerNameTextbox: function() { - document.getElementById("fxaSyncComputerName").blur(); - }, - - _focusAfterComputerNameTextbox: function() { - // Focus the most appropriate element that's *not* the "computer name" box. - Services.focus.moveFocus(window, - document.getElementById("fxaSyncComputerName"), - Services.focus.MOVEFOCUS_FORWARD, 0); - }, - - _updateComputerNameValue: function(save) { - if (save) { - let textbox = document.getElementById("fxaSyncComputerName"); - Weave.Service.clientsEngine.localName = textbox.value; - } - this._populateComputerName(Weave.Service.clientsEngine.localName); - }, - - _setupEventListeners: function() { - function setEventListener(aId, aEventType, aCallback) - { - document.getElementById(aId) - .addEventListener(aEventType, aCallback.bind(gSyncPane)); - } - - setEventListener("noAccountSetup", "click", function (aEvent) { - aEvent.stopPropagation(); - gSyncPane.openSetup(null); - }); - setEventListener("noAccountPair", "click", function (aEvent) { - aEvent.stopPropagation(); - gSyncPane.openSetup('pair'); - }); - setEventListener("syncChangePassword", "command", - () => gSyncUtils.changePassword()); - setEventListener("syncResetPassphrase", "command", - () => gSyncUtils.resetPassphrase()); - setEventListener("syncReset", "command", gSyncPane.resetSync); - setEventListener("syncAddDeviceLabel", "click", function () { - gSyncPane.openAddDevice(); - return false; - }); - setEventListener("syncEnginesList", "select", function () { - if (this.selectedCount) - this.clearSelection(); - }); - setEventListener("syncComputerName", "change", function (e) { - gSyncUtils.changeName(e.target); - }); - setEventListener("fxaChangeDeviceName", "command", function () { - this._toggleComputerNameControls(true); - this._focusComputerNameTextbox(); - }); - setEventListener("fxaCancelChangeDeviceName", "command", function () { - // We explicitly blur the textbox because of bug 75324, then after - // changing the state of the buttons, force focus to whatever the focus - // manager thinks should be next (which on the mac, depends on an OSX - // keyboard access preference) - this._blurComputerNameTextbox(); - this._toggleComputerNameControls(false); - this._updateComputerNameValue(false); - this._focusAfterComputerNameTextbox(); - }); - setEventListener("fxaSaveChangeDeviceName", "command", function () { - // Work around bug 75324 - see above. - this._blurComputerNameTextbox(); - this._toggleComputerNameControls(false); - this._updateComputerNameValue(true); - this._focusAfterComputerNameTextbox(); - }); - setEventListener("unlinkDevice", "click", function () { - gSyncPane.startOver(true); - return false; - }); - setEventListener("loginErrorUpdatePass", "click", function () { - gSyncPane.updatePass(); - return false; - }); - setEventListener("loginErrorResetPass", "click", function () { - gSyncPane.resetPass(); - return false; - }); - setEventListener("loginErrorStartOver", "click", function () { - gSyncPane.startOver(true); - return false; - }); - setEventListener("noFxaSignUp", "command", function () { - gSyncPane.signUp(); - return false; - }); - setEventListener("noFxaSignIn", "command", function () { - gSyncPane.signIn(); - return false; - }); - setEventListener("fxaUnlinkButton", "command", function () { - gSyncPane.unlinkFirefoxAccount(true); - }); - setEventListener("verifyFxaAccount", "command", - gSyncPane.verifyFirefoxAccount); - setEventListener("unverifiedUnlinkFxaAccount", "command", function () { - /* no warning as account can't have previously synced */ - gSyncPane.unlinkFirefoxAccount(false); - }); - setEventListener("rejectReSignIn", "command", - gSyncPane.reSignIn); - setEventListener("rejectUnlinkFxaAccount", "command", function () { - gSyncPane.unlinkFirefoxAccount(true); - }); - setEventListener("fxaSyncComputerName", "keypress", function (e) { - if (e.keyCode == KeyEvent.DOM_VK_RETURN) { - document.getElementById("fxaSaveChangeDeviceName").click(); - } else if (e.keyCode == KeyEvent.DOM_VK_ESCAPE) { - document.getElementById("fxaCancelChangeDeviceName").click(); - } - }); - }, - - _initProfileImageUI: function () { - try { - if (Services.prefs.getBoolPref("identity.fxaccounts.profile_image.enabled")) { - document.getElementById("fxaProfileImage").hidden = false; - } - } catch (e) { } - }, - - updateWeavePrefs: function () { - let service = Components.classes["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; - // service.fxAccountsEnabled is false iff sync is already configured for - // the legacy provider. - if (service.fxAccountsEnabled) { - let displayNameLabel = document.getElementById("fxaDisplayName"); - let fxaEmailAddress1Label = document.getElementById("fxaEmailAddress1"); - fxaEmailAddress1Label.hidden = false; - displayNameLabel.hidden = true; - - let profileInfoEnabled; - try { - profileInfoEnabled = Services.prefs.getBoolPref("identity.fxaccounts.profile_image.enabled"); - } catch (ex) {} - - // determine the fxa status... - this._showLoadPage(service); - - fxAccounts.getSignedInUser().then(data => { - if (!data) { - this.page = FXA_PAGE_LOGGED_OUT; - return false; - } - this.page = FXA_PAGE_LOGGED_IN; - // We are logged in locally, but maybe we are in a state where the - // server rejected our credentials (eg, password changed on the server) - let fxaLoginStatus = document.getElementById("fxaLoginStatus"); - let syncReady; - // Not Verfied implies login error state, so check that first. - if (!data.verified) { - fxaLoginStatus.selectedIndex = FXA_LOGIN_UNVERIFIED; - syncReady = false; - // So we think we are logged in, so login problems are next. - // (Although if the Sync identity manager is still initializing, we - // ignore login errors and assume all will eventually be good.) - // LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in". - // All other login failures are assumed to be transient and should go - // away by themselves, so aren't reflected here. - } else if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) { - fxaLoginStatus.selectedIndex = FXA_LOGIN_FAILED; - syncReady = false; - // Else we must be golden (or in an error state we expect to magically - // resolve itself) - } else { - fxaLoginStatus.selectedIndex = FXA_LOGIN_VERIFIED; - syncReady = true; - } - fxaEmailAddress1Label.textContent = data.email; - document.getElementById("fxaEmailAddress2").textContent = data.email; - document.getElementById("fxaEmailAddress3").textContent = data.email; - this._populateComputerName(Weave.Service.clientsEngine.localName); - let engines = document.getElementById("fxaSyncEngines") - for (let checkbox of engines.querySelectorAll("checkbox")) { - checkbox.disabled = !syncReady; - } - document.getElementById("fxaChangeDeviceName").disabled = !syncReady; - - // Clear the profile image (if any) of the previously logged in account. - document.getElementById("fxaProfileImage").style.removeProperty("list-style-image"); - - // If the account is verified the next promise in the chain will - // fetch profile data. - return data.verified; - }).then(isVerified => { - if (isVerified) { - return fxAccounts.getSignedInUserProfile(); - } - return null; - }).then(data => { - let fxaLoginStatus = document.getElementById("fxaLoginStatus"); - if (data && profileInfoEnabled) { - if (data.displayName) { - fxaLoginStatus.setAttribute("hasName", true); - displayNameLabel.hidden = false; - displayNameLabel.textContent = data.displayName; - } else { - fxaLoginStatus.removeAttribute("hasName"); - } - if (data.avatar) { - let bgImage = "url(\"" + data.avatar + "\")"; - let profileImageElement = document.getElementById("fxaProfileImage"); - profileImageElement.style.listStyleImage = bgImage; - - let img = new Image(); - img.onerror = () => { - // Clear the image if it has trouble loading. Since this callback is asynchronous - // we check to make sure the image is still the same before we clear it. - if (profileImageElement.style.listStyleImage === bgImage) { - profileImageElement.style.removeProperty("list-style-image"); - } - }; - img.src = data.avatar; - } - } else { - fxaLoginStatus.removeAttribute("hasName"); - } - }, err => { - FxAccountsCommon.log.error(err); - }).catch(err => { - // If we get here something's really busted - Cu.reportError(String(err)); - }); - - // If fxAccountEnabled is false and we are in a "not configured" state, - // then fxAccounts is probably fully disabled rather than just unconfigured, - // so handle this case. This block can be removed once we remove support - // for fxAccounts being disabled. - } else if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED || - Weave.Svc.Prefs.get("firstSync", "") == "notReady") { - this.page = PAGE_NO_ACCOUNT; - // else: sync was previously configured for the legacy provider, so we - // make the "old" panels available. - } 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").textContent = Weave.Service.identity.account; - document.getElementById("syncComputerName").value = Weave.Service.clientsEngine.localName; - document.getElementById("tosPP-normal").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 + - Services.prompt.BUTTON_POS_1_DEFAULT; - let buttonChoice = - Services.prompt.confirmEx(window, - this._stringBundle.GetStringFromName("syncUnlink.title"), - this._stringBundle.GetStringFromName("syncUnlink.label"), - flags, - this._stringBundle.GetStringFromName("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(); - }, - - _getEntryPoint: function () { - let params = new URLSearchParams(document.URL.split("#")[0].split("?")[1] || ""); - return params.get("entrypoint") || "preferences"; - }, - - _openAboutAccounts: function(action) { - let entryPoint = this._getEntryPoint(); - let params = new URLSearchParams(); - if (action) { - params.set("action", action); - } - params.set("entrypoint", entryPoint); - - this.replaceTabWithUrl("about:accounts?" + params); - }, - - /** - * Invoke the Sync setup wizard. - * - * @param wizardType - * Indicates type of wizard to launch: - * null -- regular set up wizard - * "pair" -- pair a device first - * "reset" -- reset sync - */ - openSetup: function (wizardType) { - let service = Components.classes["@mozilla.org/weave/service;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; - - if (service.fxAccountsEnabled) { - this._openAboutAccounts(); - } else { - let win = Services.wm.getMostRecentWindow("Weave:AccountSetup"); - if (win) - win.focus(); - else { - window.openDialog("chrome://browser/content/sync/setup.xul", - "weaveSetup", "centerscreen,chrome,resizable=no", - wizardType); - } - } - }, - - openContentInBrowser: function(url, options) { - let win = Services.wm.getMostRecentWindow("navigator:browser"); - if (!win) { - // no window to use, so use _openLink to create a new one. We don't - // always use that as it prefers to open a new window rather than use - // an existing one. - gSyncUtils._openLink(url); - return; - } - win.switchToTabHavingURI(url, true, options); - }, - - // Replace the current tab with the specified URL. - replaceTabWithUrl(url) { - // Get the <browser> element hosting us. - let browser = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell) - .chromeEventHandler; - // And tell it to load our URL. - browser.loadURI(url); - }, - - signUp: function() { - this._openAboutAccounts("signup"); - }, - - signIn: function() { - this._openAboutAccounts("signin"); - }, - - reSignIn: function() { - this._openAboutAccounts("reauth"); - }, - - - clickOrSpaceOrEnterPressed: function(event) { - // Note: charCode is deprecated, but 'char' not yet implemented. - // Replace charCode with char when implemented, see Bug 680830 - return ((event.type == "click" && event.button == 0) || - (event.type == "keypress" && - (event.charCode == KeyEvent.DOM_VK_SPACE || event.keyCode == KeyEvent.DOM_VK_RETURN))); - }, - - openChangeProfileImage: function(event) { - if (this.clickOrSpaceOrEnterPressed(event)) { - fxAccounts.promiseAccountsChangeProfileURI(this._getEntryPoint(), "avatar") - .then(url => { - this.openContentInBrowser(url, { - replaceQueryString: true - }); - }); - // Prevent page from scrolling on the space key. - event.preventDefault(); - } - }, - - openManageFirefoxAccount: function(event) { - if (this.clickOrSpaceOrEnterPressed(event)) { - this.manageFirefoxAccount(); - // Prevent page from scrolling on the space key. - event.preventDefault(); - } - }, - - manageFirefoxAccount: function() { - fxAccounts.promiseAccountsManageURI(this._getEntryPoint()) - .then(url => { - this.openContentInBrowser(url, { - replaceQueryString: true - }); - }); - }, - - verifyFirefoxAccount: function() { - let showVerifyNotification = (data) => { - let isError = !data; - let maybeNot = isError ? "Not" : ""; - let sb = this._accountsStringBundle; - let title = sb.GetStringFromName("verification" + maybeNot + "SentTitle"); - let email = !isError && data ? data.email : ""; - let body = sb.formatStringFromName("verification" + maybeNot + "SentBody", [email], 1); - new Notification(title, { body }) - } - - let onError = () => { - showVerifyNotification(); - }; - - let onSuccess = data => { - if (data) { - showVerifyNotification(data); - } else { - onError(); - } - }; - - fxAccounts.resendVerificationEmail() - .then(fxAccounts.getSignedInUser, onError) - .then(onSuccess, onError); - }, - - openOldSyncSupportPage: function() { - let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "old-sync"; - this.openContentInBrowser(url); - }, - - unlinkFirefoxAccount: function(confirm) { - if (confirm) { - // We use a string bundle shared with aboutAccounts. - let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); - let disconnectLabel = sb.GetStringFromName("disconnect.label"); - let title = sb.GetStringFromName("disconnect.verify.title"); - let body = sb.GetStringFromName("disconnect.verify.bodyHeading") + - "\n\n" + - sb.GetStringFromName("disconnect.verify.bodyText"); - let ps = Services.prompt; - let buttonFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING) + - (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL) + - ps.BUTTON_POS_1_DEFAULT; - - let factory = Cc["@mozilla.org/prompter;1"] - .getService(Ci.nsIPromptFactory); - let prompt = factory.getPrompt(window, Ci.nsIPrompt); - let bag = prompt.QueryInterface(Ci.nsIWritablePropertyBag2); - bag.setPropertyAsBool("allowTabModal", true); - - let pressed = prompt.confirmEx(title, body, buttonFlags, - disconnectLabel, null, null, null, {}); - - if (pressed != 0) { // 0 is the "continue" button - return; - } - } - fxAccounts.signOut().then(() => { - this.updateWeavePrefs(); - }); - }, - - openAddDevice: function () { - if (!Weave.Utils.ensureMPUnlocked()) - return; - - let win = Services.wm.getMostRecentWindow("Sync:AddDevice"); - if (win) - win.focus(); - else - window.openDialog("chrome://browser/content/sync/addDevice.xul", - "syncAddDevice", "centerscreen,chrome,resizable=no"); - }, - - resetSync: function () { - this.openSetup("reset"); - }, - - _populateComputerName(value) { - let textbox = document.getElementById("fxaSyncComputerName"); - if (!textbox.hasAttribute("placeholder")) { - textbox.setAttribute("placeholder", - Weave.Utils.getDefaultDeviceName()); - } - textbox.value = value; - }, -}; diff --git a/browser/components/preferences/in-content/sync.xul b/browser/components/preferences/in-content/sync.xul deleted file mode 100644 index f1aebf2aa..000000000 --- a/browser/components/preferences/in-content/sync.xul +++ /dev/null @@ -1,359 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<!-- Sync panel --> - -<preferences id="syncEnginePrefs" hidden="true" data-category="paneSync"> - <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.tabs" - name="services.sync.engine.tabs" - type="bool"/> - <preference id="engine.prefs" - name="services.sync.engine.prefs" - type="bool"/> - <preference id="engine.passwords" - name="services.sync.engine.passwords" - type="bool"/> -</preferences> - -<script type="application/javascript" - src="chrome://browser/content/preferences/in-content/sync.js"/> -<script type="application/javascript" - src="chrome://browser/content/sync/utils.js"/> - -<hbox id="header-sync" - class="header" - hidden="true" - data-category="paneSync"> - <label class="header-name" flex="1">&paneSync.title;</label> - <html:a class="help-button text-link" target="_blank" aria-label="&helpButton.label;"></html:a> -</hbox> - -<deck id="weavePrefsDeck" data-category="paneSync" hidden="true"> - <!-- These panels are for the "legacy" sync provider --> - <vbox id="noAccount" align="center"> - <spacer flex="1"/> - <description id="syncDesc"> - &weaveDesc.label; - </description> - <separator/> - <label id="noAccountSetup" class="text-link"> - &setupButton.label; - </label> - <vbox id="pairDevice"> - <separator/> - <label id="noAccountPair" class="text-link"> - &pairDevice.label; - </label> - </vbox> - <spacer flex="3"/> - </vbox> - - <vbox id="hasAccount"> - <groupbox class="syncGroupBox"> - <!-- label is set to account name --> - <caption id="accountCaption" align="center"> - <image id="accountCaptionImage"/> - <label id="accountName"/> - </caption> - - <hbox> - <button type="menu" - label="&manageAccount.label;" - accesskey="&manageAccount.accesskey;"> - <menupopup> - <menuitem id="syncChangePassword" label="&changePassword2.label;"/> - <menuitem id="syncResetPassphrase" label="&myRecoveryKey.label;"/> - <menuseparator/> - <menuitem id="syncReset" label="&resetSync2.label;"/> - </menupopup> - </button> - </hbox> - - <hbox> - <label id="syncAddDeviceLabel" - class="text-link"> - &pairDevice.label; - </label> - </hbox> - - <vbox> - <label>&syncMy.label;</label> - <richlistbox id="syncEnginesList" - orient="vertical"> - <richlistitem> - <checkbox label="&engine.addons.label;" - accesskey="&engine.addons.accesskey;" - preference="engine.addons"/> - </richlistitem> - <richlistitem> - <checkbox label="&engine.bookmarks.label;" - accesskey="&engine.bookmarks.accesskey;" - preference="engine.bookmarks"/> - </richlistitem> - <richlistitem> - <checkbox label="&engine.passwords.label;" - accesskey="&engine.passwords.accesskey;" - preference="engine.passwords"/> - </richlistitem> - <richlistitem> - <checkbox label="&engine.prefs.label;" - accesskey="&engine.prefs.accesskey;" - preference="engine.prefs"/> - </richlistitem> - <richlistitem> - <checkbox label="&engine.history.label;" - accesskey="&engine.history.accesskey;" - preference="engine.history"/> - </richlistitem> - <richlistitem> - <checkbox label="&engine.tabs.label;" - accesskey="&engine.tabs.accesskey;" - preference="engine.tabs"/> - </richlistitem> - </richlistbox> - </vbox> - </groupbox> - - <groupbox class="syncGroupBox"> - <grid> - <columns> - <column/> - <column flex="1"/> - </columns> - <rows> - <row align="center"> - <label control="syncComputerName"> - &syncDeviceName.label; - </label> - <textbox id="syncComputerName"/> - </row> - </rows> - </grid> - <hbox> - <label id="unlinkDevice" class="text-link"> - &unlinkDevice.label; - </label> - </hbox> - </groupbox> - <vbox id="tosPP-normal"> - <label id="tosPP-normal-ToS" class="text-link"> - &prefs.tosLink.label; - </label> - <label id="tosPP-normal-PP" class="text-link"> - &prefs.ppLink.label; - </label> - </vbox> - </vbox> - - <vbox id="needsUpdate" align="center" pack="center"> - <hbox> - <label id="loginError"/> - <label id="loginErrorUpdatePass" class="text-link"> - &updatePass.label; - </label> - <label id="loginErrorResetPass" class="text-link"> - &resetPass.label; - </label> - </hbox> - <label id="loginErrorStartOver" class="text-link"> - &unlinkDevice.label; - </label> - </vbox> - - <!-- These panels are for the Firefox Accounts identity provider --> - <vbox id="noFxaAccount"> - <hbox> - <vbox id="fxaContentWrapper"> - <groupbox id="noFxaGroup"> - <vbox> - <label id="noFxaCaption">&signedOut.caption;</label> - <description id="noFxaDescription" flex="1">&signedOut.description;</description> - <hbox class="fxaAccountBox"> - <vbox> - <image class="fxaFirefoxLogo"/> - </vbox> - <vbox flex="1"> - <label id="signedOutAccountBoxTitle">&signedOut.accountBox.title;</label> - <hbox class="fxaAccountBoxButtons"> - <button id="noFxaSignUp" label="&signedOut.accountBox.create;" accesskey="&signedOut.accountBox.create.accesskey;"></button> - <button id="noFxaSignIn" label="&signedOut.accountBox.signin;" accesskey="&signedOut.accountBox.signin.accesskey;"></button> - </hbox> - </vbox> - </hbox> - </vbox> - </groupbox> - </vbox> - <vbox> - <image class="fxaSyncIllustration"/> - </vbox> - </hbox> - <label class="fxaMobilePromo"> - &mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces - --><label id="fxaMobilePromo-android" - class="androidLink text-link"><!-- - -->&mobilePromo3.androidLink;</label><!-- - -->&mobilePromo3.iOSBefore;<!-- - --><label id="fxaMobilePromo-ios" - class="iOSLink text-link"><!-- - -->&mobilePromo3.iOSLink;</label><!-- - -->&mobilePromo3.end; - </label> - </vbox> - - <vbox id="hasFxaAccount"> - <hbox> - <vbox id="fxaContentWrapper"> - <groupbox id="fxaGroup"> - <caption><label>&syncBrand.fxAccount.label;</label></caption> - <deck id="fxaLoginStatus"> - - <!-- logged in and verified and all is good --> - <hbox id="fxaLoginVerified" class="fxaAccountBox"> - <vbox align="center" pack="center"> - <image id="fxaProfileImage" class="actionable" - role="button" - onclick="gSyncPane.openChangeProfileImage(event);" hidden="true" - onkeypress="gSyncPane.openChangeProfileImage(event);" - tooltiptext="&profilePicture.tooltip;"/> - </vbox> - <vbox flex="1" pack="center"> - <label id="fxaDisplayName" hidden="true"/> - <label id="fxaEmailAddress1"/> - <hbox class="fxaAccountBoxButtons"> - <button id="fxaUnlinkButton" label="&disconnect.label;" accesskey="&disconnect.accesskey;"/> - <html:a id="verifiedManage" target="_blank" - accesskey="&verifiedManage.accesskey;" - onkeypress="gSyncPane.openManageFirefoxAccount(event);"><!-- - -->&verifiedManage.label;</html:a> - </hbox> - </vbox> - </hbox> - - <!-- logged in to an unverified account --> - <hbox id="fxaLoginUnverified" class="fxaAccountBox"> - <vbox> - <image id="fxaProfileImage"/> - </vbox> - <vbox flex="1"> - <hbox> - <vbox><image id="fxaLoginRejectedWarning"/></vbox> - <description flex="1"> - &signedInUnverified.beforename.label; - <label id="fxaEmailAddress2"/> - &signedInUnverified.aftername.label; - </description> - </hbox> - <hbox class="fxaAccountBoxButtons"> - <button id="verifyFxaAccount" accesskey="&verify.accesskey;">&verify.label;</button> - <button id="unverifiedUnlinkFxaAccount" accesskey="&forget.accesskey;">&forget.label;</button> - </hbox> - </vbox> - </hbox> - - <!-- logged in locally but server rejected credentials --> - <hbox id="fxaLoginRejected" class="fxaAccountBox"> - <vbox> - <image id="fxaProfileImage"/> - </vbox> - <vbox flex="1"> - <hbox> - <vbox><image id="fxaLoginRejectedWarning"/></vbox> - <description flex="1"> - &signedInLoginFailure.beforename.label; - <label id="fxaEmailAddress3"/> - &signedInLoginFailure.aftername.label; - </description> - </hbox> - <hbox class="fxaAccountBoxButtons"> - <button id="rejectReSignIn" accessky="&signIn.accesskey;">&signIn.label;</button> - <button id="rejectUnlinkFxaAccount" accesskey="&forget.accesskey;">&forget.label;</button> - </hbox> - </vbox> - </hbox> - </deck> - </groupbox> - <groupbox id="syncOptions"> - <caption><label>&signedIn.engines.label;</label></caption> - <hbox id="fxaSyncEngines"> - <vbox align="start" flex="1"> - <checkbox label="&engine.tabs.label;" - accesskey="&engine.tabs.accesskey;" - preference="engine.tabs"/> - <checkbox label="&engine.bookmarks.label;" - accesskey="&engine.bookmarks.accesskey;" - preference="engine.bookmarks"/> - <checkbox label="&engine.passwords.label;" - accesskey="&engine.passwords.accesskey;" - preference="engine.passwords"/> - </vbox> - <vbox align="start" flex="1"> - <checkbox label="&engine.history.label;" - accesskey="&engine.history.accesskey;" - preference="engine.history"/> - <checkbox label="&engine.addons.label;" - accesskey="&engine.addons.accesskey;" - preference="engine.addons"/> - <checkbox label="&engine.prefs.label;" - accesskey="&engine.prefs.accesskey;" - preference="engine.prefs"/> - </vbox> - <spacer/> - </hbox> - </groupbox> - </vbox> - <vbox> - <image class="fxaSyncIllustration"/> - </vbox> - </hbox> - <groupbox> - <caption> - <label control="fxaSyncComputerName"> - &fxaSyncDeviceName.label; - </label> - </caption> - <hbox id="fxaDeviceName"> - <textbox id="fxaSyncComputerName" disabled="true"/> - <hbox> - <button id="fxaChangeDeviceName" - label="&changeSyncDeviceName.label;" - accesskey="&changeSyncDeviceName.accesskey;"/> - <button id="fxaCancelChangeDeviceName" - label="&cancelChangeSyncDeviceName.label;" - accesskey="&cancelChangeSyncDeviceName.accesskey;" - hidden="true"/> - <button id="fxaSaveChangeDeviceName" - label="&saveChangeSyncDeviceName.label;" - accesskey="&saveChangeSyncDeviceName.accesskey;" - hidden="true"/> - </hbox> - </hbox> - </groupbox> - <label class="fxaMobilePromo"> - &mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces - --><label class="androidLink text-link" id="fxaMobilePromo-android-hasFxaAccount"><!-- - -->&mobilePromo3.androidLink;</label><!-- - -->&mobilePromo3.iOSBefore;<!-- - --><label class="iOSLink text-link" id="fxaMobilePromo-ios-hasFxaAccount"><!-- - -->&mobilePromo3.iOSLink;</label><!-- - -->&mobilePromo3.end; - </label> - <vbox id="tosPP-small" align="start"> - <label id="tosPP-small-ToS" class="text-link"> - &prefs.tosLink.label; - </label> - <label id="tosPP-small-PP" class="text-link"> - &fxaPrivacyNotice.link.label; - </label> - </vbox> - </vbox> -</deck> |