feat: add app.getSystemLocale() method (#35697)
* feat: add app.getSystemLocale() method * Update shell/browser/electron_browser_main_parts.cc Co-authored-by: Charles Kerr <charles@charleskerr.com> * Change methods to be const * Apply PR feedback * Fix mac compile * Add missing scope * Apply style changes * Change note * Add braces to get the comment indentation right * Change to static * Apply PR feedback * Fix the documentation * Remove extraneous file Co-authored-by: Charles Kerr <charles@charleskerr.com>
This commit is contained in:
parent
626e248dea
commit
8a0b4fa338
11 changed files with 69 additions and 6 deletions
|
@ -715,7 +715,7 @@ To set the locale, you'll want to use a command line switch at app startup, whic
|
||||||
**Note:** When distributing your packaged app, you have to also ship the
|
**Note:** When distributing your packaged app, you have to also ship the
|
||||||
`locales` folder.
|
`locales` folder.
|
||||||
|
|
||||||
**Note:** On Windows, you have to call it after the `ready` events gets emitted.
|
**Note:** This API must be called after the `ready` event is emitted.
|
||||||
|
|
||||||
### `app.getLocaleCountryCode()`
|
### `app.getLocaleCountryCode()`
|
||||||
|
|
||||||
|
@ -723,6 +723,12 @@ Returns `string` - User operating system's locale two-letter [ISO 3166](https://
|
||||||
|
|
||||||
**Note:** When unable to detect locale country code, it returns empty string.
|
**Note:** When unable to detect locale country code, it returns empty string.
|
||||||
|
|
||||||
|
### `app.getSystemLocale()`
|
||||||
|
|
||||||
|
Returns `string` - The current system locale. On Windows and Linux, it is fetched using Chromium's `i18n` library. On macOS, the `NSLocale` object is used instead.
|
||||||
|
|
||||||
|
**Note:** This API must be called after the `ready` event is emitted.
|
||||||
|
|
||||||
### `app.addRecentDocument(path)` _macOS_ _Windows_
|
### `app.addRecentDocument(path)` _macOS_ _Windows_
|
||||||
|
|
||||||
* `path` string
|
* `path` string
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "shell/browser/api/electron_api_session.h"
|
#include "shell/browser/api/electron_api_session.h"
|
||||||
#include "shell/browser/api/electron_api_web_contents.h"
|
#include "shell/browser/api/electron_api_web_contents.h"
|
||||||
#include "shell/browser/api/gpuinfo_manager.h"
|
#include "shell/browser/api/gpuinfo_manager.h"
|
||||||
|
#include "shell/browser/browser_process_impl.h"
|
||||||
#include "shell/browser/electron_browser_context.h"
|
#include "shell/browser/electron_browser_context.h"
|
||||||
#include "shell/browser/electron_browser_main_parts.h"
|
#include "shell/browser/electron_browser_main_parts.h"
|
||||||
#include "shell/browser/javascript_environment.h"
|
#include "shell/browser/javascript_environment.h"
|
||||||
|
@ -1039,6 +1040,16 @@ std::string App::GetLocale() {
|
||||||
return g_browser_process->GetApplicationLocale();
|
return g_browser_process->GetApplicationLocale();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string App::GetSystemLocale(gin_helper::ErrorThrower thrower) const {
|
||||||
|
if (!Browser::Get()->is_ready()) {
|
||||||
|
thrower.ThrowError(
|
||||||
|
"app.getSystemLocale() can only be called "
|
||||||
|
"after app is ready");
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
return static_cast<BrowserProcessImpl*>(g_browser_process)->GetSystemLocale();
|
||||||
|
}
|
||||||
|
|
||||||
std::string App::GetLocaleCountryCode() {
|
std::string App::GetLocaleCountryCode() {
|
||||||
std::string region;
|
std::string region;
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
|
@ -1785,6 +1796,7 @@ gin::ObjectTemplateBuilder App::GetObjectTemplateBuilder(v8::Isolate* isolate) {
|
||||||
.SetMethod("setAppLogsPath", &App::SetAppLogsPath)
|
.SetMethod("setAppLogsPath", &App::SetAppLogsPath)
|
||||||
.SetMethod("setDesktopName", &App::SetDesktopName)
|
.SetMethod("setDesktopName", &App::SetDesktopName)
|
||||||
.SetMethod("getLocale", &App::GetLocale)
|
.SetMethod("getLocale", &App::GetLocale)
|
||||||
|
.SetMethod("getSystemLocale", &App::GetSystemLocale)
|
||||||
.SetMethod("getLocaleCountryCode", &App::GetLocaleCountryCode)
|
.SetMethod("getLocaleCountryCode", &App::GetLocaleCountryCode)
|
||||||
#if BUILDFLAG(USE_NSS_CERTS)
|
#if BUILDFLAG(USE_NSS_CERTS)
|
||||||
.SetMethod("importCertificate", &App::ImportCertificate)
|
.SetMethod("importCertificate", &App::ImportCertificate)
|
||||||
|
|
|
@ -191,6 +191,7 @@ class App : public ElectronBrowserClient::Delegate,
|
||||||
void SetDesktopName(const std::string& desktop_name);
|
void SetDesktopName(const std::string& desktop_name);
|
||||||
std::string GetLocale();
|
std::string GetLocale();
|
||||||
std::string GetLocaleCountryCode();
|
std::string GetLocaleCountryCode();
|
||||||
|
std::string GetSystemLocale(gin_helper::ErrorThrower thrower) const;
|
||||||
void OnSecondInstance(const base::CommandLine& cmd,
|
void OnSecondInstance(const base::CommandLine& cmd,
|
||||||
const base::FilePath& cwd,
|
const base::FilePath& cwd,
|
||||||
const std::vector<const uint8_t> additional_data);
|
const std::vector<const uint8_t> additional_data);
|
||||||
|
|
|
@ -293,6 +293,14 @@ HidPolicyAllowedDevices* BrowserProcessImpl::hid_policy_allowed_devices() {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BrowserProcessImpl::SetSystemLocale(const std::string& locale) {
|
||||||
|
system_locale_ = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& BrowserProcessImpl::GetSystemLocale() const {
|
||||||
|
return system_locale_;
|
||||||
|
}
|
||||||
|
|
||||||
void BrowserProcessImpl::SetApplicationLocale(const std::string& locale) {
|
void BrowserProcessImpl::SetApplicationLocale(const std::string& locale) {
|
||||||
locale_ = locale;
|
locale_ = locale;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,9 @@ class BrowserProcessImpl : public BrowserProcess {
|
||||||
void PostDestroyThreads() {}
|
void PostDestroyThreads() {}
|
||||||
void PostMainMessageLoopRun();
|
void PostMainMessageLoopRun();
|
||||||
|
|
||||||
|
void SetSystemLocale(const std::string& locale);
|
||||||
|
const std::string& GetSystemLocale() const;
|
||||||
|
|
||||||
void EndSession() override {}
|
void EndSession() override {}
|
||||||
void FlushLocalStateAndReply(base::OnceClosure reply) override {}
|
void FlushLocalStateAndReply(base::OnceClosure reply) override {}
|
||||||
bool IsShuttingDown() override;
|
bool IsShuttingDown() override;
|
||||||
|
@ -110,6 +113,7 @@ class BrowserProcessImpl : public BrowserProcess {
|
||||||
#endif
|
#endif
|
||||||
std::unique_ptr<PrefService> local_state_;
|
std::unique_ptr<PrefService> local_state_;
|
||||||
std::string locale_;
|
std::string locale_;
|
||||||
|
std::string system_locale_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ELECTRON_SHELL_BROWSER_BROWSER_PROCESS_IMPL_H_
|
#endif // ELECTRON_SHELL_BROWSER_BROWSER_PROCESS_IMPL_H_
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "base/base_switches.h"
|
#include "base/base_switches.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
#include "base/feature_list.h"
|
#include "base/feature_list.h"
|
||||||
|
#include "base/i18n/rtl.h"
|
||||||
#include "base/metrics/field_trial.h"
|
#include "base/metrics/field_trial.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
#include "base/run_loop.h"
|
#include "base/run_loop.h"
|
||||||
|
@ -282,8 +283,16 @@ void ElectronBrowserMainParts::PostEarlyInitialization() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ElectronBrowserMainParts::PreCreateThreads() {
|
int ElectronBrowserMainParts::PreCreateThreads() {
|
||||||
if (!views::LayoutProvider::Get())
|
if (!views::LayoutProvider::Get()) {
|
||||||
layout_provider_ = std::make_unique<views::LayoutProvider>();
|
layout_provider_ = std::make_unique<views::LayoutProvider>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the system locale for Electron.
|
||||||
|
#if BUILDFLAG(IS_MAC)
|
||||||
|
fake_browser_process_->SetSystemLocale(GetCurrentSystemLocale());
|
||||||
|
#else
|
||||||
|
fake_browser_process_->SetSystemLocale(base::i18n::GetConfiguredLocale());
|
||||||
|
#endif
|
||||||
|
|
||||||
auto* command_line = base::CommandLine::ForCurrentProcess();
|
auto* command_line = base::CommandLine::ForCurrentProcess();
|
||||||
std::string locale = command_line->GetSwitchValueASCII(::switches::kLang);
|
std::string locale = command_line->GetSwitchValueASCII(::switches::kLang);
|
||||||
|
@ -320,7 +329,7 @@ int ElectronBrowserMainParts::PreCreateThreads() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialize the app locale.
|
// Initialize the app locale for Electron and Chromium.
|
||||||
std::string app_locale = l10n_util::GetApplicationLocale(loaded_locale);
|
std::string app_locale = l10n_util::GetApplicationLocale(loaded_locale);
|
||||||
ElectronBrowserClient::SetApplicationLocale(app_locale);
|
ElectronBrowserClient::SetApplicationLocale(app_locale);
|
||||||
fake_browser_process_->SetApplicationLocale(app_locale);
|
fake_browser_process_->SetApplicationLocale(app_locale);
|
||||||
|
|
|
@ -130,6 +130,7 @@ class ElectronBrowserMainParts : public content::BrowserMainParts {
|
||||||
void FreeAppDelegate();
|
void FreeAppDelegate();
|
||||||
void RegisterURLHandler();
|
void RegisterURLHandler();
|
||||||
void InitializeMainNib();
|
void InitializeMainNib();
|
||||||
|
static std::string GetCurrentSystemLocale();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUILDFLAG(IS_MAC)
|
#if BUILDFLAG(IS_MAC)
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "shell/browser/electron_browser_main_parts.h"
|
#include "shell/browser/electron_browser_main_parts.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "base/mac/bundle_locations.h"
|
#include "base/mac/bundle_locations.h"
|
||||||
#include "base/mac/foundation_util.h"
|
#include "base/mac/foundation_util.h"
|
||||||
#include "base/path_service.h"
|
#include "base/path_service.h"
|
||||||
|
@ -74,4 +76,16 @@ void ElectronBrowserMainParts::InitializeMainNib() {
|
||||||
[mainNib release];
|
[mainNib release];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ElectronBrowserMainParts::GetCurrentSystemLocale() {
|
||||||
|
NSString* systemLocaleIdentifier =
|
||||||
|
[[NSLocale currentLocale] localeIdentifier];
|
||||||
|
|
||||||
|
// Mac OS X uses "_" instead of "-", so swap to get a real locale value.
|
||||||
|
std::string locale_value = [[systemLocaleIdentifier
|
||||||
|
stringByReplacingOccurrencesOfString:@"_"
|
||||||
|
withString:@"-"] UTF8String];
|
||||||
|
|
||||||
|
return locale_value;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace electron
|
} // namespace electron
|
||||||
|
|
|
@ -118,6 +118,12 @@ describe('app module', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('app.getSystemLocale()', () => {
|
||||||
|
it('should not be empty', () => {
|
||||||
|
expect(app.getSystemLocale()).to.not.equal('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('app.getLocaleCountryCode()', () => {
|
describe('app.getLocaleCountryCode()', () => {
|
||||||
it('should be empty or have length of two', () => {
|
it('should be empty or have length of two', () => {
|
||||||
const localeCountryCode = app.getLocaleCountryCode();
|
const localeCountryCode = app.getLocaleCountryCode();
|
||||||
|
|
|
@ -374,6 +374,7 @@ describe('command line switches', () => {
|
||||||
});
|
});
|
||||||
describe('--lang switch', () => {
|
describe('--lang switch', () => {
|
||||||
const currentLocale = app.getLocale();
|
const currentLocale = app.getLocale();
|
||||||
|
const currentSystemLocale = app.getSystemLocale();
|
||||||
const testLocale = async (locale: string, result: string, printEnv: boolean = false) => {
|
const testLocale = async (locale: string, result: string, printEnv: boolean = false) => {
|
||||||
const appPath = path.join(fixturesPath, 'api', 'locale-check');
|
const appPath = path.join(fixturesPath, 'api', 'locale-check');
|
||||||
const args = [appPath, `--set-lang=${locale}`];
|
const args = [appPath, `--set-lang=${locale}`];
|
||||||
|
@ -396,8 +397,9 @@ describe('command line switches', () => {
|
||||||
expect(output).to.equal(result);
|
expect(output).to.equal(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should set the locale', async () => testLocale('fr', 'fr'));
|
it('should set the locale', async () => testLocale('fr', `fr|${currentSystemLocale}`));
|
||||||
it('should not set an invalid locale', async () => testLocale('asdfkl', currentLocale));
|
it('should set the locale with country code', async () => testLocale('zh-CN', `zh-CN|${currentSystemLocale}`));
|
||||||
|
it('should not set an invalid locale', async () => testLocale('asdfkl', `${currentLocale}|${currentSystemLocale}`));
|
||||||
|
|
||||||
const lcAll = String(process.env.LC_ALL);
|
const lcAll = String(process.env.LC_ALL);
|
||||||
ifit(process.platform === 'linux')('current process has a valid LC_ALL env', async () => {
|
ifit(process.platform === 'linux')('current process has a valid LC_ALL env', async () => {
|
||||||
|
|
2
spec/fixtures/api/locale-check/main.js
vendored
2
spec/fixtures/api/locale-check/main.js
vendored
|
@ -9,7 +9,7 @@ app.whenReady().then(() => {
|
||||||
if (process.argv[3] === '--print-env') {
|
if (process.argv[3] === '--print-env') {
|
||||||
process.stdout.write(String(process.env.LC_ALL));
|
process.stdout.write(String(process.env.LC_ALL));
|
||||||
} else {
|
} else {
|
||||||
process.stdout.write(app.getLocale());
|
process.stdout.write(`${app.getLocale()}|${app.getSystemLocale()}`);
|
||||||
}
|
}
|
||||||
process.stdout.end();
|
process.stdout.end();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue