Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(273)

Side by Side Diff: extensions/browser/extension_user_script_loader.cc

Issue 1056533002: Implement <webview>.addContentScript/removeContentScript API [2] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@webview_addremove_contentscripts_2
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "extensions/browser/extension_user_script_loader.h" 5 #include "extensions/browser/extension_user_script_loader.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 15 matching lines...) Expand all
26 #include "extensions/common/message_bundle.h" 26 #include "extensions/common/message_bundle.h"
27 #include "extensions/common/one_shot_event.h" 27 #include "extensions/common/one_shot_event.h"
28 #include "ui/base/resource/resource_bundle.h" 28 #include "ui/base/resource/resource_bundle.h"
29 29
30 using content::BrowserContext; 30 using content::BrowserContext;
31 31
32 namespace extensions { 32 namespace extensions {
33 33
34 namespace { 34 namespace {
35 35
36 using LoadScriptsCallback =
37 base::Callback<void(scoped_ptr<UserScriptList>,
38 scoped_ptr<base::SharedMemory>)>;
39
36 // Verifies file contents as they are read. 40 // Verifies file contents as they are read.
37 void VerifyContent(const scoped_refptr<ContentVerifier>& verifier, 41 void VerifyContent(const scoped_refptr<ContentVerifier>& verifier,
38 const std::string& extension_id, 42 const std::string& extension_id,
39 const base::FilePath& extension_root, 43 const base::FilePath& extension_root,
40 const base::FilePath& relative_path, 44 const base::FilePath& relative_path,
41 const std::string& content) { 45 const std::string& content) {
42 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 46 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
43 scoped_refptr<ContentVerifyJob> job( 47 scoped_refptr<ContentVerifyJob> job(
44 verifier->CreateJobFor(extension_id, extension_root, relative_path)); 48 verifier->CreateJobFor(extension_id, extension_root, relative_path));
45 if (job.get()) { 49 if (job.get()) {
46 job->Start(); 50 job->Start();
47 job->BytesRead(content.size(), content.data()); 51 job->BytesRead(content.size(), content.data());
48 job->DoneReading(); 52 job->DoneReading();
49 } 53 }
50 } 54 }
51 55
52 // Loads user scripts from the extension who owns these scripts. 56 // Loads user scripts from the extension who owns these scripts.
53 bool ExtensionLoadScriptContent( 57 bool LoadScriptContent(
54 const HostID& host_id, 58 const HostID& host_id,
55 UserScript::File* script_file, 59 UserScript::File* script_file,
56 const UserScriptLoader::SubstitutionMap* localization_messages, 60 const UserScriptLoader::SubstitutionMap* localization_messages,
57 const scoped_refptr<ContentVerifier>& verifier) { 61 const scoped_refptr<ContentVerifier>& verifier) {
58 DCHECK(script_file); 62 DCHECK(script_file);
59 std::string content; 63 std::string content;
60 const base::FilePath& path = ExtensionResource::GetFilePath( 64 const base::FilePath& path = ExtensionResource::GetFilePath(
61 script_file->extension_root(), script_file->relative_path(), 65 script_file->extension_root(), script_file->relative_path(),
62 ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT); 66 ExtensionResource::SYMLINKS_MUST_RESOLVE_WITHIN_ROOT);
63 if (path.empty()) { 67 if (path.empty()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 // Remove BOM from the content. 105 // Remove BOM from the content.
102 std::string::size_type index = content.find(base::kUtf8ByteOrderMark); 106 std::string::size_type index = content.find(base::kUtf8ByteOrderMark);
103 if (index == 0) 107 if (index == 0)
104 script_file->set_content(content.substr(strlen(base::kUtf8ByteOrderMark))); 108 script_file->set_content(content.substr(strlen(base::kUtf8ByteOrderMark)));
105 else 109 else
106 script_file->set_content(content); 110 script_file->set_content(content);
107 111
108 return true; 112 return true;
109 } 113 }
110 114
115 UserScriptLoader::SubstitutionMap* GetLocalizationMessages(
116 const UserScriptLoader::HostsInfo& hosts_info,
117 const HostID& host_id) {
118 UserScriptLoader::HostsInfo::const_iterator iter = hosts_info.find(host_id);
119 if (iter == hosts_info.end())
120 return nullptr;
121 return file_util::LoadMessageBundleSubstitutionMap(
122 iter->second.first, host_id.id(), iter->second.second);
123 }
124
125 void LoadUserScripts(UserScriptList* user_scripts,
126 const UserScriptLoader::HostsInfo& hosts_info,
127 const std::set<int>& added_script_ids,
128 const scoped_refptr<ContentVerifier>& verifier) {
129 for (UserScriptList::iterator script = user_scripts->begin();
130 script != user_scripts->end(); ++script) {
131 if (added_script_ids.count(script->id()) == 0)
132 continue;
133 scoped_ptr<UserScriptLoader::SubstitutionMap> localization_messages(
134 GetLocalizationMessages(hosts_info, script->host_id()));
135 for (size_t k = 0; k < script->js_scripts().size(); ++k) {
136 UserScript::File& script_file = script->js_scripts()[k];
137 if (script_file.GetContent().empty())
138 LoadScriptContent(script->host_id(), &script_file, NULL, verifier);
139 }
140 for (size_t k = 0; k < script->css_scripts().size(); ++k) {
141 UserScript::File& script_file = script->css_scripts()[k];
142 if (script_file.GetContent().empty())
143 LoadScriptContent(script->host_id(), &script_file,
144 localization_messages.get(), verifier);
145 }
146 }
147 }
148
149 void LoadScriptsOnFileThread(scoped_ptr<UserScriptList> user_scripts,
150 const UserScriptLoader::HostsInfo& hosts_info,
151 const std::set<int>& added_script_ids,
152 const scoped_refptr<ContentVerifier>& verifier,
153 LoadScriptsCallback callback) {
154 DCHECK(user_scripts.get());
155 LoadUserScripts(user_scripts.get(), hosts_info, added_script_ids, verifier);
156 scoped_ptr<base::SharedMemory> memory =
157 UserScriptLoader::Serialize(*user_scripts);
158 content::BrowserThread::PostTask(
159 content::BrowserThread::UI, FROM_HERE,
160 base::Bind(callback, base::Passed(&user_scripts), base::Passed(&memory)));
161 }
162
111 } // namespace 163 } // namespace
112 164
113 ExtensionUserScriptLoader::ExtensionUserScriptLoader( 165 ExtensionUserScriptLoader::ExtensionUserScriptLoader(
114 BrowserContext* browser_context, 166 BrowserContext* browser_context,
115 const HostID& host_id, 167 const HostID& host_id,
116 bool listen_for_extension_system_loaded) 168 bool listen_for_extension_system_loaded)
117 : UserScriptLoader( 169 : UserScriptLoader(browser_context, host_id),
118 browser_context, 170 content_verifier_(
119 host_id,
120 ExtensionSystem::Get(browser_context)->content_verifier()), 171 ExtensionSystem::Get(browser_context)->content_verifier()),
121 extension_registry_observer_(this), 172 extension_registry_observer_(this),
122 weak_factory_(this) { 173 weak_factory_(this) {
123 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context)); 174 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context));
124 if (listen_for_extension_system_loaded) { 175 if (listen_for_extension_system_loaded) {
125 ExtensionSystem::Get(browser_context) 176 ExtensionSystem::Get(browser_context)
126 ->ready() 177 ->ready()
127 .Post(FROM_HERE, 178 .Post(FROM_HERE,
128 base::Bind(&ExtensionUserScriptLoader::OnExtensionSystemReady, 179 base::Bind(&ExtensionUserScriptLoader::OnExtensionSystemReady,
129 weak_factory_.GetWeakPtr())); 180 weak_factory_.GetWeakPtr()));
130 } else { 181 } else {
131 SetReady(true); 182 SetReady(true);
132 } 183 }
133 } 184 }
134 185
135 ExtensionUserScriptLoader::~ExtensionUserScriptLoader() { 186 ExtensionUserScriptLoader::~ExtensionUserScriptLoader() {
136 } 187 }
137 188
189 void ExtensionUserScriptLoader::LoadScriptsForTest(
190 UserScriptList* user_scripts) {
191 HostsInfo info;
192 std::set<int> added_script_ids;
193 for (UserScriptList::iterator it = user_scripts->begin();
194 it != user_scripts->end(); ++it) {
195 added_script_ids.insert(it->id());
196 }
197 LoadUserScripts(user_scripts, info, added_script_ids,
198 NULL /* no verifier for testing */);
199 }
200
201 void ExtensionUserScriptLoader::LoadScripts(
Devlin 2015/04/20 23:48:25 This would be cleaner if we kept the |user_scripts
Xi Han 2015/04/21 21:18:58 Change |user_scripts_| to a private member of base
202 const std::set<HostID>& changed_hosts,
203 const std::set<int>& added_script_ids) {
204 UpdateHostsInfo(changed_hosts);
205
206 content::BrowserThread::PostTask(
207 content::BrowserThread::FILE, FROM_HERE,
208 base::Bind(&LoadScriptsOnFileThread, base::Passed(&user_scripts_),
209 hosts_info_, added_script_ids, content_verifier_,
210 base::Bind(&ExtensionUserScriptLoader::OnScriptsLoaded,
211 weak_factory_.GetWeakPtr())));
212 ClearScripts(false);
213 user_scripts_.reset(NULL);
214 }
215
138 void ExtensionUserScriptLoader::UpdateHostsInfo( 216 void ExtensionUserScriptLoader::UpdateHostsInfo(
139 const std::set<HostID>& changed_hosts) { 217 const std::set<HostID>& changed_hosts) {
140 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context()); 218 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context());
141 for (const HostID& host_id : changed_hosts) { 219 for (const HostID& host_id : changed_hosts) {
142 const Extension* extension = 220 const Extension* extension =
143 registry->GetExtensionById(host_id.id(), ExtensionRegistry::ENABLED); 221 registry->GetExtensionById(host_id.id(), ExtensionRegistry::ENABLED);
144 // |changed_hosts_| may include hosts that have been removed, 222 // |changed_hosts_| may include hosts that have been removed,
145 // which leads to the above lookup failing. In this case, just continue. 223 // which leads to the above lookup failing. In this case, just continue.
146 if (!extension) 224 if (!extension)
147 continue; 225 continue;
148 AddHostInfo(host_id, ExtensionSet::ExtensionPathAndDefaultLocale( 226 if (hosts_info_.find(host_id) != hosts_info_.end())
149 extension->path(), 227 return;
Devlin 2015/04/20 23:48:25 Why return? Shouldn't it be continue?
Xi Han 2015/04/21 21:18:58 Good catch, thanks.
150 LocaleInfo::GetDefaultLocale(extension))); 228 hosts_info_[host_id] = ExtensionSet::ExtensionPathAndDefaultLocale(
229 extension->path(), LocaleInfo::GetDefaultLocale(extension));
151 } 230 }
152 } 231 }
153 232
154 UserScriptLoader::LoadUserScriptsContentFunction
155 ExtensionUserScriptLoader::GetLoadUserScriptsFunction() {
156 return base::Bind(&ExtensionLoadScriptContent);
157 }
158
159 void ExtensionUserScriptLoader::OnExtensionUnloaded( 233 void ExtensionUserScriptLoader::OnExtensionUnloaded(
160 content::BrowserContext* browser_context, 234 content::BrowserContext* browser_context,
161 const Extension* extension, 235 const Extension* extension,
162 UnloadedExtensionInfo::Reason reason) { 236 UnloadedExtensionInfo::Reason reason) {
163 RemoveHostInfo(HostID(HostID::EXTENSIONS, extension->id())); 237 hosts_info_.erase(HostID(HostID::EXTENSIONS, extension->id()));
164 } 238 }
165 239
166 void ExtensionUserScriptLoader::OnExtensionSystemReady() { 240 void ExtensionUserScriptLoader::OnExtensionSystemReady() {
167 SetReady(true); 241 SetReady(true);
168 } 242 }
169 243
170 } // namespace extensions 244 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698