This commit is contained in:
Ryan VanderMeulen 2017-03-30 15:21:27 -04:00
Родитель 68002ffc75 615c542a03
Коммит 05037eec1a
283 изменённых файлов: 33344 добавлений и 26410 удалений

Просмотреть файл

@ -1397,6 +1397,14 @@
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="1"/>
</emItem>
<emItem blockID="9085fdba-8498-46a9-b9fd-4c7343a15c62" id="/^(test2@test\.com)|(test3@test\.com)|(mozilla_cc2\.2@internetdownloadmanager\.com)$/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="3">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange maxVersion="*" minVersion="53.0a1"/>
</targetApplication>
</versionRange>
</emItem>
<emItem blockID="i525" id="/^({65f9f6b7-2dae-46fc-bfaf-f88e4af1beca}|{9ed31f84-c8b3-4926-b950-dff74047ff79}|{0134af61-7a0c-4649-aeca-90d776060cb3}|{02edb56b-9b33-435b-b7df-b2843273a694}|{da51d4f6-3e7e-4ef8-b400-9198e0874606}|{b24577db-155e-4077-bb37-3fdd3c302bb5})$/">
<prefs/>
<versionRange minVersion="0" maxVersion="*" severity="1"/>

Просмотреть файл

@ -5,6 +5,8 @@
const LOGGER_NAME = "Toolkit.Telemetry";
const LOGGER_PREFIX = "DataNotificationInfoBar::";
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
/**
* Represents an info bar that shows a data submission notification.
*/
@ -64,7 +66,13 @@ var gDataNotificationInfoBar = {
popup: null,
callback: () => {
this._actionTaken = true;
window.openAdvancedPreferences("dataChoicesTab");
// The advanced subpanes are only supported in the old organization, which will
// be removed by bug 1349689.
if (Preferences.get("browser.preferences.useOldOrganization", false)) {
window.openAdvancedPreferences("dataChoicesTab");
} else {
window.openPreferences("paneAdvanced");
}
},
}];

Просмотреть файл

@ -167,7 +167,7 @@ var gEMEHandler = {
let mainAction = {
label: gNavigatorBundle.getString(btnLabelId),
accessKey: gNavigatorBundle.getString(btnAccessKeyId),
callback() { openPreferences("paneContent"); },
callback() { openPreferences("panePrivacy"); },
dismiss: true
};
let options = {

Просмотреть файл

@ -13,6 +13,9 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ContextualIdentityService.jsm");
Cu.import("resource://gre/modules/NotificationDB.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
// lazy module getters
/* global AboutHome:false, AddonWatcher:false,
@ -502,7 +505,14 @@ const gStoragePressureObserver = {
label: prefStrBundle.getString(prefButtonLabelStringID),
accessKey: prefStrBundle.getString(prefButtonAccesskeyStringID),
callback(notificationBar, button) {
gBrowser.ownerGlobal.openPreferences("advanced", { advancedTab: "networkTab" });
// The advanced subpanes are only supported in the old organization, which will
// be removed by bug 1349689.
let win = gBrowser.ownerGlobal;
if (Preferences.get("browser.preferences.useOldOrganization", false)) {
win.openAdvancedPreferences("networkTab");
} else {
win.openPreferences("panePrivacy");
}
}
});
}
@ -6275,7 +6285,13 @@ var OfflineApps = {
},
manage() {
openAdvancedPreferences("networkTab");
// The advanced subpanes are only supported in the old organization, which will
// be removed by bug 1349689.
if (Preferences.get("browser.preferences.useOldOrganization", false)) {
openAdvancedPreferences("networkTab");
} else {
openPreferences("panePrivacy");
}
},
receiveMessage(msg) {

Просмотреть файл

@ -8,7 +8,7 @@ add_task(function* test_settingsOpen_observer() {
gBrowser,
url: "about:robots"
}, function* dummyTabTask(aBrowser) {
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#content");
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#privacy");
info("simulate a notifications-open-settings notification");
let uri = NetUtil.newURI("https://example.com");
let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
@ -40,7 +40,7 @@ add_task(function* test_settingsOpen_button() {
}
let closePromise = promiseWindowClosed(alertWindow);
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#content");
let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, "about:preferences#privacy");
let openSettingsMenuItem = alertWindow.document.getElementById("openSettingsMenuItem");
openSettingsMenuItem.click();

Просмотреть файл

@ -120,6 +120,16 @@ const SELECT_STYLE_OF_OPTION_IS_BASED_ON_FOCUS_OF_SELECT =
' <option selected="true">{"end": "true"}</option>' +
"</select></body></html>";
const SELECT_STYLE_OF_OPTION_CHANGES_AFTER_FOCUS_EVENT =
"<html><body><select id='one'>" +
' <option>{"color": "rgb(255, 0, 0)", "backgroundColor": "rgba(0, 0, 0, 0)"}</option>' +
' <option selected="true">{"end": "true"}</option>' +
"</select></body><scr" +
"ipt>" +
" var select = document.getElementById('one');" +
" select.addEventListener('focus', () => select.style.color = 'red');" +
"</script></html>";
function getSystemColor(color) {
// Need to convert system color to RGB color.
let textarea = document.createElementNS("http://www.w3.org/1999/xhtml", "textarea");
@ -169,6 +179,15 @@ function* testSelectColors(select, itemCount, options) {
yield BrowserTestUtils.synthesizeMouseAtCenter("#one", { type: "mousedown" }, gBrowser.selectedBrowser);
yield popupShownPromise;
if (options.waitForComputedStyle) {
let property = options.waitForComputedStyle.property;
let value = options.waitForComputedStyle.value;
yield BrowserTestUtils.waitForCondition(() => {
info(`<select> has ${property}: ${getComputedStyle(selectPopup)[property]}`);
return getComputedStyle(selectPopup)[property] == value;
}, `Waiting for <select> to have ${property}: ${value}`);
}
is(selectPopup.parentNode.itemCount, itemCount, "Correct number of items");
let child = selectPopup.firstChild;
let idx = 1;
@ -335,3 +354,14 @@ add_task(function* test_style_of_options_is_dependent_on_focus_of_select() {
yield testSelectColors(SELECT_STYLE_OF_OPTION_IS_BASED_ON_FOCUS_OF_SELECT, 2, options);
});
add_task(function* test_style_of_options_is_dependent_on_focus_of_select() {
let options = {
skipSelectColorTest: true,
waitForComputedStyle: {
property: "color",
value: "rgb(255, 0, 0)"
}
};
yield testSelectColors(SELECT_STYLE_OF_OPTION_CHANGES_AFTER_FOCUS_EVENT, 2, options);
});

Просмотреть файл

@ -25,10 +25,8 @@ registerCleanupFunction(function() {
function checkInContentPreferences(win) {
let doc = win.document;
let sel = doc.getElementById("categories").selectedItems[0].id;
let tab = doc.getElementById("advancedPrefs").selectedTab.id;
is(gBrowser.currentURI.spec, "about:preferences#advanced", "about:preferences loaded");
is(sel, "category-advanced", "Advanced pane was selected");
is(tab, "networkTab", "Network tab is selected");
is(gBrowser.currentURI.spec, "about:preferences#privacy", "about:preferences loaded");
is(sel, "category-privacy", "Privacy pane was selected");
// all good, we are done.
win.close();
finish();

Просмотреть файл

@ -8,9 +8,9 @@ function notifyStoragePressure(usage = 100) {
return notifyPromise;
}
function advancedAboutPrefPromise() {
function privacyAboutPrefPromise() {
let promises = [
BrowserTestUtils.waitForLocationChange(gBrowser, "about:preferences#advanced"),
BrowserTestUtils.waitForLocationChange(gBrowser, "about:preferences#privacy"),
TestUtils.topicObserved("advanced-pane-loaded", () => true)
];
return Promise.all(promises);
@ -53,10 +53,10 @@ add_task(function* () {
ok(notification instanceof XULElement, "Should display storage pressure notification");
let prefBtn = notification.getElementsByTagName("button")[1];
let aboutPrefPromise = advancedAboutPrefPromise();
let aboutPrefPromise = privacyAboutPrefPromise();
prefBtn.doCommand();
yield aboutPrefPromise;
let prefDoc = gBrowser.selectedBrowser.contentDocument;
let advancedPrefs = prefDoc.getElementById("advancedPrefs");
is(advancedPrefs.selectedIndex, 2, "Should open the Network tab in about:preferences#advanced");
let offlineGroup = prefDoc.getElementById("offlineGroup");
is_element_visible(offlineGroup, "Should open the Network tab in about:preferences#privacy");
});

Просмотреть файл

@ -24,7 +24,7 @@ add_task(function*() {
yield loaded;
yield popupclosed;
is(gBrowser.selectedBrowser.currentURI.spec, "about:preferences#search",
is(gBrowser.selectedBrowser.currentURI.spec, "about:preferences#general",
"Should have loaded the right page");
});
});

Просмотреть файл

@ -151,7 +151,7 @@ function* backgroundUpdateTest(url, id, checkIconFn) {
is(win.gViewController.currentViewId, VIEW, "about:addons is at extensions list");
// Wait for the permission prompt and accept it this time
updatePromise = promiseInstallEvent(addon, "onInstallEnded");
updatePromise = waitForUpdate(addon);
panel = yield popupPromise;
panel.button.click();
@ -176,7 +176,6 @@ function checkDefaultIcon(icon) {
add_task(() => backgroundUpdateTest(`${BASE}/browser_webext_update1.xpi`,
ID, checkDefaultIcon));
function checkNonDefaultIcon(icon) {
// The icon should come from the extension, don't bother with the precise
// path, just make sure we've got a jar url pointing to the right path
@ -209,7 +208,7 @@ async function testNoPrompt(origUrl, id) {
{once: true});
// Trigger an update check and wait for the update to be applied.
let updatePromise = promiseInstallEvent(addon, "onInstallEnded");
let updatePromise = waitForUpdate(addon);
AddonManagerPrivate.backgroundUpdateCheck();
await updatePromise;
@ -239,4 +238,3 @@ add_task(() => testNoPrompt(`${BASE}/browser_webext_update_perms1.xpi`,
// doesn't show a prompt even when the webextension uses
// promptable required permissions.
add_task(() => testNoPrompt(`${BASE}/browser_legacy.xpi`, ID_LEGACY));

Просмотреть файл

@ -34,7 +34,7 @@ async function testUpdateNoPrompt(filename, id,
PopupNotifications.panel.addEventListener("popupshown", popupListener);
// Trigger an update check, we should see the update get applied
let updatePromise = promiseInstallEvent(addon, "onInstallEnded");
let updatePromise = waitForUpdate(addon);
win.gViewController.doCommand("cmd_findAllUpdates");
await updatePromise;

Просмотреть файл

@ -7,8 +7,7 @@
"update_link": "https://example.com/browser/browser/base/content/test/webextensions/browser_webext_update2.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"advisory_max_version": "55.0"
"strict_min_version": "1"
}
}
}
@ -21,8 +20,7 @@
"update_link": "https://example.com/browser/browser/base/content/test/webextensions/browser_webext_update_icon2.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"advisory_max_version": "55.0"
"strict_min_version": "1"
}
}
}
@ -35,8 +33,7 @@
"update_link": "https://example.com/browser/browser/base/content/test/webextensions/browser_webext_update_perms2.xpi",
"applications": {
"gecko": {
"strict_min_version": "1",
"advisory_max_version": "55.0"
"strict_min_version": "1"
}
}
}

Просмотреть файл

@ -3,6 +3,11 @@ const BASE = getRootDirectory(gTestPath)
.replace("chrome://mochitests/content/", "https://example.com/");
Cu.import("resource:///modules/ExtensionsUI.jsm");
XPCOMUtils.defineLazyGetter(this, "Management", () => {
const {Management} = Components.utils.import("resource://gre/modules/Extension.jsm", {});
return Management;
});
/**
* Wait for the given PopupNotification to display
@ -65,19 +70,58 @@ function promiseInstallEvent(addon, event) {
* Resolves when the extension has been installed with the Addon
* object as the resolution value.
*/
function promiseInstallAddon(url) {
return AddonManager.getInstallForURL(url, null, "application/x-xpinstall")
.then(install => {
ok(install, "Created install");
return new Promise(resolve => {
install.addListener({
onInstallEnded(_install, addon) {
resolve(addon);
},
});
install.install();
});
});
async function promiseInstallAddon(url) {
let install = await AddonManager.getInstallForURL(url, null, "application/x-xpinstall");
install.install();
let addon = await new Promise(resolve => {
install.addListener({
onInstallEnded(_install, _addon) {
resolve(_addon);
},
});
});
if (addon.isWebExtension) {
await new Promise(resolve => {
function listener(event, extension) {
if (extension.id == addon.id) {
Management.off("ready", listener);
resolve();
}
}
Management.on("ready", listener);
});
}
return addon;
}
/**
* Wait for an update to the given webextension to complete.
* (This does not actually perform an update, it just watches for
* the events that occur as a result of an update.)
*
* @param {AddonWrapper} addon
* The addon to be updated.
*
* @returns {Promise}
* Resolves when the extension has ben updated.
*/
async function waitForUpdate(addon) {
let installPromise = promiseInstallEvent(addon, "onInstallEnded");
let readyPromise = new Promise(resolve => {
function listener(event, extension) {
if (extension.id == addon.id) {
Management.off("ready", listener);
resolve();
}
}
Management.on("ready", listener);
});
let [newAddon, ] = await Promise.all([installPromise, readyPromise]);
return newAddon;
}
function isDefaultIcon(icon) {

Просмотреть файл

@ -113,7 +113,9 @@ function getObserver() {
},
onBeginUpdateBatch: function() {},
onEndUpdateBatch: function() {},
onTitleChanged: function() {},
onTitleChanged: function(uri, title) {
this.emit("titleChanged", {url: uri.spec, title: title});
},
onClearHistory: function() {
this.emit("visitRemoved", {allHistory: true, urls: []});
},
@ -241,6 +243,17 @@ extensions.registerSchemaAPI("history", "addon_parent", context => {
getObserver().off("visitRemoved", listener);
};
}).api(),
onTitleChanged: new SingletonEventManager(context, "history.onTitleChanged", fire => {
let listener = (event, data) => {
fire.sync(data);
};
getObserver().on("titleChanged", listener);
return () => {
getObserver().off("titleChanged", listener);
};
}).api(),
},
};
});

Просмотреть файл

@ -310,6 +310,27 @@
}
}
]
},
{
"name": "onTitleChanged",
"type": "function",
"description": "Fired when the title of a URL is changed in the browser history.",
"parameters": [
{
"name": "changed",
"type": "object",
"properties": {
"url": {
"type": "string",
"description": "The URL for which the title has changed"
},
"title": {
"type": "string",
"description": "The new title for the URL."
}
}
}
]
}
]
}

Просмотреть файл

@ -422,6 +422,13 @@ add_task(function* test_on_visited() {
{date: new Date(visitDate += 1000)},
],
},
{
url: SINGLE_VISIT_URL,
title: "Title Changed",
visits: [
{date: new Date(visitDate)},
],
},
];
function background() {
@ -432,11 +439,16 @@ add_task(function* test_on_visited() {
return;
}
onVisitedData.push(data);
if (onVisitedData.length == 3) {
if (onVisitedData.length == 4) {
browser.test.sendMessage("on-visited-data", onVisitedData);
}
});
// Verifying onTitleChange Event along with onVisited event
browser.history.onTitleChanged.addListener(data => {
browser.test.sendMessage("on-title-changed-data", data);
});
browser.test.sendMessage("ready");
}
@ -483,5 +495,14 @@ add_task(function* test_on_visited() {
expected.visitCount = 2;
checkOnVisitedData(2, expected);
expected.url = PAGE_INFOS[2].url;
expected.title = PAGE_INFOS[2].title;
expected.time = PAGE_INFOS[2].visits[0].date.getTime();
expected.visitCount = 2;
checkOnVisitedData(3, expected);
let onTitleChangedData = yield extension.awaitMessage("on-title-changed-data");
equal(onTitleChangedData.title, "Title Changed", "ontitleChanged received the expected title.");
yield extension.unload();
});

Просмотреть файл

@ -72,7 +72,7 @@ SearchProvider.prototype = {
manageEngines(browser) {
const browserWin = browser.ownerGlobal;
browserWin.openPreferences("paneSearch");
browserWin.openPreferences("paneGeneral");
},
asyncGetState: Task.async(function*() {

Просмотреть файл

@ -205,7 +205,7 @@ BrowserGlue.prototype = {
observe: function BG_observe(subject, topic, data) {
switch (topic) {
case "notifications-open-settings":
this._openPreferences("content");
this._openPreferences("privacy");
break;
case "prefservice:after-app-defaults":
this._onAppDefaults();

Просмотреть файл

@ -9,9 +9,6 @@ Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
Components.utils.import("resource://gre/modules/LoadContextInfo.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SiteDataManager",
"resource:///modules/SiteDataManager.jsm");
const PREF_UPLOAD_ENABLED = "datareporting.healthreport.uploadEnabled";
var gAdvancedPane = {
@ -27,11 +24,6 @@ var 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() {
@ -50,101 +42,22 @@ var gAdvancedPane = {
this.initSubmitHealthReport();
}
this.updateOnScreenKeyboardVisibility();
this.updateCacheSizeInputField();
this.updateActualCacheSize();
if (Services.prefs.getBoolPref("browser.storageManager.enabled")) {
Services.obs.addObserver(this, "sitedatamanager:sites-updated", false);
let unload = () => {
window.removeEventListener("unload", unload);
Services.obs.removeObserver(this, "sitedatamanager:sites-updated");
};
window.addEventListener("unload", unload);
SiteDataManager.updateSites();
setEventListener("clearSiteDataButton", "command",
gAdvancedPane.clearSiteData);
setEventListener("siteDataSettings", "command",
gAdvancedPane.showSiteDataSettings);
let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "storage-permissions";
document.getElementById("siteDataLearnMoreLink").setAttribute("href", url);
}
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);
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 (Services.prefs.getBoolPref("browser.preferences.offlineGroup.enabled")) {
this.updateOfflineApps();
this.updateActualAppCacheSize();
setEventListener("offlineNotifyExceptions", "command",
gAdvancedPane.showOfflineExceptions);
setEventListener("offlineAppsList", "select",
gAdvancedPane.offlineAppSelected);
setEventListener("offlineAppsListRemove", "command",
gAdvancedPane.removeOfflineApp);
setEventListener("clearOfflineAppCacheButton", "command",
gAdvancedPane.clearOfflineAppCache);
let bundlePrefs = document.getElementById("bundlePreferences");
document.getElementById("offlineAppsList")
.style.height = bundlePrefs.getString("offlineAppsList.height");
let offlineGroup = document.getElementById("offlineGroup");
offlineGroup.hidden = false;
}
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() {
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
@ -212,26 +125,6 @@ var gAdvancedPane = {
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() {
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() {
var checkbox = document.getElementById("enableOCSP");
return checkbox.checked ? 1 : 0;
},
/**
* When the user toggles the layers.acceleration.disabled pref,
@ -337,326 +230,6 @@ var gAdvancedPane = {
}
},
// 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() {
gSubDialog.open("chrome://browser/content/preferences/connection.xul");
},
showSiteDataSettings() {
gSubDialog.open("chrome://browser/content/preferences/siteDataSettings.xul");
},
updateTotalSiteDataSize() {
SiteDataManager.getTotalUsage()
.then(usage => {
let size = DownloadUtils.convertByteUnits(usage);
let prefStrBundle = document.getElementById("bundlePreferences");
let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize", size);
let siteDataGroup = document.getElementById("siteDataGroup");
siteDataGroup.hidden = false;
});
},
// Retrieves the amount of space currently used by disk cache
updateActualCacheSize() {
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(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) {}
},
updateCacheSizeUI(smartSizeEnabled) {
document.getElementById("useCacheBefore").disabled = smartSizeEnabled;
document.getElementById("cacheSize").disabled = smartSizeEnabled;
document.getElementById("useCacheAfter").disabled = smartSizeEnabled;
},
readSmartSizeEnabled() {
// 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() {
try {
var cache = Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
.getService(Components.interfaces.nsICacheStorageService);
cache.clear();
} catch (ex) {}
this.updateActualCacheSize();
},
clearSiteData() {
let flags =
Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1 +
Services.prompt.BUTTON_POS_0_DEFAULT;
let prefStrBundle = document.getElementById("bundlePreferences");
let title = prefStrBundle.getString("clearSiteDataPromptTitle");
let text = prefStrBundle.getString("clearSiteDataPromptText");
let btn0Label = prefStrBundle.getString("clearSiteDataNow");
let result = Services.prompt.confirmEx(
window, title, text, flags, btn0Label, null, null, null, {});
if (result == 0) {
SiteDataManager.removeAll();
}
},
// Methods for Offline Apps(Appcache)
/**
* Clears the application cache.
*/
clearOfflineAppCache() {
Components.utils.import("resource:///modules/offlineAppCache.jsm");
OfflineAppCacheHelper.clear();
this.updateActualAppCacheSize();
this.updateOfflineApps();
},
// Retrieves the amount of space currently used by offline cache
updateActualAppCacheSize() {
var visitor = {
onCacheStorageInfo(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) {}
},
readOfflineNotify() {
var pref = document.getElementById("browser.offline-apps.notify");
var button = document.getElementById("offlineNotifyExceptions");
button.disabled = !pref.value;
return pref.value;
},
showOfflineExceptions() {
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);
if (perm.matchesURI(uri, true)) {
let cache = cacheService.getActiveCache(group);
usage += cache.usage;
}
}
return usage;
},
/**
* Updates the list of offline applications
*/
updateOfflineApps() {
var pm = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var list = document.getElementById("offlineAppsList");
while (list.firstChild) {
list.firstChild.remove();
}
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() {
var removeButton = document.getElementById("offlineAppsListRemove");
var list = document.getElementById("offlineAppsList");
if (list.selectedItem) {
removeButton.setAttribute("disabled", "false");
} else {
removeButton.setAttribute("disabled", "true");
}
},
removeOfflineApp() {
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]);
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();
},
// Methods for Offline Apps(Appcache) end
// UPDATE TAB
/*
* Preferences:
*
@ -776,19 +349,6 @@ var gAdvancedPane = {
* requests one
*/
/**
* Displays the user's certificates and associated options.
*/
showCertificates() {
gSubDialog.open("chrome://pippki/content/certManager.xul");
},
/**
* Displays a dialog from which the user can manage his security devices.
*/
showSecurityDevices() {
gSubDialog.open("chrome://pippki/content/device_manager.xul");
},
observe(aSubject, aTopic, aData) {
if (AppConstants.MOZ_UPDATER) {

Просмотреть файл

@ -12,69 +12,14 @@
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
<!-- Data Choices tab -->
<!-- Data Choices tab -->
#ifdef MOZ_CRASHREPORTER
<preference id="browser.crashReports.unsubmittedCheck.autoSubmit"
name="browser.crashReports.unsubmittedCheck.autoSubmit"
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 -->
<!-- Update tab -->
#ifdef MOZ_UPDATER
<preference id="app.update.enabled"
name="app.update.enabled"
@ -97,340 +42,108 @@
<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>
<label class="header-name" flex="1">&paneUpdates.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="&searchOnStartTyping.label;"
accesskey="&searchOnStartTyping.accesskey;"
preference="accessibility.typeaheadfind"/>
<checkbox id="blockAutoRefresh"
label="&blockAutoReload.label;"
accesskey="&blockAutoReload.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="&checkUserSpelling.label;"
accesskey="&checkUserSpelling.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" flex="1">
<label flex="1">&healthReportDesc.label;</label>
<label id="FHRLearnMore" flex="1"
class="learnMore 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" flex="1">
<label id="telemetryDataDesc" flex="1">&telemetryDesc.label;</label>
<label id="telemetryLearnMore" flex="1"
class="learnMore text-link">&telemetryLearnMore.label;</label>
</hbox>
</groupbox>
</hbox>
</vbox>
</groupbox>
#endif
#ifdef MOZ_CRASHREPORTER
<groupbox>
<caption>
<checkbox id="automaticallySubmitCrashesBox"
preference="browser.crashReports.unsubmittedCheck.autoSubmit"
label="&alwaysSubmitCrashReports.label;"
accesskey="&alwaysSubmitCrashReports.accesskey;"/>
</caption>
<hbox class="indent" flex="1">
<label flex="1">&crashReporterDesc2.label;</label>
<label id="crashReporterLearnMore" flex="1"
class="learnMore text-link">&crashReporterLearnMore.label;</label>
</hbox>
</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" hidden="true">
<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="&offlineStorageNotify.label;" accesskey="&offlineStorageNotify.accesskey;"
preference="browser.offline-apps.notify"
onsyncfrompreference="return gAdvancedPane.readOfflineNotify();"/>
<spacer flex="1"/>
<button id="offlineNotifyExceptions"
label="&offlineStorageNotifyExceptions.label;"
accesskey="&offlineStorageNotifyExceptions.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>
<!-- Site Data -->
<groupbox id="siteDataGroup" hidden="true">
<caption><label>&siteData.label;</label></caption>
<hbox align="baseline">
<label id="totalSiteDataSize"></label>
<label id="siteDataLearnMoreLink" class="learnMore text-link" value="&siteDataLearnMoreLink.label;"></label>
<spacer flex="1" />
<button id="clearSiteDataButton" icon="clear"
label="&clearSiteData.label;" accesskey="&clearSiteData.accesskey;"/>
</hbox>
<vbox align="end">
<button id="siteDataSettings"
label="&siteDataSettings.label;"
accesskey="&siteDataSettings.accesskey;"/>
</vbox>
</groupbox>
</tabpanel>
<!-- Update -->
<tabpanel id="updatePanel" orient="vertical">
<!-- Update -->
#ifdef MOZ_UPDATER
<groupbox id="updateApp" align="start">
<caption><label>&updateApplication.label;</label></caption>
<radiogroup id="updateRadioGroup" align="start">
<radio id="autoDesktop"
value="auto"
label="&updateAuto1.label;"
accesskey="&updateAuto1.accesskey;"/>
<radio value="checkOnly"
label="&updateCheckChoose.label;"
accesskey="&updateCheckChoose.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>
<groupbox id="updateApp" align="start" data-category="paneAdvanced" hidden="true">
<caption><label>&updateApplication.label;</label></caption>
<radiogroup id="updateRadioGroup" align="start">
<radio id="autoDesktop"
value="auto"
label="&updateAuto1.label;"
accesskey="&updateAuto1.accesskey;"/>
<radio value="checkOnly"
label="&updateCheckChoose.label;"
accesskey="&updateCheckChoose.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"/>
<checkbox id="useService"
label="&useService.label;"
accesskey="&useService.accesskey;"
preference="app.update.service.enabled"/>
#endif
</groupbox>
</groupbox>
#endif
<groupbox id="updateOthers" align="start">
<caption><label>&autoUpdateOthers.label;</label></caption>
<checkbox id="enableSearchUpdate"
label="&enableSearchUpdate.label;"
accesskey="&enableSearchUpdate.accesskey;"
preference="browser.search.update"/>
</groupbox>
</tabpanel>
<groupbox id="updateOthers" align="start" data-category="paneAdvanced" hidden="true">
<caption><label>&autoUpdateOthers.label;</label></caption>
<checkbox id="enableSearchUpdate"
label="&enableSearchUpdate.label;"
accesskey="&enableSearchUpdate.accesskey;"
preference="browser.search.update"/>
</groupbox>
<!-- Certificates -->
<tabpanel id="encryptionPanel" orient="vertical">
<groupbox id="certSelection" align="start">
<caption><label>&certPersonal.label;</label></caption>
<description id="CertSelectionDesc" control="certSelection">&certPersonal.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="&selectCerts.auto;"
accesskey="&selectCerts.auto.accesskey;"
value="Select Automatically"/>
<radio label="&selectCerts.ask;"
accesskey="&selectCerts.ask.accesskey;"
value="Ask Every Time"/>
</radiogroup>
<!-- Data Choices -->
#ifdef MOZ_TELEMETRY_REPORTING
<groupbox id="historyGroup" data-category="paneAdvanced" hidden="true">
<caption><label>&reports.label;</label></caption>
<vbox>
<caption>
<checkbox id="submitHealthReportBox" label="&enableHealthReport.label;"
accesskey="&enableHealthReport.accesskey;"/>
</caption>
<hbox class="indent">
<label>&healthReportDesc.label;</label>
<label id="FHRLearnMore"
class="learnMore 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">&telemetryDesc.label;</label>
<label id="telemetryLearnMore"
class="learnMore text-link">&telemetryLearnMore.label;</label>
</hbox>
</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>
</hbox>
</vbox>
</groupbox>
#endif
#ifdef MOZ_DATA_REPORTING
#ifdef MOZ_CRASHREPORTER
<groupbox data-category="paneAdvanced" hidden="true">
<caption>
<checkbox id="automaticallySubmitCrashesBox"
preference="browser.crashReports.unsubmittedCheck.autoSubmit"
label="&alwaysSubmitCrashReports.label;"
accesskey="&alwaysSubmitCrashReports.accesskey;"/>
</caption>
<hbox class="indent">
<label>&crashReporterDesc2.label;</label>
<label id="crashReporterLearnMore"
class="learnMore text-link">&crashReporterLearnMore.label;</label>
</hbox>
</groupbox>
#endif
#endif

Просмотреть файл

@ -10,6 +10,8 @@
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/AppConstants.jsm");
Components.utils.import("resource://gre/modules/Task.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";
@ -910,6 +912,8 @@ var gApplicationsPane = {
gApplicationsPane.onSelectionChanged);
setEventListener("typeColumn", "click", gApplicationsPane.sort);
setEventListener("actionColumn", "click", gApplicationsPane.sort);
setEventListener("chooseFolder", "command", gApplicationsPane.chooseFolder);
setEventListener("browser.download.dir", "change", gApplicationsPane.displayDownloadDirPref);
// Listen for window unload so we can remove our preference observers.
window.addEventListener("unload", this);
@ -1892,6 +1896,216 @@ var gApplicationsPane = {
// the icon, or if we couldn't retrieve the icon for some other reason,
// then use a generic icon.
return ICON_URL_APP;
}
},
// 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() {
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;
} else if (defDownloads && defDownloads.exists()) {
// Try the system's download dir
fp.displayDirectory = defDownloads;
} else {
// Fall back to Desktop
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(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;
})
};

Просмотреть файл

@ -63,7 +63,7 @@
class="header"
hidden="true"
data-category="paneApplications">
<label class="header-name" flex="1">&paneApplications.title;</label>
<label class="header-name" flex="1">&paneDownloadLinks.title;</label>
<html:a class="help-button" target="_blank" aria-label="&helpButton.label;"></html:a>
</hbox>
@ -71,6 +71,46 @@
data-category="paneApplications"
hidden="true"
flex="1">
<!--Downloads-->
<groupbox id="downloadsGroup"
data-category="paneApplications"
hidden="false">
<caption><label>&downloads.label;</label></caption>
<radiogroup id="saveWhere"
preference="browser.download.useDownloadDir"
onsyncfrompreference="return gApplicationsPane.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 gApplicationsPane.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="&alwaysAskWhere.label;"
accesskey="&alwaysAskWhere.accesskey;"/>
</hbox>
</radiogroup>
</groupbox>
<hbox>
<textbox id="filter" flex="1"
type="search"

Просмотреть файл

@ -1,283 +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 preferences.js */
/* import-globals-from ../../../../toolkit/mozapps/preferences/fontbuilder.js */
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 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);
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");
}
},
// UTILITY FUNCTIONS
/**
* Utility function to enable/disable the button specified by aButtonID based
* on the value of the Boolean preference specified by aPreferenceID.
*/
updateButtons(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() {
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() {
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(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(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() {
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() {
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() {
gSubDialog.open("chrome://browser/content/preferences/languages.xul");
},
/**
* Displays the translation exceptions dialog where specific site and language
* translation preferences can be set.
*/
showTranslationExceptions() {
gSubDialog.open("chrome://browser/content/preferences/translation.xul");
},
openTranslationProviderAttribution() {
Components.utils.import("resource:///modules/translation/Translation.jsm");
Translation.openProviderAttribution();
},
toggleDoNotDisturbNotifications(event) {
AlertsServiceDND.manualDoNotDisturb = event.target.checked;
},
};

Просмотреть файл

@ -1,207 +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">
<!-- DRM content -->
<preference id="media.eme.enabled"
name="media.eme.enabled"
type="bool"/>
<!-- 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>
<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">
<hbox align="center">
<checkbox id="playDRMContent" preference="media.eme.enabled"
label="&playDRMContent.label;" accesskey="&playDRMContent.accesskey;"/>
<label id="playDRMContentLink" class="learnMore text-link" value="&playDRMContent.learnMore.label;"/>
</hbox>
</row>
</rows>
</grid>
</groupbox>
<groupbox id="notificationsGroup" data-category="paneContent" hidden="true">
<caption><label>&notificationsPolicy.label;</label></caption>
<grid>
<columns>
<column flex="1"/>
<column/>
</columns>
<rows>
<row id="notificationsPolicyRow" align="center">
<hbox align="start">
<label id="notificationsPolicy">&notificationsPolicyDesc3.label;</label>
<label id="notificationsPolicyLearnMore"
class="learnMore text-link"
value="&notificationsPolicyLearnMore.label;"/>
</hbox>
<hbox pack="end">
<button id="notificationsPolicyButton" label="&notificationsPolicyButton.label;"
accesskey="&notificationsPolicyButton.accesskey;"/>
</hbox>
</row>
<row id="notificationsDoNotDisturbRow" hidden="true">
<vbox align="start">
<checkbox id="notificationsDoNotDisturb" label="&notificationsDoNotDisturb.label;"
accesskey="&notificationsDoNotDisturb.accesskey;"/>
<label id="notificationsDoNotDisturbDetails"
class="indent"
value="&notificationsDoNotDisturbDetails.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>

Просмотреть файл

@ -12,7 +12,4 @@ browser.jar:
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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -7,6 +7,11 @@
<script type="application/javascript"
src="chrome://browser/content/preferences/in-content/main.js"/>
<script type="application/javascript"
src="chrome://mozapps/content/preferences/fontbuilder.js"/>
<stringbundle id="engineManagerBundle" src="chrome://browser/locale/engineManager.properties"/>
<preferences id="mainPreferences" hidden="true" data-category="paneGeneral">
#ifdef E10S_TESTING_ONLY
@ -53,6 +58,19 @@
name="browser.privatebrowsing.autostart"
type="bool"/>
<!-- Search Engine -->
<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"/>
<!-- Downloads -->
<preference id="browser.download.useDownloadDir"
name="browser.download.useDownloadDir"
@ -108,6 +126,60 @@
<preference id="browser.ctrlTab.previews"
name="browser.ctrlTab.previews"
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"/>
<!-- General tab -->
<!-- Accessibility -->
<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
<!-- Browsing -->
<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
</preferences>
<hbox id="header-general"
@ -226,44 +298,62 @@
</html:table>
</groupbox>
<!-- Downloads -->
<groupbox id="downloadsGroup"
data-category="paneGeneral"
hidden="true">
<caption><label>&downloads.label;</label></caption>
<!-- Default Search Engine -->
<groupbox id="defaultEngineGroup" align="start" data-category="paneGeneral">
<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>
<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="&alwaysAskWhere.label;"
accesskey="&alwaysAskWhere.accesskey;"/>
</hbox>
</radiogroup>
<groupbox id="oneClickSearchProvidersGroup" data-category="paneGeneral">
<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>
<!-- Tab preferences -->
@ -299,3 +389,145 @@
preference="browser.taskbar.previews.enable"/>
#endif
</groupbox>
<!-- Accessibility -->
<groupbox data-category="paneGeneral" 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="&searchOnStartTyping.label;"
accesskey="&searchOnStartTyping.accesskey;"
preference="accessibility.typeaheadfind"/>
<checkbox id="blockAutoRefresh"
label="&blockAutoReload.label;"
accesskey="&blockAutoReload.accesskey;"
preference="accessibility.blockautorefresh"/>
</groupbox>
<!-- Languages -->
<groupbox id="languagesGroup" data-category="paneGeneral" 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 gMainPane.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>
<hbox>
<checkbox id="checkSpelling"
label="&checkUserSpelling.label;"
accesskey="&checkUserSpelling.accesskey;"
onsyncfrompreference="return gMainPane.readCheckSpelling();"
onsynctopreference="return gMainPane.writeCheckSpelling();"
preference="layout.spellcheckDefault"/>
</hbox>
</groupbox>
<!-- Fonts and Colors -->
<groupbox id="fontsGroup" data-category="paneGeneral" 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>
<!-- Browsing -->
<groupbox id="browsingGroup" align="start" data-category="paneGeneral">
<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"/>
</groupbox>

Просмотреть файл

@ -6,12 +6,9 @@
/* import-globals-from subdialogs.js */
/* import-globals-from advanced.js */
/* import-globals-from main.js */
/* import-globals-from search.js */
/* import-globals-from containers.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 */
@ -57,14 +54,11 @@ function init_all() {
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));
@ -123,29 +117,13 @@ function init_dynamic_padding() {
function telemetryBucketForCategory(category) {
switch (category) {
case "general":
case "search":
case "content":
case "applications":
case "advanced":
case "containers":
case "general":
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";
}
@ -193,7 +171,7 @@ function gotoPref(aCategory) {
mainContent.scrollTop = 0;
Services.telemetry
.getHistogramById("FX_PREFERENCES_CATEGORY_OPENED")
.getHistogramById("FX_PREFERENCES_CATEGORY_OPENED_V2")
.add(telemetryBucketForCategory(friendlyName));
}

Просмотреть файл

@ -102,44 +102,14 @@
<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;"
tooltiptext="&paneDownloadLinks.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>
<label class="category-name" flex="1">&paneDownloadLinks.title;</label>
</richlistitem>
<richlistitem id="category-containers"
@ -148,34 +118,34 @@
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;"
tooltiptext="&paneSync1.title;"
align="center">
<image class="category-icon"/>
<label class="category-name" flex="1">&paneSync.title;</label>
<label class="category-name" flex="1">&paneSync1.title;</label>
</richlistitem>
<richlistitem id="category-privacy"
class="category"
value="panePrivacy"
helpTopic="prefs-privacy"
tooltiptext="&panePrivacySecurity.title;"
align="center">
<image class="category-icon"/>
<label class="category-name" flex="1">&panePrivacySecurity.title;</label>
</richlistitem>
<richlistitem id="category-advanced"
class="category"
value="paneAdvanced"
helpTopic="prefs-advanced-general"
tooltiptext="&paneAdvanced.title;"
tooltiptext="&paneUpdates.title;"
align="center">
<image class="category-icon"/>
<label class="category-name" flex="1">&paneAdvanced.title;</label>
<label class="category-name" flex="1">&paneUpdates.title;</label>
</richlistitem>
</richlistbox>
@ -189,13 +159,10 @@
<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>

Просмотреть файл

@ -11,8 +11,28 @@ XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
"resource://gre/modules/ContextualIdentityService.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper",
"resource://gre/modules/LoginHelper.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "SiteDataManager",
"resource:///modules/SiteDataManager.jsm");
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
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 gPrivacyPane = {
_pane: null,
/**
* Whether the use has selected the auto-start private browsing mode in the UI.
@ -180,6 +200,104 @@ var gPrivacyPane = {
gPrivacyPane._checkBrowserContainers);
setEventListener("browserContainersSettings", "command",
gPrivacyPane.showContainerSettings);
setEventListener("passwordExceptions", "command",
gPrivacyPane.showPasswordExceptions);
setEventListener("useMasterPassword", "command",
gPrivacyPane.updateMasterPasswordButton);
setEventListener("changeMasterPassword", "command",
gPrivacyPane.changeMasterPassword);
setEventListener("showPasswords", "command",
gPrivacyPane.showPasswords);
setEventListener("addonExceptions", "command",
gPrivacyPane.showAddonExceptions);
setEventListener("viewCertificatesButton", "command",
gPrivacyPane.showCertificates);
setEventListener("viewSecurityDevicesButton", "command",
gPrivacyPane.showSecurityDevices);
setEventListener("connectionSettings", "command",
gPrivacyPane.showConnections);
setEventListener("clearCacheButton", "command",
gPrivacyPane.clearCache);
this._pane = document.getElementById("panePrivacy");
this._initMasterPasswordUI();
this._initSafeBrowsing();
this.updateCacheSizeInputField();
this.updateActualCacheSize();
setEventListener("notificationsPolicyButton", "command",
gPrivacyPane.showNotificationExceptions);
setEventListener("popupPolicyButton", "command",
gPrivacyPane.showPopupExceptions);
setEventListener("notificationsDoNotDisturb", "command",
gPrivacyPane.toggleDoNotDisturbNotifications);
if (AlertsServiceDND) {
let notificationsDoNotDisturbRow =
document.getElementById("notificationsDoNotDisturbRow");
notificationsDoNotDisturbRow.removeAttribute("hidden");
if (AlertsServiceDND.manualDoNotDisturb) {
let notificationsDoNotDisturb =
document.getElementById("notificationsDoNotDisturb");
notificationsDoNotDisturb.setAttribute("checked", true);
}
}
setEventListener("cacheSize", "change",
gPrivacyPane.updateCacheSizePref);
if (Services.prefs.getBoolPref("browser.preferences.offlineGroup.enabled")) {
this.updateOfflineApps();
this.updateActualAppCacheSize();
setEventListener("offlineNotifyExceptions", "command",
gPrivacyPane.showOfflineExceptions);
setEventListener("offlineAppsList", "select",
gPrivacyPane.offlineAppSelected);
setEventListener("offlineAppsListRemove", "command",
gPrivacyPane.removeOfflineApp);
setEventListener("clearOfflineAppCacheButton", "command",
gPrivacyPane.clearOfflineAppCache);
let bundlePrefs = document.getElementById("bundlePreferences");
document.getElementById("offlineAppsList")
.style.height = bundlePrefs.getString("offlineAppsList.height");
let offlineGroup = document.getElementById("offlineGroup");
offlineGroup.hidden = false;
}
if (Services.prefs.getBoolPref("browser.storageManager.enabled")) {
Services.obs.addObserver(this, "sitedatamanager:sites-updated", false);
let unload = () => {
window.removeEventListener("unload", unload);
Services.obs.removeObserver(this, "sitedatamanager:sites-updated");
};
window.addEventListener("unload", unload);
SiteDataManager.updateSites();
setEventListener("clearSiteDataButton", "command",
gPrivacyPane.clearSiteData);
setEventListener("siteDataSettings", "command",
gPrivacyPane.showSiteDataSettings);
}
let notificationInfoURL =
Services.urlFormatter.formatURLPref("app.support.baseURL") + "push";
document.getElementById("notificationsPolicyLearnMore").setAttribute("href",
notificationInfoURL);
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");
}
},
// TRACKING PROTECTION MODE
@ -691,6 +809,635 @@ var gPrivacyPane = {
var settings = document.getElementById("browserContainersSettings");
settings.disabled = !pref.value;
}
},
toggleDoNotDisturbNotifications(event) {
AlertsServiceDND.manualDoNotDisturb = event.target.checked;
},
// 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() {
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);
},
// UTILITY FUNCTIONS
/**
* Utility function to enable/disable the button specified by aButtonID based
* on the value of the Boolean preference specified by aPreferenceID.
*/
updateButtons(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
*/
// POP-UPS
/**
* Displays a dialog in which the user can view and modify the list of sites
* where passwords are never saved.
*/
showPasswordExceptions() {
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() {
var noMP = !LoginHelper.isMasterPasswordSet();
var button = document.getElementById("changeMasterPassword");
button.disabled = noMP;
var checkbox = document.getElementById("useMasterPassword");
checkbox.checked = !noMP;
},
/**
* 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() {
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 a dialog in which the master password may be changed.
*/
changeMasterPassword() {
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() {
gSubDialog.open("chrome://passwordmgr/content/passwordManager.xul");
},
/**
* 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() {
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;
},
/**
* Enables/disables the add-ons Exceptions button depending on whether
* or not add-on installation warnings are displayed.
*/
readWarnAddonInstall() {
var warn = document.getElementById("xpinstall.whitelist.required");
var exceptions = document.getElementById("addonExceptions");
exceptions.disabled = !warn.value;
// don't override the preference value
return undefined;
},
_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;
},
/**
* Displays the exceptions lists for add-on installation warnings.
*/
showAddonExceptions() {
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"
},
/**
* 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() {
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() {
var checkbox = document.getElementById("enableOCSP");
return checkbox.checked ? 1 : 0;
},
/**
* Displays the user's certificates and associated options.
*/
showCertificates() {
gSubDialog.open("chrome://pippki/content/certManager.xul");
},
/**
* Displays a dialog from which the user can manage his security devices.
*/
showSecurityDevices() {
gSubDialog.open("chrome://pippki/content/device_manager.xul");
},
// NETWORK
/**
* Displays a dialog in which proxy settings may be changed.
*/
showConnections() {
gSubDialog.open("chrome://browser/content/preferences/connection.xul");
},
/**
* Clears the cache.
*/
clearCache() {
try {
var cache = Components.classes["@mozilla.org/netwerk/cache-storage-service;1"]
.getService(Components.interfaces.nsICacheStorageService);
cache.clear();
} catch (ex) {}
this.updateActualCacheSize();
},
showOfflineExceptions() {
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);
},
offlineAppSelected() {
var removeButton = document.getElementById("offlineAppsListRemove");
var list = document.getElementById("offlineAppsList");
if (list.selectedItem) {
removeButton.setAttribute("disabled", "false");
} else {
removeButton.setAttribute("disabled", "true");
}
},
showSiteDataSettings() {
gSubDialog.open("chrome://browser/content/preferences/siteDataSettings.xul");
},
updateTotalSiteDataSize() {
SiteDataManager.getTotalUsage()
.then(usage => {
let size = DownloadUtils.convertByteUnits(usage);
let prefStrBundle = document.getElementById("bundlePreferences");
let totalSiteDataSizeLabel = document.getElementById("totalSiteDataSize");
totalSiteDataSizeLabel.textContent = prefStrBundle.getFormattedString("totalSiteDataSize", size);
let siteDataGroup = document.getElementById("siteDataGroup");
siteDataGroup.hidden = false;
});
},
// Retrieves the amount of space currently used by disk cache
updateActualCacheSize() {
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(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) {}
},
updateCacheSizeUI(smartSizeEnabled) {
document.getElementById("useCacheBefore").disabled = smartSizeEnabled;
document.getElementById("cacheSize").disabled = smartSizeEnabled;
document.getElementById("useCacheAfter").disabled = smartSizeEnabled;
},
readSmartSizeEnabled() {
// 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.
*
* Preferences:
*
* browser.cache.disk.capacity
* - the size of the browser cache in KB
* - Only used if browser.cache.disk.smart_size.enabled is disabled
*/
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;
},
clearSiteData() {
let flags =
Services.prompt.BUTTON_TITLE_IS_STRING * Services.prompt.BUTTON_POS_0 +
Services.prompt.BUTTON_TITLE_CANCEL * Services.prompt.BUTTON_POS_1 +
Services.prompt.BUTTON_POS_0_DEFAULT;
let prefStrBundle = document.getElementById("bundlePreferences");
let title = prefStrBundle.getString("clearSiteDataPromptTitle");
let text = prefStrBundle.getString("clearSiteDataPromptText");
let btn0Label = prefStrBundle.getString("clearSiteDataNow");
let result = Services.prompt.confirmEx(
window, title, text, flags, btn0Label, null, null, null, {});
if (result == 0) {
SiteDataManager.removeAll();
}
},
// Methods for Offline Apps (AppCache)
/**
* Clears the application cache.
*/
clearOfflineAppCache() {
Components.utils.import("resource:///modules/offlineAppCache.jsm");
OfflineAppCacheHelper.clear();
this.updateActualAppCacheSize();
this.updateOfflineApps();
},
// Retrieves the amount of space currently used by offline cache
updateActualAppCacheSize() {
var visitor = {
onCacheStorageInfo(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) {}
},
readOfflineNotify() {
var pref = document.getElementById("browser.offline-apps.notify");
var button = document.getElementById("offlineNotifyExceptions");
button.disabled = !pref.value;
return pref.value;
},
// 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);
if (perm.matchesURI(uri, true)) {
let cache = cacheService.getActiveCache(group);
usage += cache.usage;
}
}
return usage;
},
/**
* Updates the list of offline applications
*/
updateOfflineApps() {
var pm = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var list = document.getElementById("offlineAppsList");
while (list.firstChild) {
list.firstChild.remove();
}
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);
}
}
},
removeOfflineApp() {
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]);
if (perm.matchesURI(uri, true)) {
var cache = cacheService.getActiveCache(groups[i]);
cache.discard();
}
}
} catch (e) {}
pm.removePermission(perm);
}
list.removeChild(item);
gPrivacyPane.offlineAppSelected();
this.updateActualAppCacheSize();
},
// Methods for Offline Apps (AppCache) end
};

Просмотреть файл

@ -76,72 +76,96 @@
<preference id="browser.privatebrowsing.autostart"
name="browser.privatebrowsing.autostart"
type="bool"/>
<!-- DRM content -->
<preference id="media.eme.enabled"
name="media.eme.enabled"
type="bool"/>
<!-- Popups -->
<preference id="dom.disable_open_during_load"
name="dom.disable_open_during_load"
type="bool"/>
<!-- Passwords -->
<preference id="signon.rememberSignons" name="signon.rememberSignons" type="bool"/>
<!-- 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"/>
<!-- 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"/>
<!-- Add-ons, malware, phishing -->
<preference id="xpinstall.whitelist.required"
name="xpinstall.whitelist.required"
type="bool"/>
<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"/>
<!-- 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"/>
</preferences>
<stringbundle id="bundlePreferences" src="chrome://browser/locale/preferences/preferences.properties"/>
<hbox id="header-privacy"
class="header"
hidden="true"
data-category="panePrivacy">
<label class="header-name" flex="1">&panePrivacy.title;</label>
<label class="header-name" flex="1">&panePrivacySecurity.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="learnMore 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="learnMore 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">
@ -265,6 +289,164 @@
</deck>
</groupbox>
<!-- Passwords -->
<groupbox id="passwordsGroup" orient="vertical" data-category="panePrivacy" hidden="true">
<caption><label>&formsAndPasswords.label;</label></caption>
<hbox id="savePasswordsBox">
<checkbox id="savePasswords"
label="&rememberLogins1.label;" accesskey="&rememberLogins1.accesskey;"
preference="signon.rememberSignons"
onsyncfrompreference="return gPrivacyPane.readSavePasswords();"/>
<spacer flex="1"/>
<button id="passwordExceptions"
label="&passwordExceptions.label;"
accesskey="&passwordExceptions.accesskey;"
preference="pref.privacy.disable_button.view_passwords_exceptions"/>
</hbox>
<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>
<!-- Tracking -->
<groupbox id="trackingGroup" data-category="panePrivacy" hidden="true">
<vbox id="trackingprotectionbox" hidden="true">
<hbox align="start">
<vbox hidden="false">
<caption><label>&trackingProtectionHeader2.label;
<label id="trackingProtectionLearnMore" class="learnMore 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 hidden="true">
<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="learnMore 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 hidden="false">
<description>&doNotTrack.pre.label;<label
class="text-link" id="doNotTrackSettings"
>&doNotTrack.settings.label;</label>&doNotTrack.post.label;</description>
</vbox>
</groupbox>
<!-- Pop-ups -->
<groupbox id="miscGroup" data-category="panePrivacy" 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 gPrivacyPane.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>
<!-- Notifications -->
<groupbox id="notificationsGroup" data-category="panePrivacy" hidden="true">
<caption><label>&notificationsPolicy.label;</label></caption>
<grid>
<columns>
<column flex="1"/>
<column/>
</columns>
<rows>
<row id="notificationsPolicyRow" align="center">
<hbox align="start">
<label id="notificationsPolicy">&notificationsPolicyDesc3.label;</label>
<label id="notificationsPolicyLearnMore"
class="learnMore text-link"
value="&notificationsPolicyLearnMore.label;"/>
</hbox>
<hbox pack="end">
<button id="notificationsPolicyButton" label="&notificationsPolicyButton.label;"
accesskey="&notificationsPolicyButton.accesskey;"/>
</hbox>
</row>
<row id="notificationsDoNotDisturbRow" hidden="true">
<vbox align="start">
<checkbox id="notificationsDoNotDisturb" label="&notificationsDoNotDisturb.label;"
accesskey="&notificationsDoNotDisturb.accesskey;"/>
<label id="notificationsDoNotDisturbDetails"
class="indent"
value="&notificationsDoNotDisturbDetails.value;"/>
</vbox>
</row>
</rows>
</grid>
</groupbox>
<!-- Location Bar -->
<groupbox id="locationBarGroup"
data-category="panePrivacy"
@ -280,11 +462,106 @@
<checkbox id="openpageSuggestion" label="&locbar.openpage.label;"
accesskey="&locbar.openpage.accesskey;"
preference="browser.urlbar.suggest.openpage"/>
<label class="text-link" onclick="gotoPref('search')">
<label class="text-link" onclick="gotoPref('general')">
&suggestionSettings.label;
</label>
</groupbox>
<!-- addons, forgery (phishing) UI Security -->
<groupbox id="addonsPhishingGroup" data-category="panePrivacy" hidden="true">
<caption><label>&security.label;</label></caption>
<hbox id="addonInstallBox">
<checkbox id="warnAddonInstall"
label="&warnOnAddonInstall.label;"
accesskey="&warnOnAddonInstall.accesskey;"
preference="xpinstall.whitelist.required"
onsyncfrompreference="return gPrivacyPane.readWarnAddonInstall();"/>
<spacer flex="1"/>
<button id="addonExceptions"
label="&addonExceptions.label;"
accesskey="&addonExceptions.accesskey;"/>
</hbox>
<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="&blockUncommonAndUnwanted.label;"
accesskey="&blockUncommonAndUnwanted.accesskey;" />
</vbox>
</vbox>
</groupbox>
<!-- Certificates -->
<groupbox id="certSelection" align="start" data-category="panePrivacy" hidden="true">
<caption><label>&certificateTab.label;</label></caption>
<description id="CertSelectionDesc" control="certSelection">&certPersonal.description;</description>
<!--
The values on these radio buttons may look like l10n 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="&selectCerts.auto;"
accesskey="&selectCerts.auto.accesskey;"
value="Select Automatically"/>
<radio label="&selectCerts.ask;"
accesskey="&selectCerts.ask.accesskey;"
value="Ask Every Time"/>
</radiogroup>
<checkbox id="enableOCSP"
label="&enableOCSP.label;"
accesskey="&enableOCSP.accesskey;"
onsyncfrompreference="return gPrivacyPane.readEnableOCSP();"
onsynctopreference="return gPrivacyPane.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>
</groupbox>
<!-- DRM Content -->
<groupbox id="drmGroup" data-category="panePrivacy" hidden="true">
<caption><label>&drmContent.label;</label></caption>
<grid id="contentGrid2">
<columns>
<column flex="1"/>
<column/>
</columns>
<rows id="contentRows-2">
<row id="playDRMContentRow">
<hbox align="center">
<checkbox id="playDRMContent" preference="media.eme.enabled"
label="&playDRMContent.label;" accesskey="&playDRMContent.accesskey;"/>
<label id="playDRMContentLink" class="learnMore text-link" value="&playDRMContent.learnMore.label;"/>
</hbox>
</row>
</rows>
</grid>
</groupbox>
<!-- Containers -->
<groupbox id="browserContainersGroup" data-category="panePrivacy" hidden="true">
<vbox id="browserContainersbox" hidden="true">
@ -309,3 +586,94 @@
</hbox>
</vbox>
</groupbox>
<!-- Network -->
<!-- Connection -->
<groupbox id="connectionGroup" data-category="panePrivacy" hidden="true">
<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" data-category="panePrivacy" hidden="true">
<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 gPrivacyPane.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" data-category="panePrivacy" hidden="true">
<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="&offlineStorageNotify.label;" accesskey="&offlineStorageNotify.accesskey;"
preference="browser.offline-apps.notify"
onsyncfrompreference="return gPrivacyPane.readOfflineNotify();"/>
<spacer flex="1"/>
<button id="offlineNotifyExceptions"
label="&offlineStorageNotifyExceptions.label;"
accesskey="&offlineStorageNotifyExceptions.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>
<!-- Site Data -->
<groupbox id="siteDataGroup" hidden="true" data-category="panePrivacy">
<caption><label>&siteData.label;</label></caption>
<hbox align="center">
<label id="totalSiteDataSize" flex="1"></label>
<button id="clearSiteDataButton" icon="clear"
label="&clearSiteData.label;" accesskey="&clearSiteData.accesskey;"/>
</hbox>
<vbox align="end">
<button id="siteDataSettings"
label="&siteDataSettings.label;"
accesskey="&siteDataSettings.accesskey;"/>
</vbox>
</groupbox>

Просмотреть файл

@ -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/. */
/* import-globals-from preferences.js */
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() {
Components.classes["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
.getService(Components.interfaces.mozIPlacesAutoComplete);
},
init() {
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);
window.addEventListener("command", this);
window.addEventListener("dragstart", this);
window.addEventListener("keypress", this);
window.addEventListener("select", this);
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");
});
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() {
// 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(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(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(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() {
document.getElementById("removeEngineButton").disabled =
!gEngineView.isEngineSelectedAndRemovable();
},
onTreeKeyPress(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() {
let num = gEngineView._engineStore.restoreDefaultEngines();
gEngineView.rowCountChanged(0, num);
gEngineView.invalidate();
},
showRestoreDefaults(aEnable) {
document.getElementById("restoreDefaultSearchEngines").disabled = !aEnable;
},
remove(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() {
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() {
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(aEngine) {
return this._engines.indexOf(aEngine);
},
_getEngineByName(aName) {
return this._engines.find(engine => engine.name == aName);
},
_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(aEngineClone) {
return aEngineClone.originalEngine == this.originalEngine;
},
addEngine(aEngine) {
this._engines.push(this._cloneEngine(aEngine));
},
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(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() {
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(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() {
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(index, count) {
this.tree.rowCountChanged(index, count);
},
invalidate() {
this.tree.invalidate();
},
ensureRowIsVisible(index) {
this.tree.ensureRowIsVisible(index);
},
getSourceIndexFromDrag(dataTransfer) {
return parseInt(dataTransfer.getData(ENGINE_FLAVOR));
},
isCheckBox(index, column) {
return column.id == "engineShown";
},
isEngineSelectedAndRemovable() {
return this.selectedIndex != -1 && this.lastIndex != 0;
},
// nsITreeView
get rowCount() {
return this._engineStore.engines.length;
},
getImageSrc(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(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(tree) {
this.tree = tree;
},
canDrop(targetIndex, orientation, dataTransfer) {
var sourceIndex = this.getSourceIndexFromDrag(dataTransfer);
return (sourceIndex != -1 &&
sourceIndex != targetIndex &&
sourceIndex != targetIndex + orientation);
},
drop(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(index) { return ""; },
getCellProperties(index, column) { return ""; },
getColumnProperties(column) { return ""; },
isContainer(index) { return false; },
isContainerOpen(index) { return false; },
isContainerEmpty(index) { return false; },
isSeparator(index) { return false; },
isSorted(index) { return false; },
getParentIndex(index) { return -1; },
hasNextSibling(parentIndex, index) { return false; },
getLevel(index) { return 0; },
getProgressMode(index, column) { },
getCellValue(index, column) {
if (column.id == "engineShown")
return this._engineStore.engines[index].shown;
return undefined;
},
toggleOpenState(index) { },
cycleHeader(column) { },
selectionChanged() { },
cycleCell(row, column) { },
isEditable(index, column) { return column.id != "engineName"; },
isSelectable(index, column) { return false; },
setCellValue(index, column, value) {
if (column.id == "engineShown") {
this._engineStore.engines[index].shown = value == "true";
gEngineView.invalidate();
gSearchPane.saveOneClickEnginesList();
}
},
setCellText(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(action) { },
performActionOnRow(action, index) { },
performActionOnCell(action, index, column) { }
};

Просмотреть файл

@ -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>

Просмотреть файл

@ -1,292 +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 preferences.js */
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 setEventListener(aId, aEventType, aCallback) {
document.getElementById(aId)
.addEventListener(aEventType, aCallback.bind(gSecurityPane));
}
this._pane = document.getElementById("paneSecurity");
this._initMasterPasswordUI();
this._initSafeBrowsing();
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() {
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() {
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() {
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() {
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() {
var noMP = !LoginHelper.isMasterPasswordSet();
var button = document.getElementById("changeMasterPassword");
button.disabled = noMP;
var checkbox = document.getElementById("useMasterPassword");
checkbox.checked = !noMP;
},
_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;
},
/**
* 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() {
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() {
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() {
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() {
gSubDialog.open("chrome://passwordmgr/content/passwordManager.xul");
}
};

Просмотреть файл

@ -1,131 +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, malware, phishing -->
<preference id="xpinstall.whitelist.required"
name="xpinstall.whitelist.required"
type="bool"/>
<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"/>
<!-- Passwords -->
<preference id="signon.rememberSignons" name="signon.rememberSignons" 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, forgery (phishing) UI -->
<groupbox id="addonsPhishingGroup" data-category="paneSecurity" hidden="true">
<caption><label>&general.label;</label></caption>
<hbox id="addonInstallBox">
<checkbox id="warnAddonInstall"
label="&warnOnAddonInstall.label;"
accesskey="&warnOnAddonInstall.accesskey;"
preference="xpinstall.whitelist.required"
onsyncfrompreference="return gSecurityPane.readWarnAddonInstall();"/>
<spacer flex="1"/>
<button id="addonExceptions"
label="&addonExceptions.label;"
accesskey="&addonExceptions.accesskey;"/>
</hbox>
<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="&blockUncommonAndUnwanted.label;"
accesskey="&blockUncommonAndUnwanted.accesskey;" />
</vbox>
</vbox>
</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>
<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>

Просмотреть файл

@ -32,7 +32,7 @@
class="header"
hidden="true"
data-category="paneSync">
<label class="header-name" flex="1">&paneSync.title;</label>
<label class="header-name" flex="1">&paneSync1.title;</label>
<html:a class="help-button text-link" target="_blank" aria-label="&helpButton.label;"></html:a>
</hbox>
@ -191,8 +191,8 @@
<textbox id="fxaSyncComputerName" disabled="true"/>
<hbox>
<button id="fxaChangeDeviceName"
label="&changeSyncDeviceName.label;"
accesskey="&changeSyncDeviceName.accesskey;"/>
label="&changeSyncDeviceName1.label;"
accesskey="&changeSyncDeviceName1.accesskey;"/>
<button id="fxaCancelChangeDeviceName"
label="&cancelChangeSyncDeviceName.label;"
accesskey="&cancelChangeSyncDeviceName.accesskey;"

Просмотреть файл

@ -233,7 +233,7 @@ add_task(function* () {
yield waitForEvent(gBrowser.selectedBrowser.contentWindow, "test-indexedDB-done");
yield BrowserTestUtils.removeTab(gBrowser.selectedTab);
yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
// Test the initial states
let cacheUsage = yield cacheUsageGetter.get();
@ -299,7 +299,7 @@ add_task(function* () {
mockSiteDataManager.register();
let updatePromise = promiseSitesUpdated();
yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
yield updatePromise;
yield openSettingsDialog();
@ -390,7 +390,7 @@ add_task(function* () {
mockSiteDataManager.register();
let updatePromise = promiseSitesUpdated();
yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
yield updatePromise;
yield openSettingsDialog();
@ -429,7 +429,7 @@ add_task(function* () {
fakeOrigins.forEach(origin => addPersistentStoragePerm(origin));
let updatePromise = promiseSitesUpdated();
yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
yield updatePromise;
yield openSettingsDialog();
@ -533,7 +533,7 @@ add_task(function* () {
fakeOrigins.forEach(origin => addPersistentStoragePerm(origin));
let updatePromise = promiseSitesUpdated();
yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
yield updatePromise;
yield openSettingsDialog();
@ -617,7 +617,7 @@ add_task(function* () {
fakeOrigins.forEach(origin => addPersistentStoragePerm(origin));
let updatePromise = promiseSitesUpdated();
yield openPreferencesViaOpenPreferencesAPI("advanced", "networkTab", { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
yield updatePromise;
yield openSettingsDialog();

Просмотреть файл

@ -93,7 +93,7 @@ function formatInstallDate(sec) {
registerCleanupFunction(resetPreferences);
add_task(function*() {
yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab", { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("advanced", { leaveOpen: true });
resetPreferences();
Services.prefs.setBoolPref("browser.search.update", false);
@ -112,7 +112,7 @@ add_task(function*() {
add_task(function*() {
mockUpdateManager.register();
yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab", { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("advanced", { leaveOpen: true });
let doc = gBrowser.selectedBrowser.contentDocument;
let showBtn = doc.getElementById("showUpdateHistory");

Просмотреть файл

@ -5,7 +5,7 @@ var container;
SimpleTest.requestCompleteLog();
add_task(function* setup() {
yield openPreferencesViaOpenPreferencesAPI("applications", null, {leaveOpen: true});
yield openPreferencesViaOpenPreferencesAPI("applications", {leaveOpen: true});
info("Preferences page opened on the applications pane.");
registerCleanupFunction(() => {

Просмотреть файл

@ -5,7 +5,7 @@ registerCleanupFunction(function() {
});
add_task(function*() {
yield openPreferencesViaOpenPreferencesAPI("paneContent", null, {leaveOpen: true});
yield openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
let doc = gBrowser.contentDocument;
var langGroup = Services.prefs.getComplexValue("font.language.group", Ci.nsIPrefLocalizedString).data
is(doc.getElementById("font.language.group").value, langGroup,

Просмотреть файл

@ -11,7 +11,7 @@ registerCleanupFunction(function() {
add_task(function*() {
originalWindowHeight = window.outerHeight;
window.resizeTo(window.outerWidth, 300);
let prefs = yield openPreferencesViaOpenPreferencesAPI("paneApplications", undefined, {leaveOpen: true});
let prefs = yield openPreferencesViaOpenPreferencesAPI("paneApplications", {leaveOpen: true});
is(prefs.selectedPane, "paneApplications", "Applications pane was selected");
let mainContent = gBrowser.contentDocument.querySelector(".main-content");
mainContent.scrollTop = 50;

Просмотреть файл

@ -8,11 +8,10 @@ registerCleanupFunction(function() {
});
add_task(function*() {
let prefs = yield openPreferencesViaOpenPreferencesAPI("paneContent");
is(prefs.selectedPane, "paneContent", "Content pane was selected");
prefs = yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab");
let prefs = yield openPreferencesViaOpenPreferencesAPI("panePrivacy");
is(prefs.selectedPane, "panePrivacy", "Privacy pane was selected");
prefs = yield openPreferencesViaOpenPreferencesAPI("advanced");
is(prefs.selectedPane, "paneAdvanced", "Advanced pane was selected");
is(prefs.selectedAdvancedTab, "updateTab", "The update tab within the advanced prefs should be selected");
prefs = yield openPreferencesViaHash("privacy");
is(prefs.selectedPane, "panePrivacy", "Privacy pane is selected when hash is 'privacy'");
prefs = yield openPreferencesViaOpenPreferencesAPI("nonexistant-category");

Просмотреть файл

@ -40,7 +40,7 @@ add_task(function* () {
yield checkPageScrolling(container, "radio");
});
yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:preferences#search" }, function* (browser) {
yield BrowserTestUtils.withNewTab({ gBrowser, url: "about:preferences" }, function* (browser) {
let doc = browser.contentDocument;
let container = doc.getElementsByClassName("main-content")[0];

Просмотреть файл

@ -22,7 +22,7 @@ function test() {
getService(Ci.nsIHandlerService);
hserv.store(info);
openPreferencesViaOpenPreferencesAPI("applications", null, {leaveOpen: true}).then(
openPreferencesViaOpenPreferencesAPI("applications", {leaveOpen: true}).then(
() => runTest(gBrowser.selectedBrowser.contentWindow)
);
}

Просмотреть файл

@ -37,8 +37,8 @@ function runTest(win) {
gElements = tab.getElementById("mainPrefPane").children;
let panes = [
"General", "Search", "Content", "Applications",
"Privacy", "Security", "Sync", "Advanced",
"General", "Applications",
"Privacy", "Sync", "Advanced",
];
for (let pane of panes) {

Просмотреть файл

@ -16,7 +16,7 @@ function setupFakeHandler() {
add_task(function*() {
setupFakeHandler();
yield openPreferencesViaOpenPreferencesAPI("applications", null, {leaveOpen: true});
yield openPreferencesViaOpenPreferencesAPI("applications", {leaveOpen: true});
info("Preferences page opened on the applications pane.");
let win = gBrowser.selectedBrowser.contentWindow;

Просмотреть файл

@ -334,7 +334,7 @@ var testRunner = {
Services.prefs.clearUserPref("privacy.history.custom");
});
openPreferencesViaOpenPreferencesAPI("panePrivacy", null, {leaveOpen: true}).then(function() {
openPreferencesViaOpenPreferencesAPI("panePrivacy", {leaveOpen: true}).then(function() {
let doc = gBrowser.contentDocument;
let historyMode = doc.getElementById("historyMode");
historyMode.value = "custom";

Просмотреть файл

@ -1,7 +1,7 @@
add_task(function*() {
is(gBrowser.currentURI.spec, "about:blank", "Test starts with about:blank open");
yield BrowserTestUtils.openNewForegroundTab(gBrowser, "about:home");
yield openPreferencesViaOpenPreferencesAPI("paneGeneral", null, {leaveOpen: true});
yield openPreferencesViaOpenPreferencesAPI("paneGeneral", {leaveOpen: true});
let doc = gBrowser.contentDocument;
is(gBrowser.currentURI.spec, "about:preferences#general",
"#general should be in the URI for about:preferences");

Просмотреть файл

@ -8,8 +8,8 @@ registerCleanupFunction(function() {
});
add_task(function*() {
let prefs = yield openPreferencesViaOpenPreferencesAPI("paneContent", undefined, {leaveOpen: true});
is(prefs.selectedPane, "paneContent", "Content pane was selected");
let prefs = yield openPreferencesViaOpenPreferencesAPI("panePrivacy", {leaveOpen: true});
is(prefs.selectedPane, "panePrivacy", "Privacy pane was selected");
let doc = gBrowser.contentDocument;
let notificationsDoNotDisturbRow = doc.getElementById("notificationsDoNotDisturbRow");

Просмотреть файл

@ -3,7 +3,7 @@
const PERMISSIONS_URL = "chrome://browser/content/preferences/permissions.xul";
add_task(function* urlFieldVisibleForPopupPermissions(finish) {
yield openPreferencesViaOpenPreferencesAPI("paneContent", null, {leaveOpen: true});
yield openPreferencesViaOpenPreferencesAPI("panePrivacy", {leaveOpen: true});
let win = gBrowser.selectedBrowser.contentWindow;
let doc = win.document;
let popupPolicyCheckbox = doc.getElementById("popupPolicy");
@ -26,7 +26,7 @@ add_task(function* urlFieldVisibleForPopupPermissions(finish) {
});
add_task(function* urlFieldHiddenForNotificationPermissions() {
yield openPreferencesViaOpenPreferencesAPI("paneContent", null, {leaveOpen: true});
yield openPreferencesViaOpenPreferencesAPI("panePrivacy", {leaveOpen: true});
let win = gBrowser.selectedBrowser.contentWindow;
let doc = win.document;
let notificationsPolicyButton = doc.getElementById("notificationsPolicyButton");

Просмотреть файл

@ -28,12 +28,12 @@ add_task(function setup() {
});
add_task(function* test_preference_enabled_when_unlocked() {
yield openPreferencesViaOpenPreferencesAPI("panePrivacy", undefined, {leaveOpen: true});
yield openPreferencesViaOpenPreferencesAPI("panePrivacy", {leaveOpen: true});
testPrefStateMatchesLockedState();
});
add_task(function* test_preference_disabled_when_locked() {
Services.prefs.lockPref("privacy.sanitize.sanitizeOnShutdown");
yield openPreferencesViaOpenPreferencesAPI("panePrivacy", undefined, {leaveOpen: true});
yield openPreferencesViaOpenPreferencesAPI("panePrivacy", {leaveOpen: true});
testPrefStateMatchesLockedState();
});

Просмотреть файл

@ -8,7 +8,7 @@ registerCleanupFunction(() => {
add_task(function*() {
Services.prefs.setBoolPref("browser.search.suggest.enabled", true);
yield openPreferencesViaOpenPreferencesAPI("search", undefined, { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("general", { leaveOpen: true });
let doc = gBrowser.selectedBrowser.contentDocument;
let urlbarBox = doc.getElementById("urlBarSuggestion");
@ -25,7 +25,7 @@ add_task(function*() {
add_task(function*() {
Services.prefs.setBoolPref("browser.search.suggest.enabled", false);
yield openPreferencesViaOpenPreferencesAPI("search", undefined, { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("general", { leaveOpen: true });
let doc = gBrowser.selectedBrowser.contentDocument;
let urlbarBox = doc.getElementById("urlBarSuggestion");

Просмотреть файл

@ -21,7 +21,7 @@ add_task(function*() {
Services.prefs.setBoolPref("browser.safebrowsing.phishing.enabled", val1);
Services.prefs.setBoolPref("browser.safebrowsing.malware.enabled", val2);
yield openPreferencesViaOpenPreferencesAPI("security", undefined, { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
let doc = gBrowser.selectedBrowser.contentDocument;
let checkbox = doc.getElementById("enableSafeBrowsing");
@ -33,7 +33,8 @@ add_task(function*() {
is(blockDownloads.hasAttribute("disabled"), !checked, "block downloads checkbox is set correctly");
is(blockUncommon.hasAttribute("disabled"), !checked, "block uncommon checkbox is set correctly");
// click the checkbox
// scroll the checkbox into the viewport and click checkbox
checkbox.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(checkbox, {}, gBrowser.selectedBrowser.contentWindow);
// check that both settings are now turned on or off
@ -61,7 +62,7 @@ add_task(function*() {
function* checkPrefSwitch(val) {
Services.prefs.setBoolPref("browser.safebrowsing.downloads.enabled", val);
yield openPreferencesViaOpenPreferencesAPI("security", undefined, { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
let doc = gBrowser.selectedBrowser.contentDocument;
let checkbox = doc.getElementById("blockDownloads");
@ -71,7 +72,8 @@ add_task(function*() {
// should be disabled when val is false (= pref is turned off)
is(blockUncommon.hasAttribute("disabled"), !val, "block uncommon checkbox is set correctly");
// click the checkbox
// scroll the checkbox into view, otherwise the synthesizeMouseAtCenter will be ignored, and click it
checkbox.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(checkbox, {}, gBrowser.selectedBrowser.contentWindow);
// check that setting is now turned on or off
@ -94,14 +96,15 @@ add_task(function*() {
Services.prefs.setBoolPref("browser.safebrowsing.downloads.remote.block_potentially_unwanted", val1);
Services.prefs.setBoolPref("browser.safebrowsing.downloads.remote.block_uncommon", val2);
yield openPreferencesViaOpenPreferencesAPI("security", undefined, { leaveOpen: true });
yield openPreferencesViaOpenPreferencesAPI("privacy", { leaveOpen: true });
let doc = gBrowser.selectedBrowser.contentDocument;
let checkbox = doc.getElementById("blockUncommonUnwanted");
let checked = checkbox.checked;
is(checked, val1 && val2, "unwanted/uncommon preference is initialized correctly");
// click the checkbox
// scroll the checkbox into view, otherwise the synthesizeMouseAtCenter will be ignored, and click it
checkbox.scrollIntoView();
EventUtils.synthesizeMouseAtCenter(checkbox, {}, gBrowser.selectedBrowser.contentWindow);
// check that both settings are now turned on or off

Просмотреть файл

@ -119,21 +119,19 @@ function waitForEvent(aSubject, aEventName, aTimeoutMs, aTarget) {
return eventDeferred.promise.then(cleanup, cleanup);
}
function openPreferencesViaOpenPreferencesAPI(aPane, aAdvancedTab, aOptions) {
function openPreferencesViaOpenPreferencesAPI(aPane, aOptions) {
let deferred = Promise.defer();
gBrowser.selectedTab = gBrowser.addTab("about:blank");
openPreferences(aPane, aAdvancedTab ? {advancedTab: aAdvancedTab} : undefined);
openPreferences(aPane);
let newTabBrowser = gBrowser.selectedBrowser;
newTabBrowser.addEventListener("Initialized", function() {
newTabBrowser.contentWindow.addEventListener("load", function() {
let win = gBrowser.contentWindow;
let selectedPane = win.history.state;
let doc = win.document;
let selectedAdvancedTab = aAdvancedTab && doc.getElementById("advancedPrefs").selectedTab.id;
if (!aOptions || !aOptions.leaveOpen)
gBrowser.removeCurrentTab();
deferred.resolve({selectedPane, selectedAdvancedTab});
deferred.resolve({selectedPane});
}, {once: true});
}, {capture: true, once: true});

Просмотреть файл

@ -1420,7 +1420,7 @@
<method name="showSettings">
<body><![CDATA[
BrowserUITelemetry.countSearchSettingsEvent(this.telemetryOrigin);
openPreferences("paneSearch");
openPreferences("paneGeneral");
// If the preference tab was already selected, the panel doesn't
// close itself automatically.
this.popup.hidePopup();

Просмотреть файл

@ -41,7 +41,7 @@
<p>&searchreset.pageInfo1;</p>
<p>&searchreset.selector.label;<span id="defaultEngine"/></p>
<p>&searchreset.beforelink.pageInfo2;<a id="linkSettingsPage" href="about:preferences#search">&searchreset.link.pageInfo2;</a>&searchreset.afterlink.pageInfo2;</p>
<p>&searchreset.beforelink.pageInfo2;<a id="linkSettingsPage" href="about:preferences">&searchreset.link.pageInfo2;</a>&searchreset.afterlink.pageInfo2;</p>
</div>
<div class="button-container">

Просмотреть файл

@ -106,7 +106,7 @@ var gTests = [
*run() {
let loadPromise = BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser,
false,
"about:preferences#search")
"about:preferences")
gBrowser.contentDocument.getElementById("linkSettingsPage").click();
yield loadPromise;

Просмотреть файл

@ -72,7 +72,7 @@ add_task(function* test_yandex_attribution() {
add_task(function* test_preference_attribution() {
let prefUrl = "about:preferences#content";
let prefUrl = "about:preferences#general";
let tab = yield promiseTestPageLoad(prefUrl);
let browser = gBrowser.getBrowserForTab(tab);

Просмотреть файл

@ -126,7 +126,7 @@
label="&translation.options.neverForSite.label;"
accesskey="&translation.options.neverForSite.accesskey;"/>
<xul:menuseparator/>
<xul:menuitem oncommand="openPreferences('paneContent');"
<xul:menuitem oncommand="openPreferences('paneGeneral');"
label="&translation.options.preferences.label;"
accesskey="&translation.options.preferences.accesskey;"/>
<xul:menuitem class="subviewbutton panel-subview-footer"

19
browser/extensions/e10srollout/bootstrap.js поставляемый
Просмотреть файл

@ -9,6 +9,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/UpdateUtils.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
// The amount of people to be part of e10s
const TEST_THRESHOLD = {
@ -23,6 +24,24 @@ const ADDON_ROLLOUT_POLICY = {
"esr": "esrA", // WebExtensions and Addons with mpc=true
};
if (AppConstants.RELEASE_OR_BETA) {
// Bug 1348576 - e10s is never enabled for non-official release builds
// This is hacky, but the problem it solves is the following:
// the e10s rollout is controlled by the channel name, which
// is the only way to distinguish between Beta and Release.
// However, non-official release builds (like the ones done by distros
// to ship Firefox on their package managers) do not set a value
// for the release channel, which gets them to the default value
// of.. (drumroll) "default".
// But we can't just always configure the same settings for the
// "default" channel because that's also the name that a locally
// built Firefox gets, and e10s is managed in a different way
// there (directly by prefs, on Nightly and Aurora).
TEST_THRESHOLD.default = TEST_THRESHOLD.release;
ADDON_ROLLOUT_POLICY.default = ADDON_ROLLOUT_POLICY.release;
}
const PREF_COHORT_SAMPLE = "e10s.rollout.cohortSample";
const PREF_COHORT_NAME = "e10s.rollout.cohort";
const PREF_E10S_OPTED_IN = "browser.tabs.remote.autostart";

Просмотреть файл

@ -10,7 +10,7 @@
<Description about="urn:mozilla:install-manifest">
<em:id>e10srollout@mozilla.org</em:id>
<em:version>1.14</em:version>
<em:version>1.15</em:version>
<em:type>2</em:type>
<em:bootstrap>true</em:bootstrap>
<em:multiprocessCompatible>true</em:multiprocessCompatible>

Просмотреть файл

@ -163,6 +163,7 @@ let ProfileAutocomplete = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
_lastAutoCompleteResult: null,
_lastAutoCompleteFocusedInput: null,
_registered: false,
_factory: null,
@ -196,6 +197,7 @@ let ProfileAutocomplete = {
setProfileAutoCompleteResult(result) {
this._lastAutoCompleteResult = result;
this._lastAutoCompleteFocusedInput = formFillController.focusedInput;
},
observe(subject, topic, data) {
@ -218,6 +220,16 @@ let ProfileAutocomplete = {
.getInterface(Ci.nsIContentFrameMessageManager);
},
_getSelectedIndex(contentWindow) {
let mm = this._frameMMFromWindow(contentWindow);
let selectedIndexResult = mm.sendSyncMessage("FormAutoComplete:GetSelectedIndex", {});
if (selectedIndexResult.length != 1 || !Number.isInteger(selectedIndexResult[0])) {
throw new Error("Invalid autocomplete selectedIndex");
}
return selectedIndexResult[0];
},
_fillFromAutocompleteRow(focusedInput) {
this.log.debug("_fillFromAutocompleteRow:", focusedInput);
let formDetails = FormAutofillContent.getFormDetails(focusedInput);
@ -226,13 +238,7 @@ let ProfileAutocomplete = {
return;
}
let mm = this._frameMMFromWindow(focusedInput.ownerGlobal);
let selectedIndexResult = mm.sendSyncMessage("FormAutoComplete:GetSelectedIndex", {});
if (selectedIndexResult.length != 1 || !Number.isInteger(selectedIndexResult[0])) {
throw new Error("Invalid autocomplete selectedIndex");
}
let selectedIndex = selectedIndexResult[0];
let selectedIndex = this._getSelectedIndex(focusedInput.ownerGlobal);
if (selectedIndex == -1 ||
!this._lastAutoCompleteResult ||
this._lastAutoCompleteResult.getStyleAt(selectedIndex) != "autofill-profile") {
@ -244,6 +250,35 @@ let ProfileAutocomplete = {
formHandler.autofillFormFields(profile, focusedInput);
},
_clearProfilePreview() {
let focusedInput = formFillController.focusedInput || this._lastAutoCompleteFocusedInput;
if (!focusedInput || !FormAutofillContent.getFormDetails(focusedInput)) {
return;
}
let formHandler = FormAutofillContent.getFormHandler(focusedInput);
formHandler.clearPreviewedFormFields();
},
_previewSelectedProfile(selectedIndex) {
let focusedInput = formFillController.focusedInput;
if (!focusedInput || !FormAutofillContent.getFormDetails(focusedInput)) {
// The observer notification is for a different process/frame.
return;
}
if (!this._lastAutoCompleteResult ||
this._lastAutoCompleteResult.getStyleAt(selectedIndex) != "autofill-profile") {
return;
}
let profile = JSON.parse(this._lastAutoCompleteResult.getCommentAt(selectedIndex));
let formHandler = FormAutofillContent.getFormHandler(focusedInput);
formHandler.previewFormFields(profile);
},
};
/**
@ -303,7 +338,8 @@ var FormAutofillContent = {
getInputDetails(element) {
let formDetails = this.getFormDetails(element);
for (let detail of formDetails) {
if (element == detail.element) {
let detailElement = detail.elementWeakRef.get();
if (detailElement && element == detailElement) {
return detail;
}
}
@ -376,13 +412,29 @@ var FormAutofillContent = {
this._formsDetails.set(form.rootElement, formHandler);
this.log.debug("Adding form handler to _formsDetails:", formHandler);
formHandler.fieldDetails.forEach(detail => this._markAsAutofillField(detail.element));
formHandler.fieldDetails.forEach(detail =>
this._markAsAutofillField(detail.elementWeakRef.get())
);
});
},
_markAsAutofillField(field) {
if (!field) {
return;
}
formFillController.markAsAutofillField(field);
},
_previewProfile(doc) {
let selectedIndex = ProfileAutocomplete._getSelectedIndex(doc.ownerGlobal);
if (selectedIndex === -1) {
ProfileAutocomplete._clearProfilePreview();
} else {
ProfileAutocomplete._previewSelectedProfile(selectedIndex);
}
},
};

Просмотреть файл

@ -85,7 +85,7 @@ FormAutofillHandler.prototype = {
addressType: info.addressType,
contactType: info.contactType,
fieldName: info.fieldName,
element, // TODO: Apply Cu.getWeakReference and use get API for strong ref.
elementWeakRef: Cu.getWeakReference(element),
};
this.fieldDetails.push(formatWithElement);
@ -113,15 +113,52 @@ FormAutofillHandler.prototype = {
// 2. a non-empty input field
// 3. the invalid value set
if (fieldDetail.element === focusedInput ||
fieldDetail.element.value) {
let element = fieldDetail.elementWeakRef.get();
if (!element || element === focusedInput || element.value) {
continue;
}
let value = profile[fieldDetail.fieldName];
if (value) {
fieldDetail.element.setUserInput(value);
element.setUserInput(value);
}
}
},
/**
* Populates result to the preview layers with given profile.
*
* @param {Object} profile
* A profile to be previewed with
*/
previewFormFields(profile) {
log.debug("preview profile in autofillFormFields:", profile);
/*
for (let fieldDetail of this.fieldDetails) {
let value = profile[fieldDetail.fieldName] || "";
// Skip the fields that already has text entered
if (fieldDetail.element.value) {
continue;
}
// TODO: Set highlight style and preview text.
}
*/
},
clearPreviewedFormFields() {
log.debug("clear previewed fields in:", this.form);
/*
for (let fieldDetail of this.fieldDetails) {
// TODO: Clear preview text
// We keep the highlight of all fields if this form has
// already been auto-filled with a profile.
if (this.filledProfileGUID == null) {
// TODO: Remove highlight style
}
}
*/
},
};

Просмотреть файл

@ -8,6 +8,8 @@
"use strict";
/* global content */
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");
@ -22,6 +24,8 @@ Cu.import("resource://formautofill/FormAutofillContent.jsm");
var FormAutofillFrameScript = {
init() {
addEventListener("DOMContentLoaded", this);
addMessageListener("FormAutofill:PreviewProfile", this);
addMessageListener("FormAutoComplete:PopupClosed", this);
},
handleEvent(evt) {
@ -44,6 +48,19 @@ var FormAutofillFrameScript = {
}
}
},
receiveMessage(aMessage) {
if (!Services.prefs.getBoolPref("browser.formautofill.enabled")) {
return;
}
switch (aMessage.name) {
case "FormAutofill:PreviewProfile":
case "FormAutoComplete:PopupClosed":
FormAutofillContent._previewProfile(content.document);
break;
}
},
};
FormAutofillFrameScript.init();

Просмотреть файл

@ -43,6 +43,23 @@
]]>
</constructor>
<property name="selected" onget="return this.getAttribute('selected') == 'true';">
<setter><![CDATA[
/* global Cu */
if (val) {
this.setAttribute("selected", "true");
} else {
this.removeAttribute("selected");
}
let {AutoCompletePopup} = Cu.import("resource://gre/modules/AutoCompletePopup.jsm", {});
AutoCompletePopup.sendMessageToBrowser("FormAutofill:PreviewProfile");
return val;
]]></setter>
</property>
<method name="_cleanup">
<body>
<![CDATA[
@ -51,6 +68,10 @@
</body>
</method>
<method name="_onChanged">
<body></body>
</method>
<method name="_onOverflow">
<body></body>
</method>

Просмотреть файл

@ -141,6 +141,7 @@ const TESTCASES = [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "organization", "element": null},
],
profileData: {
"guid": "123",
@ -175,7 +176,7 @@ for (let tc of TESTCASES) {
handler.fieldDetails = testcase.fieldDetails;
handler.fieldDetails.forEach((field, index) => {
let element = doc.querySelectorAll("input")[index];
field.element = element;
field.elementWeakRef = Cu.getWeakReference(element);
if (!testcase.profileData[field.fieldName]) {
// Avoid waiting for `change` event of a input with a blank value to
// be filled.

Просмотреть файл

@ -25,11 +25,11 @@ const TESTCASES = [
<input id="email" autocomplete="email">
<input id="tel" autocomplete="tel"></form>`,
fieldDetails: [
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address", "element": {}},
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2", "element": {}},
{"section": "", "addressType": "", "contactType": "", "fieldName": "country", "element": {}},
{"section": "", "addressType": "", "contactType": "", "fieldName": "email", "element": {}},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel", "element": {}},
{"section": "", "addressType": "", "contactType": "", "fieldName": "street-address"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
],
},
{
@ -42,11 +42,11 @@ const TESTCASES = [
<input id='email' autocomplete="shipping email">
<input id="tel" autocomplete="shipping tel"></form>`,
fieldDetails: [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
],
},
{
@ -59,11 +59,11 @@ const TESTCASES = [
<input id='email' autocomplete="shipping email">
<input id="tel" autocomplete="shipping tel"></form>`,
fieldDetails: [
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel", "element": {}},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "street-address"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "address-level2"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "country"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "email"},
{"section": "", "addressType": "shipping", "contactType": "", "fieldName": "tel"},
],
},
];
@ -77,12 +77,22 @@ for (let tc of TESTCASES) {
let doc = MockDocument.createTestDocument("http://localhost:8080/test/",
testcase.document);
let form = doc.querySelector("form");
testcase.fieldDetails.forEach((detail) => {
detail.elementWeakRef = Cu.getWeakReference(doc.querySelector(
"input[autocomplete*='" + detail.fieldName + "']"));
});
let handler = new FormAutofillHandler(form);
handler.collectFormFields();
Assert.deepEqual(handler.fieldDetails, testcase.fieldDetails,
"Check the fieldDetails were set correctly");
handler.fieldDetails.forEach((detail, index) => {
Assert.equal(detail.section, testcase.fieldDetails[index].section);
Assert.equal(detail.addressType, testcase.fieldDetails[index].addressType);
Assert.equal(detail.contactType, testcase.fieldDetails[index].contactType);
Assert.equal(detail.fieldName, testcase.fieldDetails[index].fieldName);
Assert.equal(detail.elementWeakRef.get(), testcase.fieldDetails[index].elementWeakRef.get());
});
});
})();
}

Просмотреть файл

@ -70,6 +70,13 @@ const TESTCASES = [
},
];
function inputDetailAssertion(detail, expected) {
Assert.equal(detail.section, expected.section);
Assert.equal(detail.addressType, expected.addressType);
Assert.equal(detail.contactType, expected.contactType);
Assert.equal(detail.fieldName, expected.fieldName);
Assert.equal(detail.elementWeakRef.get(), expected.elementWeakRef.get());
}
TESTCASES.forEach(testcase => {
add_task(function* () {
@ -84,21 +91,22 @@ TESTCASES.forEach(testcase => {
// Put the input element reference to `element` to make sure the result of
// `getInputDetails` contains the same input element.
testcase.expectedResult[i].input.element = input;
Assert.deepEqual(FormAutofillContent.getInputDetails(input),
testcase.expectedResult[i].input,
"Check if returned input information is correct.");
testcase.expectedResult[i].input.elementWeakRef = Cu.getWeakReference(input);
inputDetailAssertion(FormAutofillContent.getInputDetails(input),
testcase.expectedResult[i].input);
let formDetails = testcase.expectedResult[i].form;
for (let formDetail of formDetails) {
// Compose a query string to get the exact reference of the input
// element, e.g. #form1 > input[autocomplete="street-address"]
let queryString = "#" + testcase.expectedResult[i].formId + " > input[autocomplete=" + formDetail.fieldName + "]";
formDetail.element = doc.querySelector(queryString);
formDetail.elementWeakRef = Cu.getWeakReference(doc.querySelector(queryString));
}
Assert.deepEqual(FormAutofillContent.getFormDetails(input),
formDetails,
"Check if returned form information is correct.");
FormAutofillContent.getFormDetails(input).forEach((detail, index) => {
inputDetailAssertion(detail, formDetails[index]);
});
}
});
});

Просмотреть файл

@ -101,6 +101,8 @@
<!ENTITY enableSearchUpdate.label "Search Engines">
<!ENTITY enableSearchUpdate.accesskey "E">
<!ENTITY reports.label "Reports">
<!ENTITY offlineStorageNotify.label "Tell you when a website asks to store data for offline use">
<!ENTITY offlineStorageNotify.accesskey "T">
<!ENTITY offlineStorageNotifyExceptions.label "Exceptions…">
@ -113,7 +115,6 @@
<!ENTITY offlineAppRemove.confirm "Remove offline data">
<!ENTITY certificateTab.label "Certificates">
<!ENTITY certPersonal.label "Requests">
<!ENTITY certPersonal.description "When a server requests your personal certificate:">
<!ENTITY selectCerts.auto "Select one automatically">
<!ENTITY selectCerts.auto.accesskey "S">

Просмотреть файл

@ -13,17 +13,13 @@
<!ENTITY prefWinMinSize.styleMac "width: 47em; min-height: 40em;">
<!ENTITY prefWinMinSize.styleGNOME "width: 45.5em; min-height: 40.5em;">
<!ENTITY paneGeneral.title "General">
<!ENTITY paneTabs.title "Tabs">
<!ENTITY paneSearch.title "Search">
<!ENTITY paneContent.title "Content">
<!ENTITY paneApplications.title "Applications">
<!ENTITY panePrivacy.title "Privacy">
<!ENTITY paneContainers.title "Container Tabs">
<!ENTITY paneSecurity.title "Security">
<!ENTITY paneAdvanced.title "Advanced">
<!ENTITY paneGeneral.title "General">
<!ENTITY paneDownloadLinks.title "Downloads &amp; Links">
<!ENTITY panePrivacySecurity.title "Privacy &amp; Security">
<!ENTITY paneContainers.title "Container Tabs">
<!ENTITY paneUpdates.title "Updates">
<!-- LOCALIZATION NOTE (paneSync.title): This should match syncBrand.shortName.label in ../syncBrand.dtd -->
<!ENTITY paneSync.title "Sync">
<!-- LOCALIZATION NOTE (paneSync1.title): This should match syncBrand.fxAccount.label in ../syncBrand.dtd -->
<!ENTITY paneSync1.title "Firefox Account">
<!ENTITY helpButton.label "Help">

Просмотреть файл

@ -2,7 +2,7 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!ENTITY trackingProtectionHeader.label "Use Tracking Protection">
<!ENTITY trackingProtectionHeader2.label "Tracking Protection">
<!ENTITY trackingProtectionAlways.label "Always">
<!ENTITY trackingProtectionAlways.accesskey "y">
<!ENTITY trackingProtectionPrivate.label "Only in private windows">

Просмотреть файл

@ -2,7 +2,7 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!ENTITY general.label "General">
<!ENTITY security.label "Security">
<!ENTITY warnOnAddonInstall.label "Warn you when sites try to install add-ons">
<!ENTITY warnOnAddonInstall.accesskey "W">
@ -24,10 +24,10 @@
<!ENTITY addonExceptions.accesskey "E">
<!ENTITY logins.label "Logins">
<!ENTITY formsAndPasswords.label "Forms &amp; Passwords">
<!ENTITY rememberLogins.label "Remember logins for sites">
<!ENTITY rememberLogins.accesskey "R">
<!ENTITY rememberLogins1.label "Remember logins and passwords for sites">
<!ENTITY rememberLogins1.accesskey "R">
<!ENTITY passwordExceptions.label "Exceptions…">
<!ENTITY passwordExceptions.accesskey "x">

Просмотреть файл

@ -19,8 +19,8 @@
<!-- Device Settings -->
<!ENTITY fxaSyncDeviceName.label "Device Name">
<!ENTITY changeSyncDeviceName.label "Change Device Name">
<!ENTITY changeSyncDeviceName.accesskey "h">
<!ENTITY changeSyncDeviceName1.label "Change Device Name">
<!ENTITY changeSyncDeviceName1.accesskey "h">
<!ENTITY cancelChangeSyncDeviceName.label "Cancel">
<!ENTITY cancelChangeSyncDeviceName.accesskey "n">
<!ENTITY saveChangeSyncDeviceName.label "Save">

Просмотреть файл

@ -420,7 +420,7 @@ this.ContentSearch = {
_onMessageManageEngines(msg, data) {
let browserWin = msg.target.ownerGlobal;
browserWin.openPreferences("paneSearch");
browserWin.openPreferences("paneGeneral");
},
_onMessageGetSuggestions: Task.async(function* (msg, data) {

Просмотреть файл

@ -10,29 +10,22 @@ const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/PromiseUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const HTML_NS = "http://www.w3.org/1999/xhtml";
const XUL_PAGE = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window%20id='win'/>";
/**
* An hidden frame object. It takes care of creating an IFRAME and attaching it the
* |hiddenDOMWindow|.
* An hidden frame object. It takes care of creating a windowless browser and
* passing the window containing a blank XUL <window> back.
*/
function HiddenFrame() {}
HiddenFrame.prototype = {
_frame: null,
_browser: null,
_listener: null,
_webProgress: null,
_deferred: null,
_retryTimerId: null,
get hiddenDOMDocument() {
return Services.appShell.hiddenDOMWindow.document;
},
get isReady() {
return this.hiddenDOMDocument.readyState === "complete";
},
/**
* Gets the |contentWindow| of the hidden frame. Creates the frame if needed.
@ -49,38 +42,43 @@ HiddenFrame.prototype = {
},
destroy() {
clearTimeout(this._retryTimerId);
if (this._frame) {
if (!Cu.isDeadWrapper(this._frame)) {
this._frame.removeEventListener("load", this, true);
this._frame.remove();
if (this._browser) {
if (this._listener) {
this._webProgress.removeProgressListener(this._listener);
this._listener = null;
this._webProgress = null;
}
this._frame = null;
this._deferred = null;
}
},
handleEvent() {
let contentWindow = this._frame.contentWindow;
if (contentWindow.location.href === XUL_PAGE) {
this._frame.removeEventListener("load", this, true);
this._deferred.resolve(contentWindow);
} else {
contentWindow.location = XUL_PAGE;
this._browser.close();
this._browser = null;
}
},
_create() {
if (this.isReady) {
let doc = this.hiddenDOMDocument;
this._frame = doc.createElementNS(HTML_NS, "iframe");
this._frame.addEventListener("load", this, true);
doc.documentElement.appendChild(this._frame);
} else {
// Check again if |hiddenDOMDocument| is ready as soon as possible.
this._retryTimerId = setTimeout(this._create.bind(this), 0);
}
this._browser = Services.appShell.createWindowlessBrowser(true);
this._browser.QueryInterface(Ci.nsIInterfaceRequestor);
this._webProgress = this._browser.getInterface(Ci.nsIWebProgress);
this._listener = {
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIWebProgressListener, Ci.nsIWebProgressListener2,
Ci.nsISupportsWeakReference]),
};
this._listener.onStateChange = (wbp, request, stateFlags, status) => {
if (!request) {
return;
}
if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
this._webProgress.removeProgressListener(this._listener);
this._listener = null;
this._webProgress = null;
// Get the window reference via the document.
this._frame = this._browser.document.ownerGlobal;
this._deferred.resolve(this._frame);
}
};
this._webProgress.addProgressListener(this._listener, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
this._browser.document.location = XUL_PAGE;
}
};

Просмотреть файл

@ -72,6 +72,9 @@ var SelfSupportBackendInternal = {
_log: null,
_progressListener: null,
// Whether we're invited to let test code talk to our frame.
_testing: false,
/**
* Initializes the self support backend.
*/
@ -136,6 +139,9 @@ var SelfSupportBackendInternal = {
this._frame.destroy();
this._frame = null;
}
if (this._testing) {
Services.obs.notifyObservers(this._browser, "self-support-browser-destroyed", "");
}
},
/**
@ -195,6 +201,9 @@ var SelfSupportBackendInternal = {
this._browser.setAttribute("disableglobalhistory", "true");
this._browser.setAttribute("src", aURL);
if (this._testing) {
Services.obs.notifyObservers(this._browser, "self-support-browser-created", "");
}
doc.documentElement.appendChild(this._browser);
});
},

Просмотреть файл

@ -26,29 +26,13 @@ function sendSessionRestoredNotification() {
selfSupportBackendImpl.observe(null, "sessionstore-windows-restored", null);
}
/**
* Find a browser, with an IFRAME as parent, who has aURL as the source attribute.
*
* @param aURL The URL to look for to identify the browser.
*
* @returns {Object} The browser element or null on failure.
*/
function findSelfSupportBrowser(aURL) {
let frames = Services.appShell.hiddenDOMWindow.document.querySelectorAll("iframe");
for (let frame of frames) {
try {
let browser = frame.contentDocument.getElementById("win").querySelectorAll("browser")[0];
let url = browser.getAttribute("src");
if (url == aURL) {
return browser;
}
} catch (e) {
continue;
}
}
return null;
function toggleSelfSupportTestMode(testing) {
let selfSupportBackendImpl =
Cu.import("resource:///modules/SelfSupportBackend.jsm", {}).SelfSupportBackendInternal;
selfSupportBackendImpl._testing = testing;
}
/**
* Wait for self support page to load.
*
@ -60,13 +44,19 @@ function findSelfSupportBrowser(aURL) {
function promiseSelfSupportLoad(aURL) {
return new Promise((resolve, reject) => {
// Find the SelfSupport browser.
let browserPromise = waitForConditionPromise(() => !!findSelfSupportBrowser(aURL),
"SelfSupport browser not found.",
TEST_WAIT_RETRIES);
let browser = null;
let browserPromise = TestUtils.topicObserved("self-support-browser-created",
(subject, topic) => {
let url = subject.getAttribute("src");
Cu.reportError("Got browser with src: " + url);
if (url == aURL) {
browser = subject;
}
return url == aURL;
});
// Once found, append a "load" listener to catch page loads.
browserPromise.then(() => {
let browser = findSelfSupportBrowser(aURL);
if (browser.contentDocument.readyState === "complete") {
resolve(browser);
} else {
@ -80,19 +70,6 @@ function promiseSelfSupportLoad(aURL) {
});
}
/**
* Wait for self support to close.
*
* @param aURL The URL to look for to identify the browser.
*
* @returns {Promise} Return a promise which is resolved when SelfSupport browser cannot
* be found anymore.
*/
function promiseSelfSupportClose(aURL) {
return waitForConditionPromise(() => !findSelfSupportBrowser(aURL),
"SelfSupport browser is still open.", TEST_WAIT_RETRIES);
}
/**
* Prepare the test environment.
*/
@ -129,16 +106,21 @@ add_task(function* setupEnvironment() {
* Test that the self support page can use the UITour API and close itself.
*/
add_task(function* test_selfSupport() {
toggleSelfSupportTestMode(true);
registerCleanupFunction(toggleSelfSupportTestMode.bind(null, false));
// Initialise the SelfSupport backend and trigger the load.
SelfSupportBackend.init();
// Wait for the SelfSupport page to load.
let selfSupportBrowserPromise = promiseSelfSupportLoad(TEST_PAGE_URL_HTTPS);
// SelfSupportBackend waits for "sessionstore-windows-restored" to start loading. Send it.
info("Sending sessionstore-windows-restored");
sendSessionRestoredNotification();
// Wait for the SelfSupport page to load.
info("Waiting for the SelfSupport local page to load.");
let selfSupportBrowser = yield promiseSelfSupportLoad(TEST_PAGE_URL_HTTPS);
let selfSupportBrowser = yield selfSupportBrowserPromise;
Assert.ok(!!selfSupportBrowser, "SelfSupport browser must exist.");
// Get a reference to the UITour API.
@ -176,39 +158,15 @@ add_task(function* test_selfSupport() {
yield observePromise;
info("Observed in the hidden frame");
let selfSupportClosed = TestUtils.topicObserved("self-support-browser-destroyed");
// Close SelfSupport from content.
contentWindow.close();
// Wait until SelfSupport closes.
info("Waiting for the SelfSupport to close.");
yield promiseSelfSupportClose(TEST_PAGE_URL_HTTPS);
// Find the SelfSupport browser, again. We don't expect to find it.
selfSupportBrowser = findSelfSupportBrowser(TEST_PAGE_URL_HTTPS);
Assert.ok(!selfSupportBrowser, "SelfSupport browser must not exist.");
yield selfSupportClosed;
Assert.ok(!selfSupportBrowser.parentNode, "SelfSupport browser must have been removed.");
// We shouldn't need this, but let's keep it to make sure closing SelfSupport twice
// doesn't create any problem.
SelfSupportBackend.uninit();
});
/**
* Test that SelfSupportBackend only allows HTTPS.
*/
add_task(function* test_selfSupport_noHTTPS() {
Preferences.set(PREF_SELFSUPPORT_URL, TEST_PAGE_URL);
SelfSupportBackend.init();
// SelfSupportBackend waits for "sessionstore-windows-restored" to start loading. Send it.
info("Sending sessionstore-windows-restored");
sendSessionRestoredNotification();
// Find the SelfSupport browser. We don't expect to find it since we are not using https.
let selfSupportBrowser = findSelfSupportBrowser(TEST_PAGE_URL);
Assert.ok(!selfSupportBrowser, "SelfSupport browser must not exist.");
// We shouldn't need this, but let's keep it to make sure closing SelfSupport twice
// doesn't create any problem.
SelfSupportBackend.uninit();
})

Просмотреть файл

@ -37,11 +37,36 @@
<path d="M18.909,9.783h-0.863V8.086C18.046,4.725,15.339,2,12,2 C8.661,2,5.954,4.725,5.954,8.086v1.697H5.091c-0.955,0-1.728,0.779-1.728,1.739v8.738c0,0.961,0.773,1.74,1.728,1.74h13.818 c0.954,0,1.728-0.779,1.728-1.74v-8.738C20.637,10.562,19.863,9.783,18.909,9.783z M8.545,8.086c0-1.92,1.547-3.478,3.455-3.478 c1.908,0,3.455,1.557,3.455,3.478v1.697h-6.91V8.086z M5.181,16.092l-0.909-1.2v-2.284l2.728,3.483H5.181z M8.818,16.092 l-2.773-3.657h1.727l2.864,3.657H8.818z M12,16.092l-2.773-3.657h1.727l2.864,3.657H12z M15.637,16.092l-2.773-3.657h1.727 l2.864,3.657H15.637z M19.728,16.092h-0.455l-2.773-3.657h1.727l1.501,1.916V16.092z"/>
</g>
<g id="sync-shape">
<path d="M17.024,3.351 c-0.562,0.331 -1.311,0.879 -1.821,1.698 -0.367,0.592 -0.752,1.288 -1.08,1.914 0.987,0.413 1.862,1.095 2.476,2.029 0.614,0.957 0.929,2.122 0.83,3.351 -0.201,1.787 -1.359,3.433 -3.046,4.36 -0.696,-0.774 -1.951,-2.945 -1.951,-2.945 -0.007,0.007 -0.004,2.556 -0.871,4.334 -0.573,1.184 -1.24,2.202 -2.305,2.995 1.431,0.51 2.915,0.886 4.282,0.909 l 0.162,0.002 c 2.99,0.021 5.844,-0.48 5.844,-0.48 0,0 -1.236,-0.802 -1.808,-1.346 1.86,-1.072 3.111,-2.791 3.634,-4.708 0.283,-0.759 0.478,-1.566 0.57,-2.409 C 22.383,9.011 20.33,5.278 17.024,3.351 Z M 6.569,12.302 C 6.526,10.271 7.755,8.327 9.644,7.29 c 0.696,0.774 2.32,2.899 2.32,2.899 0,0 -0.064,-5.157 1.657,-7.973 -6.097,-0.668 -9.69,0.443 -9.69,0.443 0,0 1.763,0.607 2.333,1.136 C 6.122,3.891 5.984,3.992 5.85,4.096 4.4,5.064 3.368,6.449 2.825,7.994 2.436,8.892 2.171,9.863 2.06,10.887 1.622,14.886 3.629,18.572 6.871,20.515 7.39,20.124 7.975,19.631 8.61,18.983 9.189,18.389 9.647,17.682 10.021,16.967 8.082,16.208 6.714,14.404 6.569,12.302 Z"/>
<path style="fill:#F1F1F1;" d="M0.9,19.9h3.3H15h3.3c0.5,0,0.9-0.4,0.9-0.9v-1.1c0-1-0.5-1.9-1.2-2.5c-2.3-1.8-4.6-2.9-5.1-3.1
c-0.1,0-0.1-0.1-0.1-0.2v-1.6c0.3-0.5,0.4-1,0.5-1.5c0.2,0.1,0.6,0.1,1-1.3c0.3-1.1,0.1-1.5-0.2-1.6C15,1.7,13,1.6,13,1.6
S12.7,1,11.8,0.5C11.3,0.2,10.5-0.1,9.5,0C9.1,0,8.8,0.1,8.5,0.2c-0.4,0.1-0.7,0.3-1,0.5C7.1,1,6.8,1.2,6.4,1.6
c-0.5,0.5-1,1.2-1.1,2C5.1,4.3,5.1,5,5.4,5.8C5,5.7,4.6,5.9,5,7.4c0.3,1.1,0.6,1.4,0.8,1.4c0.1,0.6,0.3,1.3,0.7,1.9v1.4
c0,0.1,0,0.1-0.1,0.2c-0.5,0.2-2.8,1.4-5.1,3.1C0.5,16,0,16.9,0,17.9V19C0,19.5,0.4,19.9,0.9,19.9"/>
</g>
<g id="advanced-shape">
<path d="M19.173,16.163c0.004,0.04,0.007,0.08,0.007,0.121c0,1.748-3.197,3.165-7.14,3.165 c-3.943,0-7.14-1.417-7.14-3.165c0 -0.037,0.003-0.073,0.006-0.109C3.11,16.572,2,17.243,2,18.341C2,20.362,6.477,22,12,22 c5.523,0,10-1.638,10-3.659 C22,17.22,20.922,16.553,19.173,16.163z"/>
<path d="M18.224,15.979c0.006-0.11-0.018-0.285-0.054-0.39c0,0-0.762-2.205-1.176-3.403 c-0.624-1.807-2.112-6.139-2.112-6.139c-0.036-0.104-0.031-0.273,0.01-0.376l0.497-1.234c0.041-0.102,0.116-0.266,0.166-0.364 l0.986-1.942c0.05-0.098,0.013-0.133-0.081-0.077L9.965,5.871c-0.095,0.056-0.203,0.186-0.24,0.29c0,0-0.252,0.7-0.412,1.144 C8.64,9.173,7.968,11.04,7.296,12.908c-0.26,0.723-0.52,1.446-0.78,2.168c-0.056,0.156-0.112,0.311-0.168,0.466 c-0.093,0.26-0.049,0.617,0.032,0.881c0.237,0.763,1.001,1.189,1.708,1.435c0.611,0.213,1.254,0.328,1.895,0.403 c0.895,0.105,1.805,0.14,2.706,0.112c1.356-0.041,2.767-0.261,4.004-0.846c0.429-0.203,0.854-0.459,1.174-0.816 c0.121-0.135,0.226-0.287,0.297-0.455C18.215,16.134,18.224,15.979,18.224,15.979z M14.063,16.131 c0.019,0.108-0.046,0.156-0.143,0.104l-1.466-0.772c-0.097-0.052-0.257-0.052-0.354,0l-1.466,0.773 c-0.097,0.052-0.162,0.004-0.143-0.104l0.28-1.636c0.019-0.109-0.031-0.261-0.109-0.338l-1.186-1.158 c-0.079-0.077-0.054-0.153,0.055-0.169l1.638-0.239c0.109-0.016,0.238-0.11,0.286-0.209l0.733-1.488 c0.049-0.099,0.128-0.099,0.177,0l0.733,1.488c0.049,0.099,0.178,0.193,0.286,0.209l1.639,0.239 c0.109,0.016,0.134,0.092,0.055,0.169l-1.186,1.158c-0.079,0.077-0.128,0.229-0.109,0.338L14.063,16.131z"/>
<path style="fill:#F1F1F1;" d="M19.3,13.4C19.3,13.4,19.3,13.4,19.3,13.4L19.3,13.4C19.3,13.4,19.3,13.4,19.3,13.4L19.3,13.4z
M19.3,13.4c-0.1,1-0.5,1.8-1.2,2.4c-0.5,0.5-1.1,0.9-1.7,1.2c-0.2,0.4-0.4,0.7-0.8,1c-0.5,0.4-1.3,0.8-2.1,1
c-0.9,0.2-1.6,0.3-2.3,0.3h-0.9c0.1,0.2,0.2,0.2,0.4,0.2c-1.1-0.1-2.1-0.3-2.9-0.5c0.2,0.2,0.5,0.4,0.8,0.4c-1.5-0.3-2.9-1-4.1-1.9
c-0.3-0.2-0.4-0.3-0.5-0.4c-1-0.8-1.7-1.6-2.3-2.6c-0.7-1.1-1.1-2.5-1.3-4.1c-0.1,0.5-0.1,0.9-0.1,1.1C0.1,10.2,0.1,9,0.4,7.9
C0.3,8.2,0.1,8.6,0,9c0.1-0.8,0.4-1.8,0.9-2.8C1,5.8,1.2,5.5,1.3,5.4V4.3c0-0.1,0-0.3,0.1-0.6c0-0.2,0.1-0.4,0.2-0.6v0.1
c0,0,0-0.1,0-0.1c0-0.1,0-0.1,0-0.1c0-0.1,0-0.2,0.1-0.2v0.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1s0-0.1,0-0.2C2,2.2,2,2.1,2,2.1
C2.2,2,2.2,1.9,2.3,1.9V2c0,0.2,0.1,0.5,0.3,1l0-0.1C2.8,3.1,3,3.4,3.4,3.7c0.8-0.2,1.5-0.3,2.4-0.1C5.9,3.5,5.9,3.4,6,3.3v0.1
C6.1,3.2,6.3,3.1,6.6,3v0c0.2-0.1,0.5-0.3,1-0.4L7.5,2.6c0.1-0.1,0.2-0.1,0.3-0.1c0.1,0,0.2,0,0.3,0c0.1,0,0.3,0,0.4,0
c-0.1,0-0.1,0.1-0.1,0.1c0,0-0.1,0.1-0.1,0.1s-0.1,0-0.1,0h0.1C7.8,3.2,7.4,3.7,7.2,4.4c-0.1,0-0.1,0.1-0.1,0.2l0.1,0.1
c0.2,0.3,0.5,0.5,0.9,0.5h1.4c0.2,0.1,0.3,0.2,0.3,0.2c0,0.2-0.1,0.4-0.3,0.6c0,0.1-0.1,0.2-0.3,0.4C8.5,7,8,7.3,7.7,7.6v0.1
c0,0,0,0,0,0.1c0,0,0,0,0,0.1c-0.1,0-0.1,0-0.1,0.1C7.7,7.9,7.8,8,7.8,8.2c0,0.2,0,0.4-0.1,0.6c0,0-0.1-0.1-0.1-0.1
c-0.1,0-0.1,0-0.1,0c0.1,0.1,0.2,0.1,0.2,0.2V9c0,0-0.1,0-0.1,0c0,0-0.1-0.1-0.1-0.1l-0.1,0c-0.1,0-0.1,0-0.2-0.1
c-0.1,0-0.1,0-0.1,0L7,8.7c-0.1,0-0.1,0-0.1,0L7,8.7c-0.1,0-0.1,0-0.2,0l-0.1,0C6.5,8.8,6.4,9,6.4,9.3c0,0.6,0.4,1.1,1.1,1.5
C7.7,11,8,11.1,8.3,11.2c0.3,0,0.5,0,0.7,0c0.2-0.1,0.4-0.1,0.6-0.2s0.4-0.2,0.5-0.2c0.7-0.2,1.4,0,1.9,0.5c0.2,0.1,0.2,0.2,0.1,0.4
c-0.1,0.2-0.2,0.3-0.4,0.2c-0.1,0-0.2,0-0.2,0c-0.1,0-0.1,0-0.3,0.1S11.1,12,11,12s-0.2,0.1-0.3,0.2c-0.1,0.1-0.3,0.2-0.4,0.3
c-0.9,0.5-1.9,0.6-3,0.4c0.4,0.4,0.7,0.7,1.1,0.9c0.1,0,0.2,0.1,0.6,0.1c0.3,0,0.5,0.1,0.6,0.2C9.4,14,9.1,14,8.9,14.1
c0.8,0.5,1.7,0.7,2.8,0.5c0.4-0.1,0.7-0.2,1-0.4c-0.1,0.1-0.1,0.3-0.2,0.4c0.1,0.1,0.4-0.1,0.6-0.5c0.1-0.1,0.3-0.3,0.6-0.4
c0,0,0,0.1,0,0.2c0,0.1,0,0.1,0,0.2s0,0.1,0.1,0.1c0.4,0,0.7-0.4,1.1-1.3c0.3-0.6,0.5-1.3,0.6-2.2c0.1,0.2,0.2,0.5,0.2,0.8
c0.2-0.5,0.3-1,0.3-1.3c0-0.3,0-1.3-0.1-2.9c0.3,0.4,0.5,0.7,0.7,1.1c0.1-1.2-0.1-2.2-0.5-3.1c-0.4-0.8-0.9-1.5-1.4-1.9
c0.5,0.1,1,0.3,1.4,0.6l-0.3-0.2c-1.4-1.4-3.1-2.2-5.1-2.4c-2-0.2-3.8,0.3-5.4,1.4c-0.6,0-1.1,0-1.5,0.1C3.6,2.7,3.5,2.6,3.5,2.5
C5.3,0.8,7.4,0,9.9,0s4.6,0.8,6.5,2.4L16.2,2c0.6,0.3,1,0.7,1.4,1.2l-0.1-0.3l0,0.1l0-0.1c0.9,0.7,1.4,1.6,1.7,2.7
c0.2,0.9,0.2,1.6,0.1,2.3c0.1,0.1,0.1,0.1,0.1,0.3l0.3-1.1c0.1,0.3,0.2,0.7,0.2,1C20,8.5,20,8.9,20,9.2c0,0.4-0.1,0.7-0.1,1
c-0.1,0.3-0.1,0.7-0.2,1s-0.2,0.6-0.3,0.8c-0.1,0.2-0.2,0.5-0.3,0.7C19.1,12.8,19.2,13,19.3,13.4L19.3,13.4z"/>
</g>
</defs>
<use id="general" xlink:href="#general-shape"/>

До

Ширина:  |  Высота:  |  Размер: 8.6 KiB

После

Ширина:  |  Высота:  |  Размер: 9.5 KiB

Просмотреть файл

@ -82,11 +82,11 @@ treecol {
}
#category-application > .category-icon {
list-style-image: url("chrome://browser/skin/preferences/in-content/icons.svg#applications");
list-style-image: url("chrome://browser/skin/preferences/in-content/icons.svg#content");
}
#category-privacy > .category-icon {
list-style-image: url("chrome://browser/skin/preferences/in-content/icons.svg#privacy");
list-style-image: url("chrome://browser/skin/preferences/in-content/icons.svg#security");
}
#category-security > .category-icon {

Просмотреть файл

@ -19,13 +19,13 @@
# program.
@template
def try_compile(includes=None, body='', language='C++', flags=None, check_msg=None,
when=None):
when=None, onerror=lambda: None):
compiler = {
'C': c_compiler,
'C++': cxx_compiler,
}[language]
return compiler.try_compile(includes, body, flags, check_msg, when=when)
return compiler.try_compile(includes, body, flags, check_msg, when=when, onerror=onerror)
# Checks for the presence of the given header on the target system by compiling

Просмотреть файл

@ -34,6 +34,14 @@
fun:_ZN13CrashReporter14SetupExtraDataEP7nsIFileRK10nsACString
...
}
{
PR_SetEnv requires its argument to be leaked, but does not appear on stacks. (See bug 1345153.)
Memcheck:Leak
fun:malloc
...
fun:_ZN13CrashReporterL27SetupCrashReporterDirectoryEP7nsIFilePKcS3_PS1_
...
}
{
We purposely leak the StatisticsReporter object
Memcheck:Leak

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsIScriptError.h"
#include "nsIWindowMediator.h"
#include "nsIPrefService.h"
#include "mozilla/Preferences.h"
#include "mozilla/Printf.h"
#include "mozilla/StyleSheet.h"
#include "mozilla/StyleSheetInlines.h"

Просмотреть файл

@ -0,0 +1,26 @@
# netmonitor
The Network Monitor shows you all the network requests Firefox makes (for example, when it loads a page, or due to XMLHttpRequests), how long each request takes, and details of each request.
## Prerequisite
* [node](https://nodejs.org/) >= 6.9.x
* [npm](https://docs.npmjs.com/getting-started/installing-node) >= 3.x
* [yarn](https://yarnpkg.com/docs/install) >= 0.21.x
## Quick Setup
Assume you are in netmonitor folder
```bash
# Install packages
yarn install
# Create a dev server instance for hosting netmonitor on browser
yarn start
# Run firefox
firefox http://localhost:8000 --start-debugger-server 6080
```
Then open localhost:8000 in any browser to see all tabs in Firefox.

Просмотреть файл

@ -0,0 +1,29 @@
/* 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/. */
/* eslint-env node */
"use strict";
const fs = require("fs");
const path = require("path");
function getConfig() {
if (process.env.TARGET === "firefox-panel") {
return require("../configs/firefox-panel.json");
}
const developmentConfig = require("../configs/development.json");
let localConfig = {};
if (fs.existsSync(path.resolve(__dirname, "../configs/local.json"))) {
localConfig = require("../configs/local.json");
}
return Object.assign({}, developmentConfig, localConfig);
}
module.exports = {
getConfig,
};

Просмотреть файл

@ -0,0 +1,31 @@
/* 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/. */
/* eslint-env node */
"use strict";
const path = require("path");
const toolbox = require("devtools-launchpad/index");
const feature = require("devtools-config");
const express = require("express");
const { getConfig } = require("./configure");
const envConfig = getConfig();
feature.setConfig(envConfig);
let webpackConfig = require("../webpack.config");
let { app } = toolbox.startDevServer(envConfig, webpackConfig, __dirname);
app.use(
"/integration/examples",
express.static("src/test/mochitest/examples")
);
app.get("/integration", function (req, res) {
res.sendFile(path.join(__dirname, "../src/test/integration/index.html"));
});

Просмотреть файл

@ -0,0 +1,35 @@
{
"title": "Netmonitor",
"environment": "development",
"baseWorkerURL": "http://localhost:8000/public/build/",
"host": "",
"theme": "light",
"dir": "ltr",
"logging": {
"client": false,
"firefoxProxy": false,
"actions": false
},
"features": {
},
"chrome": {
"debug": true,
"host": "localhost",
"port": 9222
},
"node": {
"debug": true,
"host": "localhost",
"port": 9229
},
"firefox": {
"webSocketConnection": false,
"proxyHost": "localhost:9000",
"webSocketHost": "localhost:6080",
"mcPath": "./firefox"
},
"development": {
"serverPort": 8000,
"examplesPort": 7999
}
}

Просмотреть файл

@ -0,0 +1,11 @@
{
"environment": "firefox-panel",
"baseWorkerURL": "resource://devtools/client/netmonitor/",
"logging": false,
"clientLogging": false,
"firefox": {
"mcPath": "./firefox"
},
"features": {
}
}

Просмотреть файл

@ -0,0 +1,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* This script is the entry point of devtools-launchpad. Make netmonitor possible
* to run on standalone browser tab without chrome privilege.
* See README.md for more information.
*/
const React = require("react");
const ReactDOM = require("react-dom");
const { bootstrap } = require("devtools-launchpad");
const { EventEmitter } = require("devtools-sham-modules");
const { configureStore } = require("./src/utils/create-store");
// require("./src/assets/styles/netmonitor.css");
EventEmitter.decorate(window);
const App = require("./src/components/app");
const store = window.gStore = configureStore();
const { NetMonitorController } = require("./src/netmonitor-controller");
bootstrap(React, ReactDOM, App, null, store).then(connection => {
if (!connection || !connection.tab) {
return;
}
NetMonitorController.startupNetMonitor(connection);
});

Просмотреть файл

@ -1,20 +1,32 @@
{
"name": "netmonitor",
"version": "0.0.1",
"engines": {
"node": ">=6.9.0"
},
"description": "Network monitor in developer tools",
"dependencies": {
"codemirror": "^5.24.2",
"devtools-launchpad": "^0.0.59",
"devtools-modules": "^0.0.18",
"devtools-reps": "^0.4.0",
"devtools-sham-modules": "^0.0.17",
"express": "^4.15.2",
"immutable": "^3.8.1",
"jszip": "^3.1.3",
"react": "=15.3.2",
"react-dom": "=15.3.2",
"react-redux": "=5.0.3",
"redux": "^3.6.0",
"redux-thunk": "^2.2.0",
"reselect": "^2.5.4"
},
"devDependencies": {
"amd-loader": "0.0.5",
"babel-preset-es2015": "^6.6.0",
"babel-register": "^6.7.2",
"cross-env": "^3.1.3",
"enzyme": "^2.4.1",
"expect": "^1.16.0",
"jsdom": "^9.4.1",
"jsdom-global": "^2.0.0",
"mocha": "^2.5.3",
"require-hacker": "^2.1.4"
"babel-register": "^6.24.0",
"file-loader": "^0.10.1"
},
"scripts": {
"postinstall": "cd ../ && npm install && cd netmonitor",
"test": "cross-env NODE_PATH=../../../ mocha test/**/*.test.js --compilers js:babel-register -r jsdom-global/register -r ./test/require-helper.js"
"start": "node bin/dev-server"
}
}

Просмотреть файл

@ -4,7 +4,6 @@
"use strict";
const { KeyCodes } = require("devtools/client/shared/keycodes");
const {
createClass,
createFactory,
@ -176,36 +175,36 @@ const RequestListContent = createClass({
* Handler for keyboard events. For arrow up/down, page up/down, home/end,
* move the selection up or down.
*/
onKeyDown(e) {
onKeyDown(evt) {
let delta;
switch (e.keyCode) {
case KeyCodes.DOM_VK_UP:
case KeyCodes.DOM_VK_LEFT:
switch (evt.key) {
case "ArrowUp":
case "ArrowLeft":
delta = -1;
break;
case KeyCodes.DOM_VK_DOWN:
case KeyCodes.DOM_VK_RIGHT:
case "ArrowDown":
case "ArrowRight":
delta = +1;
break;
case KeyCodes.DOM_VK_PAGE_UP:
case "PageUp":
delta = "PAGE_UP";
break;
case KeyCodes.DOM_VK_PAGE_DOWN:
case "PageDown":
delta = "PAGE_DOWN";
break;
case KeyCodes.DOM_VK_HOME:
case "Home":
delta = -Infinity;
break;
case KeyCodes.DOM_VK_END:
case "End":
delta = +Infinity;
break;
}
if (delta) {
// Prevent scrolling when pressing navigation keys.
e.preventDefault();
e.stopPropagation();
evt.preventDefault();
evt.stopPropagation();
this.props.onSelectDelta(delta);
}
},

Просмотреть файл

@ -10,7 +10,6 @@ const {
DOM,
} = require("devtools/client/shared/vendor/react");
const { connect } = require("devtools/client/shared/vendor/react-redux");
const { setNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
const Actions = require("../actions/index");
const { getWaterfallScale } = require("../selectors/index");
const { getFormattedTime } = require("../utils/format-utils");
@ -71,10 +70,10 @@ const RequestListHeader = createClass({
resizeWaterfall() {
// Measure its width and update the 'waterfallWidth' property in the store.
// The 'waterfallWidth' will be further updated on every window resize.
setNamedTimeout("resize-events", 50, () => {
const { width } = this.refs.header.getBoundingClientRect();
setTimeout(() => {
let { width } = this.refs.header.getBoundingClientRect();
this.props.resizeWaterfall(width);
});
}, 50);
},
render() {

Просмотреть файл

@ -68,7 +68,7 @@ add_task(function* () {
yield testWindow();
info("Moving toolbox back to the bottom...");
yield monitor.toolbox.switchHost(Toolbox.HostType.BOTTOM);
yield monitor.toolbox.switchHost("bottom");
return teardown(monitor);
function storeFirstPrefValues() {
@ -218,7 +218,7 @@ add_task(function* () {
info("Moving toolbox to the side...");
yield monitor.toolbox.switchHost(Toolbox.HostType.SIDE);
yield monitor.toolbox.switchHost("side");
info("Testing prefs reload for a side host.");
storeFirstPrefValues();
@ -243,7 +243,7 @@ add_task(function* () {
info("Moving toolbox into a window...");
yield monitor.toolbox.switchHost(Toolbox.HostType.WINDOW);
yield monitor.toolbox.switchHost("window");
info("Testing prefs reload for a window host.");
storeFirstPrefValues();

Просмотреть файл

@ -14,7 +14,6 @@ Services.scriptloader.loadSubScript(
this);
const { EVENTS } = require("devtools/client/netmonitor/src/constants");
let { Toolbox } = require("devtools/client/framework/toolbox");
const {
decodeUnicodeUrl,
getUrlBaseName,

Просмотреть файл

@ -0,0 +1,99 @@
/* 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/. */
/* eslint-env node */
/* eslint max-len: [0] */
"use strict";
const path = require("path");
const { isDevelopment } = require("devtools-config");
const { NormalModuleReplacementPlugin } = require("webpack");
const { toolboxConfig } = require("./node_modules/devtools-launchpad/index");
const { getConfig } = require("./bin/configure");
let webpackConfig = {
entry: {
netmonitor: [path.join(__dirname, "index.js")]
},
module: {
loaders: [
{
test: /\.(png|svg)$/,
loader: "file-loader?name=[name].[ext]",
},
]
},
output: {
path: path.join(__dirname, "assets/build"),
filename: "[name].js",
publicPath: "/assets/build",
libraryTarget: "umd",
},
// Fallback compatibility for npm link
resolve: {
fallback: path.join(__dirname, "node_modules"),
alias: {
"react": path.join(__dirname, "node_modules/react"),
"devtools/client/framework/devtools": "devtools-sham-modules",
"devtools/client/framework/menu": "devtools-sham-modules",
"devtools/client/framework/menu-item": "devtools-sham-modules",
"devtools/client/locales": path.join(__dirname, "../locales/en-US"),
"devtools/client/shared/components/reps/reps": "devtools-reps",
"devtools/client/shared/components/search-box": "devtools-sham-modules",
"devtools/client/shared/components/splitter/split-box": "devtools-modules",
"devtools/client/shared/components/tabs/tabbar": "devtools-sham-modules",
"devtools/client/shared/components/tabs/tabs": "devtools-sham-modules",
"devtools/client/shared/components/tree/tree-view": "devtools-modules",
"devtools/client/shared/components/tree/tree-row": "devtools-modules",
"devtools/client/shared/curl": "devtools-modules",
"devtools/client/shared/file-saver": "devtools-modules",
"devtools/client/shared/prefs": "devtools-sham-modules",
"devtools/client/shared/redux/middleware/thunk": "redux-thunk",
"devtools/client/shared/vendor/immutable": "immutable",
"devtools/client/shared/vendor/react": "react",
"devtools/client/shared/vendor/react-dom": "react-dom",
"devtools/client/shared/vendor/react-redux": "react-redux",
"devtools/client/shared/vendor/redux": "redux",
"devtools/client/shared/vendor/reselect": "reselect",
"devtools/client/shared/vendor/jszip": "jszip",
"devtools/client/shared/widgets/view-helpers": "devtools-sham-modules",
"devtools/client/shared/widgets/tooltip/HTMLTooltip": "devtools-sham-modules",
"devtools/client/shared/widgets/tooltip/ImageTooltipHelper": "devtools-sham-modules",
"devtools/client/shared/widgets/Chart": "devtools-sham-modules",
"devtools/client/sourceeditor/editor": "devtools-modules",
"devtools/shared/fronts/timeline": "devtools-sham-modules",
"devtools/shared/l10n": "devtools-modules",
"devtools/shared/platform/clipboard": "devtools-modules",
"devtools/shared/plural-form": "devtools-modules",
"Services": "devtools-modules",
},
}
};
if (!isDevelopment()) {
webpackConfig.output.libraryTarget = "umd";
webpackConfig.plugins = [];
const mappings = [
[/\.\/mocha/, "./mochitest"],
[/\.\.\/utils\/mocha/, "../utils/mochitest"],
[/\.\/utils\/mocha/, "./utils/mochitest"],
];
mappings.forEach(([regex, res]) => {
webpackConfig.plugins.push(new NormalModuleReplacementPlugin(regex, res));
});
}
let config = toolboxConfig(webpackConfig, getConfig());
// Remove loaders from devtools-launchpad webpack config
config.module.loaders = config.module.loaders
.filter((loader) => !["svg-inline"].includes(loader.loader));
module.exports = config;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -51,13 +51,6 @@ nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
return NS_OK;
}
// We want to claim that the type for SWF movies is unsupported,
// so that the internal SWF player's stream converter will get used.
if (aType.LowerCaseEqualsLiteral("application/x-shockwave-flash") &&
nsContentUtils::IsSWFPlayerEnabled()) {
return NS_OK;
}
const nsCString& flatType = PromiseFlatCString(aType);
nsresult rv = IsTypeSupportedInternal(flatType, aIsTypeSupported);
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -31,9 +31,7 @@ struct PropertyValuePair
// (string).
nsCSSValue mValue;
// The specified value when using the Servo backend. However, even when
// using the Servo backend, we still fill in |mValue| in the case where we
// fail to parse the value since we use it to store the original string.
// The specified value when using the Servo backend.
RefPtr<RawServoDeclarationBlock> mServoDeclarationBlock;
bool operator==(const PropertyValuePair&) const;

Просмотреть файл

@ -1032,8 +1032,8 @@ MakePropertyValuePair(nsCSSPropertyID aProperty, const nsAString& aStringValue,
if (servoDeclarationBlock) {
result.mServoDeclarationBlock = servoDeclarationBlock.forget();
return result;
}
return result;
}
nsCSSValue value;
@ -1067,13 +1067,6 @@ MakePropertyValuePair(nsCSSPropertyID aProperty, const nsAString& aStringValue,
"The shorthand property of a token stream should be initialized"
" to unknown");
value.SetTokenStreamValue(tokenStream);
} else {
// If we succeeded in parsing with Gecko, but not Servo the animation is
// not going to work since, for the purposes of animation, we're going to
// ignore |mValue| when the backend is Servo.
NS_WARNING_ASSERTION(aDocument->GetStyleBackendType() !=
StyleBackendType::Servo,
"Gecko succeeded in parsing where Servo failed");
}
result.mValue = value;

Просмотреть файл

@ -1,11 +1,11 @@
pref(dom.animations-api.core.enabled,true) load 1239889-1.html
pref(dom.animations-api.core.enabled,true) load 1244595-1.html
pref(dom.animations-api.core.enabled,true) load 1216842-1.html # bug 1334036
pref(dom.animations-api.core.enabled,true) load 1216842-2.html # bug 1334036
pref(dom.animations-api.core.enabled,true) load 1216842-1.html
pref(dom.animations-api.core.enabled,true) load 1216842-2.html
pref(dom.animations-api.core.enabled,true) load 1216842-3.html
pref(dom.animations-api.core.enabled,true) load 1216842-4.html
pref(dom.animations-api.core.enabled,true) load 1216842-5.html # bug 1334036
pref(dom.animations-api.core.enabled,true) load 1216842-6.html # bug 1334036
pref(dom.animations-api.core.enabled,true) load 1216842-5.html
pref(dom.animations-api.core.enabled,true) load 1216842-6.html
pref(dom.animations-api.core.enabled,true) load 1272475-1.html
pref(dom.animations-api.core.enabled,true) load 1272475-2.html
pref(dom.animations-api.core.enabled,true) load 1278485-1.html
@ -22,7 +22,7 @@ skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1325193-1.html #
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1330190-1.html # bug 1311257
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1330190-2.html # bug 1311257
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1330513-1.html # bug 1311257
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1333539-1.html
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1333539-2.html
pref(dom.animations-api.core.enabled,true) load 1333539-1.html
pref(dom.animations-api.core.enabled,true) load 1333539-2.html
skip-if(stylo) pref(dom.animations-api.core.enabled,true) load 1333418-1.html # bug 1311257
pref(dom.animations-api.core.enabled,true) load 1343589-1.html

Просмотреть файл

@ -12,6 +12,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/FunctionBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше