Current version of chromium-efl uses two different localization systems.
First from generic chromium product (pak files), second is based around
libintl. Both systems are pretty generic and serve their purpose well
enough. The problem is our current libintl system works only on tizen,
but not on desktop. This is unfortunate considering the fact libintl is
a generic library available on almsost every unix system, not only linux.
There is no good reason to make the funcionality tizen specific.
This patch tries to fix this problem. To do this it:
1. Adds a proper gyp support for compiling portable object (po) files.
It replaces the previous solution with inline shell code in RPM spec
file. Spec is only responsible for packaging output produced during
build (ninja) step.
2. All the generic code responsible for changing application locale is
moved outside of OS_TIZEN ifdefs. The only Tizen specific part is
usage of vconf to get current system locale. To keep the alternative
simple desktop uses hardcoded english localization. (Can be improved
if necessary)
3. The bindtextdomain calls are moved to
ContentMainDelegate::BasicStartupComplete function implementations
(one for UI another for renderer). Bindtextdomain should be called
only once during application initialization. The filesystem location
of translation files is not supposed to change during app lifetime.
4. Implements necessary PathsEfl support to find necessary translation
files on desktop (out.x64/{Debug|Release}/locale.
With the patch in place all the application menus which use
libintl/gettext for translation work on both desktop and tizen. It
should make it easier to test the functionality.
On a side note I also believe that the translation files should be moved
out of ewk directory into impl. Technically they are used by the code
from impl, not ewk. Still, if we'd like to do this it might be a good
idea for a separate patch.
Reviewed by: Antonio Gomes, Kamil Klimek, Piotr Tworek, arno renevier
Change-Id: I8e06778c730a7c313a08dc195d7fff513ca7e32f
Signed-off-by: Piotr Tworek <p.tworek@samsung.com>
--- /dev/null
+{
+ 'variables': {
+ 'msgfmt%': '/usr/bin/msgfmt',
+ },
+ 'targets': [{
+ 'target_name': 'locale_efl',
+ 'type': 'none',
+ 'sources': [
+ 'bn.po',
+ 'en.po',
+ 'gu.po',
+ 'hi.po',
+ 'kn.po',
+ 'ko_KR.po',
+ 'ml.po',
+ 'pl.po',
+ 'si.po',
+ 'ta.po',
+ 'te.po',
+ 'ur.po',
+ ],
+ 'rules': [{
+ 'rule_name': 'translations',
+ 'message': 'MSGFMT <(RULE_INPUT_NAME)',
+ 'extension': 'po',
+ 'outputs': [
+ '<(PRODUCT_DIR)/locale/<(RULE_INPUT_ROOT)/LC_MESSAGES/WebKit.mo',
+ ],
+ 'action': [
+ '<(msgfmt)', '-o',
+ '<(PRODUCT_DIR)/locale/<(RULE_INPUT_ROOT)/LC_MESSAGES/WebKit.mo',
+ '<(RULE_INPUT_PATH)',
+ ],
+ }],
+ }],
+}
'chromium-efl-deps.gyp:efl',
'chromium-efl-deps.gyp:gstreamer',
'theme/theme.gyp:tizen_theme',
+ '../ewk/po_tizen/locale.gyp:locale_efl',
'<(chrome_src_dir)/base/allocator/allocator.gyp:allocator',
'<(chrome_src_dir)/content/content.gyp:content',
'<(chrome_src_dir)/content/content.gyp:content_app_browser',
'gpu/gpu_thread_override_efl.h',
'http_user_agent_settings_efl.cc',
'http_user_agent_settings_efl.h',
+ 'locale_efl.h',
+ 'locale_efl.cc',
'memory_purger.cc',
'memory_purger.h',
'message_pump_for_ui_efl.cc',
#include "content_browser_client_efl.h"
#include "gpu/gpu_thread_override_efl.h"
#include "paths_efl.h"
-
-#if defined(OS_TIZEN)
-#include "vconf/vconf.h"
-#include <libintl.h>
-#include "paths_efl.h"
-#include "base/path_service.h"
-#include <unistd.h>
-#endif
+#include "locale_efl.h"
namespace content {
+namespace {
std::string SubProcessPath() {
static std::string result;
if (!result.empty())
command_line->AppendSwitchPath("disk-cache-dir", disk_cache_dir);
}
}
+} // namespace
void ContentMainDelegateEfl::PreSandboxStartup() {
PathService::Override(base::FILE_EXE, base::FilePath(SubProcessPath()));
return client_.get();
}
-
-#if defined(OS_TIZEN)
-void platformLanguageChanged(keynode_t* keynode, void* data) {
- base::FilePath locale_dir;
- PathService::Get(PathsEfl::DIR_LOCALE, &locale_dir);
- setlocale(LC_ALL, vconf_get_str(VCONFKEY_LANGSET));
- bindtextdomain("WebKit", locale_dir.value().c_str());
-}
-#endif
-
bool ContentMainDelegateEfl::BasicStartupComplete(int* /*exit_code*/) {
content::SetContentClient(&content_client_);
PathsEfl::Register();
-
-#if defined(OS_TIZEN)
- platformLanguageChanged(0, 0);
- vconf_notify_key_changed(VCONFKEY_LANGSET, platformLanguageChanged, 0);
-#endif
+ LocaleEfl::Initialize();
return false;
}
--- /dev/null
+// Copyright 2015 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "locale_efl.h"
+
+#include <libintl.h>
+#include <string>
+#include <unistd.h>
+
+#include "base/files/file_path.h"
+#include "base/command_line.h"
+#include "base/path_service.h"
+#include "content/public/common/content_switches.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "paths_efl.h"
+
+#if defined(OS_TIZEN)
+#include <vconf/vconf.h>
+#endif
+
+#if !defined(OS_TIZEN)
+typedef void keynode_t;
+#endif
+
+namespace LocaleEfl {
+
+namespace {
+
+void ReloadCorrectPakForLocale() {
+ if (!ui::ResourceBundle::HasSharedInstance())
+ return;
+
+#if defined(OS_TIZEN)
+ std::string new_locale(vconf_get_str(VCONFKEY_LANGSET));
+#else
+ std::string new_locale("en-US");
+#endif
+
+ // Note: locale from vconf is in format:
+ // xy_ZW.UTF-8
+ // blink pak files are not named same way, so we need to find correct pak.
+ std::string chosen_locale = new_locale;
+ bool pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
+ chosen_locale);
+
+ // xy_ZW.UTF-8 -> xy-ZW
+ // Note: pak files are named after IETF_language_tag, which uses '-' not '_'
+ if (!pak_exist) {
+ chosen_locale = chosen_locale.substr(0, 5);
+ if (chosen_locale.length() >=3 && chosen_locale[2] == '_')
+ chosen_locale[2] = '-';
+
+ pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
+ chosen_locale);
+ }
+
+ // xy-ZW -> xy
+ if (!pak_exist) {
+ chosen_locale = chosen_locale.substr(0, 2);
+ pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
+ chosen_locale);
+ }
+
+ if (!pak_exist) {
+ LOG(WARNING) << "Unable to find any locale pak for " << chosen_locale;
+ return;
+ }
+
+ ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources(chosen_locale);
+}
+
+void PlatformLanguageChanged(keynode_t* keynode, void* data) {
+#if defined(OS_TIZEN)
+ const char* lang = vconf_get_str(VCONFKEY_LANGSET);
+#else
+ const char* lang = "en";
+#endif
+
+ if (!setlocale(LC_ALL, lang))
+ LOG(WARNING) << "Failed to set LC_ALL to: " << lang;
+
+ // FIXME: this workaround guarantees correct order of locales which will
+ // be returned by g_get_language_names() in GetApplicationLocaleInternal()
+ // from l10n_util.cc. That function ignores it's argument: pref_locale.
+ // Without this, locale can't be changed in runtime by LoadLocaleResources()
+ setenv("LANGUAGE", lang, 1);
+
+ std::string process_type = CommandLine::ForCurrentProcess()->
+ GetSwitchValueASCII(switches::kProcessType);
+ if (process_type == switches::kRendererProcess) {
+ // Note: in case when someone will use IDS_BR_* from WebProcess this needs
+ // to be enabled or those strings have to be moved to chromium locale files.
+ // bindtextdomain("browser", "/usr/apps/org.tizen.browser/res/locale");
+ ReloadCorrectPakForLocale();
+ }
+}
+} // namespace
+
+void Initialize() {
+ base::FilePath locale_dir;
+ PathService::Get(PathsEfl::DIR_LOCALE, &locale_dir);
+ bindtextdomain("WebKit", locale_dir.value().c_str());
+
+ PlatformLanguageChanged(0, 0);
+#if defined(OS_TIZEN)
+ vconf_notify_key_changed(VCONFKEY_LANGSET, PlatformLanguageChanged, 0);
+#endif
+}
+
+}
+
--- /dev/null
+// Copyright 2015 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+namespace LocaleEfl {
+void Initialize();
+}
const base::FilePath::CharType kApplicationCacheDir[] = FILE_PATH_LITERAL("cache");
const base::FilePath::CharType kDownloadsDir[] = FILE_PATH_LITERAL("/opt/usr/media/Downloads/");
const base::FilePath::CharType kImagesDir[] = FILE_PATH_LITERAL("/opt/usr/media/Images/");
-
#else
const base::FilePath::CharType kEdjeThemesDir[] = FILE_PATH_LITERAL("resources");
+const base::FilePath::CharType kLocaleDir[] = FILE_PATH_LITERAL("locale");
const base::FilePath::CharType kDownloadsDir[] = FILE_PATH_LITERAL("/tmp/");
const base::FilePath::CharType kImagesDir[] = FILE_PATH_LITERAL("/tmp/");
#endif
*result = base::FilePath(kDataPath).Append(kEdjeThemesDir);
return true;
#else
+ case DIR_LOCALE:
+ PathService::Get(base::DIR_MODULE, result);
+ *result = result->Append(kLocaleDir);
+ return true;
case EDJE_RESOURCE_DIR:
PathService::Get(base::DIR_MODULE, result);
*result = result->Append(kEdjeThemesDir);
#include "paths_efl.h"
#include "renderer/content_renderer_client_efl.h"
#include "common/content_client_efl.h"
-#if defined(OS_TIZEN)
-#include <libintl.h>
-#include <string>
-#include <unistd.h>
-#include "vconf/vconf.h"
-#endif
+#include "locale_efl.h"
namespace content {
return new ContentRendererClientEfl();
}
-#if defined(OS_TIZEN)
-void reloadCorrectPakForLocale() {
- if (!ui::ResourceBundle::HasSharedInstance())
- return;
-
- std::string new_locale(vconf_get_str(VCONFKEY_LANGSET));
-
- // Note: locale from vconf is in format:
- // xy_ZW.UTF-8
- // blink pak files are not named same way, so we need to find correct pak.
- std::string chosen_locale = new_locale;
- bool pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
- chosen_locale);
-
- // xy_ZW.UTF-8 -> xy-ZW
- // Note: pak files are named after IETF_language_tag, which uses '-' not '_'
- if (!pak_exist) {
- chosen_locale = chosen_locale.substr(0, 5);
- if (chosen_locale.length() >=3 && chosen_locale[2] == '_')
- chosen_locale[2] = '-';
-
- pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
- chosen_locale);
- }
-
- // xy-ZW -> xy
- if (!pak_exist) {
- chosen_locale = chosen_locale.substr(0, 2);
- pak_exist = ui::ResourceBundle::GetSharedInstance().LocaleDataPakExists(
- chosen_locale);
- }
-
- if (!pak_exist) {
- LOG(WARNING) << "Unable to find any locale pak for " << chosen_locale;
- return;
- }
-
- ui::ResourceBundle::GetSharedInstance().ReloadLocaleResources(chosen_locale);
-}
-#endif
-
// ContentMainDelegate implementation:
void WebProcessContentMainDelegateEfl::PreSandboxStartup() {
base::FilePath pak_dir;
PathService::Get(base::DIR_EXE, &pak_dir);
pak_file = pak_dir.Append(FILE_PATH_LITERAL("content_shell.pak"));
ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
-#if defined(OS_TIZEN)
- reloadCorrectPakForLocale();
-#endif
}
-#if defined(OS_TIZEN)
-void webPlatformLanguageChanged(keynode_t* keynode, void* data) {
- base::FilePath locale_dir;
- PathService::Get(PathsEfl::DIR_LOCALE, &locale_dir);
- setlocale(LC_ALL, vconf_get_str(VCONFKEY_LANGSET));
-
- // FIXME: this workaround guarantees correct order of locales which will
- // be returned by g_get_language_names() in GetApplicationLocaleInternal()
- // from l10n_util.cc. That function ignores it's argument: pref_locale.
- // Without this, locale can't be changed in runtime by LoadLocaleResources()
- setenv("LANGUAGE", vconf_get_str(VCONFKEY_LANGSET), 1);
-
- bindtextdomain("WebKit", locale_dir.value().c_str());
- // Note: in case when someone will use IDS_BR_* from WebProcess this needs to be enabled
- // or those strings have to be moved to chromium locale files.
- // bindtextdomain("browser", "/usr/apps/org.tizen.browser/res/locale");
- reloadCorrectPakForLocale();
-}
-#endif
-
bool WebProcessContentMainDelegateEfl::BasicStartupComplete(int* exit_code) {
PathsEfl::Register();
-#if defined(OS_TIZEN)
- webPlatformLanguageChanged(0, 0);
- vconf_notify_key_changed(VCONFKEY_LANGSET, webPlatformLanguageChanged, 0);
-#endif
+ LocaleEfl::Initialize();
+
ContentClientEfl* content_client = new ContentClientEfl();
content::SetContentClient(content_client);
return false;
%global CHROMIUM_DATA_DIR %{_datadir}/%{name}
# Chromium unit tests install directory
%global CHROMIUM_UNITTESTS_DIR /opt/usr/chromium-unittests/
-%global LOCALE_DIR /usr/share/chromium-efl
+# Directory containing localization files
+%global CHROMIUM_LOCALE_DIR %{_datadir}/%{name}/locale
%global CHROMIUM_WEBDB_DIR /opt/usr/apps/chromium-efl
%prep
-Dexe_dir="%{CHROMIUM_EXE_DIR}" \
-Ddata_dir="%{CHROMIUM_DATA_DIR}" \
-Dedje_dir="%{CHROMIUM_DATA_DIR}"/themes \
+ -Dlocale_dir="%{CHROMIUM_LOCALE_DIR}" \
%if 0%{?_remove_webcore_debug_symbols:1}
-Dremove_webcore_debug_symbols=1 \
%endif
install -d "%{buildroot}%{CHROMIUM_EXE_DIR}"
install -d "%{buildroot}%{CHROMIUM_EXE_DIR}/locales"
install -d "%{buildroot}%{CHROMIUM_DATA_DIR}"/themes
-install -d "%{buildroot}%{CHROMIUM_DATA_DIR}"/locale
%if 0%{?build_chromedriver}
install -d "%{buildroot}"/usr/apps/com.samsung.chromedriver/bin
%endif
-mkdir -p %{OUTPUT_FOLDER}/po_tizen
-for file in ewk/po_tizen/*.po; do
- /usr/bin/msgfmt ${file} -o %{OUTPUT_FOLDER}/po_tizen/$(basename $file .po).mo
- install -d "%{buildroot}%{CHROMIUM_DATA_DIR}"/locale/$(basename $file .po)/LC_MESSAGES
- install -m 0755 %{OUTPUT_FOLDER}/po_tizen/$(basename $file .po).mo "%{buildroot}%{CHROMIUM_DATA_DIR}"/locale/$(basename $file .po)/LC_MESSAGES/WebKit.mo
-done
+cp -r "%{OUTPUT_FOLDER}/locale" "%{buildroot}/%{CHROMIUM_LOCALE_DIR}"
install -m 0755 "%{OUTPUT_FOLDER}"/locales/*.pak "%{buildroot}%{CHROMIUM_EXE_DIR}"/locales
%{CHROMIUM_EXE_DIR}/content_shell.pak
%{CHROMIUM_EXE_DIR}/locales/*.pak
%{CHROMIUM_DATA_DIR}/themes/*.edj
-%{CHROMIUM_DATA_DIR}/locale/*
+%{CHROMIUM_LOCALE_DIR}
%files devel
%defattr(-,root,root,-)