Skip to content

Commit

Permalink
feat: Add app.getLocaleCountryCode() method for region detection (ele…
Browse files Browse the repository at this point in the history
…ctron#15035)

* 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
  • Loading branch information
zarubond authored and bcpete committed Apr 18, 2019
1 parent bbd41bf commit 3ee4d2e
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 0 deletions.
41 changes: 41 additions & 0 deletions atom/browser/api/atom_api_app.cc
Expand Up @@ -65,6 +65,7 @@
#endif

#if defined(OS_MACOSX)
#include <CoreFoundation/CoreFoundation.h>
#include "atom/browser/ui/cocoa/atom_bundle_mover.h"
#endif

Expand Down Expand Up @@ -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), &region);
}
#elif defined(OS_MACOSX)
CFLocaleRef locale = CFLocaleCopyCurrent();
CFStringRef value = CFStringRef(
static_cast<CFTypeRef>(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);
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions atom/browser/api/atom_api_app.h
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions docs/api/app.md
Expand Up @@ -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
Expand Down
11 changes: 11 additions & 0 deletions spec/api-app-spec.js
Expand Up @@ -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()
Expand Down

0 comments on commit 3ee4d2e

Please sign in to comment.