Bug 1560038 - Switch Localization IDL to use UTF8String for L10nArgs r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D58858

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Zibi Braniecki 2020-03-10 18:04:55 +00:00
parent ee47c3b078
commit 603fc09fd5
7 changed files with 34 additions and 33 deletions

View File

@ -13,10 +13,10 @@
* The argument will be converted to/from JSON, and the API
* will only handle strings and numbers.
*/
typedef record<DOMString, (DOMString or double)?> L10nArgs;
typedef record<UTF8String, (UTF8String or double)?> L10nArgs;
dictionary L10nKey {
DOMString? id = null;
UTF8String? id = null;
L10nArgs? args = null;
};
@ -30,12 +30,12 @@ dictionary L10nKey {
* of a value and attributes will be used.
*/
dictionary AttributeNameValue {
required DOMString name;
required DOMString value;
required UTF8String name;
required UTF8String value;
};
dictionary L10nMessage {
DOMString? value = null;
UTF8String? value = null;
sequence<AttributeNameValue>? attributes = null;
};
@ -100,7 +100,7 @@ interface Localization {
* let value = await document.l10n.formatValue("unread-emails", {count: 5});
* assert.equal(value, "You have 5 unread emails");
*/
[NewObject] Promise<DOMString> formatValue(DOMString aId, optional L10nArgs aArgs);
[NewObject] Promise<UTF8String> formatValue(UTF8String aId, optional L10nArgs aArgs);
/**
* Formats values of a list of messages with given ids.
@ -115,7 +115,7 @@ interface Localization {
* "You have 5 unread emails"
* ]);
*/
[NewObject] Promise<sequence<DOMString>> formatValues(sequence<L10nKey> aKeys);
[NewObject] Promise<sequence<UTF8String>> formatValues(sequence<L10nKey> aKeys);
/**
* Formats values and attributes of a list of messages with given ids.

View File

@ -150,7 +150,7 @@ void DOMLocalization::GetAttributes(JSContext* aCx, Element& aElement,
nsAutoString l10nArgs;
if (aElement.GetAttr(kNameSpaceID_None, nsGkAtoms::datal10nid, l10nId)) {
aResult.mId = l10nId;
aResult.mId = NS_ConvertUTF16toUTF8(l10nId);
}
if (aElement.GetAttr(kNameSpaceID_None, nsGkAtoms::datal10nargs, l10nArgs)) {

View File

@ -120,7 +120,7 @@ class AttributeNameValueComparator {
public:
bool Equals(const AttributeNameValue& aAttribute,
const nsAttrName* aAttrName) const {
return aAttrName->Equals(aAttribute.mName);
return aAttrName->Equals(NS_ConvertUTF8toUTF16(aAttribute.mName));
}
};
@ -164,10 +164,9 @@ void L10nOverlays::OverlayAttributes(
}
for (auto& attribute : aTranslation.Value()) {
nsString attrName = attribute.mName;
RefPtr<nsAtom> nameAtom = NS_Atomize(attrName);
RefPtr<nsAtom> nameAtom = NS_Atomize(attribute.mName);
if (IsAttrNameLocalizable(nameAtom, aToElement, &explicitlyAllowed)) {
nsString value = attribute.mValue;
NS_ConvertUTF8toUTF16 value(attribute.mValue);
if (!aToElement->AttrValueIs(kNameSpaceID_None, nameAtom, value,
eCaseMatters)) {
aToElement->SetAttr(nameAtom, value, aRv);
@ -194,8 +193,11 @@ void L10nOverlays::OverlayAttributes(Element* aFromElement, Element* aToElement,
AttributeNameValue* attr = sequence.AppendElement(fallible);
MOZ_ASSERT(info.mName->NamespaceEquals(kNameSpaceID_None),
"No namespaced attributes allowed.");
info.mName->LocalName()->ToString(attr->mName);
info.mValue->ToString(attr->mValue);
info.mName->LocalName()->ToUTF8String(attr->mName);
nsAutoString value;
info.mValue->ToString(value);
attr->mValue.Assign(NS_ConvertUTF16toUTF8(value));
}
attributes.SetValue(sequence);
@ -418,26 +420,25 @@ void L10nOverlays::TranslateElement(
}
}
bool L10nOverlays::ContainsMarkup(const nsAString& aStr) {
bool L10nOverlays::ContainsMarkup(const nsACString& aStr) {
// We use our custom ContainsMarkup rather than the
// one from FragmentOrElement.cpp, because we don't
// want to trigger HTML parsing on every `Preferences & Options`
// type of string.
const char16_t* start = aStr.BeginReading();
const char16_t* end = aStr.EndReading();
const char* start = aStr.BeginReading();
const char* end = aStr.EndReading();
while (start != end) {
char16_t c = *start;
if (c == char16_t('<')) {
char c = *start;
if (c == '<') {
return true;
}
++start;
if (c == char16_t('&') && start != end) {
if (c == '&' && start != end) {
c = *start;
if (c == char16_t('#') || (c >= char16_t('0') && c <= char16_t('9')) ||
(c >= char16_t('a') && c <= char16_t('z')) ||
(c >= char16_t('A') && c <= char16_t('Z'))) {
if (c == '#' || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z')) {
return true;
}
++start;
@ -456,13 +457,13 @@ void L10nOverlays::TranslateElement(Element& aElement,
if (nodeInfo->NameAtom() == nsGkAtoms::title &&
nodeInfo->NamespaceID() == kNameSpaceID_XHTML) {
// A special case for the HTML title element whose content must be text.
aElement.SetTextContent(aTranslation.mValue, aRv);
aElement.SetTextContent(NS_ConvertUTF8toUTF16(aTranslation.mValue), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
} else if (!ContainsMarkup(aTranslation.mValue)) {
// If the translation doesn't contain any markup skip the overlay logic.
aElement.SetTextContent(aTranslation.mValue, aRv);
aElement.SetTextContent(NS_ConvertUTF8toUTF16(aTranslation.mValue), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
@ -471,9 +472,9 @@ void L10nOverlays::TranslateElement(Element& aElement,
// sanitize it and replace the element's content.
RefPtr<DocumentFragment> fragment =
new DocumentFragment(aElement.OwnerDoc()->NodeInfoManager());
nsContentUtils::ParseFragmentHTML(aTranslation.mValue, fragment,
nsGkAtoms::_template,
kNameSpaceID_XHTML, false, true);
nsContentUtils::ParseFragmentHTML(
NS_ConvertUTF8toUTF16(aTranslation.mValue), fragment,
nsGkAtoms::_template, kNameSpaceID_XHTML, false, true);
if (NS_WARN_IF(aRv.Failed())) {
return;
}

View File

@ -113,7 +113,7 @@ class L10nOverlays {
/**
* A helper used to test if the string contains HTML markup.
*/
static bool ContainsMarkup(const nsAString& aStr);
static bool ContainsMarkup(const nsACString& aStr);
};
} // namespace dom

View File

@ -181,7 +181,7 @@ uint32_t Localization::RemoveResourceIds(
}
already_AddRefed<Promise> Localization::FormatValue(
JSContext* aCx, const nsAString& aId, const Optional<L10nArgs>& aArgs,
JSContext* aCx, const nsACString& aId, const Optional<L10nArgs>& aArgs,
ErrorResult& aRv) {
JS::Rooted<JS::Value> args(aCx);

View File

@ -22,7 +22,7 @@ using namespace mozilla::dom;
namespace mozilla {
namespace intl {
typedef Record<nsString, Nullable<OwningStringOrDouble>> L10nArgs;
typedef Record<nsCString, Nullable<OwningUTF8StringOrDouble>> L10nArgs;
class Localization : public nsIObserver,
public nsSupportsWeakReference,
@ -57,7 +57,7 @@ class Localization : public nsIObserver,
uint32_t RemoveResourceIds(const nsTArray<nsString>& aResourceIds);
already_AddRefed<Promise> FormatValue(JSContext* aCx, const nsAString& aId,
already_AddRefed<Promise> FormatValue(JSContext* aCx, const nsACString& aId,
const Optional<L10nArgs>& aArgs,
ErrorResult& aRv);

View File

@ -20,7 +20,7 @@ interface mozILocalization : nsISupports
Promise formatMessages(in Array<jsval> aKeys);
Promise formatValues(in Array<jsval> aKeys);
Promise formatValue(in AString aId, [optional] in jsval aArgs);
Promise formatValue(in AUTF8String aId, [optional] in jsval aArgs);
Array<jsval> formatMessagesSync(in Array<jsval> aKeys);
void setIsSync(in boolean isSync);