Chromium Code Reviews| Index: chrome/browser/extensions/user_script_master.cc |
| diff --git a/chrome/browser/extensions/user_script_master.cc b/chrome/browser/extensions/user_script_master.cc |
| index 5e680980cd7cb94e6b3a4356884540f9d6bda263..8d14eb41709b73cfc997cc8a35f236748c2f6fde 100644 |
| --- a/chrome/browser/extensions/user_script_master.cc |
| +++ b/chrome/browser/extensions/user_script_master.cc |
| @@ -4,6 +4,7 @@ |
| #include "chrome/browser/extensions/user_script_master.h" |
| +#include <map> |
| #include <string> |
| #include <vector> |
| @@ -18,8 +19,10 @@ |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/common/chrome_notification_types.h" |
| #include "chrome/common/extensions/extension.h" |
| -#include "chrome/common/extensions/extension_messages.h" |
| +#include "chrome/common/extensions/extension_file_util.h" |
| +#include "chrome/common/extensions/extension_message_bundle.h" |
| #include "chrome/common/extensions/extension_resource.h" |
| +#include "chrome/common/extensions/extension_set.h" |
| #include "content/browser/renderer_host/render_process_host.h" |
| #include "content/common/notification_service.h" |
| @@ -141,12 +144,25 @@ void UserScriptMaster::ScriptReloader::StartLoad( |
| // Add a reference to ourselves to keep ourselves alive while we're running. |
| // Balanced by NotifyMaster(). |
| AddRef(); |
| + |
| + const ExtensionInfoMap* info_map = NULL; |
| + // Gather extensions information needed for localization. |
| + if (master_ && master_->profile_ && |
| + master_->profile_->GetExtensionInfoMap()) { |
| + info_map = master_->profile_->GetExtensionInfoMap(); |
| + // Add a reference to the info_map to keep it alive while we're in the IO |
| + // thread iterating through the available extensions set. |
| + // Balanced by GatherExtensionsInfo(). |
| + info_map->AddRef(); |
| + } |
| BrowserThread::PostTask( |
| - BrowserThread::FILE, FROM_HERE, |
| + BrowserThread::IO, FROM_HERE, |
| NewRunnableMethod( |
| - this, &UserScriptMaster::ScriptReloader::RunLoad, user_scripts)); |
| + this, &UserScriptMaster::ScriptReloader::GatherExtensionsInfo, |
| + info_map, user_scripts)); |
| } |
| + |
| void UserScriptMaster::ScriptReloader::NotifyMaster( |
| base::SharedMemory* memory) { |
| // The master went away, so these new scripts aren't useful anymore. |
| @@ -160,7 +176,8 @@ void UserScriptMaster::ScriptReloader::NotifyMaster( |
| Release(); |
| } |
| -static bool LoadScriptContent(UserScript::File* script_file) { |
| +static bool LoadScriptContent(UserScript::File* script_file, |
| + const SubstitutionMap* localization_messages) { |
| std::string content; |
| const FilePath& path = ExtensionResource::GetFilePath( |
| script_file->extension_root(), script_file->relative_path()); |
| @@ -175,6 +192,16 @@ static bool LoadScriptContent(UserScript::File* script_file) { |
| return false; |
| } |
| + // Localize the content. |
| + if (localization_messages) { |
| + std::string error; |
| + ExtensionMessageBundle::ReplaceMessagesWithExternalDictionary( |
| + *localization_messages, &content, &error); |
| + if (!error.empty()) { |
| + LOG(WARNING) << "Failed to replace messages in script: " << error; |
| + } |
| + } |
| + |
| // Remove BOM from the content. |
| std::string::size_type index = content.find(kUtf8ByteOrderMark); |
| if (index == 0) { |
| @@ -186,24 +213,37 @@ static bool LoadScriptContent(UserScript::File* script_file) { |
| return true; |
| } |
| -// static |
| void UserScriptMaster::ScriptReloader::LoadUserScripts( |
| UserScriptList* user_scripts) { |
| for (size_t i = 0; i < user_scripts->size(); ++i) { |
| UserScript& script = user_scripts->at(i); |
| + scoped_ptr<SubstitutionMap> localization_messages( |
| + GetLocalizationMessages(script.extension_id())); |
| for (size_t k = 0; k < script.js_scripts().size(); ++k) { |
| UserScript::File& script_file = script.js_scripts()[k]; |
| if (script_file.GetContent().empty()) |
| - LoadScriptContent(&script_file); |
| + LoadScriptContent(&script_file, NULL); |
| } |
| for (size_t k = 0; k < script.css_scripts().size(); ++k) { |
| UserScript::File& script_file = script.css_scripts()[k]; |
| if (script_file.GetContent().empty()) |
| - LoadScriptContent(&script_file); |
| + LoadScriptContent(&script_file, localization_messages.get()); |
| } |
| } |
| } |
| +SubstitutionMap* UserScriptMaster::ScriptReloader::GetLocalizationMessages( |
| + std::string extension_id) { |
| + if (extensions_info_.find(extension_id) == extensions_info_.end()) { |
| + return NULL; |
| + } |
| + |
| + return extension_file_util::LoadExtensionMessageBundleSubstitutionMap( |
| + extensions_info_[extension_id].first, |
| + extension_id, |
| + extensions_info_[extension_id].second); |
| +} |
| + |
| // Pickle user scripts and return pointer to the shared memory. |
| static base::SharedMemory* Serialize(const UserScriptList& scripts) { |
| Pickle pickle; |
| @@ -238,6 +278,22 @@ static base::SharedMemory* Serialize(const UserScriptList& scripts) { |
| return shared_memory.release(); |
| } |
| +// This method will be called on the IO thread |
| +void UserScriptMaster::ScriptReloader::GatherExtensionsInfo( |
|
Nebojša Ćirić
2011/08/19 22:02:25
Maybe:
CollectExtensionsInfo, GetExtensionsInfo?
|
| + const ExtensionInfoMap* const info_map, |
| + const UserScriptList& user_scripts) { |
| + if (info_map) { |
| + info_map->extensions().GetExtensionsPathAndDefaultLocale(&extensions_info_); |
| + // Drop the reference on the ExtensionInfoMap object after reading from it. |
| + // Balances StartLoad(). |
| + info_map->Release(); |
| + } |
| + BrowserThread::PostTask( |
| + BrowserThread::FILE, FROM_HERE, |
| + NewRunnableMethod( |
| + this, &UserScriptMaster::ScriptReloader::RunLoad, user_scripts)); |
| +} |
| + |
| // This method will be called from the file thread |
| void UserScriptMaster::ScriptReloader::RunLoad( |
| const UserScriptList& user_scripts) { |