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

Side by Side Diff: extensions/browser/api/web_view/web_view_internal_api.cc

Issue 959413003: Implement <webview>.addContentScript/removeContentScript API [1] (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add a test. Created 5 years, 9 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/api/web_view/web_view_internal_api.h" 5 #include "extensions/browser/api/web_view/web_view_internal_api.h"
6 6
7 #include "base/strings/string_number_conversions.h"
7 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
9 #include "content/public/browser/render_process_host.h" 10 #include "content/public/browser/render_process_host.h"
10 #include "content/public/browser/render_view_host.h" 11 #include "content/public/browser/render_view_host.h"
11 #include "content/public/browser/storage_partition.h" 12 #include "content/public/browser/storage_partition.h"
12 #include "content/public/browser/web_contents.h" 13 #include "content/public/browser/web_contents.h"
13 #include "content/public/common/stop_find_action.h" 14 #include "content/public/common/stop_find_action.h"
14 #include "extensions/common/api/web_view_internal.h" 15 #include "extensions/common/api/web_view_internal.h"
16 #include "extensions/common/error_utils.h"
17 #include "extensions/common/user_script.h"
15 #include "third_party/WebKit/public/web/WebFindOptions.h" 18 #include "third_party/WebKit/public/web/WebFindOptions.h"
16 19
17 using content::WebContents; 20 using content::WebContents;
18 using extensions::core_api::web_view_internal::SetPermission::Params; 21 using extensions::core_api::web_view_internal::SetPermission::Params;
19 using extensions::core_api::extension_types::InjectDetails; 22 using extensions::core_api::extension_types::InjectDetails;
23 using extensions::core_api::web_view_internal::ContentScriptDetails;
24 using extensions::ExtensionResource;
25 using extensions::UserScript;
20 namespace webview = extensions::core_api::web_view_internal; 26 namespace webview = extensions::core_api::web_view_internal;
21 27
22 namespace { 28 namespace {
23 29
24 const char kAppCacheKey[] = "appcache"; 30 const char kAppCacheKey[] = "appcache";
25 const char kCookiesKey[] = "cookies"; 31 const char kCookiesKey[] = "cookies";
26 const char kFileSystemsKey[] = "fileSystems"; 32 const char kFileSystemsKey[] = "fileSystems";
27 const char kIndexedDBKey[] = "indexedDB"; 33 const char kIndexedDBKey[] = "indexedDB";
28 const char kLocalStorageKey[] = "localStorage"; 34 const char kLocalStorageKey[] = "localStorage";
29 const char kWebSQLKey[] = "webSQL"; 35 const char kWebSQLKey[] = "webSQL";
30 const char kSinceKey[] = "since"; 36 const char kSinceKey[] = "since";
31 37
32 int MaskForKey(const char* key) { 38 int MaskForKey(const char* key) {
33 if (strcmp(key, kAppCacheKey) == 0) 39 if (strcmp(key, kAppCacheKey) == 0)
34 return content::StoragePartition::REMOVE_DATA_MASK_APPCACHE; 40 return content::StoragePartition::REMOVE_DATA_MASK_APPCACHE;
35 if (strcmp(key, kCookiesKey) == 0) 41 if (strcmp(key, kCookiesKey) == 0)
36 return content::StoragePartition::REMOVE_DATA_MASK_COOKIES; 42 return content::StoragePartition::REMOVE_DATA_MASK_COOKIES;
37 if (strcmp(key, kFileSystemsKey) == 0) 43 if (strcmp(key, kFileSystemsKey) == 0)
38 return content::StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS; 44 return content::StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
39 if (strcmp(key, kIndexedDBKey) == 0) 45 if (strcmp(key, kIndexedDBKey) == 0)
40 return content::StoragePartition::REMOVE_DATA_MASK_INDEXEDDB; 46 return content::StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
41 if (strcmp(key, kLocalStorageKey) == 0) 47 if (strcmp(key, kLocalStorageKey) == 0)
42 return content::StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE; 48 return content::StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
43 if (strcmp(key, kWebSQLKey) == 0) 49 if (strcmp(key, kWebSQLKey) == 0)
44 return content::StoragePartition::REMOVE_DATA_MASK_WEBSQL; 50 return content::StoragePartition::REMOVE_DATA_MASK_WEBSQL;
45 return 0; 51 return 0;
46 } 52 }
47 53
54 scoped_ptr<const HostID> GenerateHostID(const extensions::Extension* extension,
55 const content::RenderViewHost* rvh) {
56 if (extension)
57 return scoped_ptr<const HostID>(
58 new HostID(HostID::EXTENSIONS, extension->id()));
59 if (rvh) {
60 WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
61 if (web_contents && web_contents->GetWebUI()) {
62 const GURL& url = rvh->GetSiteInstance()->GetSiteURL();
63 return scoped_ptr<const HostID>(new HostID(HostID::WEBUI, url.spec()));
64 }
65 }
66 NOTREACHED();
67 return scoped_ptr<const HostID>();
68 }
69
70 // Initialize the user script.
71 void InitUserScript(UserScript* script, extensions::WebViewGuest* guest) {
Fady Samuel 2015/03/11 11:43:17 This is a lot of code that isn't basic binding glu
72 if (!script)
73 return;
74 script->set_id(UserScript::GenerateUserScriptID());
75 script->set_host_id(*(guest->host_id()));
76 script->set_consumer_instance_type(UserScript::WEBVIEW);
77 content::WebContents* web_contents = guest->web_contents();
78 if (web_contents) {
79 script->set_routing_info(
80 UserScript::RoutingInfo(web_contents->GetRenderProcessHost()->GetID(),
81 web_contents->GetRoutingID()));
82 }
83 }
84
85 bool Parse(const ContentScriptDetails& script_value,
86 UserScript* script,
87 extensions::WebViewGuest* guest,
88 const extensions::Extension* extension) {
89 // matches (required):
90 const std::vector<std::string>& matches = script_value.matches;
91 if (matches.size() == 0) {
92 return false;
93 }
94
95 for (const std::string& match : matches) {
96 URLPattern pattern(UserScript::ValidUserScriptSchemes(
97 true /* canExecuteScriptEverywhere */));
98 if (pattern.Parse(match) != URLPattern::PARSE_SUCCESS)
99 return false;
100 script->add_url_pattern(pattern);
101 }
102
103 // exclude_matches:
104 if (script_value.exclude_matches) {
105 const std::vector<std::string>& exclude_matches =
106 *(script_value.exclude_matches.get());
107 for (const std::string& exclude_match : exclude_matches) {
108 URLPattern pattern(UserScript::ValidUserScriptSchemes(
109 true /* canExecuteScriptEverywhere */));
110
111 if (pattern.Parse(exclude_match) != URLPattern::PARSE_SUCCESS)
112 return false;
113 script->add_exclude_url_pattern(pattern);
114 }
115 }
116 // run_at:
117 if (script_value.run_at) {
118 UserScript::RunLocation run_at = UserScript::UNDEFINED;
119 switch (script_value.run_at) {
120 case ContentScriptDetails::RUN_AT_NONE:
121 case ContentScriptDetails::RUN_AT_DOCUMENT_IDLE:
122 run_at = UserScript::DOCUMENT_IDLE;
123 break;
124 case ContentScriptDetails::RUN_AT_DOCUMENT_START:
125 run_at = UserScript::DOCUMENT_START;
126 break;
127 case ContentScriptDetails::RUN_AT_DOCUMENT_END:
128 run_at = UserScript::DOCUMENT_END;
129 break;
130 }
131 script->set_run_location(run_at);
132 }
133
134 // match_about_blank
135 if (script_value.match_about_blank)
136 script->set_match_about_blank(*script_value.match_about_blank);
137
138 GURL owner_base_url(guest->GetOwnerSiteURL().GetWithEmptyPath());
139
140 // css:
141 if (script_value.css) {
142 const std::vector<std::string>& css_files = *(script_value.css.get());
143 for (const std::string& relative : css_files) {
144 GURL url = owner_base_url.Resolve(relative);
145 if (extension) {
146 ExtensionResource resource = extension->GetResource(relative);
147 script->css_scripts().push_back(UserScript::File(
148 resource.extension_root(), resource.relative_path(), url));
149 } else {
150 script->css_scripts().push_back(extensions::UserScript::File(
151 base::FilePath(), base::FilePath(), url));
152 }
153 }
154 }
155
156 // js:
157 if (script_value.js) {
158 const std::vector<std::string>& js_files = *(script_value.js.get());
159 for (const std::string& relative : js_files) {
160 GURL url = owner_base_url.Resolve(relative);
161 if (extension) {
162 ExtensionResource resource = extension->GetResource(relative);
163 script->js_scripts().push_back(UserScript::File(
164 resource.extension_root(), resource.relative_path(), url));
165 } else {
166 script->js_scripts().push_back(extensions::UserScript::File(
167 base::FilePath(), base::FilePath(), url));
168 }
169 }
170 }
171
172 // all_frames:
173 if (script_value.all_frames) {
174 script->set_match_all_frames(*(script_value.all_frames));
175 }
176
177 // include_globs:
178 if (script_value.include_globs) {
179 const std::vector<std::string>& include_globs =
180 *(script_value.include_globs.get());
181 for (const std::string& glob : include_globs)
182 script->add_glob(glob);
183 }
184
185 // exclude_globs:
186 if (script_value.exclude_globs) {
187 const auto& exclude_globs = *(script_value.exclude_globs.get());
188 for (const std::string& glob : exclude_globs)
189 script->add_exclude_glob(glob);
190 }
191
192 InitUserScript(script, guest);
193 return true;
194 }
195
48 } // namespace 196 } // namespace
49 197
50 namespace extensions { 198 namespace extensions {
51 199
52 bool WebViewInternalExtensionFunction::RunAsync() { 200 bool WebViewInternalExtensionFunction::RunAsync() {
53 int instance_id = 0; 201 int instance_id = 0;
54 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id)); 202 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
55 WebViewGuest* guest = WebViewGuest::From( 203 WebViewGuest* guest = WebViewGuest::From(
56 render_view_host()->GetProcess()->GetID(), instance_id); 204 render_view_host()->GetProcess()->GetID(), instance_id);
57 if (!guest) 205 if (!guest)
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 error, on_url, result); 294 error, on_url, result);
147 } 295 }
148 296
149 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() { 297 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() {
150 } 298 }
151 299
152 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const { 300 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const {
153 return true; 301 return true;
154 } 302 }
155 303
304 WebViewInternalAddContentScriptsFunction::
305 WebViewInternalAddContentScriptsFunction() {
306 }
307
308 WebViewInternalAddContentScriptsFunction::
309 ~WebViewInternalAddContentScriptsFunction() {
310 }
311
312 bool WebViewInternalAddContentScriptsFunction::RunAsyncSafe(
313 WebViewGuest* guest) {
314 scoped_ptr<webview::AddContentScripts::Params> params(
315 webview::AddContentScripts::Params::Create(*args_));
316 EXTENSION_FUNCTION_VALIDATE(params.get());
317 auto script_list = params->content_script_list;
318 if (!guest->host_id())
319 guest->set_host_id(GenerateHostID(extension(), render_view_host()));
Fady Samuel 2015/03/11 11:43:17 Move this into AddContentScripts?
320
321 for (size_t i = 0; i < script_list.size(); ++i) {
322 const ContentScriptDetails& script_value = *script_list[i];
323 const std::string& name = script_value.name;
324 UserScript script;
325 if (Parse(script_value, &script, guest, extension())) {
326 guest->AddContentScripts(name, script);
Fady Samuel 2015/03/11 11:43:17 There's too much magic going on at this layer. Thi
327 } else {
328 SendResponse(false);
329 return false;
330 }
331 }
332 SendResponse(true);
333 return true;
334 }
335
336 WebViewInternalRemoveContentScriptsFunction::
337 WebViewInternalRemoveContentScriptsFunction() {
338 }
339
340 WebViewInternalRemoveContentScriptsFunction::
341 ~WebViewInternalRemoveContentScriptsFunction() {
342 }
343
344 bool WebViewInternalRemoveContentScriptsFunction::RunAsyncSafe(
345 WebViewGuest* guest) {
346 scoped_ptr<webview::RemoveContentScripts::Params> params(
347 webview::RemoveContentScripts::Params::Create(*args_));
348 EXTENSION_FUNCTION_VALIDATE(params.get());
349 if (!params->script_name_list) {
Fady Samuel 2015/03/11 11:43:17 I'd move this code into WebViewGuest.
Fady Samuel 2015/03/11 11:43:17 Move this logic into WebViewGuest.
350 guest->RemoveAllContentScripts();
351 } else {
352 for (const std::string& name : *params->script_name_list)
353 guest->RemoveContentScripts(name);
354 }
355 SendResponse(true);
356 return true;
357 }
156 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() { 358 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() {
157 } 359 }
158 360
159 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() { 361 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() {
160 } 362 }
161 363
162 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest* guest) { 364 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest* guest) {
163 scoped_ptr<webview::SetName::Params> params( 365 scoped_ptr<webview::SetName::Params> params(
164 webview::SetName::Params::Create(*args_)); 366 webview::SetName::Params::Create(*args_));
165 EXTENSION_FUNCTION_VALIDATE(params.get()); 367 EXTENSION_FUNCTION_VALIDATE(params.get());
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 // Will finish asynchronously. 712 // Will finish asynchronously.
511 return true; 713 return true;
512 } 714 }
513 715
514 void WebViewInternalClearDataFunction::ClearDataDone() { 716 void WebViewInternalClearDataFunction::ClearDataDone() {
515 Release(); // Balanced in RunAsync(). 717 Release(); // Balanced in RunAsync().
516 SendResponse(true); 718 SendResponse(true);
517 } 719 }
518 720
519 } // namespace extensions 721 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698