зеркало из https://github.com/mozilla/gecko-dev.git
195924, 195921, 195928 - popup blocking changes to use whitelisting only and provide info dlg when popup first encountered. r=danm, sr=jag.
This commit is contained in:
Родитель
a20bb0c282
Коммит
79b6cd410d
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is mozilla.org code.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Netscape Communications Corporation.
|
||||
- Portions created by the Initial Developer are Copyright (C) 2002
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
- in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
- of those above. If you wish to allow use of your version of this file only
|
||||
- under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
- use your version of this file under the terms of the MPL, indicate your
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the LGPL or the GPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://navigator/skin/navigator.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
|
||||
%brandDTD;
|
||||
<!ENTITY % aboutPopupsDTD SYSTEM "chrome://communicator/locale/aboutPopups.dtd" >
|
||||
%aboutPopupsDTD;
|
||||
]>
|
||||
|
||||
<dialog id="aboutPopups"
|
||||
buttons="accept,cancel,help"
|
||||
title="&windowtitle.label;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
width="380" height="260"
|
||||
onload="init();"
|
||||
ondialogaccept="return onAccept();"
|
||||
ondialoghelp="return doHelpButton();">
|
||||
|
||||
<script type="application/x-javascript" src="chrome://help/content/contextHelp.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/utilityOverlay.js"/>
|
||||
|
||||
<script type="application/x-javascript">
|
||||
<![CDATA[
|
||||
|
||||
var enableBlock = true;
|
||||
|
||||
function init() {
|
||||
if (!window.arguments[0])
|
||||
document.getElementById("popupDesc").hidden = true;
|
||||
else
|
||||
document.getElementById("popupDescAlt").hidden = true;
|
||||
}
|
||||
|
||||
function onAccept() {
|
||||
var pref;
|
||||
try {
|
||||
var prefService = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService);
|
||||
pref = prefService.getBranch(null);
|
||||
}
|
||||
catch(ex) { }
|
||||
|
||||
goPreferences("securityItem", "chrome://communicator/content/cookie/pref-popups.xul", "popupspref");
|
||||
}
|
||||
|
||||
function doHelpButton() {
|
||||
openHelp("pop_up_blocking");
|
||||
return true;
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<keyset id="dialogKeys"/>
|
||||
|
||||
<description id="popupDesc">&popupDesc.label;</description>
|
||||
<description id="popupDescAlt">&popupDescAlt.label;</description>
|
||||
<vbox align="center">
|
||||
<image id="popupImage"/>
|
||||
</vbox>
|
||||
<description>&popupNote1.label;</description>
|
||||
<separator class="thin"/>
|
||||
<description>&popupNote2.label;</description>
|
||||
<spacer flex="1"/>
|
||||
<hbox class="dialog-button-box" pack="center">
|
||||
<button dlgtype="accept" label="&acceptButton.label;"/>
|
||||
<button dlgtype="cancel" label="&cancelButton.label;"/>
|
||||
<button dlgtype="help"/>
|
||||
</hbox>
|
||||
|
||||
</dialog>
|
|
@ -24,24 +24,15 @@
|
|||
const nsIPermissionManager = Components.interfaces.nsIPermissionManager;
|
||||
const popupType = nsIPermissionManager.POPUP_TYPE;
|
||||
|
||||
var popupManager = null;
|
||||
var permissionManager = null;
|
||||
|
||||
var permissions = [];
|
||||
|
||||
var listCapability; // the capability of sites on the currently viewed list
|
||||
// TRUE: current popup policy is BLOCK ALL WITH EXCEPTIONS - sites on
|
||||
// the whitelist are allowed and have permission.capability = true
|
||||
// FALSE: current popup policy is ALLOW ALL WITH EXCEPTIONS - sites on
|
||||
// the blacklist are blocked and have permission.capability = false
|
||||
|
||||
var additions = [];
|
||||
var removals = [];
|
||||
|
||||
const SIMPLEURI_CONTRACTID = "@mozilla.org/network/simple-uri;1";
|
||||
|
||||
var sortColumn = "host";
|
||||
var lastSort = false;
|
||||
var sortAscending = false;
|
||||
|
||||
var permissionsTreeView = {
|
||||
rowCount: 0,
|
||||
|
@ -66,76 +57,27 @@ var permissionsTree;
|
|||
var popupStringBundle;
|
||||
|
||||
function Startup() {
|
||||
popupManager = Components.classes["@mozilla.org/PopupWindowManager;1"]
|
||||
.getService(Components.interfaces.nsIPopupWindowManager);
|
||||
permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Components.interfaces.nsIPermissionManager);
|
||||
.getService(Components.interfaces.nsIPermissionManager);
|
||||
|
||||
permissionsTree = document.getElementById("permissionsTree");
|
||||
|
||||
popupStringBundle = document.getElementById("popupStringBundle");
|
||||
var title;
|
||||
|
||||
if (window.arguments[0]) {
|
||||
document.getElementById("blockExcept").hidden = false;
|
||||
lastSort = (permissionsTree.getAttribute("lastSortWhitelist") == "true");
|
||||
title = popupStringBundle.getString("whitelistTitle");
|
||||
}
|
||||
else {
|
||||
document.getElementById("allowExcept").hidden = false;
|
||||
lastSort = (permissionsTree.getAttribute("lastSortBlacklist") == "true");
|
||||
title = popupStringBundle.getString("blacklistTitle");
|
||||
}
|
||||
// window.args[0]: host to prefill
|
||||
// window.args[1]: true = opened from pref panel, false = opened from tools menu or statusbar icon
|
||||
|
||||
document.getElementById("popupManager").setAttribute("title", title);
|
||||
|
||||
listCapability = window.arguments[0];
|
||||
sortAscending = (permissionsTree.getAttribute("sortAscending") == "true");
|
||||
|
||||
loadPermissions(permissions);
|
||||
loadTree();
|
||||
|
||||
if (window.arguments[1]) { // dialog opened from statusbar icon
|
||||
if (listCapability) {
|
||||
document.getElementById("addSiteBox").value = window.arguments[1];
|
||||
}
|
||||
else {
|
||||
// pre-pend '.' so we always match on host boundaries. Otherwise
|
||||
// we might think notfoo.com matches foo.com
|
||||
var currentLoc = '.'+window.arguments[1];
|
||||
var nextHost;
|
||||
var inList;
|
||||
|
||||
var matchIndex;
|
||||
var matchLength = 0;
|
||||
|
||||
for (var i = 0; i < permissionsTreeView.rowCount; i++) {
|
||||
nextHost = '.'+permissions[i].host;
|
||||
|
||||
if (currentLoc.length < nextHost.length)
|
||||
continue; // can't be a match, list host is more specific
|
||||
|
||||
// look for an early out exact match -- check length first for speed
|
||||
if (currentLoc.length == nextHost.length && nextHost == currentLoc) {
|
||||
inList = true;
|
||||
matchIndex = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextHost == currentLoc.substr(currentLoc.length - nextHost.length)) {
|
||||
inList = true;
|
||||
if (listCapability) // host is already on whitelist, don't prefill
|
||||
break;
|
||||
|
||||
if (nextHost.length > matchLength) {
|
||||
matchIndex = i;
|
||||
matchLength = nextHost.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inList) // host is in blacklist, select for removal
|
||||
permissionsTree.treeBoxObject.view.selection.select(matchIndex);
|
||||
}
|
||||
if (window.arguments[0] != "") {
|
||||
// fill textbox to unblock/add to whitelist
|
||||
var prefill = window.arguments[0];
|
||||
if (prefill.indexOf("www.") == 0)
|
||||
prefill = prefill.slice(4);
|
||||
document.getElementById("addSiteBox").value = prefill;
|
||||
}
|
||||
|
||||
document.documentElement.addEventListener("keypress", onReturnHit, true);
|
||||
|
@ -143,19 +85,47 @@ function Startup() {
|
|||
window.sizeToContent();
|
||||
}
|
||||
|
||||
function getMatch(host) {
|
||||
// pre-pend '.' so we always match on host boundaries. Otherwise
|
||||
// we might think notfoo.com matches foo.com
|
||||
var currentLoc = '.'+host;
|
||||
var nextHost;
|
||||
var inList;
|
||||
|
||||
var matchIndex = null;
|
||||
var matchLength = 0;
|
||||
|
||||
for (var i = 0; i < permissionsTreeView.rowCount; i++) {
|
||||
nextHost = '.'+permissions[i].host;
|
||||
|
||||
if (currentLoc.length < nextHost.length)
|
||||
continue; // can't be a match, list host is more specific
|
||||
|
||||
// look for an early out exact match -- check length first for speed
|
||||
if (currentLoc.length == nextHost.length && nextHost == currentLoc) {
|
||||
inList = true;
|
||||
matchIndex = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextHost == currentLoc.substr(currentLoc.length - nextHost.length)) {
|
||||
inList = true;
|
||||
if (nextHost.length > matchLength) {
|
||||
matchIndex = i;
|
||||
matchLength = nextHost.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return matchIndex;
|
||||
}
|
||||
|
||||
function onAccept() {
|
||||
finalizeChanges();
|
||||
|
||||
var unblocked;
|
||||
var unblocked = additions;
|
||||
|
||||
if (listCapability) {
|
||||
unblocked = additions;
|
||||
permissionsTree.setAttribute("lastSortWhitelist", !lastSort);
|
||||
}
|
||||
else {
|
||||
unblocked = removals;
|
||||
permissionsTree.setAttribute("lastSortBlacklist", !lastSort);
|
||||
}
|
||||
permissionsTree.setAttribute("sortAscending", !sortAscending);
|
||||
|
||||
var nextLocation;
|
||||
var nextUnblocked;
|
||||
|
@ -195,10 +165,9 @@ function onAccept() {
|
|||
}
|
||||
}
|
||||
|
||||
if (window.arguments[2])
|
||||
if (window.arguments[1])
|
||||
window.opener.setButtons();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -215,8 +184,7 @@ function loadPermissions(table) {
|
|||
var permission = enumerator.getNext();
|
||||
if (permission) {
|
||||
permission = permission.QueryInterface(Components.interfaces.nsIPermission);
|
||||
if ((permission.type == popupType) &&
|
||||
(permission.capability == listCapability)) {
|
||||
if ((permission.type == popupType) && (permission.capability == nsIPermissionManager.ALLOW_ACTION)) {
|
||||
var host = permission.host;
|
||||
table[count] = new Permission(host,count++);
|
||||
}
|
||||
|
@ -237,9 +205,9 @@ function loadTree() {
|
|||
}
|
||||
|
||||
function permissionColumnSort() {
|
||||
lastSort =
|
||||
sortAscending =
|
||||
SortTree(permissionsTree, permissionsTreeView, permissions,
|
||||
sortColumn, sortColumn, lastSort);
|
||||
sortColumn, sortColumn, sortAscending);
|
||||
}
|
||||
|
||||
function permissionSelected() {
|
||||
|
@ -327,8 +295,7 @@ function finalizeChanges() {
|
|||
var uri;
|
||||
var host;
|
||||
var i;
|
||||
|
||||
var perm = (listCapability == true) ? nsIPermissionManager.ALLOW_ACTION : nsIPermissionManager.DENY_ACTION
|
||||
|
||||
//note: the scheme will be taken off later, it is being added now only to
|
||||
//create the uri for add/remove
|
||||
for (i in additions) {
|
||||
|
@ -336,7 +303,7 @@ function finalizeChanges() {
|
|||
if (host != null) {
|
||||
host = "http://" + host;
|
||||
uri = ioService.newURI(host, null, null);
|
||||
permissionManager.add(uri, popupType, listCapability);
|
||||
permissionManager.add(uri, popupType, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,7 +369,7 @@ function addPermission() {
|
|||
var newPermission = new Permission(host, length);
|
||||
permissions.push(newPermission);
|
||||
|
||||
lastSort = !lastSort; //keep same sort direction
|
||||
sortAscending = !sortAscending; //keep same sort direction
|
||||
loadTree();
|
||||
|
||||
if (removals[host] != null)
|
||||
|
@ -434,7 +401,7 @@ function onReturnHit(event) {
|
|||
}
|
||||
|
||||
function doHelpButton() {
|
||||
openHelp("pop_up_blocking_prefs");
|
||||
openHelp("pop_up_blocking");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,8 +58,7 @@
|
|||
|
||||
<vbox id="servers" flex="1">
|
||||
|
||||
<description id="allowExcept" value="&allowExcept.label;" hidden="true"/>
|
||||
<description id="blockExcept" value="&blockExcept.label;" hidden="true"/>
|
||||
<description id="allowPopups" value="&allowPopups.label;"/>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
|
@ -78,8 +77,8 @@
|
|||
hidecolumnpicker="true"
|
||||
onkeypress="handlePermissionKeyPress(event)"
|
||||
onselect="permissionSelected();"
|
||||
lastSortBlacklist="false" lastSortWhitelist="false"
|
||||
persist="lastSortBlacklist lastSortWhitelist">
|
||||
sortAscending="false"
|
||||
persist="sortAscending">
|
||||
<treecols>
|
||||
<treecol id="siteCol" label="&treehead.sitename.label;" flex="1"
|
||||
onclick="permissionColumnSort();"/>
|
||||
|
|
|
@ -110,10 +110,16 @@
|
|||
var policy = pref.getBoolPref("dom.disable_open_during_load");
|
||||
|
||||
blocked = permissionmanager.testPermission(getBrowser().currentURI, nsIPermissionManager.POPUP_TYPE);
|
||||
|
||||
document.getElementById("AboutPopups").hidden = policy;
|
||||
document.getElementById("ManagePopups").hidden = !policy;
|
||||
|
||||
enableElement("BlockPopups", blocked != nsIPermissionManager.DENY_ACTION);
|
||||
enableElement("AllowPopups", blocked != nsIPermissionManager.ALLOW_ACTION);
|
||||
enableElement("ManagePopups", true);
|
||||
if (policy) {
|
||||
enableElement("AllowPopups", blocked != nsIPermissionManager.ALLOW_ACTION);
|
||||
return;
|
||||
}
|
||||
|
||||
enableElement("AllowPopups", false);
|
||||
}
|
||||
|
||||
function enableElement(elementID, enable) {
|
||||
|
@ -158,32 +164,23 @@
|
|||
}
|
||||
}
|
||||
|
||||
function PopupAction(action) {
|
||||
var policy = pref.getBoolPref("dom.disable_open_during_load");
|
||||
var uri = getBrowser().currentURI;
|
||||
|
||||
switch (action) {
|
||||
case "block":
|
||||
permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.DENY_ACTION);
|
||||
break;
|
||||
case "allow":
|
||||
var browsers = getBrowser().browsers;
|
||||
var popupIcon = document.getElementById("popupIcon");
|
||||
permissionmanager.add(uri, nsIPermissionManager.POPUP_TYPE, nsIPermissionManager.ALLOW_ACTION);
|
||||
for (var i = 0; i < browsers.length; i++) {
|
||||
if (browsers[i].popupDomain == uri.host) {
|
||||
browsers[i].popupDomain = null;
|
||||
popupIcon.hidden = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
function PopupAction() {
|
||||
var hostPort = getBrowser().currentURI.hostPort;
|
||||
window.openDialog("chrome://communicator/content/popupManager.xul", "",
|
||||
"chrome,resizable=yes,modal=yes",
|
||||
hostPort,
|
||||
false);
|
||||
}
|
||||
|
||||
function ViewPopupManager() {
|
||||
function OpenAboutPopups() {
|
||||
window.openDialog("chrome://communicator/content/aboutPopups.xul", "",
|
||||
"chrome,centerscreen,resizable=yes",
|
||||
false);
|
||||
}
|
||||
|
||||
function OpenManagePopups() {
|
||||
window.openDialog("chrome://communicator/content/popupManager.xul", "",
|
||||
"chrome,resizable=yes,modal=yes",
|
||||
pref.getBoolPref("dom.disable_open_during_load"),
|
||||
"chrome,resizable=yes",
|
||||
"",
|
||||
false);
|
||||
}
|
||||
|
@ -235,18 +232,17 @@
|
|||
id="popup"
|
||||
insertbefore="navBeginGlobalItems">
|
||||
<menupopup>
|
||||
<menuitem id="BlockPopups" label="&cookieBlockPopupsCmd.label;"
|
||||
accesskey="&cookieBlockPopupsCmd.accesskey;"
|
||||
msg="&cookieBlockPopupsMsg.label;"
|
||||
oncommand="PopupAction('block');"/>
|
||||
<menuitem id="AllowPopups" label="&cookieAllowPopupsCmd.label;"
|
||||
accesskey="&cookieAllowPopupsCmd.accesskey;"
|
||||
msg="&cookieAllowPopupsMsg.label;"
|
||||
oncommand="PopupAction('allow');"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="ManagePopups" label="&cookieDisplayPopupsCmd.label;"
|
||||
accesskey="&cookieDisplayPopupsCmd.accesskey;"
|
||||
oncommand="ViewPopupManager();"/>
|
||||
oncommand="PopupAction();"/>
|
||||
<menuitem id="AboutPopups" label="&cookieAboutPopupBlocking.label;"
|
||||
accesskey="&cookieAboutPopupBlocking.accesskey;"
|
||||
oncommand="OpenAboutPopups();"
|
||||
hidden="true"/>
|
||||
<menuitem id="ManagePopups" label="&cookieManagePopups.label;"
|
||||
accesskey="&cookieManagePopups.accesskey;"
|
||||
oncommand="OpenManagePopups();"
|
||||
hidden="true"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
|
|
|
@ -20,18 +20,12 @@
|
|||
|
||||
var COOKIEPERMISSION = 0;
|
||||
var IMAGEPERMISSION = 1;
|
||||
var WINDOWPERMISSION = 2;
|
||||
|
||||
function viewImages() {
|
||||
window.openDialog("chrome://communicator/content/wallet/CookieViewer.xul","_blank",
|
||||
"chrome,resizable=yes", "imageManager" );
|
||||
}
|
||||
|
||||
function viewPopups() {
|
||||
window.openDialog("chrome://communicator/content/wallet/CookieViewer.xul","_blank",
|
||||
"chrome,resizable=yes", "popupManager" );
|
||||
}
|
||||
|
||||
function viewCookies() {
|
||||
window.openDialog("chrome://communicator/content/wallet/CookieViewer.xul","_blank",
|
||||
"chrome,resizable=yes", "cookieManager");
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<!ENTITY windowtitle.label "About Popups">
|
||||
|
||||
<!ENTITY popupDesc.label "This web site has opened an unrequested popup window. &brandShortName; can prevent popups from opening without your approval. When a popup is blocked, &brandShortName; can be set up to display an icon in the status bar.">
|
||||
<!ENTITY popupDescAlt.label "&brandShortName; can prevent popups from opening without your approval. When a popup is blocked, &brandShortName; can be set up to display an icon in the status bar.">
|
||||
<!ENTITY popupNote1.label "To set preferences for controlling popups, open the Edit menu and choose Preferences. Under the Privacy & Security category, click Popup Windows.">
|
||||
<!ENTITY popupNote2.label "Would you like to block popups and set preferences now?">
|
||||
|
||||
<!ENTITY acceptButton.label "Yes">
|
||||
<!ENTITY cancelButton.label "No">
|
|
@ -1,8 +1,6 @@
|
|||
<!ENTITY windowtitle.label "Popup Exceptions">
|
||||
<!ENTITY windowtitle.label "Allowed Web Sites">
|
||||
|
||||
<!ENTITY allowExcept.label "Suppress popups from the following web sites:">
|
||||
|
||||
<!ENTITY blockExcept.label "Allow popups from the following web sites:">
|
||||
<!ENTITY allowPopups.label "Allow popups from the following web sites:">
|
||||
|
||||
<!ENTITY addSite.label "Add">
|
||||
<!ENTITY addSite.accesskey "A">
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
blacklistTitle=Popup Exceptions - Suppressed Web Sites
|
||||
whitelistTitle=Popup Exceptions - Allowed Web Sites
|
||||
alertDuplicate=The web site %S already exists in this list.
|
||||
alertInvalid=The web site %S is invalid.
|
||||
|
|
|
@ -18,14 +18,12 @@
|
|||
<!ENTITY cookieBlockImagesCmd.accesskey "b">
|
||||
<!ENTITY cookieBlockImagesMsg.label "Images from this site will never be downloaded">
|
||||
|
||||
<!ENTITY cookieDisplayPopupsCmd.label "Manage Popup Permissions">
|
||||
<!ENTITY cookieDisplayPopupsCmd.accesskey "M">
|
||||
<!ENTITY cookieAllowPopupsCmd.label "Allow Popups from this Site">
|
||||
<!ENTITY cookieAllowPopupsCmd.label "Allow Popups From This Site">
|
||||
<!ENTITY cookieAllowPopupsCmd.accesskey "A">
|
||||
<!ENTITY cookieAllowPopupsMsg.label "Popup windows from this site will always be allowed">
|
||||
<!ENTITY cookieBlockPopupsCmd.label "Suppress Popups from this Site">
|
||||
<!ENTITY cookieBlockPopupsCmd.accesskey "S">
|
||||
<!ENTITY cookieBlockPopupsMsg.label "Popup windows from this site will always be blocked">
|
||||
<!ENTITY cookieAboutPopupBlocking.label "About Popup Blocking">
|
||||
<!ENTITY cookieAboutPopupBlocking.accesskey "b">
|
||||
<!ENTITY cookieManagePopups.label "Manage Popups">
|
||||
<!ENTITY cookieManagePopups.accesskey "M">
|
||||
|
||||
<!ENTITY cookieTutorialCmd.label "Understanding Privacy">
|
||||
<!ENTITY cookieTutorialCmd.accesskey "u">
|
||||
|
|
Загрузка…
Ссылка в новой задаче