Commit b2850e38 authored by Sam McNally's avatar Sam McNally Committed by Commit Bot

Add support for $i18n{} for component app/extension resources.

i18n-values and i18n-content are deprecated, to be replaced by $i18n{}
in Web UI. Allow component apps/extensions to use the same i18n template
replacements as Web UI during serving.

Update the Files app quickview localization covered by a test to use
this method.

Bug: 923206,923204
Change-Id: I647bdea906c6bc427a82981fac780cc0e6badf2c
Reviewed-on: https://chromium-review.googlesource.com/c/1424619
Commit-Queue: Sam McNally <sammc@chromium.org>
Reviewed-by: default avatarNoel Gordon <noel@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Reviewed-by: default avatarLuciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#625122}
parent df90eab0
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/path_service.h" #include "base/path_service.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/values.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths.h"
#include "chrome/grit/chrome_unscaled_resources.h" #include "chrome/grit/chrome_unscaled_resources.h"
...@@ -14,7 +15,11 @@ ...@@ -14,7 +15,11 @@
#include "chrome/grit/theme_resources.h" #include "chrome/grit/theme_resources.h"
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/file_manager/file_manager_string_util.h"
#include "extensions/common/constants.h"
#include "third_party/ink/grit/ink_resources.h" #include "third_party/ink/grit/ink_resources.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/file_manager/file_manager_resource_util.h" #include "ui/file_manager/file_manager_resource_util.h"
#include "ui/file_manager/grit/file_manager_resources.h" #include "ui/file_manager/grit/file_manager_resources.h"
#include "ui/keyboard/resources/keyboard_resource_util.h" #include "ui/keyboard/resources/keyboard_resource_util.h"
...@@ -56,6 +61,16 @@ ChromeComponentExtensionResourceManager() { ...@@ -56,6 +61,16 @@ ChromeComponentExtensionResourceManager() {
file_manager_resources, file_manager_resources,
file_manager_resource_size); file_manager_resource_size);
// ResourceBundle and g_browser_process are not always initialized in unit
// tests.
if (ui::ResourceBundle::HasSharedInstance() && g_browser_process) {
ui::TemplateReplacements file_manager_replacements;
ui::TemplateReplacementsFromDictionaryValue(*GetFileManagerStrings(),
&file_manager_replacements);
extension_template_replacements_[extension_misc::kFilesManagerAppId] =
std::move(file_manager_replacements);
}
size_t keyboard_resource_size; size_t keyboard_resource_size;
const GritResourceMap* keyboard_resources = const GritResourceMap* keyboard_resources =
keyboard::GetKeyboardExtensionResources(&keyboard_resource_size); keyboard::GetKeyboardExtensionResources(&keyboard_resource_size);
...@@ -89,6 +104,16 @@ bool ChromeComponentExtensionResourceManager::IsComponentExtensionResource( ...@@ -89,6 +104,16 @@ bool ChromeComponentExtensionResourceManager::IsComponentExtensionResource(
return entry != path_to_resource_id_.end(); return entry != path_to_resource_id_.end();
} }
const ui::TemplateReplacements*
ChromeComponentExtensionResourceManager::GetTemplateReplacementsForExtension(
const std::string& extension_id) const {
auto it = extension_template_replacements_.find(extension_id);
if (it == extension_template_replacements_.end()) {
return nullptr;
}
return &it->second;
}
void ChromeComponentExtensionResourceManager::AddComponentResourceEntries( void ChromeComponentExtensionResourceManager::AddComponentResourceEntries(
const GritResourceMap* entries, const GritResourceMap* entries,
size_t size) { size_t size) {
......
...@@ -27,6 +27,8 @@ class ChromeComponentExtensionResourceManager ...@@ -27,6 +27,8 @@ class ChromeComponentExtensionResourceManager
bool IsComponentExtensionResource(const base::FilePath& extension_path, bool IsComponentExtensionResource(const base::FilePath& extension_path,
const base::FilePath& resource_path, const base::FilePath& resource_path,
int* resource_id) const override; int* resource_id) const override;
const ui::TemplateReplacements* GetTemplateReplacementsForExtension(
const std::string& extension_id) const override;
private: private:
void AddComponentResourceEntries(const GritResourceMap* entries, size_t size); void AddComponentResourceEntries(const GritResourceMap* entries, size_t size);
...@@ -35,6 +37,10 @@ class ChromeComponentExtensionResourceManager ...@@ -35,6 +37,10 @@ class ChromeComponentExtensionResourceManager
// IsComponentExtensionResource. // IsComponentExtensionResource.
std::map<base::FilePath, int> path_to_resource_id_; std::map<base::FilePath, int> path_to_resource_id_;
// A map from an extension ID to its i18n template replacements.
std::map<std::string, ui::TemplateReplacements>
extension_template_replacements_;
DISALLOW_COPY_AND_ASSIGN(ChromeComponentExtensionResourceManager); DISALLOW_COPY_AND_ASSIGN(ChromeComponentExtensionResourceManager);
}; };
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
#include "net/url_request/url_request_simple_job.h" #include "net/url_request/url_request_simple_job.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/base/template_expressions.h"
using extensions::ExtensionsBrowserClient; using extensions::ExtensionsBrowserClient;
...@@ -51,6 +52,30 @@ void DetermineCharset(const std::string& mime_type, ...@@ -51,6 +52,30 @@ void DetermineCharset(const std::string& mime_type,
} }
} }
scoped_refptr<base::RefCountedMemory> GetResource(
int resource_id,
const std::string& extension_id) {
const ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
scoped_refptr<base::RefCountedMemory> bytes =
rb.LoadDataResourceBytes(resource_id);
auto* replacements =
ExtensionsBrowserClient::Get()->GetComponentExtensionResourceManager()
? ExtensionsBrowserClient::Get()
->GetComponentExtensionResourceManager()
->GetTemplateReplacementsForExtension(extension_id)
: nullptr;
if (!bytes->size() || !replacements) {
return bytes;
}
base::StringPiece input(reinterpret_cast<const char*>(bytes->front()),
bytes->size());
std::string temp_str = ui::ReplaceTemplateExpressions(input, *replacements);
return base::RefCountedString::TakeString(&temp_str);
}
// A request for an extension resource in a Chrome .pak file. These are used // A request for an extension resource in a Chrome .pak file. These are used
// by component extensions. // by component extensions.
class URLRequestResourceBundleJob : public net::URLRequestSimpleJob { class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
...@@ -75,8 +100,7 @@ class URLRequestResourceBundleJob : public net::URLRequestSimpleJob { ...@@ -75,8 +100,7 @@ class URLRequestResourceBundleJob : public net::URLRequestSimpleJob {
std::string* charset, std::string* charset,
scoped_refptr<base::RefCountedMemory>* data, scoped_refptr<base::RefCountedMemory>* data,
net::CompletionOnceCallback callback) const override { net::CompletionOnceCallback callback) const override {
const ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); *data = GetResource(resource_id_, request()->url().host());
*data = rb.LoadDataResourceBytes(resource_id_);
// Add the Content-Length header now that we know the resource length. // Add the Content-Length header now that we know the resource length.
response_info_.headers->AddHeader( response_info_.headers->AddHeader(
...@@ -182,9 +206,7 @@ class ResourceBundleFileLoader : public network::mojom::URLLoader { ...@@ -182,9 +206,7 @@ class ResourceBundleFileLoader : public network::mojom::URLLoader {
&ResourceBundleFileLoader::OnBindingError, base::Unretained(this))); &ResourceBundleFileLoader::OnBindingError, base::Unretained(this)));
client_.set_connection_error_handler(base::BindOnce( client_.set_connection_error_handler(base::BindOnce(
&ResourceBundleFileLoader::OnConnectionError, base::Unretained(this))); &ResourceBundleFileLoader::OnConnectionError, base::Unretained(this)));
const ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); auto data = GetResource(resource_id, request.url.host());
scoped_refptr<base::RefCountedMemory> data =
rb.LoadDataResourceBytes(resource_id);
std::string* read_mime_type = new std::string; std::string* read_mime_type = new std::string;
base::PostTaskWithTraitsAndReplyWithResult( base::PostTaskWithTraitsAndReplyWithResult(
......
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
#ifndef EXTENSIONS_BROWSER_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_ #ifndef EXTENSIONS_BROWSER_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
#define EXTENSIONS_BROWSER_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_ #define EXTENSIONS_BROWSER_COMPONENT_EXTENSION_RESOURCE_MANAGER_H_
#include <string>
#include "ui/base/template_expressions.h"
namespace base { namespace base {
class FilePath; class FilePath;
} }
...@@ -25,6 +29,12 @@ class ComponentExtensionResourceManager { ...@@ -25,6 +29,12 @@ class ComponentExtensionResourceManager {
const base::FilePath& extension_path, const base::FilePath& extension_path,
const base::FilePath& resource_path, const base::FilePath& resource_path,
int* resource_id) const = 0; int* resource_id) const = 0;
// Returns the i18n template replacements for a component extension if they
// exist, or nullptr otherwise. If non-null, the returned value must remain
// valid for the life of this ComponentExtensionResourceManager.
virtual const ui::TemplateReplacements* GetTemplateReplacementsForExtension(
const std::string& extension_id) const = 0;
}; };
} // namespace extensions } // namespace extensions
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
<div class="category" i18n-content="METADATA_BOX_GENERAL_INFO"></div> <div class="category" i18n-content="METADATA_BOX_GENERAL_INFO"></div>
<files-metadata-entry i18n-values="key:METADATA_BOX_FILE_SIZE" value="[[size]]" loading="[[isSizeLoading]]"></files-metadata-entry> <files-metadata-entry i18n-values="key:METADATA_BOX_FILE_SIZE" value="[[size]]" loading="[[isSizeLoading]]"></files-metadata-entry>
<files-metadata-entry i18n-values="key:METADATA_BOX_MODIFICATION_TIME" value="[[modificationTime]]"></files-metadata-entry> <files-metadata-entry i18n-values="key:METADATA_BOX_MODIFICATION_TIME" value="[[modificationTime]]"></files-metadata-entry>
<files-metadata-entry i18n-values="key:METADATA_BOX_MEDIA_MIME_TYPE" value="[[mediaMimeType]]"></files-metadata-entry> <files-metadata-entry key="$i18n{METADATA_BOX_MEDIA_MIME_TYPE}" value="[[mediaMimeType]]"></files-metadata-entry>
<div hidden="[[!hasFileSpecificInfo_]]"> <div hidden="[[!hasFileSpecificInfo_]]">
<hr> <hr>
......
...@@ -116,9 +116,7 @@ testcase.openQuickViewDrive = async function() { ...@@ -116,9 +116,7 @@ testcase.openQuickViewDrive = async function() {
const mimeTypeSelector = [ const mimeTypeSelector = [
'#quick-view', '#quick-view',
'#metadata-box', '#metadata-box',
// TODO(crbug.com/677338): Replace the attribute selector with key="Type" 'files-metadata-entry[key="Type"]',
// once the key is populated with polymer2 enabled.
'files-metadata-entry[i18n-values="key:METADATA_BOX_MEDIA_MIME_TYPE"]',
'#value div', '#value div',
]; ];
chrome.test.assertEq( chrome.test.assertEq(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment