diff options
14 files changed, 187 insertions, 41 deletions
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 000000000..7acdedb4f --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,86 @@ +# Code contribution guidelines
+
+To make sure code changes remain easy to organize, find and troubleshoot, please use the following guidelines when contributing code to the Pale Moon project (and UXP). These guidelines may, for some of you, sound tedious or more work than you'd prefer to put in, but keep in mind that a single paragraph of explanation with a code commit can save hours of work later on, and code comments can save your hide when trying to debug or improve code.
+
+## General guideline for issues
+
+Issues are the main drivers behind getting code changes accepted into our source tree. Issues should be opened, and properly labeled, for any of the following:
+- Code bugs (broken functionality)
+- Regressions (functionality that worked before but has either stopped working, is working in a different way than intended, or e.g. has become poorly performing)
+- Enhancements (new code/features)
+- Improvements (better/improved way of existing functionality)
+- General development direction goals (META issues)
+
+Labels should mostly be assigned to issues, not pull requests (PRs).
+
+Issues opened should, where possible, only address one thing at a time. Never roll multiple bugs or enhancements that aren't directly required to be done at the same time into a single issue.
+
+Issues should include:
+### For bugs
+- Description of the bug
+- Affected versions/features
+- Steps to reproduce the bug
+- Expected result when performing the steps
+- Actual result when performing the steps
+### For regressions
+- Description of the regression
+- Affected versions/features
+- What the previous behavior was
+- What the current (incorrect) behavior is
+### For enhancements and improvements
+- Description of the enhancement
+- Background: why is this needed or desired?
+- Impact of the enhancement/improvement
+### META issues
+- A general description, including **what** and **why** should be tackled
+- Links from the individual components of the META goal (by referencing from the actual individual issues)
+For META issues it is important that discussion about specific implementation parts are in the individual component issues and not in the META issue, so it can keep a quick overview of linked components that need to be tackled.
+
+
+## General guideline for submitting pull requests
+
+Most of our code changes will likely be submitted by collaborators from our community. This will be ported from other projects (e.g. Mozilla-based code) or new implementations, or a mix. The standard way of getting your code into Pale Moon or UXP is by way of creating a pull request against the master branch (trunk).
+
+A good pull request will:
+- **Have an issue associated with it!** Even though GitHub offers very similar tools for PRs as it does for issues, any reasoning behind code commits in a PR have to be explained in an accompanying issue.
+- Describe in detail **what** the code change attempts to achieve, and **how** it achieves this. If you have references to external sources, e.g. if your code is based on specific code from Mozilla, then including them is of course excellent, but it's important to provide a clear description alongside it.
+- Not just be a list of links or references. See the previous point. References are OK but do not provide a reason by themselves for a code change. Especially with porting code across from other projects, it is important to keep PRs and explanations in our tree and not dependent on third-party sources.
+- Verify that the code is exactly catered to our tree and in line with our feature set(s) and direction. Just 'porting something across because it is in other browsers" is not a reason or justification by itself. If needed, discuss the **why** for a code change in the attached issue before putting work into a PR that may otherwise be rejected.
+- Only address one bug, issue or enhancement. It is extremely important to keep individual code commits separate so that in case of back-outs, this can be done in a controlled and isolated manner.
+- If there are dependencies on other code being checked in, it is important that the PR lists exactly which other PRs need to be checked in first before the one in question can be merged. If at all possible, keep PR interdependency to a minimum.
+
+The odd small minor one-liner pull request may not need an issue dedicated to it, but when it comes to modifying and refactoring chunks of many files, then yes it would be not only nice, but required, to have a chance to have discussion about it before it is accepted into the tree.
+
+PRs that encompass major code changes or touch many files or functions should preferably get a review. Reviewing can be volunteered or requested.
+
+## Code Style
+
+Because our software encompasses many components of which a good portion is third-party, code style can vary significantly throughout our code base. It's therefore important to keep code as consistent as possible.
+
+Important when editing/adding code:
+
+1. Stick to the style of surrounding code. If you're editing code in a module that deviates from our generally-used code style, don't mix in generally-used code style with the deviating code style. E.g. if a source file uses tabs everywhere, and you edit this code, also use tabs. If you feel code style should be rewritten to improve legibility, preferably create a separate issue to change it and do not roll it in with functional code changes!
+2. Use the following guideline where there's no clear deviating style in use:
+ - Put opening function/scope braces at the end of the line.
+ - Align closing braces with the indentation of the first character of the function/scope
+ - Use a line cap of 80 characters. Put continuations on the next line if it overflows.
+ - Use spaces for indentation, and indent scopes 2 spaces.
+ Example:
+ ```C++
+ nsSVGFilterFrame*
+ nsSVGFilterFrame::GetReferencedFilterIfNotInUse() {
+ nsSVGFilterFrame* referenced = GetReferencedFilter();
+ if (!referenced)
+ return nullptr;
+
+ if (referenced->mLoopFlag) {
+ // XXXjwatt: we should really send an error to the JavaScript Console here:
+ NS_WARNING("Filter reference loop detected while inheriting attribute!");
+ return nullptr;
+ }
+
+ return referenced;
+ }
+ ```
+3. Comment your code where prudent! Documenting what you're doing, especially in a complex piece of code, is very important to keep it easy to debug.
+4. Try not to write "as compact as possible" source code. Many languages have facilities to write very compact source code by gluing a lot of statements together on single lines, but you should avoid this to keep it readable. Other people than yourself will be looking at and trying to understand your code, and it's important to keep proper paragraphing, whitespace and above all logical names for variables and functions.
diff --git a/application/palemoon/components/preferences/cookies.js b/application/palemoon/components/preferences/cookies.js index ea7e7d4e2..543aeb186 100644 --- a/application/palemoon/components/preferences/cookies.js +++ b/application/palemoon/components/preferences/cookies.js @@ -5,6 +5,8 @@ const nsICookie = Components.interfaces.nsICookie; +Components.utils.import("resource://gre/modules/PluralForm.jsm"); + var gCookiesWindow = { _cm : Components.classes["@mozilla.org/cookiemanager;1"] .getService(Components.interfaces.nsICookieManager), @@ -24,6 +26,11 @@ var gCookiesWindow = { this._bundle = document.getElementById("bundlePreferences"); this._tree = document.getElementById("cookiesList"); + let removeAllCookies = document.getElementById("removeAllCookies"); + removeAllCookies.setAttribute("accesskey", this._bundle.getString("removeAllCookies.accesskey")); + let removeSelectedCookies = document.getElementById("removeSelectedCookies"); + removeSelectedCookies.setAttribute("accesskey", this._bundle.getString("removeSelectedCookies.accesskey")); + this._populateList(true); document.getElementById("filter").focus(); @@ -558,12 +565,12 @@ var gCookiesWindow = { if (item && seln.count == 1 && item.container && item.open) selectedCookieCount += 2; - var removeCookie = document.getElementById("removeCookie"); - var removeCookies = document.getElementById("removeCookies"); - removeCookie.parentNode.selectedPanel = - selectedCookieCount == 1 ? removeCookie : removeCookies; + let buttonLabel = this._bundle.getString("removeSelectedCookies.label"); + let removeSelectedCookies = document.getElementById("removeSelectedCookies"); + removeSelectedCookies.label = PluralForm.get(selectedCookieCount, buttonLabel) + .replace("#1", selectedCookieCount); - removeCookie.disabled = removeCookies.disabled = !(seln.count > 0); + removeSelectedCookies.disabled = !(seln.count > 0); }, performDeletion: function gCookiesWindow_performDeletion(deleteItems) { @@ -868,7 +875,17 @@ var gCookiesWindow = { }, _updateRemoveAllButton: function gCookiesWindow__updateRemoveAllButton() { - document.getElementById("removeAllCookies").disabled = this._view._rowCount == 0; + let removeAllCookies = document.getElementById("removeAllCookies"); + removeAllCookies.disabled = this._view._rowCount == 0; + + let labelStringID = "removeAllCookies.label"; + let accessKeyStringID = "removeAllCookies.accesskey"; + if (this._view._filtered) { + labelStringID = "removeAllShownCookies.label"; + accessKeyStringID = "removeAllShownCookies.accesskey"; + } + removeAllCookies.setAttribute("label", this._bundle.getString(labelStringID)); + removeAllCookies.setAttribute("accesskey", this._bundle.getString(accessKeyStringID)); }, filter: function () { diff --git a/application/palemoon/components/preferences/cookies.xul b/application/palemoon/components/preferences/cookies.xul index 8ff0d90ec..60725e9d8 100644 --- a/application/palemoon/components/preferences/cookies.xul +++ b/application/palemoon/components/preferences/cookies.xul @@ -91,16 +91,9 @@ </vbox> <hbox align="end"> <hbox class="actionButtons" flex="1"> - <deck oncommand="gCookiesWindow.deleteCookie();"> - <button id="removeCookie" disabled="true" icon="remove" - label="&button.removecookie.label;" - accesskey="&button.removecookie.accesskey;"/> - <button id="removeCookies" disabled="true" icon="remove" - label="&button.removecookies.label;" - accesskey="&button.removecookie.accesskey;"/> - </deck> + <button id="removeSelectedCookies" disabled="true" icon="clear" + oncommand="gCookiesWindow.deleteCookie();"/> <button id="removeAllCookies" disabled="true" icon="clear" - label="&button.removeallcookies.label;" accesskey="&button.removeallcookies.accesskey;" oncommand="gCookiesWindow.deleteAllCookies();"/> <spacer flex="1"/> #ifndef XP_MACOSX diff --git a/application/palemoon/locales/en-US/chrome/browser/preferences/cookies.dtd b/application/palemoon/locales/en-US/chrome/browser/preferences/cookies.dtd index 06f57c435..c83331328 100644 --- a/application/palemoon/locales/en-US/chrome/browser/preferences/cookies.dtd +++ b/application/palemoon/locales/en-US/chrome/browser/preferences/cookies.dtd @@ -7,11 +7,6 @@ <!ENTITY cookiesonsystem.label "The following cookies are stored on your computer:"> <!ENTITY cookiename.label "Cookie Name"> <!ENTITY cookiedomain.label "Site"> -<!ENTITY button.removecookies.label "Remove Cookies"> -<!ENTITY button.removecookie.label "Remove Cookie"> -<!ENTITY button.removecookie.accesskey "R"> -<!ENTITY button.removeallcookies.label "Remove All Cookies"> -<!ENTITY button.removeallcookies.accesskey "A"> <!ENTITY props.name.label "Name:"> <!ENTITY props.value.label "Content:"> diff --git a/application/palemoon/locales/en-US/chrome/browser/preferences/preferences.properties b/application/palemoon/locales/en-US/chrome/browser/preferences/preferences.properties index 826f1463d..356922982 100644 --- a/application/palemoon/locales/en-US/chrome/browser/preferences/preferences.properties +++ b/application/palemoon/locales/en-US/chrome/browser/preferences/preferences.properties @@ -15,7 +15,7 @@ labelDefaultFont=Default (%S) #### Permissions Manager -cookiepermissionstext=You can specify which websites are always or never allowed to use cookies. Type the exact address of the site you want to manage and then click Block, Allow for Session, or Allow. +cookiepermissionstext=You can specify which websites are always or never allowed to use cookies. Type the exact address of the site you want to manage and then click Block, Allow for Session, or Allow. cookiepermissionstitle=Exceptions - Cookies addonspermissionstext=You can specify which websites are allowed to install add-ons. Type the exact address of the site you want to allow and then click Allow. addons_permissions_title=Allowed Sites - Add-ons Installation @@ -93,9 +93,30 @@ noCookieSelected=<no cookie selected> cookiesAll=The following cookies are stored on your computer: cookiesFiltered=The following cookies match your search: +# LOCALIZATION NOTE (removeAllCookies, removeAllShownCookies): +# removeAllCookies and removeAllShownCookies are both used on the same one button, +# never displayed together and can share the same accesskey. +# When only partial cookies are shown as a result of keyword search, +# removeAllShownCookies is displayed as button label. +# removeAllCookies is displayed when no keyword search and all cookies are shown. +removeAllCookies.label=Remove All +removeAllCookies.accesskey=A +removeAllShownCookies.label=Remove All Shown +removeAllShownCookies.accesskey=A + +# LOCALIZATION NOTE (removeSelectedCookies): +# Semicolon-separated list of plural forms. See: +# http://developer.mozilla.org/en/docs/Localization_and_Plurals +# If you need to display the number of selected elements in your language, +# you can use #1 in your localization as a placeholder for the number. +# For example this is the English string with numbers: +# removeSelectedCookied=Remove #1 Selected;Remove #1 Selected +removeSelectedCookies.label=Remove Selected;Remove Selected +removeSelectedCookies.accesskey=R + #### Offline apps offlineAppRemoveTitle=Remove offline website data -offlineAppRemovePrompt=After removing this data, %S will not be available offline. Are you sure you want to remove this offline website? +offlineAppRemovePrompt=After removing this data, %S will not be available offline. Are you sure you want to remove this offline website? offlineAppRemoveConfirm=Remove offline data # LOCALIZATION NOTE: The next string is for the disk usage of the diff --git a/browser/components/preferences/cookies.js b/browser/components/preferences/cookies.js index 1042642da..921eee4c0 100644 --- a/browser/components/preferences/cookies.js +++ b/browser/components/preferences/cookies.js @@ -30,6 +30,11 @@ var gCookiesWindow = { this._bundle = document.getElementById("bundlePreferences"); this._tree = document.getElementById("cookiesList"); + let removeAllCookies = document.getElementById("removeAllCookies"); + removeAllCookies.setAttribute("accesskey", this._bundle.getString("removeAllCookies.accesskey")); + let removeSelectedCookies = document.getElementById("removeSelectedCookies"); + removeSelectedCookies.setAttribute("accesskey", this._bundle.getString("removeSelectedCookies.accesskey")); + this._populateList(true); document.getElementById("filter").focus(); @@ -582,7 +587,7 @@ var gCookiesWindow = { } } - let buttonLabel = this._bundle.getString("removeSelectedCookies"); + let buttonLabel = this._bundle.getString("removeSelectedCookies.label"); let removeSelectedCookies = document.getElementById("removeSelectedCookies"); removeSelectedCookies.label = PluralForm.get(selectedCookieCount, buttonLabel) .replace("#1", selectedCookieCount); @@ -894,7 +899,17 @@ var gCookiesWindow = { }, _updateRemoveAllButton: function gCookiesWindow__updateRemoveAllButton() { - document.getElementById("removeAllCookies").disabled = this._view._rowCount == 0; + let removeAllCookies = document.getElementById("removeAllCookies"); + removeAllCookies.disabled = this._view._rowCount == 0; + + let labelStringID = "removeAllCookies.label"; + let accessKeyStringID = "removeAllCookies.accesskey"; + if (this._view._filtered) { + labelStringID = "removeAllShownCookies.label"; + accessKeyStringID = "removeAllShownCookies.accesskey"; + } + removeAllCookies.setAttribute("label", this._bundle.getString(labelStringID)); + removeAllCookies.setAttribute("accesskey", this._bundle.getString(accessKeyStringID)); }, filter: function () { diff --git a/browser/components/preferences/cookies.xul b/browser/components/preferences/cookies.xul index cda6ea220..bd60d9346 100644 --- a/browser/components/preferences/cookies.xul +++ b/browser/components/preferences/cookies.xul @@ -96,10 +96,8 @@ <hbox align="end"> <hbox class="actionButtons" flex="1"> <button id="removeSelectedCookies" disabled="true" icon="clear" - accesskey="&button.removeSelectedCookies.accesskey;" oncommand="gCookiesWindow.deleteCookie();"/> <button id="removeAllCookies" disabled="true" icon="clear" - label="&button.removeAllCookies.label;" accesskey="&button.removeAllCookies.accesskey;" oncommand="gCookiesWindow.deleteAllCookies();"/> <spacer flex="1"/> #ifndef XP_MACOSX diff --git a/browser/locales/en-US/chrome/browser/preferences/cookies.dtd b/browser/locales/en-US/chrome/browser/preferences/cookies.dtd index 9dfafffa5..5e7df9609 100644 --- a/browser/locales/en-US/chrome/browser/preferences/cookies.dtd +++ b/browser/locales/en-US/chrome/browser/preferences/cookies.dtd @@ -7,13 +7,6 @@ <!ENTITY cookiesonsystem.label "The following cookies are stored on your computer:"> <!ENTITY cookiename.label "Cookie Name"> <!ENTITY cookiedomain.label "Site"> -<!-- LOCALIZATION NOTE (button.removeSelectedCookies.accesskey): - The label associated with this accesskey can be found in - preferences.properties as removeSelectedCookies. ---> -<!ENTITY button.removeSelectedCookies.accesskey "R"> -<!ENTITY button.removeAllCookies.label "Remove All"> -<!ENTITY button.removeAllCookies.accesskey "A"> <!ENTITY props.name.label "Name:"> <!ENTITY props.value.label "Content:"> diff --git a/browser/locales/en-US/chrome/browser/preferences/preferences.properties b/browser/locales/en-US/chrome/browser/preferences/preferences.properties index bf9ac602b..da40f40a9 100644 --- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties +++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties @@ -21,7 +21,7 @@ acceptVeryLargeMinimumFont=Keep my changes anyway trackingprotectionpermissionstext=You have disabled Tracking Protection on these sites. trackingprotectionpermissionstitle=Exceptions - Tracking Protection -cookiepermissionstext=You can specify which websites are always or never allowed to use cookies. Type the exact address of the site you want to manage and then click Block, Allow for Session, or Allow. +cookiepermissionstext=You can specify which websites are always or never allowed to use cookies. Type the exact address of the site you want to manage and then click Block, Allow for Session, or Allow. cookiepermissionstitle=Exceptions - Cookies addonspermissionstext=You can specify which websites are allowed to install add-ons. Type the exact address of the site you want to allow and then click Allow. addons_permissions_title=Allowed Sites - Add-ons Installation @@ -123,6 +123,18 @@ cannot=Block noCookieSelected=<no cookie selected> cookiesAll=The following cookies are stored on your computer: cookiesFiltered=The following cookies match your search: + +# LOCALIZATION NOTE (removeAllCookies, removeAllShownCookies): +# removeAllCookies and removeAllShownCookies are both used on the same one button, +# never displayed together and can share the same accesskey. +# When only partial cookies are shown as a result of keyword search, +# removeAllShownCookies is displayed as button label. +# removeAllCookies is displayed when no keyword search and all cookies are shown. +removeAllCookies.label=Remove All +removeAllCookies.accesskey=A +removeAllShownCookies.label=Remove All Shown +removeAllShownCookies.accesskey=A + # LOCALIZATION NOTE (removeSelectedCookies): # Semicolon-separated list of plural forms. See: # http://developer.mozilla.org/en/docs/Localization_and_Plurals @@ -130,13 +142,15 @@ cookiesFiltered=The following cookies match your search: # you can use #1 in your localization as a placeholder for the number. # For example this is the English string with numbers: # removeSelectedCookied=Remove #1 Selected;Remove #1 Selected -removeSelectedCookies=Remove Selected;Remove Selected +removeSelectedCookies.label=Remove Selected;Remove Selected +removeSelectedCookies.accesskey=R + defaultUserContextLabel=None #### Offline apps offlineAppsList.height=7em offlineAppRemoveTitle=Remove offline website data -offlineAppRemovePrompt=After removing this data, %S will not be available offline. Are you sure you want to remove this offline website? +offlineAppRemovePrompt=After removing this data, %S will not be available offline. Are you sure you want to remove this offline website? offlineAppRemoveConfirm=Remove offline data # LOCALIZATION NOTE: The next string is for the disk usage of the diff --git a/security/nss/lib/softoken/sftkpwd.c b/security/nss/lib/softoken/sftkpwd.c index 68f6e4152..0b8c91bfd 100644 --- a/security/nss/lib/softoken/sftkpwd.c +++ b/security/nss/lib/softoken/sftkpwd.c @@ -273,7 +273,7 @@ sftkdb_EncryptAttribute(PLArenaPool *arena, SECItem *passKey, RNG_GenerateGlobalRandomBytes(saltData, cipherValue.salt.len); param = nsspkcs5_NewParam(cipherValue.alg, HASH_AlgSHA1, &cipherValue.salt, - 30000); + 1); if (param == NULL) { rv = SECFailure; goto loser; @@ -444,7 +444,7 @@ sftkdb_SignAttribute(PLArenaPool *arena, SECItem *passKey, RNG_GenerateGlobalRandomBytes(saltData, prfLength); /* initialize our pkcs5 parameter */ - param = nsspkcs5_NewParam(signValue.alg, HASH_AlgSHA1, &signValue.salt, 30000); + param = nsspkcs5_NewParam(signValue.alg, HASH_AlgSHA1, &signValue.salt, 1); if (param == NULL) { rv = SECFailure; goto loser; diff --git a/toolkit/components/passwordmgr/content/passwordManager.js b/toolkit/components/passwordmgr/content/passwordManager.js index 3fccb5d30..da63d7de8 100644 --- a/toolkit/components/passwordmgr/content/passwordManager.js +++ b/toolkit/components/passwordmgr/content/passwordManager.js @@ -80,6 +80,8 @@ function Startup() { togglePasswordsButton.label = kSignonBundle.getString("showPasswords"); togglePasswordsButton.accessKey = kSignonBundle.getString("showPasswordsAccessKey"); signonsIntro.textContent = kSignonBundle.getString("loginsDescriptionAll"); + removeAllButton.setAttribute("label", kSignonBundle.getString("removeAll.label")); + removeAllButton.setAttribute("accesskey", kSignonBundle.getString("removeAll.accesskey")); document.getElementsByTagName("treecols")[0].addEventListener("click", (event) => { let { target, button } = event; let sortField = target.getAttribute("data-field-name"); @@ -555,6 +557,8 @@ function SignonClearFilter() { signonsTreeView._lastSelectedRanges = []; signonsIntro.textContent = kSignonBundle.getString("loginsDescriptionAll"); + removeAllButton.setAttribute("label", kSignonBundle.getString("removeAll.label")); + removeAllButton.setAttribute("accesskey", kSignonBundle.getString("removeAll.accesskey")); } function FocusFilterBox() { @@ -623,6 +627,8 @@ function FilterPasswords() { signonsTreeView.selection.select(0); signonsIntro.textContent = kSignonBundle.getString("loginsDescriptionFiltered"); + removeAllButton.setAttribute("label", kSignonBundle.getString("removeAllShown.label")); + removeAllButton.setAttribute("accesskey", kSignonBundle.getString("removeAllShown.accesskey")); } function CopyPassword() { diff --git a/toolkit/components/passwordmgr/content/passwordManager.xul b/toolkit/components/passwordmgr/content/passwordManager.xul index 78dbd7ebc..c0a10bf8e 100644 --- a/toolkit/components/passwordmgr/content/passwordManager.xul +++ b/toolkit/components/passwordmgr/content/passwordManager.xul @@ -110,7 +110,6 @@ label="&remove.label;" accesskey="&remove.accesskey;" oncommand="DeleteSignon();"/> <button id="removeAllSignons" icon="clear" - label="&removeall.label;" accesskey="&removeall.accesskey;" oncommand="DeleteAllSignons();"/> <spacer flex="1"/> #if defined(MC_BASILISK) && defined(XP_WIN) diff --git a/toolkit/locales/en-US/chrome/passwordmgr/passwordManager.dtd b/toolkit/locales/en-US/chrome/passwordmgr/passwordManager.dtd index 36a61cfd9..84e4ff69c 100644 --- a/toolkit/locales/en-US/chrome/passwordmgr/passwordManager.dtd +++ b/toolkit/locales/en-US/chrome/passwordmgr/passwordManager.dtd @@ -17,8 +17,6 @@ <!ENTITY remove.label "Remove"> <!ENTITY remove.accesskey "R"> -<!ENTITY removeall.label "Remove All"> -<!ENTITY removeall.accesskey "A"> <!ENTITY addLogin.label "Add Login"> <!ENTITY addLogin.accesskey "L"> diff --git a/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties b/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties index 96190a2d7..6a399bbfc 100644 --- a/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties +++ b/toolkit/locales/en-US/chrome/passwordmgr/passwordmgr.properties @@ -68,3 +68,14 @@ duplicateLogin=A duplicate login already exists. insecureFieldWarningDescription = This connection is not secure. Logins entered here could be compromised. insecureFieldWarningLearnMore = Learn More + +# LOCALIZATION NOTE (removeAll, removeAllShown): +# removeAll and removeAllShown are both used on the same one button, +# never displayed together and can share the same accesskey. +# When only partial sites are shown as a result of keyword search, +# removeAllShown is displayed as button label. +# removeAll is displayed when no keyword search and all sites are shown. +removeAll.label=Remove All +removeAll.accesskey=A +removeAllShown.label=Remove All Shown +removeAllShown.accesskey=A |