diff options
author | Szabolcs David <davidsz@inf.u-szeged.hu> | 2021-03-24 14:23:31 +0100 |
---|---|---|
committer | Szabolcs David <davidsz@inf.u-szeged.hu> | 2021-04-21 16:09:49 +0200 |
commit | 0b7510efcde8220e55b0cef5fefc1db76a3bd99a (patch) | |
tree | 5e1c9399185d2484cd880d8910d237cce4f407ea | |
parent | b29b245fcb9db741d14180ea7e8dcb3ad2d4f49a (diff) |
Fix application locales again
Different countries (with the same language) can have different number
formatting and navigator.language should report not only the language,
but also the country. Locale normalization often falls back by cutting
the country off, because we have common .pak files for countries with
the same language.
This patch:
- Uses the locale resolvation only for concatenating .pak file paths
and reports the full locale everywhere else.
- Properly sets default ICU locale for JS number formats and prevents
l10n_util::GetApplicationLocale() to set it sneakily to some resolved
one.
- Fixes the crashing --lang command line argument and always prefers
its value over QLocale.
Task-number: QTBUG-91225
Change-Id: I1c09798abdb523b80f0b7a3d69fa8d7a08c7c09a
Reviewed-by: Kirill Burtsev <kirill.burtsev@qt.io>
-rw-r--r-- | src/core/content_browser_client_qt.cpp | 15 | ||||
-rw-r--r-- | src/core/content_browser_client_qt.h | 2 | ||||
-rw-r--r-- | src/core/content_main_delegate_qt.cpp | 4 | ||||
-rw-r--r-- | src/core/renderer/content_renderer_client_qt.cpp | 3 | ||||
-rw-r--r-- | src/core/resource_bundle_qt.cpp | 2 | ||||
-rw-r--r-- | src/core/web_engine_library_info.cpp | 10 | ||||
-rw-r--r-- | src/core/web_engine_library_info.h | 1 | ||||
-rw-r--r-- | tests/auto/widgets/qwebengineview/BLACKLIST | 3 | ||||
-rw-r--r-- | tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | 49 |
9 files changed, 60 insertions, 29 deletions
diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index 76f94c61f..24aa19c91 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -39,6 +39,7 @@ #include "content_browser_client_qt.h" +#include "base/files/file_util.h" #include "base/optional.h" #include "base/task/post_task.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" @@ -479,12 +480,7 @@ std::unique_ptr<net::ClientCertStore> ContentBrowserClientQt::CreateClientCertSt std::string ContentBrowserClientQt::GetApplicationLocale() { - std::string bcp47Name = QLocale().bcp47Name().toStdString(); - if (m_cachedQtLocale != bcp47Name) { - m_cachedQtLocale = bcp47Name; - m_appLocale = WebEngineLibraryInfo::getApplicationLocale(); - } - return m_appLocale; + return WebEngineLibraryInfo::getApplicationLocale(); } std::string ContentBrowserClientQt::GetAcceptLangs(content::BrowserContext *context) @@ -500,7 +496,7 @@ void ContentBrowserClientQt::AppendExtraCommandLineSwitches(base::CommandLine* c std::string processType = command_line->GetSwitchValueASCII(switches::kProcessType); if (processType == switches::kZygoteProcess) - command_line->AppendSwitchASCII(switches::kLang, GetApplicationLocale()); + command_line->AppendSwitchASCII(switches::kLang, WebEngineLibraryInfo::getApplicationLocale()); } void ContentBrowserClientQt::GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes) @@ -528,9 +524,8 @@ void ContentBrowserClientQt::GetAdditionalAllowedSchemesForFileSystem(std::vecto #if defined(Q_OS_LINUX) void ContentBrowserClientQt::GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::PosixFileDescriptorInfo* mappings) { - const std::string &locale = GetApplicationLocale(); - const base::FilePath &locale_file_path = ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(locale); - if (locale_file_path.empty()) + const base::FilePath &locale_file_path = ui::ResourceBundle::GetSharedInstance().GetLocaleFilePath(WebEngineLibraryInfo::getResolvedLocale()); + if (locale_file_path.empty() || !base::PathExists(locale_file_path)) return; // Open pak file of the current locale in the Browser process and pass its file descriptor to the sandboxed diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index 1ccd2926d..7c8aa3ac9 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -269,8 +269,6 @@ public: private: scoped_refptr<ShareGroupQtQuick> m_shareGroupQtQuick; - std::string m_appLocale; - std::string m_cachedQtLocale; }; } // namespace QtWebEngineCore diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp index 59d7050a4..6137b0bea 100644 --- a/src/core/content_main_delegate_qt.cpp +++ b/src/core/content_main_delegate_qt.cpp @@ -179,7 +179,9 @@ void ContentMainDelegateQt::PreSandboxStartup() #endif net::NetModule::SetResourceProvider(PlatformResourceProvider); - ui::ResourceBundle::InitSharedInstanceWithLocale(WebEngineLibraryInfo::getApplicationLocale(), nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES); + + base::i18n::SetICUDefaultLocale(WebEngineLibraryInfo::getApplicationLocale()); + ui::ResourceBundle::InitSharedInstanceWithLocale(WebEngineLibraryInfo::getResolvedLocale(), nullptr, ui::ResourceBundle::LOAD_COMMON_RESOURCES); base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess(); logging::LoggingSettings settings; diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index 28815b5c1..d704e81b1 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -118,6 +118,8 @@ #include "chrome/renderer/media/webrtc_logging_agent_impl.h" #endif +#include "web_engine_library_info.h" + namespace QtWebEngineCore { static const char kHttpErrorDomain[] = "http"; @@ -134,6 +136,7 @@ ContentRendererClientQt::~ContentRendererClientQt() {} void ContentRendererClientQt::RenderThreadStarted() { + base::i18n::SetICUDefaultLocale(WebEngineLibraryInfo::getApplicationLocale()); content::RenderThread *renderThread = content::RenderThread::Get(); m_renderConfiguration.reset(new RenderConfiguration()); m_userResourceController.reset(new UserResourceController()); diff --git a/src/core/resource_bundle_qt.cpp b/src/core/resource_bundle_qt.cpp index 22622f216..4e814a806 100644 --- a/src/core/resource_bundle_qt.cpp +++ b/src/core/resource_bundle_qt.cpp @@ -98,7 +98,7 @@ std::string ResourceBundle::LoadLocaleResources(const std::string &pref_locale, { DCHECK(!locale_resources_data_.get()) << "locale.pak already loaded"; - std::string app_locale = l10n_util::GetApplicationLocale(pref_locale); + std::string app_locale = l10n_util::GetApplicationLocale(pref_locale, false /* set_icu_locale */); #if defined(OS_LINUX) int locale_fd = base::GlobalDescriptors::GetInstance()->MaybeGet(kWebEngineLocale); diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp index 09a4141b0..3a6492273 100644 --- a/src/core/web_engine_library_info.cpp +++ b/src/core/web_engine_library_info.cpp @@ -351,7 +351,7 @@ base::string16 WebEngineLibraryInfo::getApplicationName() return toString16(qApp->applicationName()); } -std::string WebEngineLibraryInfo::getApplicationLocale() +std::string WebEngineLibraryInfo::getResolvedLocale() { base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess(); if (parsedCommandLine->HasSwitch(switches::kLang)) { @@ -365,6 +365,14 @@ std::string WebEngineLibraryInfo::getApplicationLocale() return "en-US"; } +std::string WebEngineLibraryInfo::getApplicationLocale() +{ + base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess(); + return parsedCommandLine->HasSwitch(switches::kLang) + ? parsedCommandLine->GetSwitchValueASCII(switches::kLang) + : QLocale().bcp47Name().toStdString(); +} + #if defined(OS_WIN) bool WebEngineLibraryInfo::isRemoteDrivePath(const QString &path) { diff --git a/src/core/web_engine_library_info.h b/src/core/web_engine_library_info.h index 4d23d8921..e7dc195f6 100644 --- a/src/core/web_engine_library_info.h +++ b/src/core/web_engine_library_info.h @@ -57,6 +57,7 @@ public: static base::FilePath getPath(int key); // Called by localized_error in our custom chrome layer static base::string16 getApplicationName(); + static std::string getResolvedLocale(); static std::string getApplicationLocale(); #if defined(OS_WIN) static bool isRemoteDrivePath(const QString &path); diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST index 05ebee4ce..c1a46e16d 100644 --- a/tests/auto/widgets/qwebengineview/BLACKLIST +++ b/tests/auto/widgets/qwebengineview/BLACKLIST @@ -6,3 +6,6 @@ windows [horizontalScrollbarTest] osx + +[mixLangLocale:eu_ES] +* diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index d86810713..4854b3603 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -124,6 +124,7 @@ private Q_SLOTS: void doNotBreakLayout(); void changeLocale(); + void mixLangLocale_data(); void mixLangLocale(); void inputMethodsTextFormat_data(); void inputMethodsTextFormat(); @@ -1213,26 +1214,46 @@ void tst_QWebEngineView::changeLocale() QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar")); } +void tst_QWebEngineView::mixLangLocale_data() +{ + QTest::addColumn<QString>("locale"); + QTest::addColumn<QByteArray>("formattedNumber"); + QTest::newRow("en_DK") << "en-DK" << QByteArray("1.234.567.890"); + QTest::newRow("de") << "de" << QByteArray("1.234.567.890"); + QTest::newRow("de_CH") << "de-CH" << QByteArray("1’234’567’890"); + QTest::newRow("eu_ES") << "eu-ES" << QByteArray("1.234.567.890"); + QTest::newRow("hu_HU") << "hu-HU" << QByteArray("1\xC2\xA0""234\xC2\xA0""567\xC2\xA0""890"); // no-break spaces +} + void tst_QWebEngineView::mixLangLocale() { - for (QString locale : { "en_DK", "de_CH", "eu_ES" }) { - QLocale::setDefault(locale); - QWebEngineView view; - QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished); + QFETCH(QString, locale); + QFETCH(QByteArray, formattedNumber); - bool terminated = false; - auto sc = connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; }); + QLocale::setDefault(locale); - view.load(QUrl("qrc:///resources/dummy.html")); - QTRY_VERIFY(terminated || loadSpy.count() == 1); + QWebEngineView view; + QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished); - QVERIFY2(!terminated, - qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.count()))); - QVERIFY(loadSpy.first().first().toBool()); + bool terminated = false; + auto sc = connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; }); + + view.load(QUrl("qrc:///resources/dummy.html")); + QTRY_VERIFY(terminated || loadSpy.count() == 1); + + QVERIFY2(!terminated, + qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.count()))); + QVERIFY(loadSpy.first().first().toBool()); + + QString content = toPlainTextSync(view.page()); + QVERIFY2(!content.isEmpty() && content.contains("test content"), qPrintable(content)); + + QCOMPARE(evaluateJavaScriptSync(view.page(), "navigator.language").toString(), QLocale().bcp47Name()); + + if (locale == "eu-ES") + QEXPECT_FAIL("", "Basque number formatting is somehow dependent on environment", Continue); + QCOMPARE(evaluateJavaScriptSync(view.page(), "Number(1234567890).toLocaleString()").toByteArray(), formattedNumber); - QString content = toPlainTextSync(view.page()); - QVERIFY2(!content.isEmpty() && content.contains("test content"), qPrintable(content)); - } QLocale::setDefault(QLocale("en")); } |