Chromium Code Reviews| 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" |
| 22 #include "chrome/common/extensions/extension_file_util.h" | |
| 21 #include "chrome/common/extensions/extension_messages.h" | 23 #include "chrome/common/extensions/extension_messages.h" |
| 24 #include "chrome/common/extensions/extension_message_bundle.h" | |
| 22 #include "chrome/common/extensions/extension_resource.h" | 25 #include "chrome/common/extensions/extension_resource.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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 137 } | 146 } |
| 138 | 147 |
| 139 void UserScriptMaster::ScriptReloader::StartLoad( | 148 void UserScriptMaster::ScriptReloader::StartLoad( |
| 140 const UserScriptList& user_scripts) { | 149 const UserScriptList& user_scripts) { |
| 141 // Add a reference to ourselves to keep ourselves alive while we're running. | 150 // Add a reference to ourselves to keep ourselves alive while we're running. |
| 142 // Balanced by NotifyMaster(). | 151 // Balanced by NotifyMaster(). |
| 143 AddRef(); | 152 AddRef(); |
| 144 BrowserThread::PostTask( | 153 BrowserThread::PostTask( |
| 145 BrowserThread::FILE, FROM_HERE, | 154 BrowserThread::FILE, FROM_HERE, |
| 146 NewRunnableMethod( | 155 NewRunnableMethod( |
| 147 this, &UserScriptMaster::ScriptReloader::RunLoad, user_scripts)); | 156 this, &UserScriptMaster::ScriptReloader::RunLoad, user_scripts)); |
|
Nebojša Ćirić
2011/08/10 20:38:57
Do you wanna pass your map here to file thread?
adriansc
2011/08/10 23:20:53
I could, but the methods executing on BrowserThrea
| |
| 148 } | 157 } |
| 149 | 158 |
| 150 void UserScriptMaster::ScriptReloader::NotifyMaster( | 159 void UserScriptMaster::ScriptReloader::NotifyMaster( |
| 151 base::SharedMemory* memory) { | 160 base::SharedMemory* memory) { |
| 152 // The master went away, so these new scripts aren't useful anymore. | 161 // The master went away, so these new scripts aren't useful anymore. |
| 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() || !file_util::ReadFileToString(path, &content)) { | 177 if (path.empty() || !file_util::ReadFileToString(path, &content)) { |
| 168 LOG(WARNING) << "Failed to load user script file: " << path.value(); | 178 LOG(WARNING) << "Failed to load user script file: " << path.value(); |
| 169 return false; | 179 return false; |
| 170 } | 180 } |
| 171 | 181 |
| 182 // Localize the content. | |
| 183 if (!localization_messages.empty()) { | |
| 184 std::string error; | |
| 185 LOG(INFO) << "$$$_BEFORE_LOCALIZATION " << content; | |
|
Nebojša Ćirić
2011/08/10 20:38:57
Remove LOG(INFO).
adriansc
2011/08/10 23:20:53
Done.
| |
| 186 ExtensionMessageBundle::ReplaceMessagesWithExternalDictionary( | |
| 187 localization_messages, &content, &error); | |
| 188 LOG(INFO) << "@@@_AFTER__LOCALIZATION " << content; | |
| 189 } | |
| 190 | |
| 172 // Remove BOM from the content. | 191 // Remove BOM from the content. |
| 173 std::string::size_type index = content.find(kUtf8ByteOrderMark); | 192 std::string::size_type index = content.find(kUtf8ByteOrderMark); |
| 174 if (index == 0) { | 193 if (index == 0) { |
| 175 script_file->set_content(content.substr(strlen(kUtf8ByteOrderMark))); | 194 script_file->set_content(content.substr(strlen(kUtf8ByteOrderMark))); |
| 176 } else { | 195 } else { |
| 177 script_file->set_content(content); | 196 script_file->set_content(content); |
| 178 } | 197 } |
| 179 | 198 |
| 180 return true; | 199 return true; |
| 181 } | 200 } |
| 182 | 201 |
| 183 // static | |
| 184 void UserScriptMaster::ScriptReloader::LoadUserScripts( | 202 void UserScriptMaster::ScriptReloader::LoadUserScripts( |
| 185 UserScriptList* user_scripts) { | 203 UserScriptList* user_scripts) { |
| 186 for (size_t i = 0; i < user_scripts->size(); ++i) { | 204 for (size_t i = 0; i < user_scripts->size(); ++i) { |
| 187 UserScript& script = user_scripts->at(i); | 205 UserScript& script = user_scripts->at(i); |
| 206 SubstitutionMap localization_messages; | |
| 207 if (extensions_info_.find(script.extension_id()) != | |
| 208 extensions_info_.end()) { | |
| 209 localization_messages = | |
| 210 extension_file_util::LoadExtensionMessageBundleSubstitutionMap( | |
| 211 extensions_info_[script.extension_id()].first, | |
| 212 script.extension_id(), | |
| 213 extensions_info_[script.extension_id()].second); | |
|
Nebojša Ćirić
2011/08/10 20:38:57
Refactor this into a method call.
adriansc
2011/08/10 23:20:53
Done.
| |
| 214 } | |
| 188 for (size_t k = 0; k < script.js_scripts().size(); ++k) { | 215 for (size_t k = 0; k < script.js_scripts().size(); ++k) { |
| 189 UserScript::File& script_file = script.js_scripts()[k]; | 216 UserScript::File& script_file = script.js_scripts()[k]; |
| 190 if (script_file.GetContent().empty()) | 217 if (script_file.GetContent().empty()) |
| 191 LoadScriptContent(&script_file); | 218 LoadScriptContent(&script_file, localization_messages); |
| 192 } | 219 } |
| 193 for (size_t k = 0; k < script.css_scripts().size(); ++k) { | 220 for (size_t k = 0; k < script.css_scripts().size(); ++k) { |
| 194 UserScript::File& script_file = script.css_scripts()[k]; | 221 UserScript::File& script_file = script.css_scripts()[k]; |
| 195 if (script_file.GetContent().empty()) | 222 if (script_file.GetContent().empty()) |
| 196 LoadScriptContent(&script_file); | 223 LoadScriptContent(&script_file, localization_messages); |
| 197 } | 224 } |
| 198 } | 225 } |
| 199 } | 226 } |
| 200 | 227 |
| 201 // Pickle user scripts and return pointer to the shared memory. | 228 // Pickle user scripts and return pointer to the shared memory. |
| 202 static base::SharedMemory* Serialize(const UserScriptList& scripts) { | 229 static base::SharedMemory* Serialize(const UserScriptList& scripts) { |
| 203 Pickle pickle; | 230 Pickle pickle; |
| 204 pickle.WriteSize(scripts.size()); | 231 pickle.WriteSize(scripts.size()); |
| 205 for (size_t i = 0; i < scripts.size(); i++) { | 232 for (size_t i = 0; i < scripts.size(); i++) { |
| 206 const UserScript& script = scripts[i]; | 233 const UserScript& script = scripts[i]; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 if (!handle) | 401 if (!handle) |
| 375 return; | 402 return; |
| 376 | 403 |
| 377 base::SharedMemoryHandle handle_for_process; | 404 base::SharedMemoryHandle handle_for_process; |
| 378 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) | 405 if (!shared_memory->ShareToProcess(handle, &handle_for_process)) |
| 379 return; // This can legitimately fail if the renderer asserts at startup. | 406 return; // This can legitimately fail if the renderer asserts at startup. |
| 380 | 407 |
| 381 if (base::SharedMemory::IsHandleValid(handle_for_process)) | 408 if (base::SharedMemory::IsHandleValid(handle_for_process)) |
| 382 process->Send(new ExtensionMsg_UpdateUserScripts(handle_for_process)); | 409 process->Send(new ExtensionMsg_UpdateUserScripts(handle_for_process)); |
| 383 } | 410 } |
| OLD | NEW |