From de05ff894bc10e5c931f5bcb4005b36f48f76045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Z=C3=A1ruba?= Date: Tue, 20 Nov 2018 21:33:23 +0100 Subject: [PATCH] feat: Add app.getLocaleCountryCode() method for region detection (#15035) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add method to get system´s user region * Fix linter * Remove auto types * Improved detection for POSIX * Change name, add specs, minor fixes * Remove left overs * Fix locale test * Fix Linux test * Coding style fixes * Fix docs * Add test excaption for Linux * fix spelling * Polishing --- atom/browser/api/atom_api_app.cc | 41 ++++++++++++++++++++++++++++++++ atom/browser/api/atom_api_app.h | 1 + docs/api/app.md | 5 ++++ spec/api-app-spec.js | 11 +++++++++ 4 files changed, 58 insertions(+) diff --git a/atom/browser/api/atom_api_app.cc b/atom/browser/api/atom_api_app.cc index a19192baa1bcb..92a3978c9c109 100644 --- a/atom/browser/api/atom_api_app.cc +++ b/atom/browser/api/atom_api_app.cc @@ -65,6 +65,7 @@ #endif #if defined(OS_MACOSX) +#include #include "atom/browser/ui/cocoa/atom_bundle_mover.h" #endif @@ -882,6 +883,45 @@ std::string App::GetLocale() { return g_browser_process->GetApplicationLocale(); } +std::string App::GetLocaleCountryCode() { + std::string region; +#if defined(OS_WIN) + WCHAR locale_name[LOCALE_NAME_MAX_LENGTH] = {0}; + + if (GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, + (LPWSTR)&locale_name, + sizeof(locale_name) / sizeof(WCHAR)) || + GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SISO3166CTRYNAME, + (LPWSTR)&locale_name, + sizeof(locale_name) / sizeof(WCHAR))) { + base::WideToUTF8(locale_name, wcslen(locale_name), ®ion); + } +#elif defined(OS_MACOSX) + CFLocaleRef locale = CFLocaleCopyCurrent(); + CFStringRef value = CFStringRef( + static_cast(CFLocaleGetValue(locale, kCFLocaleCountryCode))); + const CFIndex kCStringSize = 128; + char temporaryCString[kCStringSize] = {0}; + CFStringGetCString(value, temporaryCString, kCStringSize, + kCFStringEncodingUTF8); + region = temporaryCString; +#else + const char* locale_ptr = setlocale(LC_TIME, NULL); + if (!locale_ptr) + locale_ptr = setlocale(LC_NUMERIC, NULL); + if (locale_ptr) { + std::string locale = locale_ptr; + std::string::size_type rpos = locale.find('.'); + if (rpos != std::string::npos) + locale = locale.substr(0, rpos); + rpos = locale.find('_'); + if (rpos != std::string::npos && rpos + 1 < locale.size()) + region = locale.substr(rpos + 1); + } +#endif + return region.size() == 2 ? region : std::string(); +} + void App::OnSecondInstance(const base::CommandLine::StringVector& cmd, const base::FilePath& cwd) { Emit("second-instance", cmd, cwd); @@ -1315,6 +1355,7 @@ void App::BuildPrototype(v8::Isolate* isolate, .SetMethod("getPath", &App::GetPath) .SetMethod("setDesktopName", &App::SetDesktopName) .SetMethod("getLocale", &App::GetLocale) + .SetMethod("getLocaleCountryCode", &App::GetLocaleCountryCode) #if defined(USE_NSS_CERTS) .SetMethod("importCertificate", &App::ImportCertificate) #endif diff --git a/atom/browser/api/atom_api_app.h b/atom/browser/api/atom_api_app.h index 166438f30f776..25488cefc9233 100644 --- a/atom/browser/api/atom_api_app.h +++ b/atom/browser/api/atom_api_app.h @@ -182,6 +182,7 @@ class App : public AtomBrowserClient::Delegate, void SetDesktopName(const std::string& desktop_name); std::string GetLocale(); + std::string GetLocaleCountryCode(); void OnSecondInstance(const base::CommandLine::StringVector& cmd, const base::FilePath& cwd); bool HasSingleInstanceLock() const; diff --git a/docs/api/app.md b/docs/api/app.md index f07a6a061b8e0..c65d4b8f17144 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -603,6 +603,11 @@ To set the locale, you'll want to use a command line switch at app startup, whic **Note:** On Windows you have to call it after the `ready` events gets emitted. +### `app.getLocaleCountryCode()` +Returns `string` - User operating system's locale two-letter [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) country code. The value is taken from native OS APIs. + +**Note:** When unable to detect locale country code, it returns empty string. + ### `app.addRecentDocument(path)` _macOS_ _Windows_ * `path` String diff --git a/spec/api-app-spec.js b/spec/api-app-spec.js index 5407bed579b34..c44cef392a97f 100644 --- a/spec/api-app-spec.js +++ b/spec/api-app-spec.js @@ -122,6 +122,17 @@ describe('app module', () => { }) }) + describe('app.getLocaleCountryCode()', () => { + it('should be empty or have length of two', () => { + let expectedLength = 2 + if (isCI && process.platform === 'linux') { + // Linux CI machines have no locale. + expectedLength = 0 + } + expect(app.getLocaleCountryCode()).to.be.a('string').and.have.lengthOf(expectedLength) + }) + }) + describe('app.isPackaged', () => { it('should be false durings tests', () => { expect(app.isPackaged).to.be.false()