tbb-commits
Threads by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 20638 discussions
[tor-browser/tor-browser-68.2.0esr-9.5-1] Bug 32220: Improve the letterboxing experience
by gk@torproject.org 06 Nov '19
by gk@torproject.org 06 Nov '19
06 Nov '19
commit ff8083901a19421e9a3f0dba5346bd6873fee956
Author: Richard Pospesel <richard(a)torproject.org>
Date: Mon Oct 28 17:42:17 2019 -0700
Bug 32220: Improve the letterboxing experience
CSS and JS changes to alter the UX surrounding letterboxing. The
browser element containing page content is now anchored to the bottom
of the toolbar, and the remaining letterbox margin is the same color
as the firefox chrome. The letterbox margin and border are tied to
the currently selected theme.
Also adds a 'needsLetterbox' property to tabbrowser.xml to fix a race
condition present when using the 'isEmpty' property. Using 'isEmpty'
as a proxy for 'needsLetterbox' resulted in over-zealous/unnecessary
letterboxing of about:blank tabs.
---
browser/base/content/browser.css | 7 ++
browser/base/content/tabbrowser.xml | 10 +++
browser/themes/shared/tabs.inc.css | 6 ++
.../components/resistfingerprinting/RFPHelper.jsm | 94 +++++++++++++++++++---
4 files changed, 105 insertions(+), 12 deletions(-)
diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css
index 8137435f9ed6..c5ca3de4a67f 100644
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -70,6 +70,13 @@
min-width: 25px;
}
+.browserStack > browser.letterboxing {
+ border-color: var(--chrome-content-separator-color);
+ border-style: solid;
+ border-width : 1px;
+ border-top: none;
+}
+
%ifdef MENUBAR_CAN_AUTOHIDE
#toolbar-menubar[autohide="true"] {
overflow: hidden;
diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml
index 3430b8a1d69d..dc1baa71f6c4 100644
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2090,6 +2090,16 @@
</getter>
</property>
+ <property name="needsLetterbox" readonly="true">
+ <getter>
+ let browser = this.linkedBrowser;
+ if (isBlankPageURL(browser.currentURI.spec))
+ return false;
+
+ return true;
+ </getter>
+ </property>
+
<property name="lastAccessed">
<getter>
return this._lastAccessed == Infinity ? Date.now() : this._lastAccessed;
diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css
index 7fc107e8d997..1e05b592d6c8 100644
--- a/browser/themes/shared/tabs.inc.css
+++ b/browser/themes/shared/tabs.inc.css
@@ -33,6 +33,12 @@
background-color: #f9f9fa;
}
+/* extend down the toolbar's colors when letterboxing is enabled*/
+#tabbrowser-tabpanels.letterboxing {
+ background-color: var(--toolbar-bgcolor);
+ background-image: var(--toolbar-bgimage);
+}
+
:root[privatebrowsingmode=temporary] #tabbrowser-tabpanels {
/* Value for --in-content-page-background in aboutPrivateBrowsing.css */
background-color: #25003e;
diff --git a/toolkit/components/resistfingerprinting/RFPHelper.jsm b/toolkit/components/resistfingerprinting/RFPHelper.jsm
index f73ccf1797b0..6c9306dc7bb3 100644
--- a/toolkit/components/resistfingerprinting/RFPHelper.jsm
+++ b/toolkit/components/resistfingerprinting/RFPHelper.jsm
@@ -41,6 +41,7 @@ class _RFPHelper {
// ============================================================================
constructor() {
this._initialized = false;
+ this._borderDimensions = null;
}
init() {
@@ -348,6 +349,24 @@ class _RFPHelper {
});
}
+ getBorderDimensions(aBrowser) {
+ if (this._borderDimensions) {
+ return this._borderDimensions;
+ }
+
+ const win = aBrowser.ownerGlobal;
+ const browserStyle = win.getComputedStyle(aBrowser);
+
+ this._borderDimensions = {
+ top : parseInt(browserStyle.borderTopWidth),
+ right: parseInt(browserStyle.borderRightWidth),
+ bottom : parseInt(browserStyle.borderBottomWidth),
+ left : parseInt(browserStyle.borderLeftWidth),
+ };
+
+ return this._borderDimensions;
+ }
+
_addOrClearContentMargin(aBrowser) {
let tab = aBrowser.getTabBrowser().getTabForBrowser(aBrowser);
@@ -356,9 +375,13 @@ class _RFPHelper {
return;
}
+ // we add the letterboxing class even if the content does not need letterboxing
+ // in which case margins are set such that the borders are hidden
+ aBrowser.classList.add("letterboxing");
+
// We should apply no margin around an empty tab or a tab with system
// principal.
- if (tab.isEmpty || aBrowser.contentPrincipal.isSystemPrincipal) {
+ if (!tab.needsLetterbox || aBrowser.contentPrincipal.isSystemPrincipal) {
this._clearContentViewMargin(aBrowser);
} else {
this._roundContentView(aBrowser);
@@ -523,10 +546,29 @@ class _RFPHelper {
// Calculating the margins around the browser element in order to round the
// content viewport. We will use a 200x100 stepping if the dimension set
// is not given.
- let margins = calcMargins(containerWidth, containerHeight);
+
+ const borderDimensions = this.getBorderDimensions(aBrowser);
+ const marginDims = calcMargins(containerWidth, containerHeight - borderDimensions.top);
+
+ let margins = {
+ top : 0,
+ right : 0,
+ bottom : 0,
+ left : 0,
+ };
+
+ // snap browser element to top
+ margins.top = 0;
+ // and leave 'double' margin at the bottom
+ margins.bottom = 2 * marginDims.height - borderDimensions.bottom;
+ // identical margins left and right
+ margins.right = marginDims.width - borderDimensions.right;
+ margins.left = marginDims.width - borderDimensions.left;
+
+ const marginStyleString = `${margins.top}px ${margins.right}px ${margins.bottom}px ${margins.left}px`;
// If the size of the content is already quantized, we do nothing.
- if (aBrowser.style.margin == `${margins.height}px ${margins.width}px`) {
+ if (aBrowser.style.margin === marginStyleString) {
log("_roundContentView[" + logId + "] is_rounded == true");
if (this._isLetterboxingTesting) {
log(
@@ -547,19 +589,35 @@ class _RFPHelper {
"_roundContentView[" +
logId +
"] setting margins to " +
- margins.width +
- " x " +
- margins.height
+ marginStyleString
);
- // One cannot (easily) control the color of a margin unfortunately.
- // An initial attempt to use a border instead of a margin resulted
- // in offset event dispatching; so for now we use a colorless margin.
- aBrowser.style.margin = `${margins.height}px ${margins.width}px`;
+
+ // The margin background color is determined by the background color of the
+ // window's tabpanels#tabbrowser-tabpanels element
+ aBrowser.style.margin = marginStyleString;
});
}
_clearContentViewMargin(aBrowser) {
+ const borderDimensions = this.getBorderDimensions(aBrowser);
+ // set the margins such that the browser elements border is visible up top, but
+ // are rendered off-screen on the remaining sides
+ let margins = {
+ top : 0,
+ right : -borderDimensions.right,
+ bottom : -borderDimensions.bottom,
+ left : -borderDimensions.left,
+ };
+ const marginStyleString = `${margins.top}px ${margins.right}px ${margins.bottom}px ${margins.left}px`;
+
+ aBrowser.ownerGlobal.requestAnimationFrame(() => {
+ aBrowser.style.margin = marginStyleString;
+ });
+ }
+
+ _removeLetterboxing(aBrowser) {
aBrowser.ownerGlobal.requestAnimationFrame(() => {
+ aBrowser.classList.remove("letterboxing");
aBrowser.style.margin = "";
});
}
@@ -581,6 +639,11 @@ class _RFPHelper {
this
);
+ const tabPanel = aWindow.document.getElementById("tabbrowser-tabpanels");
+ if (tabPanel) {
+ tabPanel.classList.add("letterboxing");
+ }
+
// Rounding the content viewport.
this._updateMarginsForTabsInWindow(aWindow);
}
@@ -608,10 +671,17 @@ class _RFPHelper {
this
);
- // Clear all margins and tooltip for all browsers.
+ // revert tabpanel's background colors to default
+ const tabPanel = aWindow.document.getElementById("tabbrowser-tabpanels");
+ if (tabPanel) {
+ tabPanel.classList.remove("letterboxing");
+ }
+
+ // and revert each browser element to default,
+ // restore default margins and remove letterboxing class
for (let tab of tabBrowser.tabs) {
let browser = tab.linkedBrowser;
- this._clearContentViewMargin(browser);
+ this._removeLetterboxing(browser);
}
}
1
0
[tor-browser/tor-browser-68.2.0esr-9.5-1] Revert "Bug 30683: Prevent detection of locale via some *.properties"
by gk@torproject.org 06 Nov '19
by gk@torproject.org 06 Nov '19
06 Nov '19
commit cb255f2504b37916160e886a181f1a02f85dba7c
Author: Alex Catarineu <acat(a)torproject.org>
Date: Tue Nov 5 10:53:21 2019 +0100
Revert "Bug 30683: Prevent detection of locale via some *.properties"
This reverts commit ab53cf71411a60ca56d5f6e24ec118802b8788df.
---
browser/installer/package-manifest.in | 3 ---
dom/base/nsContentUtils.cpp | 17 ++++-------------
dom/base/nsContentUtils.h | 4 ----
dom/html/HTMLSelectElement.cpp | 2 +-
dom/html/HTMLTextAreaElement.cpp | 6 +++---
dom/html/MediaDocument.cpp | 4 +---
dom/html/MediaDocument.h | 3 ---
dom/html/input/CheckableInputTypes.cpp | 4 ++--
dom/html/input/DateTimeInputTypes.cpp | 6 +++---
dom/html/input/FileInputType.cpp | 2 +-
dom/html/input/InputType.cpp | 16 ++++++++--------
dom/html/input/NumericInputTypes.cpp | 8 ++++----
dom/html/input/SingleLineTextInputTypes.cpp | 6 +++---
dom/locales/moz.build | 6 ------
mobile/android/installer/package-manifest.in | 3 ---
parser/htmlparser/nsParserMsgUtils.cpp | 6 ------
parser/htmlparser/nsParserMsgUtils.h | 3 ---
17 files changed, 30 insertions(+), 69 deletions(-)
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index 1825397678d1..1a2a24f9b5b9 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -345,9 +345,6 @@
@RESPATH@/res/dtd/*
@RESPATH@/res/language.properties
@RESPATH@/res/locale/layout/HtmlForm.properties
-@RESPATH@/res/locale/layout/MediaDocument.properties
-@RESPATH@/res/locale/layout/xmlparser.properties
-@RESPATH@/res/locale/dom/dom.properties
#ifdef XP_MACOSX
@RESPATH@/res/MainMenu.nib/
#endif
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index cfae3ef224b3..9c60c1befe1e 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3575,9 +3575,7 @@ static const char* gPropertiesFiles[nsContentUtils::PropertiesFile_COUNT] = {
"chrome://global/locale/security/security.properties",
"chrome://necko/locale/necko.properties",
"chrome://global/locale/layout/HtmlForm.properties",
- "resource://gre/res/locale/layout/HtmlForm.properties",
- "chrome://global/locale/dom/dom.properties",
- "resource://gre/res/locale/dom/dom.properties"};
+ "resource://gre/res/locale/layout/HtmlForm.properties"};
/* static */
nsresult nsContentUtils::EnsureStringBundle(PropertiesFile aFile) {
@@ -3626,8 +3624,7 @@ void nsContentUtils::AsyncPrecreateStringBundles() {
}
}
-/* static */
-bool nsContentUtils::SpoofLocaleEnglish() {
+static bool SpoofLocaleEnglish() {
// 0 - will prompt
// 1 - don't spoof
// 2 - spoof
@@ -3638,12 +3635,9 @@ bool nsContentUtils::SpoofLocaleEnglish() {
nsresult nsContentUtils::GetLocalizedString(PropertiesFile aFile,
const char* aKey,
nsAString& aResult) {
- // When we spoof English, use en-US properties in strings that are accessible
- // by content.
+ // When we spoof English, use en-US default strings in HTML forms.
if (aFile == eFORMS_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) {
aFile = eFORMS_PROPERTIES_en_US;
- } else if (aFile == eDOM_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) {
- aFile = eDOM_PROPERTIES_en_US;
}
nsresult rv = EnsureStringBundle(aFile);
@@ -3658,12 +3652,9 @@ nsresult nsContentUtils::FormatLocalizedString(PropertiesFile aFile,
const char16_t** aParams,
uint32_t aParamsLength,
nsAString& aResult) {
- // When we spoof English, use en-US properties in strings that are accessible
- // by content.
+ // When we spoof English, use en-US default strings in HTML forms.
if (aFile == eFORMS_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) {
aFile = eFORMS_PROPERTIES_en_US;
- } else if (aFile == eDOM_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) {
- aFile = eDOM_PROPERTIES_en_US;
}
nsresult rv = EnsureStringBundle(aFile);
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 2bf27250e68b..ee23a540871d 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1119,8 +1119,6 @@ class nsContentUtils {
eNECKO_PROPERTIES,
eFORMS_PROPERTIES_MAYBESPOOF,
eFORMS_PROPERTIES_en_US,
- eDOM_PROPERTIES_MAYBESPOOF,
- eDOM_PROPERTIES_en_US,
PropertiesFile_COUNT
};
static nsresult ReportToConsole(
@@ -1134,8 +1132,6 @@ class nsContentUtils {
static void LogMessageToConsole(const char* aMsg);
- static bool SpoofLocaleEnglish();
-
/**
* Get the localized string named |aKey| in properties file |aFile|.
*/
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index afa01ee224ba..76f21db23b31 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -1539,7 +1539,7 @@ nsresult HTMLSelectElement::GetValidationMessage(nsAString& aValidationMessage,
case VALIDITY_STATE_VALUE_MISSING: {
nsAutoString message;
nsresult rv = nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationSelectMissing",
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationSelectMissing",
message);
aValidationMessage = message;
return rv;
diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp
index 2844267b9bb8..0d1ba35c8b59 100644
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -1001,7 +1001,7 @@ nsresult HTMLTextAreaElement::GetValidationMessage(
const char16_t* params[] = {strMaxLength.get(), strTextLength.get()};
rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationTextTooLong", params,
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong", params,
message);
aValidationMessage = message;
} break;
@@ -1017,13 +1017,13 @@ nsresult HTMLTextAreaElement::GetValidationMessage(
const char16_t* params[] = {strMinLength.get(), strTextLength.get()};
rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationTextTooShort", params,
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooShort", params,
message);
aValidationMessage = message;
} break;
case VALIDITY_STATE_VALUE_MISSING: {
nsAutoString message;
- rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF,
+ rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationValueMissing",
message);
aValidationMessage = message;
diff --git a/dom/html/MediaDocument.cpp b/dom/html/MediaDocument.cpp
index 7ec66b31e63d..196adddc0f38 100644
--- a/dom/html/MediaDocument.cpp
+++ b/dom/html/MediaDocument.cpp
@@ -125,9 +125,7 @@ nsresult MediaDocument::Init() {
nsCOMPtr<nsIStringBundleService> stringService =
mozilla::services::GetStringBundleService();
if (stringService) {
- stringService->CreateBundle(nsContentUtils::SpoofLocaleEnglish()
- ? NSMEDIADOCUMENT_PROPERTIES_URI_en_US
- : NSMEDIADOCUMENT_PROPERTIES_URI,
+ stringService->CreateBundle(NSMEDIADOCUMENT_PROPERTIES_URI,
getter_AddRefs(mStringBundle));
}
diff --git a/dom/html/MediaDocument.h b/dom/html/MediaDocument.h
index 37e005c7fffa..e11fd2ec8551 100644
--- a/dom/html/MediaDocument.h
+++ b/dom/html/MediaDocument.h
@@ -16,9 +16,6 @@
#define NSMEDIADOCUMENT_PROPERTIES_URI \
"chrome://global/locale/layout/MediaDocument.properties"
-#define NSMEDIADOCUMENT_PROPERTIES_URI_en_US \
- "resource://gre/res/locale/layout/MediaDocument.properties"
-
namespace mozilla {
namespace dom {
diff --git a/dom/html/input/CheckableInputTypes.cpp b/dom/html/input/CheckableInputTypes.cpp
index f0306b69cbd0..f55000c766ea 100644
--- a/dom/html/input/CheckableInputTypes.cpp
+++ b/dom/html/input/CheckableInputTypes.cpp
@@ -23,7 +23,7 @@ bool CheckboxInputType::IsValueMissing() const {
}
nsresult CheckboxInputType::GetValueMissingMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF,
+ return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationCheckboxMissing",
aMessage);
}
@@ -32,5 +32,5 @@ nsresult CheckboxInputType::GetValueMissingMessage(nsAString& aMessage) {
nsresult RadioInputType::GetValueMissingMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationRadioMissing", aMessage);
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationRadioMissing", aMessage);
}
diff --git a/dom/html/input/DateTimeInputTypes.cpp b/dom/html/input/DateTimeInputTypes.cpp
index 0efbe9a9121a..11dfc9e541b9 100644
--- a/dom/html/input/DateTimeInputTypes.cpp
+++ b/dom/html/input/DateTimeInputTypes.cpp
@@ -138,7 +138,7 @@ nsresult DateTimeInputTypeBase::GetRangeOverflowMessage(nsAString& aMessage) {
const char16_t* params[] = {maxStr.get()};
return nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationDateTimeRangeOverflow",
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationDateTimeRangeOverflow",
params, aMessage);
}
@@ -148,7 +148,7 @@ nsresult DateTimeInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
const char16_t* params[] = {minStr.get()};
return nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationDateTimeRangeUnderflow",
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationDateTimeRangeUnderflow",
params, aMessage);
}
@@ -194,7 +194,7 @@ nsresult DateInputType::GetBadInputMessage(nsAString& aMessage) {
}
return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationInvalidDate", aMessage);
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidDate", aMessage);
}
bool DateInputType::ConvertStringToNumber(
diff --git a/dom/html/input/FileInputType.cpp b/dom/html/input/FileInputType.cpp
index 82a4c2de8659..2536a875b2ca 100644
--- a/dom/html/input/FileInputType.cpp
+++ b/dom/html/input/FileInputType.cpp
@@ -22,5 +22,5 @@ bool FileInputType::IsValueMissing() const {
nsresult FileInputType::GetValueMissingMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationFileMissing", aMessage);
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationFileMissing", aMessage);
}
diff --git a/dom/html/input/InputType.cpp b/dom/html/input/InputType.cpp
index f7a28f4c1a3a..210daeafad14 100644
--- a/dom/html/input/InputType.cpp
+++ b/dom/html/input/InputType.cpp
@@ -167,7 +167,7 @@ nsresult InputType::GetValidationMessage(
const char16_t* params[] = {strMaxLength.get(), strTextLength.get()};
rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationTextTooLong", params,
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong", params,
message);
aValidationMessage = message;
break;
@@ -185,7 +185,7 @@ nsresult InputType::GetValidationMessage(
const char16_t* params[] = {strMinLength.get(), strTextLength.get()};
rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationTextTooShort", params,
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooShort", params,
message);
aValidationMessage = message;
@@ -216,7 +216,7 @@ nsresult InputType::GetValidationMessage(
nsAutoString title;
mInputElement->GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
if (title.IsEmpty()) {
- rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF,
+ rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationPatternMismatch",
message);
} else {
@@ -227,7 +227,7 @@ nsresult InputType::GetValidationMessage(
}
const char16_t* params[] = {title.get()};
rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF,
+ nsContentUtils::eDOM_PROPERTIES,
"FormValidationPatternMismatchWithTitle", params, message);
}
aValidationMessage = message;
@@ -279,12 +279,12 @@ nsresult InputType::GetValidationMessage(
if (valueLowStr.Equals(valueHighStr)) {
const char16_t* params[] = {valueLowStr.get()};
rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF,
+ nsContentUtils::eDOM_PROPERTIES,
"FormValidationStepMismatchOneValue", params, message);
} else {
const char16_t* params[] = {valueLowStr.get(), valueHighStr.get()};
rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationStepMismatch",
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationStepMismatch",
params, message);
}
} else {
@@ -293,7 +293,7 @@ nsresult InputType::GetValidationMessage(
const char16_t* params[] = {valueLowStr.get()};
rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF,
+ nsContentUtils::eDOM_PROPERTIES,
"FormValidationStepMismatchOneValue", params, message);
}
@@ -319,7 +319,7 @@ nsresult InputType::GetValidationMessage(
nsresult InputType::GetValueMissingMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationValueMissing", aMessage);
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationValueMissing", aMessage);
}
nsresult InputType::GetTypeMismatchMessage(nsAString& aMessage) {
diff --git a/dom/html/input/NumericInputTypes.cpp b/dom/html/input/NumericInputTypes.cpp
index ab0f6f36eb95..6332e028c17e 100644
--- a/dom/html/input/NumericInputTypes.cpp
+++ b/dom/html/input/NumericInputTypes.cpp
@@ -73,7 +73,7 @@ nsresult NumericInputTypeBase::GetRangeOverflowMessage(nsAString& aMessage) {
const char16_t* params[] = {maxStr.get()};
return nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationNumberRangeOverflow",
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationNumberRangeOverflow",
params, aMessage);
}
@@ -90,7 +90,7 @@ nsresult NumericInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
const char16_t* params[] = {minStr.get()};
return nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationNumberRangeUnderflow",
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationNumberRangeUnderflow",
params, aMessage);
}
@@ -150,13 +150,13 @@ bool NumberInputType::HasBadInput() const {
}
nsresult NumberInputType::GetValueMissingMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF,
+ return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationBadInputNumber",
aMessage);
}
nsresult NumberInputType::GetBadInputMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF,
+ return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
"FormValidationBadInputNumber",
aMessage);
}
diff --git a/dom/html/input/SingleLineTextInputTypes.cpp b/dom/html/input/SingleLineTextInputTypes.cpp
index c879276c86da..15cbe65a1941 100644
--- a/dom/html/input/SingleLineTextInputTypes.cpp
+++ b/dom/html/input/SingleLineTextInputTypes.cpp
@@ -117,7 +117,7 @@ bool URLInputType::HasTypeMismatch() const {
nsresult URLInputType::GetTypeMismatchMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationInvalidURL", aMessage);
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidURL", aMessage);
}
/* input type=email */
@@ -155,12 +155,12 @@ bool EmailInputType::HasBadInput() const {
nsresult EmailInputType::GetTypeMismatchMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationInvalidEmail", aMessage);
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail", aMessage);
}
nsresult EmailInputType::GetBadInputMessage(nsAString& aMessage) {
return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES_MAYBESPOOF, "FormValidationInvalidEmail", aMessage);
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail", aMessage);
}
/* static */
diff --git a/dom/locales/moz.build b/dom/locales/moz.build
index 51f4b88ccd47..b2bcd271de7c 100644
--- a/dom/locales/moz.build
+++ b/dom/locales/moz.build
@@ -62,10 +62,4 @@ JAR_MANIFESTS += ['jar.mn']
RESOURCE_FILES.locale.layout += [
'en-US/chrome/layout/HtmlForm.properties',
- 'en-US/chrome/layout/MediaDocument.properties',
- 'en-US/chrome/layout/xmlparser.properties',
-]
-
-RESOURCE_FILES.locale.dom += [
- 'en-US/chrome/dom/dom.properties',
]
diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in
index 33e0175a624e..2002a894fc51 100644
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -203,9 +203,6 @@
@BINPATH@/res/dtd/*
@BINPATH@/res/language.properties
@BINPATH@/res/locale/layout/HtmlForm.properties
-@BINPATH@/res/locale/layout/MediaDocument.properties
-@BINPATH@/res/locale/layout/xmlparser.properties
-@BINPATH@/res/locale/dom/dom.properties
#ifndef MOZ_ANDROID_EXCLUDE_FONTS
@BINPATH@/res/fonts/*
diff --git a/parser/htmlparser/nsParserMsgUtils.cpp b/parser/htmlparser/nsParserMsgUtils.cpp
index 47749732839e..3e369893d4f7 100644
--- a/parser/htmlparser/nsParserMsgUtils.cpp
+++ b/parser/htmlparser/nsParserMsgUtils.cpp
@@ -9,7 +9,6 @@
#include "nsParserMsgUtils.h"
#include "nsNetCID.h"
#include "mozilla/Services.h"
-#include "nsContentUtils.h"
static nsresult GetBundle(const char* aPropFileName,
nsIStringBundle** aBundle) {
@@ -22,11 +21,6 @@ static nsresult GetBundle(const char* aPropFileName,
mozilla::services::GetStringBundleService();
if (!stringService) return NS_ERROR_FAILURE;
- if (nsContentUtils::SpoofLocaleEnglish() &&
- strcmp(aPropFileName, XMLPARSER_PROPERTIES) == 0) {
- aPropFileName = XMLPARSER_PROPERTIES_en_US;
- }
-
return stringService->CreateBundle(aPropFileName, aBundle);
}
diff --git a/parser/htmlparser/nsParserMsgUtils.h b/parser/htmlparser/nsParserMsgUtils.h
index 3645610385c1..b4ec4784d65f 100644
--- a/parser/htmlparser/nsParserMsgUtils.h
+++ b/parser/htmlparser/nsParserMsgUtils.h
@@ -11,9 +11,6 @@
#define XMLPARSER_PROPERTIES \
"chrome://global/locale/layout/xmlparser.properties"
-#define XMLPARSER_PROPERTIES_en_US \
- "resource://gre/res/locale/layout/xmlparser.properties"
-
class nsParserMsgUtils {
nsParserMsgUtils(); // Currently this is not meant to be created, use the
// static methods
1
0
[tor-browser/tor-browser-68.2.0esr-9.5-1] Bug 1581537 - Avoid several browser language leaks r=smaug
by gk@torproject.org 06 Nov '19
by gk@torproject.org 06 Nov '19
06 Nov '19
commit 79d87f543224b0e9d69a7520e25d9179d4f2c2bc
Author: Alex Catarineu <acat(a)torproject.org>
Date: Mon Nov 4 16:56:27 2019 +0000
Bug 1581537 - Avoid several browser language leaks r=smaug
Spoof dom/dom.properties, layout/xmlparser.properties,
layout/MediaDocument.properties to en-US if needed.
Differential Revision: https://phabricator.services.mozilla.com/D46034
--HG--
extra : moz-landing-system : lando
---
.../browser_misused_characters_in_strings.js | 6 +++
browser/installer/package-manifest.in | 3 ++
dom/base/Document.cpp | 8 ++-
dom/base/Document.h | 5 ++
dom/base/nsContentUtils.cpp | 55 +++++++++++++++-----
dom/base/nsContentUtils.h | 32 +++++++++++-
dom/html/HTMLInputElement.cpp | 40 ++++++++-------
dom/html/HTMLSelectElement.cpp | 4 +-
dom/html/HTMLTextAreaElement.cpp | 18 +++----
dom/html/ImageDocument.cpp | 7 ++-
dom/html/MediaDocument.cpp | 59 ++++++++++++++--------
dom/html/MediaDocument.h | 7 +++
dom/html/input/CheckableInputTypes.cpp | 11 ++--
dom/html/input/DateTimeInputTypes.cpp | 13 ++---
dom/html/input/FileInputType.cpp | 5 +-
dom/html/input/InputType.cpp | 42 ++++++++-------
dom/html/input/NumericInputTypes.cpp | 20 ++++----
dom/html/input/SingleLineTextInputTypes.cpp | 15 +++---
dom/locales/moz.build | 6 +++
layout/base/nsCSSFrameConstructor.cpp | 9 ++--
layout/forms/nsFileControlFrame.cpp | 4 +-
layout/forms/nsGfxButtonControlFrame.cpp | 4 +-
layout/generic/DetailsFrame.cpp | 6 +--
mobile/android/installer/package-manifest.in | 3 ++
parser/htmlparser/nsExpatDriver.cpp | 23 ++++++---
parser/htmlparser/nsParserMsgUtils.h | 3 ++
26 files changed, 272 insertions(+), 136 deletions(-)
diff --git a/browser/base/content/test/static/browser_misused_characters_in_strings.js b/browser/base/content/test/static/browser_misused_characters_in_strings.js
index 4b1d9a75d3bb..a9667b4feb96 100644
--- a/browser/base/content/test/static/browser_misused_characters_in_strings.js
+++ b/browser/base/content/test/static/browser_misused_characters_in_strings.js
@@ -99,6 +99,12 @@ let gWhitelist = [
key: "PatternAttributeCompileFailure",
type: "single-quote",
},
+ // dom.properties is packaged twice so we need to have two exceptions for this string.
+ {
+ file: "dom.properties",
+ key: "PatternAttributeCompileFailure",
+ type: "single-quote",
+ },
{
file: "netError.dtd",
key: "inadequateSecurityError.longDesc",
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index 1a2a24f9b5b9..1825397678d1 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -345,6 +345,9 @@
@RESPATH@/res/dtd/*
@RESPATH@/res/language.properties
@RESPATH@/res/locale/layout/HtmlForm.properties
+@RESPATH@/res/locale/layout/MediaDocument.properties
+@RESPATH@/res/locale/layout/xmlparser.properties
+@RESPATH@/res/locale/dom/dom.properties
#ifdef XP_MACOSX
@RESPATH@/res/MainMenu.nib/
#endif
diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp
index cdeabc4dc7b9..df9e7bd78e72 100644
--- a/dom/base/Document.cpp
+++ b/dom/base/Document.cpp
@@ -3231,7 +3231,7 @@ bool Document::DocumentSupportsL10n(JSContext* aCx, JSObject* aObject) {
}
void Document::LocalizationLinkAdded(Element* aLinkElement) {
- if (!nsContentUtils::PrincipalAllowsL10n(NodePrincipal(), GetDocumentURI())) {
+ if (!AllowsL10n()) {
return;
}
@@ -3262,7 +3262,7 @@ void Document::LocalizationLinkAdded(Element* aLinkElement) {
}
void Document::LocalizationLinkRemoved(Element* aLinkElement) {
- if (!nsContentUtils::PrincipalAllowsL10n(NodePrincipal(), GetDocumentURI())) {
+ if (!AllowsL10n()) {
return;
}
@@ -3314,6 +3314,10 @@ void Document::InitialDocumentTranslationCompleted() {
mPendingInitialTranslation = false;
}
+bool Document::AllowsL10n() const {
+ return nsContentUtils::PrincipalAllowsL10n(NodePrincipal(), GetDocumentURI());
+}
+
bool Document::IsWebAnimationsEnabled(JSContext* aCx, JSObject* /*unused*/) {
MOZ_ASSERT(NS_IsMainThread());
diff --git a/dom/base/Document.h b/dom/base/Document.h
index e65bb95d94c9..9c338b0bb153 100644
--- a/dom/base/Document.h
+++ b/dom/base/Document.h
@@ -3661,6 +3661,11 @@ class Document : public nsINode,
*/
virtual void InitialDocumentTranslationCompleted();
+ /**
+ * Returns whether the document allows localization.
+ */
+ bool AllowsL10n() const;
+
protected:
RefPtr<DocumentL10n> mDocumentL10n;
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 9c60c1befe1e..e75fd6c9af8b 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3574,8 +3574,8 @@ static const char* gPropertiesFiles[nsContentUtils::PropertiesFile_COUNT] = {
"chrome://global/locale/mathml/mathml.properties",
"chrome://global/locale/security/security.properties",
"chrome://necko/locale/necko.properties",
- "chrome://global/locale/layout/HtmlForm.properties",
- "resource://gre/res/locale/layout/HtmlForm.properties"};
+ "resource://gre/res/locale/layout/HtmlForm.properties",
+ "resource://gre/res/locale/dom/dom.properties"};
/* static */
nsresult nsContentUtils::EnsureStringBundle(PropertiesFile aFile) {
@@ -3624,22 +3624,47 @@ void nsContentUtils::AsyncPrecreateStringBundles() {
}
}
-static bool SpoofLocaleEnglish() {
+/* static */
+bool nsContentUtils::SpoofLocaleEnglish() {
// 0 - will prompt
// 1 - don't spoof
// 2 - spoof
return StaticPrefs::privacy_spoof_english() == 2;
}
+static nsContentUtils::PropertiesFile GetMaybeSpoofedPropertiesFile(
+ nsContentUtils::PropertiesFile aFile, const char* aKey,
+ Document* aDocument) {
+ // When we spoof English, use en-US properties in strings that are accessible
+ // by content.
+ bool spoofLocale = nsContentUtils::SpoofLocaleEnglish() &&
+ (!aDocument || !aDocument->AllowsL10n());
+ if (spoofLocale) {
+ switch (aFile) {
+ case nsContentUtils::eFORMS_PROPERTIES:
+ return nsContentUtils::eFORMS_PROPERTIES_en_US;
+ case nsContentUtils::eDOM_PROPERTIES:
+ return nsContentUtils::eDOM_PROPERTIES_en_US;
+ default:
+ break;
+ }
+ }
+ return aFile;
+}
+
+/* static */
+nsresult nsContentUtils::GetMaybeLocalizedString(PropertiesFile aFile,
+ const char* aKey,
+ Document* aDocument,
+ nsAString& aResult) {
+ return GetLocalizedString(
+ GetMaybeSpoofedPropertiesFile(aFile, aKey, aDocument), aKey, aResult);
+}
+
/* static */
nsresult nsContentUtils::GetLocalizedString(PropertiesFile aFile,
const char* aKey,
nsAString& aResult) {
- // When we spoof English, use en-US default strings in HTML forms.
- if (aFile == eFORMS_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) {
- aFile = eFORMS_PROPERTIES_en_US;
- }
-
nsresult rv = EnsureStringBundle(aFile);
NS_ENSURE_SUCCESS(rv, rv);
nsIStringBundle* bundle = sStringBundles[aFile];
@@ -3647,16 +3672,20 @@ nsresult nsContentUtils::GetLocalizedString(PropertiesFile aFile,
}
/* static */
+nsresult nsContentUtils::FormatMaybeLocalizedString(
+ PropertiesFile aFile, const char* aKey, Document* aDocument,
+ const char16_t** aParams, uint32_t aParamsLength, nsAString& aResult) {
+ return FormatLocalizedString(
+ GetMaybeSpoofedPropertiesFile(aFile, aKey, aDocument), aKey, aParams,
+ aParamsLength, aResult);
+}
+
+/* static */
nsresult nsContentUtils::FormatLocalizedString(PropertiesFile aFile,
const char* aKey,
const char16_t** aParams,
uint32_t aParamsLength,
nsAString& aResult) {
- // When we spoof English, use en-US default strings in HTML forms.
- if (aFile == eFORMS_PROPERTIES_MAYBESPOOF && SpoofLocaleEnglish()) {
- aFile = eFORMS_PROPERTIES_en_US;
- }
-
nsresult rv = EnsureStringBundle(aFile);
NS_ENSURE_SUCCESS(rv, rv);
nsIStringBundle* bundle = sStringBundles[aFile];
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index ee23a540871d..5b1eefef3854 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -1117,8 +1117,8 @@ class nsContentUtils {
eMATHML_PROPERTIES,
eSECURITY_PROPERTIES,
eNECKO_PROPERTIES,
- eFORMS_PROPERTIES_MAYBESPOOF,
eFORMS_PROPERTIES_en_US,
+ eDOM_PROPERTIES_en_US,
PropertiesFile_COUNT
};
static nsresult ReportToConsole(
@@ -1132,6 +1132,8 @@ class nsContentUtils {
static void LogMessageToConsole(const char* aMsg);
+ static bool SpoofLocaleEnglish();
+
/**
* Get the localized string named |aKey| in properties file |aFile|.
*/
@@ -1139,6 +1141,15 @@ class nsContentUtils {
nsAString& aResult);
/**
+ * Same as GetLocalizedString, except that it might use en-US locale depending
+ * on SpoofLocaleEnglish() and whether the document is a built-in browser
+ * page.
+ */
+ static nsresult GetMaybeLocalizedString(PropertiesFile aFile,
+ const char* aKey, Document* aDocument,
+ nsAString& aResult);
+
+ /**
* A helper function that parses a sandbox attribute (of an <iframe> or a CSP
* directive) and converts it to the set of flags used internally.
*
@@ -1210,6 +1221,15 @@ class nsContentUtils {
uint32_t aParamsLength,
nsAString& aResult);
+ /**
+ * Same as FormatLocalizedString, except that it might use en-US locale
+ * depending on SpoofLocaleEnglish() and whether the document is a built-in
+ * browser page.
+ */
+ static nsresult FormatMaybeLocalizedString(
+ PropertiesFile aFile, const char* aKey, Document* aDocument,
+ const char16_t** aParams, uint32_t aParamsLength, nsAString& aResult);
+
public:
template <uint32_t N>
static nsresult FormatLocalizedString(PropertiesFile aFile, const char* aKey,
@@ -1218,6 +1238,16 @@ class nsContentUtils {
return FormatLocalizedString(aFile, aKey, aParams, N, aResult);
}
+ template <uint32_t N>
+ static nsresult FormatMaybeLocalizedString(PropertiesFile aFile,
+ const char* aKey,
+ Document* aDocument,
+ const char16_t* (&aParams)[N],
+ nsAString& aResult) {
+ return FormatMaybeLocalizedString(aFile, aKey, aDocument, aParams, N,
+ aResult);
+ }
+
/**
* Fill (with the parameters given) the localized string named |aKey| in
* properties file |aFile| consuming an nsTArray of nsString parameters rather
diff --git a/dom/html/HTMLInputElement.cpp b/dom/html/HTMLInputElement.cpp
index dd0365a7646c..3217c78a2757 100644
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -725,15 +725,16 @@ nsresult HTMLInputElement::InitFilePicker(FilePickerType aType) {
nsAutoString title;
nsAutoString okButtonLabel;
if (aType == FILE_PICKER_DIRECTORY) {
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "DirectoryUpload", title);
+ nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "DirectoryUpload", OwnerDoc(),
+ title);
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF,
- "DirectoryPickerOkButtonLabel", okButtonLabel);
+ nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "DirectoryPickerOkButtonLabel",
+ OwnerDoc(), okButtonLabel);
} else {
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "FileUpload", title);
+ nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "FileUpload", OwnerDoc(), title);
}
nsCOMPtr<nsIFilePicker> filePicker =
@@ -2339,24 +2340,25 @@ void HTMLInputElement::GetDisplayFileName(nsAString& aValue) const {
if ((IsDirPickerEnabled() && Allowdirs()) ||
(StaticPrefs::dom_webkitBlink_dirPicker_enabled() &&
HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) {
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "NoDirSelected", value);
+ nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "NoDirSelected", OwnerDoc(),
+ value);
} else if (HasAttr(kNameSpaceID_None, nsGkAtoms::multiple)) {
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "NoFilesSelected",
- value);
+ nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "NoFilesSelected", OwnerDoc(),
+ value);
} else {
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "NoFileSelected",
- value);
+ nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "NoFileSelected", OwnerDoc(),
+ value);
}
} else {
nsString count;
count.AppendInt(int(mFileData->mFilesOrDirectories.Length()));
const char16_t* params[] = {count.get()};
- nsContentUtils::FormatLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "XFilesSelected", params,
+ nsContentUtils::FormatMaybeLocalizedString(
+ nsContentUtils::eFORMS_PROPERTIES, "XFilesSelected", OwnerDoc(), params,
value);
}
@@ -5828,8 +5830,8 @@ HTMLInputElement::SubmitNamesValues(HTMLFormSubmission* aFormSubmission) {
!HasAttr(kNameSpaceID_None, nsGkAtoms::value)) {
// Get our default value, which is the same as our default label
nsAutoString defaultValue;
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "Submit", defaultValue);
+ nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "Submit", OwnerDoc(), defaultValue);
value = defaultValue;
}
diff --git a/dom/html/HTMLSelectElement.cpp b/dom/html/HTMLSelectElement.cpp
index 76f21db23b31..a7a93468af02 100644
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -1538,9 +1538,9 @@ nsresult HTMLSelectElement::GetValidationMessage(nsAString& aValidationMessage,
switch (aType) {
case VALIDITY_STATE_VALUE_MISSING: {
nsAutoString message;
- nsresult rv = nsContentUtils::GetLocalizedString(
+ nsresult rv = nsContentUtils::GetMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationSelectMissing",
- message);
+ OwnerDoc(), message);
aValidationMessage = message;
return rv;
}
diff --git a/dom/html/HTMLTextAreaElement.cpp b/dom/html/HTMLTextAreaElement.cpp
index 0d1ba35c8b59..5a5a81545142 100644
--- a/dom/html/HTMLTextAreaElement.cpp
+++ b/dom/html/HTMLTextAreaElement.cpp
@@ -1000,9 +1000,9 @@ nsresult HTMLTextAreaElement::GetValidationMessage(
strTextLength.AppendInt(textLength);
const char16_t* params[] = {strMaxLength.get(), strTextLength.get()};
- rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong", params,
- message);
+ rv = nsContentUtils::FormatMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong",
+ OwnerDoc(), params, message);
aValidationMessage = message;
} break;
case VALIDITY_STATE_TOO_SHORT: {
@@ -1016,16 +1016,16 @@ nsresult HTMLTextAreaElement::GetValidationMessage(
strTextLength.AppendInt(textLength);
const char16_t* params[] = {strMinLength.get(), strTextLength.get()};
- rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooShort", params,
- message);
+ rv = nsContentUtils::FormatMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooShort",
+ OwnerDoc(), params, message);
aValidationMessage = message;
} break;
case VALIDITY_STATE_VALUE_MISSING: {
nsAutoString message;
- rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
- "FormValidationValueMissing",
- message);
+ rv = nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationValueMissing",
+ OwnerDoc(), message);
aValidationMessage = message;
} break;
default:
diff --git a/dom/html/ImageDocument.cpp b/dom/html/ImageDocument.cpp
index 87b70961a386..2de785f5fb51 100644
--- a/dom/html/ImageDocument.cpp
+++ b/dom/html/ImageDocument.cpp
@@ -577,14 +577,13 @@ nsresult ImageDocument::OnLoadComplete(imgIRequest* aRequest,
UpdateTitleAndCharset();
// mImageContent can be null if the document is already destroyed
- if (NS_FAILED(aStatus) && mStringBundle && mImageContent) {
+ if (NS_FAILED(aStatus) && mImageContent) {
nsAutoCString src;
mDocumentURI->GetSpec(src);
NS_ConvertUTF8toUTF16 srcString(src);
const char16_t* formatString[] = {srcString.get()};
nsAutoString errorMsg;
- mStringBundle->FormatStringFromName("InvalidImage", formatString, 1,
- errorMsg);
+ FormatStringFromName("InvalidImage", formatString, 1, errorMsg);
mImageContent->SetAttr(kNameSpaceID_None, nsGkAtoms::alt, errorMsg, false);
}
@@ -788,7 +787,7 @@ void ImageDocument::UpdateTitleAndCharset() {
ratioStr.AppendInt(NSToCoordFloor(GetRatio() * 100));
const char16_t* formatString[1] = {ratioStr.get()};
- mStringBundle->FormatStringFromName("ScaledImage", formatString, 1, status);
+ FormatStringFromName("ScaledImage", formatString, 1, status);
}
static const char* const formatNames[4] = {
diff --git a/dom/html/MediaDocument.cpp b/dom/html/MediaDocument.cpp
index 196adddc0f38..48d209d67b11 100644
--- a/dom/html/MediaDocument.cpp
+++ b/dom/html/MediaDocument.cpp
@@ -121,14 +121,6 @@ nsresult MediaDocument::Init() {
nsresult rv = nsHTMLDocument::Init();
NS_ENSURE_SUCCESS(rv, rv);
- // Create a bundle for the localization
- nsCOMPtr<nsIStringBundleService> stringService =
- mozilla::services::GetStringBundleService();
- if (stringService) {
- stringService->CreateBundle(NSMEDIADOCUMENT_PROPERTIES_URI,
- getter_AddRefs(mStringBundle));
- }
-
mIsSyntheticDocument = true;
return NS_OK;
@@ -327,6 +319,38 @@ nsresult MediaDocument::LinkScript(const nsAString& aScript) {
return head->AppendChildTo(script, false);
}
+void MediaDocument::FormatStringFromName(const char* aName,
+ const char16_t** aParams,
+ uint32_t aLength, nsAString& aResult) {
+ bool spoofLocale = nsContentUtils::SpoofLocaleEnglish() && !AllowsL10n();
+ if (!spoofLocale) {
+ if (!mStringBundle) {
+ nsCOMPtr<nsIStringBundleService> stringService =
+ mozilla::services::GetStringBundleService();
+ if (stringService) {
+ stringService->CreateBundle(NSMEDIADOCUMENT_PROPERTIES_URI,
+ getter_AddRefs(mStringBundle));
+ }
+ }
+ if (mStringBundle) {
+ mStringBundle->FormatStringFromName(aName, aParams, aLength, aResult);
+ }
+ } else {
+ if (!mStringBundleEnglish) {
+ nsCOMPtr<nsIStringBundleService> stringService =
+ mozilla::services::GetStringBundleService();
+ if (stringService) {
+ stringService->CreateBundle(NSMEDIADOCUMENT_PROPERTIES_URI_en_US,
+ getter_AddRefs(mStringBundleEnglish));
+ }
+ }
+ if (mStringBundleEnglish) {
+ mStringBundleEnglish->FormatStringFromName(aName, aParams, aLength,
+ aResult);
+ }
+ }
+}
+
void MediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
nsIChannel* aChannel,
const char* const* aFormatNames,
@@ -338,7 +362,6 @@ void MediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
NS_ConvertASCIItoUTF16 typeStr(aTypeStr);
nsAutoString title;
- if (mStringBundle) {
// if we got a valid size (not all media have a size)
if (aWidth != 0 && aHeight != 0) {
nsAutoString widthStr;
@@ -349,27 +372,24 @@ void MediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
if (!fileStr.IsEmpty()) {
const char16_t* formatStrings[4] = {fileStr.get(), typeStr.get(),
widthStr.get(), heightStr.get()};
- mStringBundle->FormatStringFromName(aFormatNames[eWithDimAndFile],
- formatStrings, 4, title);
+ FormatStringFromName(aFormatNames[eWithDimAndFile], formatStrings, 4,
+ title);
} else {
const char16_t* formatStrings[3] = {typeStr.get(), widthStr.get(),
heightStr.get()};
- mStringBundle->FormatStringFromName(aFormatNames[eWithDim],
- formatStrings, 3, title);
+ FormatStringFromName(aFormatNames[eWithDim], formatStrings, 3, title);
}
} else {
// If we got a filename, display it
if (!fileStr.IsEmpty()) {
const char16_t* formatStrings[2] = {fileStr.get(), typeStr.get()};
- mStringBundle->FormatStringFromName(aFormatNames[eWithFile],
- formatStrings, 2, title);
+ FormatStringFromName(aFormatNames[eWithFile], formatStrings, 2, title);
} else {
const char16_t* formatStrings[1] = {typeStr.get()};
- mStringBundle->FormatStringFromName(aFormatNames[eWithNoInfo],
- formatStrings, 1, title);
+ FormatStringFromName(aFormatNames[eWithNoInfo], formatStrings, 1,
+ title);
}
}
- }
// set it on the document
if (aStatus.IsEmpty()) {
@@ -379,8 +399,7 @@ void MediaDocument::UpdateTitleAndCharset(const nsACString& aTypeStr,
nsAutoString titleWithStatus;
const nsPromiseFlatString& status = PromiseFlatString(aStatus);
const char16_t* formatStrings[2] = {title.get(), status.get()};
- mStringBundle->FormatStringFromName("TitleWithStatus", formatStrings, 2,
- titleWithStatus);
+ FormatStringFromName("TitleWithStatus", formatStrings, 2, titleWithStatus);
IgnoredErrorResult ignored;
SetTitle(titleWithStatus, ignored);
}
diff --git a/dom/html/MediaDocument.h b/dom/html/MediaDocument.h
index e11fd2ec8551..9c295e70d85f 100644
--- a/dom/html/MediaDocument.h
+++ b/dom/html/MediaDocument.h
@@ -16,6 +16,9 @@
#define NSMEDIADOCUMENT_PROPERTIES_URI \
"chrome://global/locale/layout/MediaDocument.properties"
+#define NSMEDIADOCUMENT_PROPERTIES_URI_en_US \
+ "resource://gre/res/locale/layout/MediaDocument.properties"
+
namespace mozilla {
namespace dom {
@@ -60,6 +63,9 @@ class MediaDocument : public nsHTMLDocument {
nsresult LinkStylesheet(const nsAString& aStylesheet);
nsresult LinkScript(const nsAString& aScript);
+ void FormatStringFromName(const char* aName, const char16_t** aParams,
+ uint32_t aLength, nsAString& aResult);
+
// |aFormatNames[]| needs to have four elements in the following order:
// a format name with neither dimension nor file, a format name with
// filename but w/o dimension, a format name with dimension but w/o filename,
@@ -77,6 +83,7 @@ class MediaDocument : public nsHTMLDocument {
const nsAString& aStatus = EmptyString());
nsCOMPtr<nsIStringBundle> mStringBundle;
+ nsCOMPtr<nsIStringBundle> mStringBundleEnglish;
static const char* const sFormatNames[4];
private:
diff --git a/dom/html/input/CheckableInputTypes.cpp b/dom/html/input/CheckableInputTypes.cpp
index f55000c766ea..c564c36b884a 100644
--- a/dom/html/input/CheckableInputTypes.cpp
+++ b/dom/html/input/CheckableInputTypes.cpp
@@ -23,14 +23,15 @@ bool CheckboxInputType::IsValueMissing() const {
}
nsresult CheckboxInputType::GetValueMissingMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
- "FormValidationCheckboxMissing",
- aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationCheckboxMissing",
+ mInputElement->OwnerDoc(), aMessage);
}
/* input type=radio */
nsresult RadioInputType::GetValueMissingMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationRadioMissing", aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationRadioMissing",
+ mInputElement->OwnerDoc(), aMessage);
}
diff --git a/dom/html/input/DateTimeInputTypes.cpp b/dom/html/input/DateTimeInputTypes.cpp
index 11dfc9e541b9..6d87313907f4 100644
--- a/dom/html/input/DateTimeInputTypes.cpp
+++ b/dom/html/input/DateTimeInputTypes.cpp
@@ -137,9 +137,9 @@ nsresult DateTimeInputTypeBase::GetRangeOverflowMessage(nsAString& aMessage) {
mInputElement->GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxStr);
const char16_t* params[] = {maxStr.get()};
- return nsContentUtils::FormatLocalizedString(
+ return nsContentUtils::FormatMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationDateTimeRangeOverflow",
- params, aMessage);
+ mInputElement->OwnerDoc(), params, aMessage);
}
nsresult DateTimeInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
@@ -147,9 +147,9 @@ nsresult DateTimeInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
mInputElement->GetAttr(kNameSpaceID_None, nsGkAtoms::min, minStr);
const char16_t* params[] = {minStr.get()};
- return nsContentUtils::FormatLocalizedString(
+ return nsContentUtils::FormatMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationDateTimeRangeUnderflow",
- params, aMessage);
+ mInputElement->OwnerDoc(), params, aMessage);
}
nsresult DateTimeInputTypeBase::MinMaxStepAttrChanged() {
@@ -193,8 +193,9 @@ nsresult DateInputType::GetBadInputMessage(nsAString& aMessage) {
return NS_ERROR_UNEXPECTED;
}
- return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidDate", aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidDate",
+ mInputElement->OwnerDoc(), aMessage);
}
bool DateInputType::ConvertStringToNumber(
diff --git a/dom/html/input/FileInputType.cpp b/dom/html/input/FileInputType.cpp
index 2536a875b2ca..856684080825 100644
--- a/dom/html/input/FileInputType.cpp
+++ b/dom/html/input/FileInputType.cpp
@@ -21,6 +21,7 @@ bool FileInputType::IsValueMissing() const {
}
nsresult FileInputType::GetValueMissingMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationFileMissing", aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationFileMissing",
+ mInputElement->OwnerDoc(), aMessage);
}
diff --git a/dom/html/input/InputType.cpp b/dom/html/input/InputType.cpp
index 210daeafad14..51dbe9b93527 100644
--- a/dom/html/input/InputType.cpp
+++ b/dom/html/input/InputType.cpp
@@ -166,9 +166,9 @@ nsresult InputType::GetValidationMessage(
strTextLength.AppendInt(textLength);
const char16_t* params[] = {strMaxLength.get(), strTextLength.get()};
- rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong", params,
- message);
+ rv = nsContentUtils::FormatMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooLong",
+ mInputElement->OwnerDoc(), params, message);
aValidationMessage = message;
break;
}
@@ -184,9 +184,9 @@ nsresult InputType::GetValidationMessage(
strTextLength.AppendInt(textLength);
const char16_t* params[] = {strMinLength.get(), strTextLength.get()};
- rv = nsContentUtils::FormatLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooShort", params,
- message);
+ rv = nsContentUtils::FormatMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationTextTooShort",
+ mInputElement->OwnerDoc(), params, message);
aValidationMessage = message;
break;
@@ -216,9 +216,9 @@ nsresult InputType::GetValidationMessage(
nsAutoString title;
mInputElement->GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
if (title.IsEmpty()) {
- rv = nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
- "FormValidationPatternMismatch",
- message);
+ rv = nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationPatternMismatch",
+ mInputElement->OwnerDoc(), message);
} else {
if (title.Length() >
nsIConstraintValidation::sContentSpecifiedMaxLengthMessage) {
@@ -226,9 +226,10 @@ nsresult InputType::GetValidationMessage(
nsIConstraintValidation::sContentSpecifiedMaxLengthMessage);
}
const char16_t* params[] = {title.get()};
- rv = nsContentUtils::FormatLocalizedString(
+ rv = nsContentUtils::FormatMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES,
- "FormValidationPatternMismatchWithTitle", params, message);
+ "FormValidationPatternMismatchWithTitle", mInputElement->OwnerDoc(),
+ params, message);
}
aValidationMessage = message;
break;
@@ -278,23 +279,25 @@ nsresult InputType::GetValidationMessage(
if (valueLowStr.Equals(valueHighStr)) {
const char16_t* params[] = {valueLowStr.get()};
- rv = nsContentUtils::FormatLocalizedString(
+ rv = nsContentUtils::FormatMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES,
- "FormValidationStepMismatchOneValue", params, message);
+ "FormValidationStepMismatchOneValue", mInputElement->OwnerDoc(),
+ params, message);
} else {
const char16_t* params[] = {valueLowStr.get(), valueHighStr.get()};
- rv = nsContentUtils::FormatLocalizedString(
+ rv = nsContentUtils::FormatMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationStepMismatch",
- params, message);
+ mInputElement->OwnerDoc(), params, message);
}
} else {
nsAutoString valueLowStr;
ConvertNumberToString(valueLow, valueLowStr);
const char16_t* params[] = {valueLowStr.get()};
- rv = nsContentUtils::FormatLocalizedString(
+ rv = nsContentUtils::FormatMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES,
- "FormValidationStepMismatchOneValue", params, message);
+ "FormValidationStepMismatchOneValue", mInputElement->OwnerDoc(),
+ params, message);
}
aValidationMessage = message;
@@ -318,8 +321,9 @@ nsresult InputType::GetValidationMessage(
}
nsresult InputType::GetValueMissingMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationValueMissing", aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationValueMissing",
+ mInputElement->OwnerDoc(), aMessage);
}
nsresult InputType::GetTypeMismatchMessage(nsAString& aMessage) {
diff --git a/dom/html/input/NumericInputTypes.cpp b/dom/html/input/NumericInputTypes.cpp
index 6332e028c17e..9770ccd416b1 100644
--- a/dom/html/input/NumericInputTypes.cpp
+++ b/dom/html/input/NumericInputTypes.cpp
@@ -72,9 +72,9 @@ nsresult NumericInputTypeBase::GetRangeOverflowMessage(nsAString& aMessage) {
MOZ_ASSERT(ok, "buf not big enough");
const char16_t* params[] = {maxStr.get()};
- return nsContentUtils::FormatLocalizedString(
+ return nsContentUtils::FormatMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationNumberRangeOverflow",
- params, aMessage);
+ mInputElement->OwnerDoc(), params, aMessage);
}
nsresult NumericInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
@@ -89,9 +89,9 @@ nsresult NumericInputTypeBase::GetRangeUnderflowMessage(nsAString& aMessage) {
MOZ_ASSERT(ok, "buf not big enough");
const char16_t* params[] = {minStr.get()};
- return nsContentUtils::FormatLocalizedString(
+ return nsContentUtils::FormatMaybeLocalizedString(
nsContentUtils::eDOM_PROPERTIES, "FormValidationNumberRangeUnderflow",
- params, aMessage);
+ mInputElement->OwnerDoc(), params, aMessage);
}
bool NumericInputTypeBase::ConvertStringToNumber(
@@ -150,15 +150,15 @@ bool NumberInputType::HasBadInput() const {
}
nsresult NumberInputType::GetValueMissingMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
- "FormValidationBadInputNumber",
- aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationBadInputNumber",
+ mInputElement->OwnerDoc(), aMessage);
}
nsresult NumberInputType::GetBadInputMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(nsContentUtils::eDOM_PROPERTIES,
- "FormValidationBadInputNumber",
- aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationBadInputNumber",
+ mInputElement->OwnerDoc(), aMessage);
}
bool NumberInputType::IsMutable() const {
diff --git a/dom/html/input/SingleLineTextInputTypes.cpp b/dom/html/input/SingleLineTextInputTypes.cpp
index 15cbe65a1941..090de7466fae 100644
--- a/dom/html/input/SingleLineTextInputTypes.cpp
+++ b/dom/html/input/SingleLineTextInputTypes.cpp
@@ -116,8 +116,9 @@ bool URLInputType::HasTypeMismatch() const {
}
nsresult URLInputType::GetTypeMismatchMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidURL", aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidURL",
+ mInputElement->OwnerDoc(), aMessage);
}
/* input type=email */
@@ -154,13 +155,15 @@ bool EmailInputType::HasBadInput() const {
}
nsresult EmailInputType::GetTypeMismatchMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail", aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail",
+ mInputElement->OwnerDoc(), aMessage);
}
nsresult EmailInputType::GetBadInputMessage(nsAString& aMessage) {
- return nsContentUtils::GetLocalizedString(
- nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail", aMessage);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eDOM_PROPERTIES, "FormValidationInvalidEmail",
+ mInputElement->OwnerDoc(), aMessage);
}
/* static */
diff --git a/dom/locales/moz.build b/dom/locales/moz.build
index b2bcd271de7c..51f4b88ccd47 100644
--- a/dom/locales/moz.build
+++ b/dom/locales/moz.build
@@ -62,4 +62,10 @@ JAR_MANIFESTS += ['jar.mn']
RESOURCE_FILES.locale.layout += [
'en-US/chrome/layout/HtmlForm.properties',
+ 'en-US/chrome/layout/MediaDocument.properties',
+ 'en-US/chrome/layout/xmlparser.properties',
+]
+
+RESOURCE_FILES.locale.dom += [
+ 'en-US/chrome/dom/dom.properties',
]
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index 7a5a96d1769a..491274c9b2a6 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -1654,8 +1654,8 @@ already_AddRefed<nsIContent> nsCSSFrameConstructor::CreateGeneratedContent(
}
nsAutoString temp;
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "Submit", temp);
+ nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eFORMS_PROPERTIES, "Submit", mDocument, temp);
return CreateGenConTextNode(aState, temp, nullptr, nullptr);
}
@@ -7899,8 +7899,9 @@ void nsCSSFrameConstructor::GetAlternateTextFor(Element* aElement, nsAtom* aTag,
// If there's no "value" attribute either, then use the localized string for
// "Submit" as the alternate text.
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "Submit", aAltText);
+ nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ "Submit", aElement->OwnerDoc(),
+ aAltText);
}
}
diff --git a/layout/forms/nsFileControlFrame.cpp b/layout/forms/nsFileControlFrame.cpp
index 9be30011aa8e..8da00f76dcea 100644
--- a/layout/forms/nsFileControlFrame.cpp
+++ b/layout/forms/nsFileControlFrame.cpp
@@ -215,8 +215,8 @@ static already_AddRefed<Element> MakeAnonButton(Document* aDoc,
// Set the file picking button text depending on the current locale.
nsAutoString buttonTxt;
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, labelKey, buttonTxt);
+ nsContentUtils::GetMaybeLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
+ labelKey, aDoc, buttonTxt);
// Set the browse button text. It's a bit of a pain to do because we want to
// make sure we are not notifying.
diff --git a/layout/forms/nsGfxButtonControlFrame.cpp b/layout/forms/nsGfxButtonControlFrame.cpp
index 03186ef7bf54..fa4219a5308f 100644
--- a/layout/forms/nsGfxButtonControlFrame.cpp
+++ b/layout/forms/nsGfxButtonControlFrame.cpp
@@ -88,8 +88,8 @@ nsresult nsGfxButtonControlFrame::GetDefaultLabel(nsAString& aString) const {
return NS_OK;
}
- return nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, prop, aString);
+ return nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eFORMS_PROPERTIES, prop, mContent->OwnerDoc(), aString);
}
nsresult nsGfxButtonControlFrame::GetLabel(nsString& aLabel) {
diff --git a/layout/generic/DetailsFrame.cpp b/layout/generic/DetailsFrame.cpp
index e1a9f0c70b2b..20f93b2f328f 100644
--- a/layout/generic/DetailsFrame.cpp
+++ b/layout/generic/DetailsFrame.cpp
@@ -98,9 +98,9 @@ nsresult DetailsFrame::CreateAnonymousContent(
mDefaultSummary = new HTMLSummaryElement(nodeInfo.forget());
nsAutoString defaultSummaryText;
- nsContentUtils::GetLocalizedString(
- nsContentUtils::eFORMS_PROPERTIES_MAYBESPOOF, "DefaultSummary",
- defaultSummaryText);
+ nsContentUtils::GetMaybeLocalizedString(
+ nsContentUtils::eFORMS_PROPERTIES, "DefaultSummary",
+ GetContent()->OwnerDoc(), defaultSummaryText);
RefPtr<nsTextNode> description = new nsTextNode(nodeInfoManager);
description->SetText(defaultSummaryText, false);
mDefaultSummary->AppendChildTo(description, false);
diff --git a/mobile/android/installer/package-manifest.in b/mobile/android/installer/package-manifest.in
index 2002a894fc51..33e0175a624e 100644
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -203,6 +203,9 @@
@BINPATH@/res/dtd/*
@BINPATH@/res/language.properties
@BINPATH@/res/locale/layout/HtmlForm.properties
+@BINPATH@/res/locale/layout/MediaDocument.properties
+@BINPATH@/res/locale/layout/xmlparser.properties
+@BINPATH@/res/locale/dom/dom.properties
#ifndef MOZ_ANDROID_EXCLUDE_FONTS
@BINPATH@/res/fonts/*
diff --git a/parser/htmlparser/nsExpatDriver.cpp b/parser/htmlparser/nsExpatDriver.cpp
index 73a0e65328f0..0c35f87bc321 100644
--- a/parser/htmlparser/nsExpatDriver.cpp
+++ b/parser/htmlparser/nsExpatDriver.cpp
@@ -673,12 +673,13 @@ static nsresult CreateErrorText(const char16_t* aDescription,
const char16_t* aSourceURL,
const uint32_t aLineNumber,
const uint32_t aColNumber,
- nsString& aErrorString) {
+ nsString& aErrorString, bool spoofEnglish) {
aErrorString.Truncate();
nsAutoString msg;
nsresult rv = nsParserMsgUtils::GetLocalizedStringByName(
- XMLPARSER_PROPERTIES, "XMLParsingError", msg);
+ spoofEnglish ? XMLPARSER_PROPERTIES_en_US : XMLPARSER_PROPERTIES,
+ "XMLParsingError", msg);
NS_ENSURE_SUCCESS(rv, rv);
// XML Parsing Error: %1$S\nLocation: %2$S\nLine Number %3$u, Column %4$u:
@@ -719,8 +720,15 @@ nsresult nsExpatDriver::HandleError() {
// Map Expat error code to an error string
// XXX Deal with error returns.
nsAutoString description;
- nsParserMsgUtils::GetLocalizedStringByID(XMLPARSER_PROPERTIES, code,
- description);
+ nsCOMPtr<Document> doc;
+ if (mOriginalSink) {
+ doc = do_QueryInterface(mOriginalSink->GetTarget());
+ }
+ bool spoofEnglish =
+ nsContentUtils::SpoofLocaleEnglish() && (!doc || !doc->AllowsL10n());
+ nsParserMsgUtils::GetLocalizedStringByID(
+ spoofEnglish ? XMLPARSER_PROPERTIES_en_US : XMLPARSER_PROPERTIES, code,
+ description);
if (code == XML_ERROR_TAG_MISMATCH) {
/**
@@ -756,8 +764,9 @@ nsresult nsExpatDriver::HandleError() {
tagName.Append(nameStart, (nameEnd ? nameEnd : pos) - nameStart);
nsAutoString msg;
- nsParserMsgUtils::GetLocalizedStringByName(XMLPARSER_PROPERTIES, "Expected",
- msg);
+ nsParserMsgUtils::GetLocalizedStringByName(
+ spoofEnglish ? XMLPARSER_PROPERTIES_en_US : XMLPARSER_PROPERTIES,
+ "Expected", msg);
// . Expected: </%S>.
nsAutoString message;
@@ -771,7 +780,7 @@ nsresult nsExpatDriver::HandleError() {
nsAutoString errorText;
CreateErrorText(description.get(), XML_GetBase(mExpatParser), lineNumber,
- colNumber, errorText);
+ colNumber, errorText, spoofEnglish);
nsAutoString sourceText(mLastLine);
AppendErrorPointer(colNumber, mLastLine.get(), sourceText);
diff --git a/parser/htmlparser/nsParserMsgUtils.h b/parser/htmlparser/nsParserMsgUtils.h
index b4ec4784d65f..3645610385c1 100644
--- a/parser/htmlparser/nsParserMsgUtils.h
+++ b/parser/htmlparser/nsParserMsgUtils.h
@@ -11,6 +11,9 @@
#define XMLPARSER_PROPERTIES \
"chrome://global/locale/layout/xmlparser.properties"
+#define XMLPARSER_PROPERTIES_en_US \
+ "resource://gre/res/locale/layout/xmlparser.properties"
+
class nsParserMsgUtils {
nsParserMsgUtils(); // Currently this is not meant to be created, use the
// static methods
1
0
commit eab41780abd544091ebb532b128c6d6d07087a70
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Nov 4 12:20:38 2019 +0000
Pick up better fix for #32342
---
rbm.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rbm.conf b/rbm.conf
index 8bd5805..727c09f 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -25,7 +25,7 @@ buildconf:
var:
torbrowser_version: '9.5a2'
- torbrowser_build: 'build3'
+ torbrowser_build: 'build4'
torbrowser_incremental_from:
- 9.5a1
project_name: tor-browser
1
0
[tor-browser-build/master] Bug 32342: Don't compress .ja files inside apks
by gk@torproject.org 04 Nov '19
by gk@torproject.org 04 Nov '19
04 Nov '19
commit 631ff5a05eda26da61f75f175c056142c171640a
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Nov 4 11:47:24 2019 +0100
Bug 32342: Don't compress .ja files inside apks
---
projects/tor-browser/build.android | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-browser/build.android b/projects/tor-browser/build.android
index 2c1c3b2..f8f3a8d 100644
--- a/projects/tor-browser/build.android
+++ b/projects/tor-browser/build.android
@@ -51,7 +51,7 @@ rm $apk
cd tmp
[% c('zip', {
zip_src => [ '.' ],
- zip_args => '$apk',
+ zip_args => '-n ja $apk',
}) %]
# Sign a QA build. This apk is not a debug version and doesn't contain a debug flag in the manifest
1
0
[tor-browser-build/master] Revert "Bug 32342 - Store omni.ja after recreating apk"
by gk@torproject.org 04 Nov '19
by gk@torproject.org 04 Nov '19
04 Nov '19
commit d8f62baa1d4436e90db842cc8ab42b4454b87684
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Nov 4 12:15:35 2019 +0100
Revert "Bug 32342 - Store omni.ja after recreating apk"
This reverts commit 3c7fb0e610a4f85d7b157221ac9049d99d958c24.
---
projects/tor-browser/build.android | 4 ----
1 file changed, 4 deletions(-)
diff --git a/projects/tor-browser/build.android b/projects/tor-browser/build.android
index 5148c36..2c1c3b2 100644
--- a/projects/tor-browser/build.android
+++ b/projects/tor-browser/build.android
@@ -54,9 +54,5 @@ cd tmp
zip_args => '$apk',
}) %]
-# omni.ja was likely deflated in the above zipping operation. It must be stored, instead.
-zip $apk -d assets/omni.ja
-zip -Z store $apk assets/omni.ja
-
# Sign a QA build. This apk is not a debug version and doesn't contain a debug flag in the manifest
java -jar /usr/share/apksigner/apksigner.jar sign --verbose --min-sdk-version [% c("var/android_min_api") %] --ks $rootdir/android-qa.keystore --out $qa_apk --in $apk --ks-key-alias androidqakey --key-pass pass:android --ks-pass pass:android
1
0
04 Nov '19
commit 1ff5c73b5a969f4b7ff1e9940fa976de7d66cd64
Author: Georg Koppen <gk(a)torproject.org>
Date: Mon Nov 4 12:15:01 2019 +0000
Pick up better fix for #32342
---
rbm.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rbm.conf b/rbm.conf
index dc43b62..e2e9c75 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -25,7 +25,7 @@ buildconf:
var:
torbrowser_version: '9.0.1'
- torbrowser_build: 'build1'
+ torbrowser_build: 'build2'
torbrowser_incremental_from:
- 9.0
project_name: tor-browser
1
0
[tor-browser-build/maint-9.0] Bug 32342: Don't compress .ja files inside apks
by gk@torproject.org 04 Nov '19
by gk@torproject.org 04 Nov '19
04 Nov '19
commit c13d170d9182d9f8809734995ae8cfdd721b5faf
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Nov 4 11:47:24 2019 +0100
Bug 32342: Don't compress .ja files inside apks
---
projects/tor-browser/build.android | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor-browser/build.android b/projects/tor-browser/build.android
index 2c1c3b2..f8f3a8d 100644
--- a/projects/tor-browser/build.android
+++ b/projects/tor-browser/build.android
@@ -51,7 +51,7 @@ rm $apk
cd tmp
[% c('zip', {
zip_src => [ '.' ],
- zip_args => '$apk',
+ zip_args => '-n ja $apk',
}) %]
# Sign a QA build. This apk is not a debug version and doesn't contain a debug flag in the manifest
1
0
[tor-browser-build/maint-9.0] Revert "Bug 32342 - Store omni.ja after recreating apk"
by gk@torproject.org 04 Nov '19
by gk@torproject.org 04 Nov '19
04 Nov '19
commit c80c3516ce9e4eada876fdcbb8361749097cd984
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Nov 4 11:45:27 2019 +0100
Revert "Bug 32342 - Store omni.ja after recreating apk"
This reverts commit f9d0383fb9e7585e8476029913c1a22572fa042e.
---
projects/tor-browser/build.android | 4 ----
1 file changed, 4 deletions(-)
diff --git a/projects/tor-browser/build.android b/projects/tor-browser/build.android
index 5148c36..2c1c3b2 100644
--- a/projects/tor-browser/build.android
+++ b/projects/tor-browser/build.android
@@ -54,9 +54,5 @@ cd tmp
zip_args => '$apk',
}) %]
-# omni.ja was likely deflated in the above zipping operation. It must be stored, instead.
-zip $apk -d assets/omni.ja
-zip -Z store $apk assets/omni.ja
-
# Sign a QA build. This apk is not a debug version and doesn't contain a debug flag in the manifest
java -jar /usr/share/apksigner/apksigner.jar sign --verbose --min-sdk-version [% c("var/android_min_api") %] --ks $rootdir/android-qa.keystore --out $qa_apk --in $apk --ks-key-alias androidqakey --key-pass pass:android --ks-pass pass:android
1
0
commit 2dfa0e0c9cff7cfad93664e0b0b6cdc05b24b7f2
Author: Alex Catarineu <acat(a)torproject.org>
Date: Sat Jun 8 15:10:01 2019 +0200
Remove cookie-jar-selector component
---
chrome.manifest | 5 -
chrome/content/torbutton.js | 18 +-
components/cookie-jar-selector.js | 460 ------------------------------------
components/startup-observer.js | 18 ++
defaults/preferences/preferences.js | 2 -
jar.mn | 5 -
6 files changed, 19 insertions(+), 489 deletions(-)
diff --git a/chrome.manifest b/chrome.manifest
index 13bef661..d1ffe6d6 100644
--- a/chrome.manifest
+++ b/chrome.manifest
@@ -143,9 +143,6 @@ contract @torproject.org/torbutton-extAppBlocker;1 {3da0269f-fc29-4e9e-a678-c3b1
component {06322def-6fde-4c06-aef6-47ae8e799629} components/startup-observer.js
contract @torproject.org/startup-observer;1 {06322def-6fde-4c06-aef6-47ae8e799629}
-component {e6204253-b690-4159-bfe8-d4eedab6b3be} components/cookie-jar-selector.js
-contract @torproject.org/cookie-jar-selector;1 {e6204253-b690-4159-bfe8-d4eedab6b3be}
-
component {5d57312b-5d8c-4169-b4af-e80d6a28a72e} components/torCheckService.js
contract @torproject.org/torbutton-torCheckService;1 {5d57312b-5d8c-4169-b4af-e80d6a28a72e}
@@ -155,8 +152,6 @@ contract @torproject.org/torbutton-logger;1 {f36d72c9-9718-4134-b550-e109638331d
component {e33fd6d4-270f-475f-a96f-ff3140279f68} components/domain-isolator.js
contract @torproject.org/domain-isolator;1 {e33fd6d4-270f-475f-a96f-ff3140279f68}
-category profile-after-change CookieJarSelector @torproject.org/cookie-jar-selector;1
-
category profile-after-change StartupObserver @torproject.org/startup-observer;1
category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
category profile-after-change DragDropFilter @torproject.org/torbutton-dragDropFilter;1
diff --git a/chrome/content/torbutton.js b/chrome/content/torbutton.js
index 9846b864..72636125 100644
--- a/chrome/content/torbutton.js
+++ b/chrome/content/torbutton.js
@@ -1039,16 +1039,7 @@ async function torbutton_do_new_identity() {
torbutton_log(3, "New Identity: Clearing Cookies and DOM Storage");
- if (m_tb_prefs.getBoolPref("extensions.torbutton.cookie_protections")) {
- var selector = Cc["@torproject.org/cookie-jar-selector;1"]
- .getService(Ci.nsISupports)
- .wrappedJSObject;
- // This emits "cookie-changed", "cleared", which kills DOM storage
- // and the safe browsing API key
- selector.clearUnprotectedCookies("tor");
- } else {
- torbutton_clear_cookies();
- }
+ torbutton_clear_cookies();
torbutton_log(3, "New Identity: Closing open connections");
@@ -1558,13 +1549,6 @@ function torbutton_check_protections()
document.getElementById("torbutton-checkForUpdate").hidden = false;
}
- var cookie_pref = m_tb_prefs.getBoolPref("extensions.torbutton.cookie_protections");
- document.getElementById("torbutton-cookie-protector").disabled = !cookie_pref;
-
- // XXX: Bug 14632: The cookie dialog is useless in private browsing mode in FF31ESR
- // See https://trac.torproject.org/projects/tor/ticket/10353 for more info.
- document.getElementById("torbutton-cookie-protector").hidden = m_tb_prefs.getBoolPref("browser.privatebrowsing.autostart");
-
if (!m_tb_control_pass || (!m_tb_control_ipc_file && !m_tb_control_port)) {
// TODO: Remove the Torbutton menu entry again once we have done our
// security control redesign.
diff --git a/components/cookie-jar-selector.js b/components/cookie-jar-selector.js
deleted file mode 100644
index 79a66e8a..00000000
--- a/components/cookie-jar-selector.js
+++ /dev/null
@@ -1,460 +0,0 @@
-// Bug 1506 P1: This component is currently only used to protect
-// user-selected cookies from deletion. Moreover, all the E4X code is
-// deprecated and needs to be replaced with JSON.
-
-/*************************************************************************
- * Cookie Jar Selector (JavaScript XPCOM component)
- * Enables selection of separate cookie jars for (more) anonymous browsing.
- * Designed as a component of FoxTor, http://cups.cs.cmu.edu/foxtor/
- * Copyright 2006, distributed under the same (open source) license as FoxTor
- *
- * Contributor(s):
- * Collin Jackson <mozilla(a)collinjackson.com>
- *
- *************************************************************************/
-
-// Module specific constants
-const kMODULE_NAME = "Cookie Jar Selector";
-const kMODULE_CONTRACTID = "@torproject.org/cookie-jar-selector;1";
-const kMODULE_CID = Components.ID("e6204253-b690-4159-bfe8-d4eedab6b3be");
-
-ChromeUtils.import("resource://torbutton/modules/default-prefs.js", {})
- .ensureDefaultPrefs();
-
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-function Cookie(number,name,value,isDomain,host,rawHost,HttpOnly,path,isSecure,isSession,
- expires,isProtected) {
- this.number = number;
- this.name = name;
- this.value = value;
- this.isDomain = isDomain;
- this.host = host;
- this.rawHost = rawHost;
- this.isHttpOnly = HttpOnly;
- this.path = path;
- this.isSecure = isSecure;
- this.isSession = isSession;
- this.expires = expires;
- this.isProtected = isProtected;
-}
-
-function CookieJarSelector() {
- this.logger = Cc["@torproject.org/torbutton-logger;1"]
- .getService(Ci.nsISupports).wrappedJSObject;
-
- this.logger.log(3, "Component Load 5: New CookieJarSelector " + kMODULE_CONTRACTID);
-
- this.prefs = Services.prefs;
-
- var getProfileFile = function(filename) {
- var loc = "ProfD"; // profile directory
- var file = Services.dirsvc
- .get(loc, Ci.nsIFile)
- .clone();
- file.append(filename);
- return file;
- };
-
- this.clearCookies = function() {
- try {
- Services.cookies.removeAll();
- } catch (e) {
- this.logger.log(4, "Cookie clearing exception: " + e);
- }
- };
-
- this._cookiesToJS = function(getSession) {
- var cookieManager = Services.cookies;
- var cookiesEnum = cookieManager.enumerator;
- var cookiesAsJS = [];
- var count = 0;
- while (cookiesEnum.hasMoreElements()) {
- var nextCookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
- var JSCookie = new Cookie(count++, nextCookie.name, nextCookie.value, nextCookie.isDomain, nextCookie.host,
- (nextCookie.host.charAt(0)==".") ? nextCookie.host.substring(1,nextCookie.host.length) : nextCookie.host,
- nextCookie.isHttpOnly, nextCookie.path, nextCookie.isSecure, nextCookie.isSession, nextCookie.expires,
- false);
- // Save either session or non-session cookies this time around:
- if (JSCookie.isSession && getSession ||
- !JSCookie.isSession && !getSession)
- cookiesAsJS.push(JSCookie);
- }
- return cookiesAsJS;
- };
-
- this._loadCookiesFromJS = function(cookiesAsJS) {
- if (typeof(cookiesAsJS) == "undefined" || !cookiesAsJS)
- return;
-
- var cookieManager = Services.cookies;
-
- for (var i = 0; i < cookiesAsJS.length; i++) {
- var cookie = cookiesAsJS[i];
- //this.logger.log(2, "Loading cookie: "+host+":"+cname+" until: "+expiry);
- cookieManager.add(cookie.host, cookie.path, cookie.name, cookie.value,
- cookie.isSecure, cookie.isHttpOnly, cookie.isSession,
- cookie.expires);
- }
- };
-
- this._cookiesToFile = function(name) {
- var file = getProfileFile("cookies-" + name + ".json");
- var foStream = Cc["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Ci.nsIFileOutputStream);
- foStream.init(file, 0x02 | 0x08 | 0x20, 0o666, 0);
- var data = JSON.stringify(this["cookiesobj-" + name]);
- foStream.write(data, data.length);
- foStream.close();
- };
-
- // Start1506
- this._protectedCookiesToFile = function(name) {
- var file = getProfileFile("protected-" + name + ".json");
- var foStream = Cc["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Ci.nsIFileOutputStream);
- foStream.init(file, 0x02 | 0x08 | 0x20, 0o666, 0);
- var data = JSON.stringify(this["protected-" + name]);
- foStream.write(data, data.length);
- foStream.close();
- };
-
- this.addProtectedCookie = function(cookie) {
- var name = "tor";
- var cookies = this.getProtectedCookies(name);
-
- if (typeof(cookies) == "undefined" || cookies == null
- || cookies.length == 0)
- cookies = [];
-
- if (cookie.isSession) {
- // session cookies get fucked up expiry. Give it 1yr if
- // the user wants to save their session cookies
- cookie.expires = Date.now()/1000 + 365*24*60*60;
- }
-
- cookies.push(cookie);
- this["protected-" + name] = cookies;
-
- if (!this.prefs.getBoolPref("browser.privatebrowsing.autostart")) {
- // save protected cookies to file
- this._protectedCookiesToFile(name);
- } else {
- try {
- var file = getProfileFile("protected-" + name + ".json");
- if (file.exists()) {
- file.remove(false);
- }
- } catch(e) {
- this.logger.log(5, "Can't remove "+name+" cookie file: "+e);
- }
- }
- };
-
- this.getProtectedCookies = function(name) {
- var file = getProfileFile("protected-" + name + ".json");
- if (!file.exists()) {
- return this["protected-" + name];
- }
- var data = "";
- var fstream = Cc["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Ci.nsIFileInputStream);
- var sstream = Cc["@mozilla.org/scriptableinputstream;1"]
- .createInstance(Ci.nsIScriptableInputStream);
- fstream.init(file, -1, 0, 0);
- sstream.init(fstream);
-
- var str = sstream.read(4096);
- while (str.length > 0) {
- data += str;
- str = sstream.read(4096);
- }
-
- sstream.close();
- fstream.close();
- try {
- var ret = JSON.parse(data);
- } catch(e) { // file has been corrupted; XXX: handle error differently
- this.logger.log(5, "Cookies corrupted: "+e);
- try {
- file.remove(false); //XXX: is it necessary to remove it ?
- var ret = null;
- } catch(e2) {
- this.logger.log(5, "Can't remove file "+e);
- }
- }
- return ret;
- };
-
- this.protectCookies = function(cookies) {
- var name = "tor";
- this._writeProtectCookies(cookies,name);
- if (!this.prefs.getBoolPref("browser.privatebrowsing.autostart")) {
- // save protected cookies to file
- this._protectedCookiesToFile(name);
- } else {
- try {
- var file = getProfileFile("protected-" + name + ".json");
- if (file.exists()) {
- file.remove(false);
- }
- } catch(e) {
- this.logger.log(5, "Can't remove "+name+" cookie file: "+e);
- }
- }
- };
-
- this._writeProtectCookies = function(cookies, name) {
- for (var i = 0; i < cookies.length; i++) {
- if (cookies[i].isSession) {
- // session cookies get fucked up expiry. Give it 1yr if
- // the user wants to save their session cookies
- cookies[i].expires = Date.now()/1000 + 365*24*60*60;
- }
- cookies[i].isProtected = true;
- }
- this["protected-" + name] = cookies;
- };
- // End1506
-
- this._cookiesFromFile = function(name) {
- var file = getProfileFile("cookies-" + name + ".json");
- if (!file.exists())
- return null;
- var data = "";
- var fstream = Cc["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Ci.nsIFileInputStream);
- var sstream = Cc["@mozilla.org/scriptableinputstream;1"]
- .createInstance(Ci.nsIScriptableInputStream);
- fstream.init(file, -1, 0, 0);
- sstream.init(fstream);
-
- var str = sstream.read(4096);
- while (str.length > 0) {
- data += str;
- str = sstream.read(4096);
- }
-
- sstream.close();
- fstream.close();
- try {
- var ret = JSON.parse(data);
- } catch(e) { // file has been corrupted; XXX: handle error differently
- this.logger.log(5, "Cookies corrupted: "+e);
- try {
- file.remove(false); //XXX: is it necessary to remove it ?
- var ret = null;
- } catch(e2) {
- this.logger.log(5, "Can't remove file "+e);
- }
- }
- return ret;
- };
-
- this.saveCookies = function(name) {
- // transition removes old tor-style cookie file
- try {
- var oldCookieFile = getProfileFile("cookies-"+name+".xml");
- if (oldCookieFile.exists()) {
- oldCookieFile.remove(false);
- }
- } catch(e) {
- this.logger.log(5, "Can't remove old "+name+" file "+e);
- }
-
- // save cookies to JS objects
- this["session-cookiesobj-" + name] = this._cookiesToJS(true);
- this["cookiesobj-" + name] = this._cookiesToJS(false);
-
- if (!this.prefs.getBoolPref("browser.privatebrowsing.autostart")) {
- // save cookies to file
- this._cookiesToFile(name);
- } else {
- // Clear the old file
- try {
- var file = getProfileFile("cookies-" + name + ".json");
- if (file.exists()) {
- file.remove(false);
- }
- } catch(e) {
- this.logger.log(5, "Can't remove "+name+" cookie file "+e);
- }
- }
-
- // ok, everything's fine
- this.logger.log(2, "Cookies saved");
- };
-
- // Start1506
- this.clearUnprotectedCookies = function(name) {
- try {
- var protCookies = this.getProtectedCookies(name);
- if (protCookies == null || typeof(protCookies) == "undefined"
- || protCookies.length == 0) {
- //file does not exist - no protected cookies. Clear them all.
- this.logger.log(3, "No protected cookies. Clearing all cookies.");
- this.clearCookies();
- return;
- }
- var cookiemanager = Services.cookies;
-
- var enumerator = cookiemanager.enumerator;
- var count = 0;
- var protcookie = false;
-
- while (enumerator.hasMoreElements()) {
- var nextCookie = enumerator.getNext();
- if (!nextCookie) break;
-
- nextCookie = nextCookie.QueryInterface(Ci.nsICookie);
- for (var i = 0; i < protCookies.length; i++) {
- protcookie = protcookie || (nextCookie.host == protCookies[i].host &&
- nextCookie.name == protCookies[i].name &&
- nextCookie.path == protCookies[i].path);
- }
-
- if (!protcookie) {
- cookiemanager.remove(nextCookie.host,
- nextCookie.name,
- nextCookie.path, false);
- } else {
- this.logger.log(3, "Found protected cookie for "+nextCookie.host);
- }
- protcookie = false;
- }
- // Emit cookie-changed event. This instructs other components to clear their identifiers
- // (Specifically DOM storage and safe browsing, but possibly others)
- var obsSvc = Services.obs;
- obsSvc.notifyObservers(this, "cookie-changed", "cleared");
- } catch (e) {
- this.logger.log(5, "Error deleting unprotected cookies: " + e);
- }
- };
- // End1506
-
- this.loadCookies = function(name, deleteSavedCookieJar) {
- // remove cookies before loading old ones
- this.clearCookies();
-
- if (!this.prefs.getBoolPref("browser.privatebrowsing.autostart")) {
- // load cookies from file
- this["cookiesobj-" + name] = this._cookiesFromFile(name);
- }
-
- //delete file if needed
- if (deleteSavedCookieJar) {
- try {
- var file = getProfileFile("cookies-" + name + ".json");
- if (file.exists())
- file.remove(false);
- } catch(e) {
- this.logger.log(5, "Can't remove saved "+name+" file "+e);
- }
- }
-
- // load cookies from JS objects
- this._loadCookiesFromJS(this["cookiesobj-"+name]);
- this._loadCookiesFromJS(this["session-cookiesobj-"+name]);
-
- // XXX: send a profile-do-change event?
-
- // ok, everything's fine
- this.logger.log(2, "Cookies reloaded");
- };
-
- // This JSObject is exported directly to chrome
- this.wrappedJSObject = this;
-
- // This timer is done so that in the event of a crash, we at least
- // have recent cookies in a jar to reload from.
- var jarThis = this;
- this.timerCallback = {
- cookie_changed: false,
-
- QueryInterface: ChromeUtils.generateQI(["nsITimer"]),
- notify() {
- // this refers to timerCallback object. use jarThis to reference
- // CookieJarSelector object.
- if(!this.cookie_changed) {
- jarThis.logger.log(2, "Got timer update, but no cookie change.");
- return;
- }
- jarThis.logger.log(3, "Got timer update. Saving changed cookies to jar.");
-
- this.cookie_changed = false;
-
- jarThis.saveCookies("tor");
- jarThis.logger.log(2, "Timer done. Cookies saved");
- }
- };
-
-}
-
-const nsIClassInfo = Ci.nsIClassInfo;
-const nsIObserver = Ci.nsIObserver;
-const nsITimer = Ci.nsITimer;
-
-// Start1506: You may or may not care about this:
-CookieJarSelector.prototype =
-{
- QueryInterface: ChromeUtils.generateQI(["nsIClassInfo", "nsIObserver"]),
-
- wrappedJSObject: null, // Initialized by constructor
-
- // make this an nsIClassInfo object
- flags: nsIClassInfo.DOM_OBJECT,
-
- _xpcom_categories: [{category:"profile-after-change"}],
- classID: kMODULE_CID,
- contractID: kMODULE_CONTRACTID,
- classDescription: "CookieJarSelector",
-
- // method of nsIClassInfo
- getInterfaces: function(count) {
- var interfaceList = [nsIClassInfo];
- count.value = interfaceList.length;
- return interfaceList;
- },
-
- // method of nsIClassInfo
- getHelperForLanguage: function(count) { return null; },
-
- // method of nsIObserver
- observe : function(aSubject, aTopic, aData) {
- switch(aTopic) {
- case "cookie-changed":
- var prefs = Services.prefs;
- this.timerCallback.cookie_changed = true;
-
- if (aData == "added"
- && prefs.getBoolPref("extensions.torbutton.cookie_auto_protect")
- && !prefs.getBoolPref("extensions.torbutton.tor_memory_jar")) {
- this.addProtectedCookie(aSubject.QueryInterface(Ci.nsICookie2));// protect the new cookie!
- }
- break;
- case "profile-after-change":
- var obsSvc = Services.obs;
- obsSvc.addObserver(this, "cookie-changed");
- // after profil loading, initialize a timer to call timerCallback
- // at a specified interval
- this.timer.initWithCallback(this.timerCallback, 60 * 1000, nsITimer.TYPE_REPEATING_SLACK); // 1 minute
- this.logger.log(3, "Cookie jar selector got profile-after-change");
- break;
- }
- },
-
- timer: Cc["@mozilla.org/timer;1"].createInstance(nsITimer),
-
-}
-
-/**
-* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
-* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
-*/
-if (XPCOMUtils.generateNSGetFactory)
- var NSGetFactory = XPCOMUtils.generateNSGetFactory([CookieJarSelector]);
-else
- var NSGetModule = XPCOMUtils.generateNSGetModule([CookieJarSelector]);
-
-// End1506
diff --git a/components/startup-observer.js b/components/startup-observer.js
index bf2f0f48..008134f8 100644
--- a/components/startup-observer.js
+++ b/components/startup-observer.js
@@ -29,6 +29,22 @@ const kMODULE_NAME = "Startup";
const kMODULE_CONTRACTID = "@torproject.org/startup-observer;1";
const kMODULE_CID = Components.ID("06322def-6fde-4c06-aef6-47ae8e799629");
+function cleanupCookies() {
+ const migratedPref = "extensions.torbutton.cookiejar_migrated";
+ if (!Services.prefs.getBoolPref(migratedPref, false)) {
+ // Cleanup stored cookie-jar-selector json files
+ const profileFolder = Services.dirsvc.get("ProfD", Ci.nsIFile).clone();
+ for (const file of profileFolder.directoryEntries) {
+ if (file.leafName.match(/^(cookies|protected)-.*[.]json$/)) {
+ try {
+ file.remove(false);
+ } catch (e) {}
+ }
+ }
+ Services.prefs.setBoolPref(migratedPref, true);
+ }
+}
+
function StartupObserver() {
this.logger = Cc["@torproject.org/torbutton-logger;1"]
.getService(Ci.nsISupports).wrappedJSObject;
@@ -62,6 +78,8 @@ function StartupObserver() {
this.logger.log(4, "Early proxy change failed. Will try again at profile load. Error: "+e);
}
+ cleanupCookies();
+
// Using all possible locales so that we do not have to change this list every time we support
// a new one.
const allLocales = [
diff --git a/defaults/preferences/preferences.js b/defaults/preferences/preferences.js
index acea0a3d..2d1bd99f 100644
--- a/defaults/preferences/preferences.js
+++ b/defaults/preferences/preferences.js
@@ -26,8 +26,6 @@ pref("extensions.torbutton.inserted_security_level",false);
pref("extensions.torbutton.maximize_warnings_remaining", 3);
// Security prefs:
-pref("extensions.torbutton.cookie_protections",true);
-pref("extensions.torbutton.cookie_auto_protect",false);
pref("extensions.torbutton.clear_http_auth",true);
pref("extensions.torbutton.close_newnym",true);
pref("extensions.torbutton.resize_new_windows",false);
diff --git a/jar.mn b/jar.mn
index 6697b543..8b6cbcf7 100644
--- a/jar.mn
+++ b/jar.mn
@@ -97,9 +97,6 @@ torbutton.jar:
% component {06322def-6fde-4c06-aef6-47ae8e799629} %components/startup-observer.js
% contract @torproject.org/startup-observer;1 {06322def-6fde-4c06-aef6-47ae8e799629}
-% component {e6204253-b690-4159-bfe8-d4eedab6b3be} %components/cookie-jar-selector.js
-% contract @torproject.org/cookie-jar-selector;1 {e6204253-b690-4159-bfe8-d4eedab6b3be}
-
% component {5d57312b-5d8c-4169-b4af-e80d6a28a72e} %components/torCheckService.js
% contract @torproject.org/torbutton-torCheckService;1 {5d57312b-5d8c-4169-b4af-e80d6a28a72e}
@@ -109,8 +106,6 @@ torbutton.jar:
% component {e33fd6d4-270f-475f-a96f-ff3140279f68} %components/domain-isolator.js
% contract @torproject.org/domain-isolator;1 {e33fd6d4-270f-475f-a96f-ff3140279f68}
-% category profile-after-change CookieJarSelector @torproject.org/cookie-jar-selector;1
-
% category profile-after-change StartupObserver @torproject.org/startup-observer;1
% category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
% category profile-after-change DragDropFilter @torproject.org/torbutton-dragDropFilter;1
1
0