add app.setLocale() (#11469)

* infrastructure for setLocale via klang

* add documentation for setLocale

* add test for setLocale

* fix spec

* add spec and update docs

* fix carriage feeds on windows

* SetLocale() sets LC_ALL on Linux

* in SetLocale() on Linux, use g_setenv()

* fix tyop: '#ifdef OSX_POSIX'

* make the linter happy

* improvements from review
This commit is contained in:
shelley vohr 2018-02-08 09:26:37 -05:00 committed by Charles Kerr
parent e3f1d90854
commit ca34978e73
9 changed files with 92 additions and 16 deletions

View file

@ -154,9 +154,12 @@ void AtomBrowserMainParts::PostEarlyInitialization() {
}
int AtomBrowserMainParts::PreCreateThreads() {
fake_browser_process_->SetApplicationLocale(
l10n_util::GetApplicationLocale(""));
return brightray::BrowserMainParts::PreCreateThreads();
const int result = brightray::BrowserMainParts::PreCreateThreads();
if (!result) {
fake_browser_process_->SetApplicationLocale(
brightray::BrowserClient::Get()->GetApplicationLocale());
}
return result;
}
void AtomBrowserMainParts::PreMainMessageLoopRun() {

View file

@ -4,13 +4,17 @@
#include "brightray/browser/browser_main_parts.h"
#if defined(OSX_POSIX)
#if defined(OS_POSIX)
#include <stdlib.h>
#endif
#include <sys/stat.h>
#include <string>
#if defined(OS_LINUX)
#include <glib.h> // for g_setenv()
#endif
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/message_loop/message_loop.h"
@ -29,6 +33,8 @@
#include "net/proxy/proxy_resolver_v8.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/material_design/material_design_controller.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/ui_base_switches.h"
#if defined(USE_AURA)
#include "ui/display/display.h"
@ -220,10 +226,29 @@ void BrowserMainParts::ToolkitInitialized() {
}
void BrowserMainParts::PreMainMessageLoopStart() {
#if defined(OS_MACOSX)
l10n_util::OverrideLocaleWithCocoaLocale();
// Initialize ui::ResourceBundle.
ui::ResourceBundle::InitSharedInstanceWithLocale(
"", nullptr, ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES);
auto cmd_line = base::CommandLine::ForCurrentProcess();
if (cmd_line->HasSwitch(switches::kLang)) {
const std::string locale = cmd_line->GetSwitchValueASCII(switches::kLang);
const base::FilePath locale_file_path =
ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(locale, true);
if (!locale_file_path.empty()) {
custom_locale_ = locale;
#if defined(OS_LINUX)
/* When built with USE_GLIB, libcc's GetApplicationLocaleInternal() uses
* glib's g_get_language_names(), which keys off of getenv("LC_ALL") */
g_setenv("LC_ALL", custom_locale_.c_str(), TRUE);
#endif
InitializeResourceBundle("");
}
}
#if defined(OS_MACOSX)
if (custom_locale_.empty())
l10n_util::OverrideLocaleWithCocoaLocale();
#endif
LoadResourceBundle(custom_locale_);
#if defined(OS_MACOSX)
InitializeMainNib();
#endif
@ -277,7 +302,8 @@ int BrowserMainParts::PreCreateThreads() {
layout_provider_.reset(new views::LayoutProvider());
// Initialize the app locale.
BrowserClient::SetApplicationLocale(l10n_util::GetApplicationLocale(""));
BrowserClient::SetApplicationLocale(
l10n_util::GetApplicationLocale(custom_locale_));
// Manage global state of net and other IO thread related.
io_thread_ = base::MakeUnique<IOThread>();

View file

@ -6,6 +6,7 @@
#define BRIGHTRAY_BROWSER_BROWSER_MAIN_PARTS_H_
#include <memory>
#include <string>
#include "base/compiler_specific.h"
#include "base/macros.h"
@ -62,6 +63,7 @@ class BrowserMainParts : public content::BrowserMainParts {
#endif
std::unique_ptr<views::LayoutProvider> layout_provider_;
std::string custom_locale_;
DISALLOW_COPY_AND_ASSIGN(BrowserMainParts);
};

View file

@ -42,17 +42,22 @@ bool SubprocessNeedsResourceBundle(const std::string& process_type) {
} // namespace
void InitializeResourceBundle(const std::string& locale) {
// Load locales.
ui::ResourceBundle::InitSharedInstanceWithLocale(
locale, nullptr, ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES);
void LoadResourceBundle(const std::string& locale) {
const bool initialized = ui::ResourceBundle::HasSharedInstance();
if (initialized)
ui::ResourceBundle::CleanupSharedInstance();
// Load other resource files.
ui::ResourceBundle::InitSharedInstanceWithLocale(
locale, nullptr, ui::ResourceBundle::DO_NOT_LOAD_COMMON_RESOURCES);
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
bundle.ReloadLocaleResources(locale);
// Load other resource files.
#if defined(OS_MACOSX)
LoadCommonResources();
#else
base::FilePath pak_dir;
ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance();
PathService::Get(base::DIR_MODULE, &pak_dir);
bundle.AddDataPackFromPath(
pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak")),
@ -104,7 +109,7 @@ void MainDelegate::PreSandboxStartup() {
// browser process as a command line flag.
if (SubprocessNeedsResourceBundle(process_type)) {
std::string locale = cmd.GetSwitchValueASCII(switches::kLang);
InitializeResourceBundle(locale);
LoadResourceBundle(locale);
}
}

View file

@ -24,7 +24,7 @@ namespace brightray {
class BrowserClient;
class ContentClient;
void InitializeResourceBundle(const std::string& locale);
void LoadResourceBundle(const std::string& locale);
void LoadCommonResources();
class MainDelegate : public content::ContentMainDelegate {

View file

@ -530,6 +530,12 @@ Returns `String` - The current application locale. Possible return values are do
**Note:** On Windows you have to call it after the `ready` events gets emitted.
### `app.setLocale(locale)`
* `locale` String
Set the locale of the app (must be called before the `ready` event).
### `app.addRecentDocument(path)` _macOS_ _Windows_
* `path` String

View file

@ -112,6 +112,25 @@ describe('app module', () => {
})
})
describe('app.setLocale()', () => {
const testLocale = (locale, result, done) => {
const appPath = path.join(__dirname, 'fixtures', 'api', 'locale-check')
const electronPath = remote.getGlobal('process').execPath
let output = ''
let appProcess = ChildProcess.spawn(electronPath, [appPath, `--lang=${locale}`])
appProcess.stdout.on('data', (data) => { output += data })
appProcess.stdout.on('end', () => {
output = output.replace(/(\r\n|\n|\r)/gm, '')
assert.equal(output, result)
done()
})
}
it('should set the locale', (done) => testLocale('fr', 'fr', done))
it('should not set an invalid locale', (done) => testLocale('asdfkl', 'en-US', done))
})
describe('app.isInApplicationsFolder()', () => {
before(function () {
if (process.platform !== 'darwin') {

10
spec/fixtures/api/locale-check/main.js vendored Normal file
View file

@ -0,0 +1,10 @@
const {app} = require('electron')
app.on('ready', () => {
process.stdout.write(app.getLocale())
process.stdout.end()
setImmediate(() => {
app.quit()
})
})

View file

@ -0,0 +1,5 @@
{
"name": "locale-check",
"main": "main.js"
}