OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/user_script_master.h" | 5 #include "chrome/browser/extensions/user_script_master.h" |
6 | 6 |
| 7 #include <map> |
7 #include <string> | 8 #include <string> |
8 #include <vector> | 9 #include <vector> |
9 | 10 |
10 #include "base/file_path.h" | 11 #include "base/file_path.h" |
11 #include "base/file_util.h" | 12 #include "base/file_util.h" |
12 #include "base/pickle.h" | 13 #include "base/pickle.h" |
13 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
14 #include "base/string_util.h" | 15 #include "base/string_util.h" |
15 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
16 #include "base/version.h" | 17 #include "base/version.h" |
17 #include "chrome/browser/extensions/extension_service.h" | 18 #include "chrome/browser/extensions/extension_service.h" |
18 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/common/chrome_notification_types.h" | 20 #include "chrome/common/chrome_notification_types.h" |
20 #include "chrome/common/extensions/extension.h" | 21 #include "chrome/common/extensions/extension.h" |
21 #include "chrome/common/extensions/extension_messages.h" | 22 #include "chrome/common/extensions/extension_file_util.h" |
| 23 #include "chrome/common/extensions/extension_message_bundle.h" |
22 #include "chrome/common/extensions/extension_resource.h" | 24 #include "chrome/common/extensions/extension_resource.h" |
| 25 #include "chrome/common/extensions/extension_set.h" |
23 #include "content/browser/renderer_host/render_process_host.h" | 26 #include "content/browser/renderer_host/render_process_host.h" |
24 #include "content/common/notification_service.h" | 27 #include "content/common/notification_service.h" |
25 | 28 |
26 // Helper function to parse greasesmonkey headers | 29 // Helper function to parse greasesmonkey headers |
27 static bool GetDeclarationValue(const base::StringPiece& line, | 30 static bool GetDeclarationValue(const base::StringPiece& line, |
28 const base::StringPiece& prefix, | 31 const base::StringPiece& prefix, |
29 std::string* value) { | 32 std::string* value) { |
30 base::StringPiece::size_type index = line.find(prefix); | 33 base::StringPiece::size_type index = line.find(prefix); |
31 if (index == base::StringPiece::npos) | 34 if (index == base::StringPiece::npos) |
32 return false; | 35 return false; |
33 | 36 |
34 std::string temp(line.data() + index + prefix.length(), | 37 std::string temp(line.data() + index + prefix.length(), |
35 line.length() - index - prefix.length()); | 38 line.length() - index - prefix.length()); |
36 | 39 |
37 if (temp.empty() || !IsWhitespace(temp[0])) | 40 if (temp.empty() || !IsWhitespace(temp[0])) |
38 return false; | 41 return false; |
39 | 42 |
40 TrimWhitespaceASCII(temp, TRIM_ALL, value); | 43 TrimWhitespaceASCII(temp, TRIM_ALL, value); |
41 return true; | 44 return true; |
42 } | 45 } |
43 | 46 |
44 UserScriptMaster::ScriptReloader::ScriptReloader(UserScriptMaster* master) | 47 UserScriptMaster::ScriptReloader::ScriptReloader(UserScriptMaster* master) |
45 : master_(master) { | 48 : master_(master) { |
46 CHECK(BrowserThread::GetCurrentThreadIdentifier(&master_thread_id_)); | 49 CHECK(BrowserThread::GetCurrentThreadIdentifier(&master_thread_id_)); |
| 50 |
| 51 // Gather extensions information needed for localization. |
| 52 if (master && master->profile_ && master->profile_->GetExtensionInfoMap()) { |
| 53 const ExtensionInfoMap* info_map = master->profile_->GetExtensionInfoMap(); |
| 54 info_map->extensions().GetExtensionsPathAndDefaultLocale(extensions_info_); |
| 55 } |
47 } | 56 } |
48 | 57 |
49 // static | 58 // static |
50 bool UserScriptMaster::ScriptReloader::ParseMetadataHeader( | 59 bool UserScriptMaster::ScriptReloader::ParseMetadataHeader( |
51 const base::StringPiece& script_text, UserScript* script) { | 60 const base::StringPiece& script_text, UserScript* script) { |
52 // http://wiki.greasespot.net/Metadata_block | 61 // http://wiki.greasespot.net/Metadata_block |
53 base::StringPiece line; | 62 base::StringPiece line; |
54 size_t line_start = 0; | 63 size_t line_start = 0; |
55 size_t line_end = line_start; | 64 size_t line_end = line_start; |
56 bool in_metadata = false; | 65 bool in_metadata = false; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 if (!master_) | 162 if (!master_) |
154 delete memory; | 163 delete memory; |
155 else | 164 else |
156 master_->NewScriptsAvailable(memory); | 165 master_->NewScriptsAvailable(memory); |
157 | 166 |
158 // Drop our self-reference. | 167 // Drop our self-reference. |
159 // Balances StartLoad(). | 168 // Balances StartLoad(). |
160 Release(); | 169 Release(); |
161 } | 170 } |
162 | 171 |
163 static bool LoadScriptContent(UserScript::File* script_file) { | 172 static bool LoadScriptContent(UserScript::File* script_file, |
| 173 const SubstitutionMap* localization_messages) { |
164 std::string content; | 174 std::string content; |
165 const FilePath& path = ExtensionResource::GetFilePath( | 175 const FilePath& path = ExtensionResource::GetFilePath( |
166 script_file->extension_root(), script_file->relative_path()); | 176 script_file->extension_root(), script_file->relative_path()); |
167 if (path.empty()) { | 177 if (path.empty()) { |
168 LOG(WARNING) << "Failed to get file path to " | 178 LOG(WARNING) << "Failed to get file path to " |
169 << script_file->relative_path().value() << " from " | 179 << script_file->relative_path().value() << " from " |
170 << script_file->extension_root().value(); | 180 << script_file->extension_root().value(); |
171 return false; | 181 return false; |
172 } | 182 } |
173 if (!file_util::ReadFileToString(path, &content)) { | 183 if (!file_util::ReadFileToString(path, &content)) { |
174 LOG(WARNING) << "Failed to load user script file: " << path.value(); | 184 LOG(WARNING) << "Failed to load user script file: " << path.value(); |
175 return false; | 185 return false; |
176 } | 186 } |
177 | 187 |
| 188 // Localize the content. |
| 189 if (localization_messages) { |
| 190 std::string error; |
| 191 ExtensionMessageBundle::ReplaceMessagesWithExternalDictionary( |
| 192 *localization_messages, &content, &error); |
| 193 if (!error.empty()) { |
| 194 LOG(WARNING) << "Failed to replace messages in script: " << error; |
| 195 } |
| 196 } |
| 197 |
178 // Remove BOM from the content. | 198 // Remove BOM from the content. |
179 std::string::size_type index = content.find(kUtf8ByteOrderMark); | 199 std::string::size_type index = content.find(kUtf8ByteOrderMark); |
180 if (index == 0) { | 200 if (index == 0) { |
181 script_file->set_content(content.substr(strlen(kUtf8ByteOrderMark))); | 201 script_file->set_content(content.substr(strlen(kUtf8ByteOrderMark))); |
182 } else { | 202 } else { |
183 script_file->set_content(content); | 203 script_file->set_content(content); |
184 } | 204 } |
185 | 205 |
186 return true; | 206 return true; |
187 } | 207 } |
188 | 208 |
189 // static | |
190 void UserScriptMaster::ScriptReloader::LoadUserScripts( | 209 void UserScriptMaster::ScriptReloader::LoadUserScripts( |
191 UserScriptList* user_scripts) { | 210 UserScriptList* user_scripts) { |
192 for (size_t i = 0; i < user_scripts->size(); ++i) { | 211 for (size_t i = 0; i < user_scripts->size(); ++i) { |
193 UserScript& script = user_scripts->at(i); | 212 UserScript& script = user_scripts->at(i); |
| 213 scoped_ptr<SubstitutionMap> localization_messages( |
| 214 GetLocalizationMessages(script.extension_id())); |
194 for (size_t k = 0; k < script.js_scripts().size(); ++k) { | 215 for (size_t k = 0; k < script.js_scripts().size(); ++k) { |
195 UserScript::File& script_file = script.js_scripts()[k]; | 216 UserScript::File& script_file = script.js_scripts()[k]; |
196 if (script_file.GetContent().empty()) | 217 if (script_file.GetContent().empty()) |
197 LoadScriptContent(&script_file); | 218 LoadScriptContent(&script_file, NULL); |
198 } | 219 } |
199 for (size_t k = 0; k < script.css_scripts().size(); ++k) { | 220 for (size_t k = 0; k < script.css_scripts().size(); ++k) { |
200 UserScript::File& script_file = script.css_scripts()[k]; | 221 UserScript::File& script_file = script.css_scripts()[k]; |
201 if (script_file.GetContent().empty()) | 222 if (script_file.GetContent().empty()) |
202 LoadScriptContent(&script_file); | 223 LoadScriptContent(&script_file, localization_messages.get()); |
203 } | 224 } |
204 } | 225 } |
205 } | 226 } |
206 | 227 |
| 228 SubstitutionMap* UserScriptMaster::ScriptReloader::GetLocalizationMessages( |
| 229 std::string extension_id) { |
| 230 if (extensions_info_.find(extension_id) == extensions_info_.end()) { |
| 231 return NULL; |
| 232 } |
| 233 |
| 234 return extension_file_util::LoadExtensionMessageBundleSubstitutionMap( |
| 235 extensions_info_[extension_id].first, |
| 236 extension_id, |
| 237 extensions_info_[extension_id].second); |
| 238 } |
| 239 |
207 // Pickle user scripts and return pointer to the shared memory. | 240 // Pickle user scripts and return pointer to the shared memory. |
208 static base::SharedMemory* Serialize(const UserScriptList& scripts) { | 241 static base::SharedMemory* Serialize(const UserScriptList& scripts) { |
209 Pickle pickle; | 242 Pickle pickle; |
210 pickle.WriteSize(scripts.size()); | 243 pickle.WriteSize(scripts.size()); |
211 for (size_t i = 0; i < scripts.size(); i++) { | 244 for (size_t i = 0; i < scripts.size(); i++) { |
212 const UserScript& script = scripts[i]; | 245 const UserScript& script = scripts[i]; |
213 // TODO(aa): This can be replaced by sending content script metadata to | 246 // TODO(aa): This can be replaced by sending content script metadata to |
214 // renderers along with other extension data in ExtensionMsg_Loaded. | 247 // renderers along with other extension data in ExtensionMsg_Loaded. |
215 // See crbug.com/70516. | 248 // See crbug.com/70516. |
216 script.Pickle(&pickle); | 249 script.Pickle(&pickle); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
380 if (!handle) | 413 if (!handle) |
381 return; | 414 return; |
382 | 415 |
383 base::SharedMemoryHandle handle_for_process; | 416 base::SharedMemoryHandle handle_for_process; |
384 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) | 417 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) |
385 return; // This can legitimately fail if the renderer asserts at startup. | 418 return; // This can legitimately fail if the renderer asserts at startup. |
386 | 419 |
387 if (base::SharedMemory::IsHandleValid(handle_for_process)) | 420 if (base::SharedMemory::IsHandleValid(handle_for_process)) |
388 process->Send(new ExtensionMsg_UpdateUserScripts(handle_for_process)); | 421 process->Send(new ExtensionMsg_UpdateUserScripts(handle_for_process)); |
389 } | 422 } |
OLD | NEW |