Browse Source

browser-omni: add new preferences pages (from omni.ja dated 2018-01-01 08:38)

master
roytam1 1 year ago
parent
commit
9438ea839e
  1. 7
      browser-omni/chrome/kmeleon/content/browser/preferences/aboutPermissions.css
  2. 895
      browser-omni/chrome/kmeleon/content/browser/preferences/aboutPermissions.js
  3. 18
      browser-omni/chrome/kmeleon/content/browser/preferences/aboutPermissions.xml
  4. 260
      browser-omni/chrome/kmeleon/content/browser/preferences/aboutPermissions.xul
  5. 818
      browser-omni/chrome/kmeleon/content/browser/preferences/advanced.js
  6. 371
      browser-omni/chrome/kmeleon/content/browser/preferences/advanced.xul
  7. 97
      browser-omni/chrome/kmeleon/content/browser/preferences/applicationManager.js
  8. 59
      browser-omni/chrome/kmeleon/content/browser/preferences/applicationManager.xul
  9. 1872
      browser-omni/chrome/kmeleon/content/browser/preferences/applications.js
  10. 99
      browser-omni/chrome/kmeleon/content/browser/preferences/applications.xul
  11. 33
      browser-omni/chrome/kmeleon/content/browser/preferences/handlers.css
  12. 81
      browser-omni/chrome/kmeleon/content/browser/preferences/handlers.xml
  13. 32
      browser-omni/chrome/kmeleon/content/browser/preferences/in-content/applications.js

7
browser-omni/chrome/kmeleon/content/browser/preferences/aboutPermissions.css

@ -0,0 +1,7 @@
/* 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/. */
.site {
-moz-binding: url("chrome://browser/content/preferences/aboutPermissions.xml#site");
}

895
browser-omni/chrome/kmeleon/content/browser/preferences/aboutPermissions.js

@ -0,0 +1,895 @@
/* 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";
let Ci = Components.interfaces;
let Cc = Components.classes;
let Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DownloadUtils.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/ForgetAboutSite.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
"resource://gre/modules/PluralForm.jsm");
let gFaviconService = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService);
let gPlacesDatabase = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsPIPlacesDatabase).
DBConnection.
clone(true);
let gSitesStmt = gPlacesDatabase.createAsyncStatement(
"SELECT get_unreversed_host(rev_host) AS host " +
"FROM moz_places " +
"WHERE rev_host > '.' " +
"AND visit_count > 0 " +
"GROUP BY rev_host " +
"ORDER BY MAX(frecency) DESC " +
"LIMIT :limit");
let gVisitStmt = gPlacesDatabase.createAsyncStatement(
"SELECT SUM(visit_count) AS count " +
"FROM moz_places " +
"WHERE rev_host = :rev_host");
/**
* Permission types that should be tested with testExactPermission, as opposed
* to testPermission. This is based on what consumers use to test these permissions.
*/
let TEST_EXACT_PERM_TYPES = ["geo", "camera", "microphone"];
/**
* Site object represents a single site, uniquely identified by a host.
*/
function Site(host) {
this.host = host;
this.listitem = null;
this.httpURI = NetUtil.newURI("http://" + this.host);
this.httpsURI = NetUtil.newURI("https://" + this.host);
}
Site.prototype = {
/**
* Gets the favicon to use for the site. The callback only gets called if
* a favicon is found for either the http URI or the https URI.
*
* @param aCallback
* A callback function that takes a favicon image URL as a parameter.
*/
getFavicon: function Site_getFavicon(aCallback) {
function invokeCallback(aFaviconURI) {
try {
// Use getFaviconLinkForIcon to get image data from the database instead
// of using the favicon URI to fetch image data over the network.
aCallback(gFaviconService.getFaviconLinkForIcon(aFaviconURI).spec);
} catch (e) {
Cu.reportError("AboutPermissions: " + e);
}
}
// Try to find favicon for both URIs, but always prefer the https favicon.
gFaviconService.getFaviconURLForPage(this.httpsURI, function (aURI) {
if (aURI) {
invokeCallback(aURI);
} else {
gFaviconService.getFaviconURLForPage(this.httpURI, function (aURI) {
if (aURI) {
invokeCallback(aURI);
}
});
}
}.bind(this));
},
/**
* Gets the number of history visits for the site.
*
* @param aCallback
* A function that takes the visit count (a number) as a parameter.
*/
getVisitCount: function Site_getVisitCount(aCallback) {
let rev_host = this.host.split("").reverse().join("") + ".";
gVisitStmt.params.rev_host = rev_host;
gVisitStmt.executeAsync({
handleResult: function(aResults) {
let row = aResults.getNextRow();
let count = row.getResultByName("count") || 0;
try {
aCallback(count);
} catch (e) {
Cu.reportError("AboutPermissions: " + e);
}
},
handleError: function(aError) {
Cu.reportError("AboutPermissions: " + aError);
},
handleCompletion: function(aReason) {
}
});
},
/**
* Gets the permission value stored for a specified permission type.
*
* @param aType
* The permission type string stored in permission manager.
* e.g. "cookie", "geo", "indexedDB", "popup", "image"
* @param aResultObj
* An object that stores the permission value set for aType.
*
* @return A boolean indicating whether or not a permission is set.
*/
getPermission: function Site_getPermission(aType, aResultObj) {
// Password saving isn't a nsIPermissionManager permission type, so handle
// it seperately.
if (aType == "password") {
aResultObj.value = this.loginSavingEnabled ?
Ci.nsIPermissionManager.ALLOW_ACTION :
Ci.nsIPermissionManager.DENY_ACTION;
return true;
}
let permissionValue;
if (TEST_EXACT_PERM_TYPES.indexOf(aType) == -1) {
permissionValue = Services.perms.testPermission(this.httpURI, aType);
} else {
permissionValue = Services.perms.testExactPermission(this.httpURI, aType);
}
aResultObj.value = permissionValue;
return permissionValue != Ci.nsIPermissionManager.UNKNOWN_ACTION;
},
/**
* Sets a permission for the site given a permission type and value.
*
* @param aType
* The permission type string stored in permission manager.
* e.g. "cookie", "geo", "indexedDB", "popup", "image"
* @param aPerm
* The permission value to set for the permission type. This should
* be one of the constants defined in nsIPermissionManager.
*/
setPermission: function Site_setPermission(aType, aPerm) {
// Password saving isn't a nsIPermissionManager permission type, so handle
// it seperately.
if (aType == "password") {
this.loginSavingEnabled = aPerm == Ci.nsIPermissionManager.ALLOW_ACTION;
return;
}
// Using httpURI is kind of bogus, but the permission manager stores the
// permission for the host, so the right thing happens in the end.
Services.perms.add(this.httpURI, aType, aPerm);
},
/**
* Clears a user-set permission value for the site given a permission type.
*
* @param aType
* The permission type string stored in permission manager.
* e.g. "cookie", "geo", "indexedDB", "popup", "image"
*/
clearPermission: function Site_clearPermission(aType) {
Services.perms.remove(this.host, aType);
},
/**
* Gets cookies stored for the site. This does not return cookies stored
* for the base domain, only the exact hostname stored for the site.
*
* @return An array of the cookies set for the site.
*/
get cookies() {
let cookies = [];
let enumerator = Services.cookies.getCookiesFromHost(this.host);
while (enumerator.hasMoreElements()) {
let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
// getCookiesFromHost returns cookies for base domain, but we only want
// the cookies for the exact domain.
if (cookie.rawHost == this.host) {
cookies.push(cookie);
}
}
return cookies;
},
/**
* Removes a set of specific cookies from the browser.
*/
clearCookies: function Site_clearCookies() {
this.cookies.forEach(function(aCookie) {
Services.cookies.remove(aCookie.host, aCookie.name, aCookie.path, false);
});
},
/**
* Gets logins stored for the site.
*
* @return An array of the logins stored for the site.
*/
get logins() {
let httpLogins = Services.logins.findLogins({}, this.httpURI.prePath, "", "");
let httpsLogins = Services.logins.findLogins({}, this.httpsURI.prePath, "", "");
return httpLogins.concat(httpsLogins);
},
get loginSavingEnabled() {
// Only say that login saving is blocked if it is blocked for both http and https.
return Services.logins.getLoginSavingEnabled(this.httpURI.prePath) &&
Services.logins.getLoginSavingEnabled(this.httpsURI.prePath);
},
set loginSavingEnabled(isEnabled) {
Services.logins.setLoginSavingEnabled(this.httpURI.prePath, isEnabled);
Services.logins.setLoginSavingEnabled(this.httpsURI.prePath, isEnabled);
},
/**
* Removes all data from the browser corresponding to the site.
*/
forgetSite: function Site_forgetSite() {
ForgetAboutSite.removeDataFromDomain(this.host);
}
}
/**
* PermissionDefaults object keeps track of default permissions for sites based
* on global preferences.
*
* Inspired by pageinfo/permissions.js
*/
let PermissionDefaults = {
UNKNOWN: Ci.nsIPermissionManager.UNKNOWN_ACTION, // 0
ALLOW: Ci.nsIPermissionManager.ALLOW_ACTION, // 1
DENY: Ci.nsIPermissionManager.DENY_ACTION, // 2
SESSION: Ci.nsICookiePermission.ACCESS_SESSION, // 8
get password() {
if (Services.prefs.getBoolPref("signon.rememberSignons")) {
return this.ALLOW;
}
return this.DENY;
},
set password(aValue) {
let value = (aValue != this.DENY);
Services.prefs.setBoolPref("signon.rememberSignons", value);
},
// For use with network.cookie.* prefs.
COOKIE_ACCEPT: 0,
COOKIE_DENY: 2,
COOKIE_NORMAL: 0,
COOKIE_SESSION: 2,
get cookie() {
if (Services.prefs.getIntPref("network.cookie.cookieBehavior") == this.COOKIE_DENY) {
return this.DENY;
}
if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") == this.COOKIE_SESSION) {
return this.SESSION;
}
return this.ALLOW;
},
set cookie(aValue) {
let value = (aValue == this.DENY) ? this.COOKIE_DENY : this.COOKIE_ACCEPT;
Services.prefs.setIntPref("network.cookie.cookieBehavior", value);
let lifetimeValue = aValue == this.SESSION ? this.COOKIE_SESSION :
this.COOKIE_NORMAL;
Services.prefs.setIntPref("network.cookie.lifetimePolicy", lifetimeValue);
},
get geo() {
if (!Services.prefs.getBoolPref("geo.enabled")) {
return this.DENY;
}
// We always ask for permission to share location with a specific site, so
// there is no global ALLOW.
return this.UNKNOWN;
},
set geo(aValue) {
let value = (aValue != this.DENY);
Services.prefs.setBoolPref("geo.enabled", value);
},
get indexedDB() {
if (!Services.prefs.getBoolPref("dom.indexedDB.enabled")) {
return this.DENY;
}
// We always ask for permission to enable indexedDB storage for a specific
// site, so there is no global ALLOW.
return this.UNKNOWN;
},
set indexedDB(aValue) {
let value = (aValue != this.DENY);
Services.prefs.setBoolPref("dom.indexedDB.enabled", value);
},
get popup() {
if (Services.prefs.getBoolPref("dom.disable_open_during_load")) {
return this.DENY;
}
return this.ALLOW;
},
set popup(aValue) {
let value = (aValue == this.DENY);
Services.prefs.setBoolPref("dom.disable_open_during_load", value);
},
get fullscreen() {
if (!Services.prefs.getBoolPref("full-screen-api.enabled")) {
return this.DENY;
}
return this.UNKNOWN;
},
set fullscreen(aValue) {
let value = (aValue != this.DENY);
Services.prefs.setBoolPref("full-screen-api.enabled", value);
},
get camera() this.UNKNOWN,
get microphone() this.UNKNOWN
};
/**
* AboutPermissions manages the about:permissions page.
*/
let AboutPermissions = {
/**
* Number of sites to return from the places database.
*/
PLACES_SITES_LIMIT: 50,
/**
* When adding sites to the dom sites-list, divide workload into intervals.
*/
LIST_BUILD_CHUNK: 5, // interval size
LIST_BUILD_DELAY: 100, // delay between intervals
/**
* Stores a mapping of host strings to Site objects.
*/
_sites: {},
sitesList: null,
_selectedSite: null,
/**
* For testing, track initializations so we can send notifications
*/
_initPlacesDone: false,
_initServicesDone: false,
/**
* This reflects the permissions that we expose in the UI. These correspond
* to permission type strings in the permission manager, PermissionDefaults,
* and element ids in aboutPermissions.xul.
*
* Potential future additions: "sts/use", "sts/subd"
*/
_supportedPermissions: ["password", "cookie", "geo", "indexedDB", "popup",
"fullscreen", "camera", "microphone"],
/**
* Permissions that don't have a global "Allow" option.
*/
_noGlobalAllow: ["geo", "indexedDB", "fullscreen", "camera", "microphone"],
/**
* Permissions that don't have a global "Deny" option.
*/
_noGlobalDeny: ["camera", "microphone"],
_stringBundle: Services.strings.
createBundle("chrome://browser/locale/preferences/aboutPermissions.properties"),
/**
* Called on page load.
*/
init: function() {
this.sitesList = document.getElementById("sites-list");
this.getSitesFromPlaces();
this.enumerateServicesGenerator = this.getEnumerateServicesGenerator();
setTimeout(this.enumerateServicesDriver.bind(this), this.LIST_BUILD_DELAY);
// Attach observers in case data changes while the page is open.
Services.prefs.addObserver("signon.rememberSignons", this, false);
Services.prefs.addObserver("network.cookie.", this, false);
Services.prefs.addObserver("geo.enabled", this, false);
Services.prefs.addObserver("dom.indexedDB.enabled", this, false);
Services.prefs.addObserver("dom.disable_open_during_load", this, false);
Services.prefs.addObserver("full-screen-api.enabled", this, false);
Services.obs.addObserver(this, "perm-changed", false);
Services.obs.addObserver(this, "passwordmgr-storage-changed", false);
Services.obs.addObserver(this, "cookie-changed", false);
Services.obs.addObserver(this, "browser:purge-domain-data", false);
this._observersInitialized = true;
Services.obs.notifyObservers(null, "browser-permissions-preinit", null);
},
/**
* Called on page unload.
*/
cleanUp: function() {
if (this._observersInitialized) {
Services.prefs.removeObserver("signon.rememberSignons", this, false);
Services.prefs.removeObserver("network.cookie.", this, false);
Services.prefs.removeObserver("geo.enabled", this, false);
Services.prefs.removeObserver("dom.indexedDB.enabled", this, false);
Services.prefs.removeObserver("dom.disable_open_during_load", this, false);
Services.prefs.removeObserver("full-screen-api.enabled", this, false);
Services.obs.removeObserver(this, "perm-changed");
Services.obs.removeObserver(this, "passwordmgr-storage-changed");
Services.obs.removeObserver(this, "cookie-changed");
Services.obs.removeObserver(this, "browser:purge-domain-data");
}
gSitesStmt.finalize();
gVisitStmt.finalize();
gPlacesDatabase.asyncClose(null);
},
observe: function (aSubject, aTopic, aData) {
switch(aTopic) {
case "perm-changed":
// Permissions changes only affect individual sites.
if (!this._selectedSite) {
break;
}
// aSubject is null when nsIPermisionManager::removeAll() is called.
if (!aSubject) {
this._supportedPermissions.forEach(function(aType){
this.updatePermission(aType);
}, this);
break;
}
let permission = aSubject.QueryInterface(Ci.nsIPermission);
// We can't compare selectedSite.host and permission.host here because
// we need to handle the case where a parent domain was changed in a
// way that affects the subdomain.
if (this._supportedPermissions.indexOf(permission.type) != -1) {
this.updatePermission(permission.type);
}
break;
case "nsPref:changed":
this._supportedPermissions.forEach(function(aType){
this.updatePermission(aType);
}, this);
break;
case "passwordmgr-storage-changed":
this.updatePermission("password");
if (this._selectedSite) {
this.updatePasswordsCount();
}
break;
case "cookie-changed":
if (this._selectedSite) {
this.updateCookiesCount();
}
break;
case "browser:purge-domain-data":
this.deleteFromSitesList(aData);
break;
}
},
/**
* Creates Site objects for the top-frecency sites in the places database and stores
* them in _sites. The number of sites created is controlled by PLACES_SITES_LIMIT.
*/
getSitesFromPlaces: function() {
gSitesStmt.params.limit = this.PLACES_SITES_LIMIT;
gSitesStmt.executeAsync({
handleResult: function(aResults) {
AboutPermissions.startSitesListBatch();
let row;
while (row = aResults.getNextRow()) {
let host = row.getResultByName("host");
AboutPermissions.addHost(host);
}
AboutPermissions.endSitesListBatch();
},
handleError: function(aError) {
Cu.reportError("AboutPermissions: " + aError);
},
handleCompletion: function(aReason) {
// Notify oberservers for testing purposes.
AboutPermissions._initPlacesDone = true;
if (AboutPermissions._initServicesDone) {
Services.obs.notifyObservers(null, "browser-permissions-initialized", null);
}
}
});
},
/**
* Drives getEnumerateServicesGenerator to work in intervals.
*/
enumerateServicesDriver: function() {
if (this.enumerateServicesGenerator.next()) {
// Build top sitesList items faster so that the list never seems sparse
let delay = Math.min(this.sitesList.itemCount * 5, this.LIST_BUILD_DELAY);
setTimeout(this.enumerateServicesDriver.bind(this), delay);
} else {
this.enumerateServicesGenerator.close();
this._initServicesDone = true;
if (this._initPlacesDone) {
Services.obs.notifyObservers(null, "browser-permissions-initialized", null);
}
}
},
/**
* Finds sites that have non-default permissions and creates Site objects for
* them if they are not already stored in _sites.
*/
getEnumerateServicesGenerator: function() {
let itemCnt = 1;
let logins = Services.logins.getAllLogins();
logins.forEach(function(aLogin) {
if (itemCnt % this.LIST_BUILD_CHUNK == 0) {
yield true;
}
try {
// aLogin.hostname is a string in origin URL format (e.g. "http://foo.com")
let uri = NetUtil.newURI(aLogin.hostname);
this.addHost(uri.host);
} catch (e) {
// newURI will throw for add-ons logins stored in chrome:// URIs
}
itemCnt++;
}, this);
let disabledHosts = Services.logins.getAllDisabledHosts();
disabledHosts.forEach(function(aHostname) {
if (itemCnt % this.LIST_BUILD_CHUNK == 0) {
yield true;
}
try {
// aHostname is a string in origin URL format (e.g. "http://foo.com")
let uri = NetUtil.newURI(aHostname);
this.addHost(uri.host);
} catch (e) {
// newURI will throw for add-ons logins stored in chrome:// URIs
}
itemCnt++;
}, this);
let enumerator = Services.perms.enumerator;
while (enumerator.hasMoreElements()) {
if (itemCnt % this.LIST_BUILD_CHUNK == 0) {
yield true;
}
let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
// Only include sites with exceptions set for supported permission types.
if (this._supportedPermissions.indexOf(permission.type) != -1) {
this.addHost(permission.host);
}
itemCnt++;
}
yield false;
},
/**
* Creates a new Site and adds it to _sites if it's not already there.
*
* @param aHost
* A host string.
*/
addHost: function(aHost) {
if (aHost in this._sites) {
return;
}
let site = new Site(aHost);
this._sites[aHost] = site;
this.addToSitesList(site);
},
/**
* Populates sites-list richlistbox with data from Site object.
*
* @param aSite
* A Site object.
*/
addToSitesList: function(aSite) {
let item = document.createElement("richlistitem");
item.setAttribute("class", "site");
item.setAttribute("value", aSite.host);
aSite.getFavicon(function(aURL) {
item.setAttribute("favicon", aURL);
});
aSite.listitem = item;
// Make sure to only display relevant items when list is filtered
let filterValue = document.getElementById("sites-filter").value.toLowerCase();
item.collapsed = aSite.host.toLowerCase().indexOf(filterValue) == -1;
(this._listFragment || this.sitesList).appendChild(item);
},
startSitesListBatch: function () {
if (!this._listFragment)
this._listFragment = document.createDocumentFragment();
},
endSitesListBatch: function () {
if (this._listFragment) {
this.sitesList.appendChild(this._listFragment);
this._listFragment = null;
}
},
/**
* Hides sites in richlistbox based on search text in sites-filter textbox.
*/
filterSitesList: function() {
let siteItems = this.sitesList.children;
let filterValue = document.getElementById("sites-filter").value.toLowerCase();
if (filterValue == "") {
for (let i = 0; i < siteItems.length; i++) {
siteItems[i].collapsed = false;
}
return;
}
for (let i = 0; i < siteItems.length; i++) {
let siteValue = siteItems[i].value.toLowerCase();
siteItems[i].collapsed = siteValue.indexOf(filterValue) == -1;
}
},
/**
* Removes all evidence of the selected site. The "forget this site" observer
* will call deleteFromSitesList to update the UI.
*/
forgetSite: function() {
this._selectedSite.forgetSite();
},
/**
* Deletes sites for a host and all of its sub-domains. Removes these sites
* from _sites and removes their corresponding elements from the DOM.
*
* @param aHost
* The host string corresponding to the site to delete.
*/
deleteFromSitesList: function(aHost) {
for (let host in this._sites) {
let site = this._sites[host];
if (site.host.hasRootDomain(aHost)) {
if (site == this._selectedSite) {
// Replace site-specific interface with "All Sites" interface.
this.sitesList.selectedItem = document.getElementById("all-sites-item");
}
this.sitesList.removeChild(site.listitem);
delete this._sites[site.host];
}
}
},
/**
* Shows interface for managing site-specific permissions.
*/
onSitesListSelect: function(event) {
if (event.target.selectedItem.id == "all-sites-item") {
// Clear the header label value from the previously selected site.
document.getElementById("site-label").value = "";
this.manageDefaultPermissions();
return;
}
let host = event.target.value;
let site = this._selectedSite = this._sites[host];
document.getElementById("site-label").value = host;
document.getElementById("header-deck").selectedPanel =
document.getElementById("site-header");
this.updateVisitCount();
this.updatePermissionsBox();
},
/**
* Shows interface for managing default permissions. This corresponds to
* the "All Sites" list item.
*/
manageDefaultPermissions: function() {
this._selectedSite = null;
document.getElementById("header-deck").selectedPanel =
document.getElementById("defaults-header");
this.updatePermissionsBox();
},
/**
* Updates permissions interface based on selected site.
*/
updatePermissionsBox: function() {
this._supportedPermissions.forEach(function(aType){
this.updatePermission(aType);
}, this);
this.updatePasswordsCount();
this.updateCookiesCount();
},
/**
* Sets menulist for a given permission to the correct state, based on the
* stored permission.
*
* @param aType
* The permission type string stored in permission manager.
* e.g. "cookie", "geo", "indexedDB", "popup", "image"
*/
updatePermission: function(aType) {
let allowItem = document.getElementById(aType + "-" + PermissionDefaults.ALLOW);
allowItem.hidden = !this._selectedSite &&
this._noGlobalAllow.indexOf(aType) != -1;
let denyItem = document.getElementById(aType + "-" + PermissionDefaults.DENY);
denyItem.hidden = !this._selectedSite &&
this._noGlobalDeny.indexOf(aType) != -1;
let permissionMenulist = document.getElementById(aType + "-menulist");
let permissionValue;
if (!this._selectedSite) {
// If there is no selected site, we are updating the default permissions interface.
permissionValue = PermissionDefaults[aType];
if (aType == "cookie")
// cookie-9 corresponds to ALLOW_FIRST_PARTY_ONLY, which is reserved
// for site-specific preferences only.
document.getElementById("cookie-9").hidden = true;
} else {
if (aType == "cookie")
document.getElementById("cookie-9").hidden = false;
let result = {};
permissionValue = this._selectedSite.getPermission(aType, result) ?
result.value : PermissionDefaults[aType];
}
permissionMenulist.selectedItem = document.getElementById(aType + "-" + permissionValue);
},
onPermissionCommand: function(event) {
let permissionType = event.currentTarget.getAttribute("type");
let permissionValue = event.target.value;
if (!this._selectedSite) {
// If there is no selected site, we are setting the default permission.
PermissionDefaults[permissionType] = permissionValue;
} else {
this._selectedSite.setPermission(permissionType, permissionValue);
}
},
updateVisitCount: function() {
this._selectedSite.getVisitCount(function(aCount) {
let visitForm = AboutPermissions._stringBundle.GetStringFromName("visitCount");
let visitLabel = PluralForm.get(aCount, visitForm)
.replace("#1", aCount);
document.getElementById("site-visit-count").value = visitLabel;
});
},
updatePasswordsCount: function() {
if (!this._selectedSite) {
document.getElementById("passwords-count").hidden = true;
document.getElementById("passwords-manage-all-button").hidden = false;
return;
}
let passwordsCount = this._selectedSite.logins.length;
let passwordsForm = this._stringBundle.GetStringFromName("passwordsCount");
let passwordsLabel = PluralForm.get(passwordsCount, passwordsForm)
.replace("#1", passwordsCount);
document.getElementById("passwords-label").value = passwordsLabel;
document.getElementById("passwords-manage-button").disabled = (passwordsCount < 1);
document.getElementById("passwords-manage-all-button").hidden = true;
document.getElementById("passwords-count").hidden = false;
},
/**
* Opens password manager dialog.
*/
managePasswords: function() {
let selectedHost = "";
if (this._selectedSite) {
selectedHost = this._selectedSite.host;
}
let win = Services.wm.getMostRecentWindow("Toolkit:PasswordManager");
if (win) {
win.setFilter(selectedHost);
win.focus();
} else {
window.openDialog("chrome://passwordmgr/content/passwordManager.xul",
"Toolkit:PasswordManager", "", {filterString : selectedHost});
}
},
updateCookiesCount: function() {
if (!this._selectedSite) {
document.getElementById("cookies-count").hidden = true;
document.getElementById("cookies-clear-all-button").hidden = false;
document.getElementById("cookies-manage-all-button").hidden = false;
return;
}
let cookiesCount = this._selectedSite.cookies.length;
let cookiesForm = this._stringBundle.GetStringFromName("cookiesCount");
let cookiesLabel = PluralForm.get(cookiesCount, cookiesForm)
.replace("#1", cookiesCount);
document.getElementById("cookies-label").value = cookiesLabel;
document.getElementById("cookies-clear-button").disabled = (cookiesCount < 1);
document.getElementById("cookies-manage-button").disabled = (cookiesCount < 1);
document.getElementById("cookies-clear-all-button").hidden = true;
document.getElementById("cookies-manage-all-button").hidden = true;
document.getElementById("cookies-count").hidden = false;
},
/**
* Clears cookies for the selected site.
*/
clearCookies: function() {
if (!this._selectedSite) {
return;
}
let site = this._selectedSite;
site.clearCookies(site.cookies);
this.updateCookiesCount();
},
/**
* Opens cookie manager dialog.
*/
manageCookies: function() {
let selectedHost = "";
if (this._selectedSite) {
selectedHost = this._selectedSite.host;
}
let win = Services.wm.getMostRecentWindow("Browser:Cookies");
if (win) {
win.gCookiesWindow.setFilter(selectedHost);
win.focus();
} else {
window.openDialog("chrome://browser/content/preferences/cookies.xul",
"Browser:Cookies", "", {filterString : selectedHost});
}
}
}
// See nsPrivateBrowsingService.js
String.prototype.hasRootDomain = function hasRootDomain(aDomain) {
let index = this.indexOf(aDomain);
if (index == -1)
return false;
if (this == aDomain)
return true;
let prevChar = this[index - 1];
return (index == (this.length - aDomain.length)) &&
(prevChar == "." || prevChar == "/");
}

18
browser-omni/chrome/kmeleon/content/browser/preferences/aboutPermissions.xml

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE bindings>
<bindings xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="site" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<content>
<xul:hbox class="site-container" align="center" flex="1">
<xul:image xbl:inherits="src=favicon" class="site-favicon"/>
<xul:label xbl:inherits="value,selected" class="site-domain" crop="end" flex="1"/>
</xul:hbox>
</content>
</binding>
</bindings>

260
browser-omni/chrome/kmeleon/content/browser/preferences/aboutPermissions.xul

@ -0,0 +1,260 @@
<?xml version="1.0"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/preferences/aboutPermissions.css"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/aboutPermissions.css"?>
<!DOCTYPE page [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % aboutPermissionsDTD SYSTEM "chrome://browser/locale/preferences/aboutPermissions.dtd" >
%aboutPermissionsDTD;
]>
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
id="permissions-page" title="&permissionsManager.title;"
onload="AboutPermissions.init();"
onunload="AboutPermissions.cleanUp();"
disablefastfind="true"
role="application">
<script type="application/javascript"
src="chrome://browser/content/preferences/aboutPermissions.js"/>
<hbox flex="1" id="permissions-content" class="main-content">
<vbox id="sites-box">
<textbox id="sites-filter"
emptytext="&sites.search;"
oncommand="AboutPermissions.filterSitesList();"
type="search"/>
<richlistbox id="sites-list"
flex="1"
class="list"
onselect="AboutPermissions.onSitesListSelect(event);">
<richlistitem id="all-sites-item"
class="site"
value="&sites.allSites;"/>
</richlistbox>
</vbox>
<vbox id="permissions-box" flex="1">
<deck id="header-deck">
<hbox id="site-header" class="pref-item" align="center">
<description id="site-description">
&header.site.start;<label id="site-label"/>&header.site.end;
</description>
<label id="site-visit-count"/>
<spacer flex="1"/>
<button id="forget-site-button"
label="&permissions.forgetSite;"
oncommand="AboutPermissions.forgetSite();"/>
</hbox>
<hbox id="defaults-header" class="pref-item" align="center">
<description id="defaults-description">
&header.defaults;
</description>
</hbox>
</deck>
<!-- Passwords -->
<hbox id="password-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="password"/>
<vbox>
<label class="pref-title" value="&password.label;"/>
<hbox align="center">
<menulist id="password-menulist"
class="pref-menulist"
type="password"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="password-1" value="1" label="&permission.allow;"/>
<menuitem id="password-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
<button id="passwords-manage-all-button"
label="&password.manage;"
oncommand="AboutPermissions.managePasswords();"/>
</hbox>
<hbox id="passwords-count" align="center">
<label id="passwords-label"/>
<button id="passwords-manage-button"
label="&password.manage;"
oncommand="AboutPermissions.managePasswords();"/>
</hbox>
</vbox>
</hbox>
<!-- Geolocation -->
<hbox id="geo-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="geo"/>
<vbox>
<label class="pref-title" value="&geo.label;"/>
<hbox>
<menulist id="geo-menulist"
class="pref-menulist"
type="geo"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="geo-0" value="0" label="&permission.alwaysAsk;"/>
<menuitem id="geo-1" value="1" label="&permission.allow;"/>
<menuitem id="geo-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
</hbox>
</vbox>
</hbox>
<!-- Camera -->
<hbox id="camera-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="camera"/>
<vbox>
<label class="pref-title" value="&camera.label;"/>
<hbox align="center">
<menulist id="camera-menulist"
class="pref-menulist"
type="camera"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="camera-0" value="0" label="&permission.alwaysAsk;"/>
<menuitem id="camera-1" value="1" label="&permission.allow;"/>
<menuitem id="camera-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
</hbox>
</vbox>
</hbox>
<!-- Microphone -->
<hbox id="microphone-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="microphone"/>
<vbox>
<label class="pref-title" value="&microphone.label;"/>
<hbox align="center">
<menulist id="microphone-menulist"
class="pref-menulist"
type="microphone"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="microphone-0" value="0" label="&permission.alwaysAsk;"/>
<menuitem id="microphone-1" value="1" label="&permission.allow;"/>
<menuitem id="microphone-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
</hbox>
</vbox>
</hbox>
<!-- Cookies -->
<hbox id="cookie-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="cookie"/>
<vbox>
<label class="pref-title" value="&cookie.label;"/>
<hbox align="center">
<menulist id="cookie-menulist"
class="pref-menulist"
type="cookie"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="cookie-1" value="1" label="&permission.allow;"/>
<menuitem id="cookie-8" value="8" label="&permission.allowForSession;"/>
<menuitem id="cookie-9" value="9" label="&permission.allowFirstPartyOnly;"/>
<menuitem id="cookie-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
<button id="cookies-clear-all-button"
label="&cookie.removeAll;"
oncommand="Services.cookies.removeAll();"/>
<button id="cookies-manage-all-button"
label="&cookie.manage;"
oncommand="AboutPermissions.manageCookies();"/>
</hbox>
<hbox id="cookies-count" align="center">
<label id="cookies-label"/>
<button id="cookies-clear-button"
label="&cookie.remove;"
oncommand="AboutPermissions.clearCookies();"/>
<button id="cookies-manage-button"
label="&cookie.manage;"
oncommand="AboutPermissions.manageCookies();"/>
</hbox>
</vbox>
</hbox>
<!-- Pop-up Blocking -->
<hbox id="popup-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="popup"/>
<vbox>
<label class="pref-title" value="&popup.label;"/>
<hbox>
<menulist id="popup-menulist"
class="pref-menulist"
type="popup"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="popup-1" value="1" label="&permission.allow;"/>
<menuitem id="popup-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
</hbox>
</vbox>
</hbox>
<!-- IndexedDB Storage -->
<hbox id="indexedDB-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="indexedDB"/>
<vbox>
<label class="pref-title" value="&indexedDB.label;"/>
<hbox>
<menulist id="indexedDB-menulist"
class="pref-menulist"
type="indexedDB"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="indexedDB-0" value="0" label="&permission.alwaysAsk;"/>
<menuitem id="indexedDB-1" value="1" label="&permission.allow;"/>
<menuitem id="indexedDB-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
</hbox>
</vbox>
</hbox>
<!-- Fullscreen -->
<hbox id="fullscreen-pref-item"
class="pref-item" align="top">
<image class="pref-icon" type="fullscreen"/>
<vbox>
<label class="pref-title" value="&fullscreen.label;"/>
<hbox align="center">
<menulist id="fullscreen-menulist"
class="pref-menulist"
type="fullscreen"
oncommand="AboutPermissions.onPermissionCommand(event);">
<menupopup>
<menuitem id="fullscreen-0" value="0" label="&permission.alwaysAsk;"/>
<menuitem id="fullscreen-1" value="1" label="&permission.allow;"/>
<menuitem id="fullscreen-2" value="2" label="&permission.block;"/>
</menupopup>
</menulist>
</hbox>
</vbox>
</hbox>
</vbox>
</hbox>
</page>

818
browser-omni/chrome/kmeleon/content/browser/preferences/advanced.js

@ -0,0 +1,818 @@
//@line 5 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
// Load DownloadUtils module for convertByteUnits
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
Components.utils.import("resource://gre/modules/ctypes.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/LoadContextInfo.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var gAdvancedPane = {
_inited: false,
/**
* Brings the appropriate tab to the front and initializes various bits of UI.
*/
init: function ()
{
this._inited = true;
var advancedPrefs = document.getElementById("advancedPrefs");
var extraArgs = window.arguments[1];
if (extraArgs && extraArgs["advancedTab"]){
advancedPrefs.selectedTab = document.getElementById(extraArgs["advancedTab"]);
} else {
var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex");
if (preference.value !== null)
advancedPrefs.selectedIndex = preference.value;
}
//@line 34 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
let onUnload = function () {
window.removeEventListener("unload", onUnload, false);
Services.prefs.removeObserver("app.update.", this);
}.bind(this);
window.addEventListener("unload", onUnload, false);
Services.prefs.addObserver("app.update.", this, false);
this.updateReadPrefs();
//@line 42 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
this.updateOfflineApps();
//@line 44 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
this.initSubmitCrashes();
//@line 46 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
this.initTelemetry();
//@line 48 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
this.initSubmitHealthReport();
//@line 50 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
this.updateActualCacheSize();
this.updateActualAppCacheSize();
let bundlePrefs = document.getElementById("bundlePreferences");
document.getElementById("offlineAppsList")
.style.height = bundlePrefs.getString("offlineAppsList.height");
// Notify observers that the UI is now ready
Services.obs.notifyObservers(window, "advanced-pane-loaded", null);
},
/**
* Stores the identity of the current tab in preferences so that the selected
* tab can be persisted between openings of the preferences window.
*/
tabSelectionChanged: function ()
{
if (!this._inited)
return;
var advancedPrefs = document.getElementById("advancedPrefs");
var preference = document.getElementById("browser.preferences.advanced.selectedTabIndex");
preference.valueFromPreferences = advancedPrefs.selectedIndex;
},
// GENERAL TAB
/*
* Preferences:
*
* accessibility.browsewithcaret
* - true enables keyboard navigation and selection within web pages using a
* visible caret, false uses normal keyboard navigation with no caret
* accessibility.typeaheadfind
* - when set to true, typing outside text areas and input boxes will
* automatically start searching for what's typed within the current
* document; when set to false, no search action happens
* general.autoScroll
* - when set to true, clicking the scroll wheel on the mouse activates a
* mouse mode where moving the mouse down scrolls the document downward with
* speed correlated with the distance of the cursor from the original
* position at which the click occurred (and likewise with movement upward);
* if false, this behavior is disabled
* general.smoothScroll
* - set to true to enable finer page scrolling than line-by-line on page-up,
* page-down, and other such page movements
* layout.spellcheckDefault
* - an integer:
* 0 disables spellchecking
* 1 enables spellchecking, but only for multiline text fields
* 2 enables spellchecking for all text fields
*/
/**
* Stores the original value of the spellchecking preference to enable proper
* restoration if unchanged (since we're mapping a tristate onto a checkbox).
*/
_storedSpellCheck: 0,
/**
* Returns true if any spellchecking is enabled and false otherwise, caching
* the current value to enable proper pref restoration if the checkbox is
* never changed.
*/
readCheckSpelling: function ()
{
var pref = document.getElementById("layout.spellcheckDefault");
this._storedSpellCheck = pref.value;
return (pref.value != 0);
},
/**
* Returns the value of the spellchecking preference represented by UI,
* preserving the preference's "hidden" value if the preference is
* unchanged and represents a value not strictly allowed in UI.
*/
writeCheckSpelling: function ()
{
var checkbox = document.getElementById("checkSpelling");
return checkbox.checked ? (this._storedSpellCheck == 2 ? 2 : 1) : 0;
},
/**
* security.OCSP.enabled is an integer value for legacy reasons.
* A value of 1 means OCSP is enabled. Any other value means it is disabled.
*/
readEnableOCSP: function ()
{
var preference = document.getElementById("security.OCSP.enabled");
// This is the case if the preference is the default value.
if (preference.value === undefined) {
return true;
}
return preference.value == 1;
},
/**
* See documentation for readEnableOCSP.
*/
writeEnableOCSP: function ()
{
var checkbox = document.getElementById("enableOCSP");
return checkbox.checked ? 1 : 0;
},
/**
* When the user toggles the layers.acceleration.disabled pref,
* sync its new value to the gfx.direct2d.disabled pref too.
*/
updateHardwareAcceleration: function()
{
//@line 163 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
var fromPref = document.getElementById("layers.acceleration.disabled");
var toPref = document.getElementById("gfx.direct2d.disabled");
toPref.value = fromPref.value;
//@line 167 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
},
// DATA CHOICES TAB
/**
* opening links behind a modal dialog is poor form. Work around flawed text-link handling here.
*/
openTextLink: function (evt) {
let where = Services.prefs.getBoolPref("browser.preferences.instantApply") ? "tab" : "window";
openUILinkIn(evt.target.getAttribute("href"), where);
evt.preventDefault();
},
/**
* Set up or hide the Learn More links for various data collection options
*/
_setupLearnMoreLink: function (pref, element) {
// set up the Learn More link with the correct URL
let url = Services.prefs.getCharPref(pref);
let el = document.getElementById(element);
if (url) {
el.setAttribute("href", url);
} else {
el.setAttribute("hidden", "true");
}
},
/**
*
*/
initSubmitCrashes: function ()
{
var checkbox = document.getElementById("submitCrashesBox");
try {
var cr = Components.classes["@mozilla.org/toolkit/crash-reporter;1"].
getService(Components.interfaces.nsICrashReporter);
checkbox.checked = cr.submitReports;
} catch (e) {
checkbox.style.display = "none";
}
this._setupLearnMoreLink("toolkit.crashreporter.infoURL", "crashReporterLearnMore");
},
/**
*
*/
updateSubmitCrashes: function ()
{
var checkbox = document.getElementById("submitCrashesBox");
try {
var cr = Components.classes["@mozilla.org/toolkit/crash-reporter;1"].
getService(Components.interfaces.nsICrashReporter);
cr.submitReports = checkbox.checked;
} catch (e) { }
},
/**
* The preference/checkbox is configured in XUL.
*
* In all cases, set up the Learn More link sanely
*/
initTelemetry: function ()
{
//@line 233 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
this._setupLearnMoreLink("toolkit.telemetry.infoURL", "telemetryLearnMore");
//@line 235 "c:\builds\moz2_slave\rel-m-esr38-w32_bld-0000000000\build\browser\components\preferences\advanced.js"
},
/**
* Set the status of the telemetry controls based on the input argument.
* @param {Boolean} aEnabled False disables the controls, true enables them.
*/
setTelemetrySectionEnabled: function (aEnabled)</