Bug 1449505 - Add mozIntl.getLocaleDisplayNames using ICU. draft
authorZibi Braniecki <zbraniecki@mozilla.com>
Wed, 28 Mar 2018 15:26:56 +0200
changeset 773792 51da01608d8a521b08df27a6ea06184d562092e6
parent 773564 56d6db4ad38c869d0bbc2aea449a4a382f109163
push id104305
push userbmo:gandalf@aviary.pl
push dateWed, 28 Mar 2018 13:27:50 +0000
bugs1449505
milestone61.0a1
Bug 1449505 - Add mozIntl.getLocaleDisplayNames using ICU. MozReview-Commit-ID: JRij8tllorI
toolkit/components/mozintl/MozIntlHelper.cpp
toolkit/components/mozintl/mozIMozIntl.idl
toolkit/components/mozintl/mozIMozIntlHelper.idl
toolkit/components/mozintl/mozIntl.js
--- a/toolkit/components/mozintl/MozIntlHelper.cpp
+++ b/toolkit/components/mozintl/MozIntlHelper.cpp
@@ -1,16 +1,20 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode:nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "MozIntlHelper.h"
 #include "js/Wrapper.h"
 #include "mozilla/ModuleUtils.h"
+#include "nsString.h"
+#include "nsTArray.h"
+
+#include "unicode/uloc.h"
 
 #define MOZ_MOZINTLHELPER_CID \
   { 0xb43c96be, 0x2b3a, 0x4dc4, { 0x90, 0xe9, 0xb0, 0x6d, 0x34, 0x21, 0x9b, 0x68 } }
 
 using namespace mozilla;
 
 NS_IMPL_ISUPPORTS(MozIntlHelper, mozIMozIntlHelper)
 
@@ -34,16 +38,27 @@ AddFunctions(JSContext* cx, JS::Handle<J
 
   if (!JS_DefineFunctions(cx, realIntlObj, funcs)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
+static char**
+CreateOutArray(const nsTArray<nsCString>& aArray)
+{
+  uint32_t n = aArray.Length();
+  char** result = static_cast<char**>(moz_xmalloc(n * sizeof(char*)));
+  for (uint32_t i = 0; i < n; i++) {
+    result[i] = moz_xstrdup(aArray[i].get());
+  }
+  return result;
+}
+
 NS_IMETHODIMP
 MozIntlHelper::AddGetCalendarInfo(JS::Handle<JS::Value> val, JSContext* cx)
 {
   static const JSFunctionSpec funcs[] = {
     JS_SELF_HOSTED_FN("getCalendarInfo", "Intl_getCalendarInfo", 1, 0),
     JS_FS_END
   };
 
@@ -57,16 +72,35 @@ MozIntlHelper::AddGetDisplayNames(JS::Ha
     JS_SELF_HOSTED_FN("getDisplayNames", "Intl_getDisplayNames", 2, 0),
     JS_FS_END
   };
 
   return AddFunctions(cx, val, funcs);
 }
 
 NS_IMETHODIMP
+MozIntlHelper::GetDisplayLocaleNames(const char** aLocales, uint32_t aLocalesCount, uint32_t* aCount, char*** aOutArray)
+{
+  nsTArray<nsCString> locales;
+  UErrorCode status = U_ZERO_ERROR;
+  for (uint32_t i = 0; i < aLocalesCount; i++) {
+    nsAutoCString locale(aLocales[i]);
+    UChar result[160];
+    int32_t len = uloc_getDisplayName(locale.get(), "en", result, 160, &status);
+    nsAutoCString result2;
+    result2.Assign(NS_ConvertUTF16toUTF8(result, len));
+    locales.AppendElement(result2);
+  }
+
+  *aCount = locales.Length();
+  *aOutArray = CreateOutArray(locales);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 MozIntlHelper::AddDateTimeFormatConstructor(JS::Handle<JS::Value> val, JSContext* cx)
 {
   if (!val.isObject()) {
     return NS_ERROR_INVALID_ARG;
   }
 
   JS::Rooted<JSObject*> realIntlObj(cx, js::CheckedUnwrap(&val.toObject()));
   if (!realIntlObj) {
--- a/toolkit/components/mozintl/mozIMozIntl.idl
+++ b/toolkit/components/mozintl/mozIMozIntl.idl
@@ -34,16 +34,17 @@
  * current application locale by default, and fetching OS regional preferences
  * for date time format.
  */
 [scriptable, uuid(7f63279a-1a29-4ae6-9e7a-dc9684a23530)]
 interface mozIMozIntl : nsISupports
 {
   jsval getCalendarInfo([optional] in jsval locales);
   jsval getDisplayNames([optional] in jsval locales, [optional] in jsval options);
+  jsval getDisplayLocaleNames([optional] in jsval locales);
   jsval getLocaleInfo([optional] in jsval locales);
 
   readonly attribute jsval DateTimeFormat;
   readonly attribute jsval NumberFormat;
   readonly attribute jsval Collator;
   readonly attribute jsval PluralRules;
   readonly attribute jsval RelativeTimeFormat;
 };
--- a/toolkit/components/mozintl/mozIMozIntlHelper.idl
+++ b/toolkit/components/mozintl/mozIMozIntlHelper.idl
@@ -13,16 +13,20 @@
  * that exposes the thin wrapper around them that binds the functionality
  * to Gecko.
  */
 [scriptable, uuid(189eaa7d-b29a-43a9-b1fb-7658990df940)]
 interface mozIMozIntlHelper : nsISupports
 {
   [implicit_jscontext] void addGetCalendarInfo(in jsval intlObject);
   [implicit_jscontext] void addGetDisplayNames(in jsval intlObject);
+  void getDisplayLocaleNames([array, size_is(aLocalesCount)] in string aLocales,
+                             [optional] in unsigned long aLocalesCount,
+                             [optional] out unsigned long aCount,
+                             [retval, array, size_is(aCount)] out string aOutArray);
   [implicit_jscontext] void addGetLocaleInfo(in jsval intlObject);
 
   /**
    * Adds a MozDateTimeFormat contructor to the given object. This function may only
    * be called once within a realm/global object: calling it multiple times will
    * throw.
    *
    * The difference between regular Intl.DateTimeFormat and the method created here
--- a/toolkit/components/mozintl/mozIntl.js
+++ b/toolkit/components/mozintl/mozIntl.js
@@ -162,16 +162,20 @@ class MozIntl {
   getDisplayNames(locales, ...args) {
     if (!this._cache.hasOwnProperty("getDisplayNames")) {
       mozIntlHelper.addGetDisplayNames(this._cache);
     }
 
     return this._cache.getDisplayNames(getLocales(locales), ...args);
   }
 
+  getDisplayLocaleNames(locales) {
+    return mozIntlHelper.getDisplayLocaleNames(locales);
+  }
+
   getLocaleInfo(locales, ...args) {
     if (!this._cache.hasOwnProperty("getLocaleInfo")) {
       mozIntlHelper.addGetLocaleInfo(this._cache);
     }
 
     return this._cache.getLocaleInfo(getLocales(locales), ...args);
   }