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

Side by Side Diff: extensions/browser/api/guest_view/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: Make the API work before the first navigation of guest. 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/guest_view/web_view/web_view_internal_api.h" 5 #include "extensions/browser/api/guest_view/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"
15 #include "extensions/browser/guest_view/web_view/web_view_content_script_manager .h"
14 #include "extensions/common/api/web_view_internal.h" 16 #include "extensions/common/api/web_view_internal.h"
17 #include "extensions/common/error_utils.h"
18 #include "extensions/common/manifest_constants.h"
19 #include "extensions/common/user_script.h"
15 #include "third_party/WebKit/public/web/WebFindOptions.h" 20 #include "third_party/WebKit/public/web/WebFindOptions.h"
16 21
17 using content::WebContents; 22 using content::WebContents;
18 using extensions::core_api::web_view_internal::SetPermission::Params; 23 using extensions::core_api::web_view_internal::SetPermission::Params;
19 using extensions::core_api::extension_types::InjectDetails; 24 using extensions::core_api::extension_types::InjectDetails;
25 using extensions::core_api::web_view_internal::ContentScriptDetails;
26 using extensions::ExtensionResource;
27 using extensions::UserScript;
20 namespace webview = extensions::core_api::web_view_internal; 28 namespace webview = extensions::core_api::web_view_internal;
29 // error messages for content scripts:
30 namespace errors = extensions::manifest_errors;
21 31
22 namespace { 32 namespace {
23 33
24 const char kAppCacheKey[] = "appcache"; 34 const char kAppCacheKey[] = "appcache";
25 const char kCookiesKey[] = "cookies"; 35 const char kCookiesKey[] = "cookies";
26 const char kFileSystemsKey[] = "fileSystems"; 36 const char kFileSystemsKey[] = "fileSystems";
27 const char kIndexedDBKey[] = "indexedDB"; 37 const char kIndexedDBKey[] = "indexedDB";
28 const char kLocalStorageKey[] = "localStorage"; 38 const char kLocalStorageKey[] = "localStorage";
29 const char kWebSQLKey[] = "webSQL"; 39 const char kWebSQLKey[] = "webSQL";
30 const char kSinceKey[] = "since"; 40 const char kSinceKey[] = "since";
31 41
32 int MaskForKey(const char* key) { 42 int MaskForKey(const char* key) {
33 if (strcmp(key, kAppCacheKey) == 0) 43 if (strcmp(key, kAppCacheKey) == 0)
34 return content::StoragePartition::REMOVE_DATA_MASK_APPCACHE; 44 return content::StoragePartition::REMOVE_DATA_MASK_APPCACHE;
35 if (strcmp(key, kCookiesKey) == 0) 45 if (strcmp(key, kCookiesKey) == 0)
36 return content::StoragePartition::REMOVE_DATA_MASK_COOKIES; 46 return content::StoragePartition::REMOVE_DATA_MASK_COOKIES;
37 if (strcmp(key, kFileSystemsKey) == 0) 47 if (strcmp(key, kFileSystemsKey) == 0)
38 return content::StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS; 48 return content::StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
39 if (strcmp(key, kIndexedDBKey) == 0) 49 if (strcmp(key, kIndexedDBKey) == 0)
40 return content::StoragePartition::REMOVE_DATA_MASK_INDEXEDDB; 50 return content::StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
41 if (strcmp(key, kLocalStorageKey) == 0) 51 if (strcmp(key, kLocalStorageKey) == 0)
42 return content::StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE; 52 return content::StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
43 if (strcmp(key, kWebSQLKey) == 0) 53 if (strcmp(key, kWebSQLKey) == 0)
44 return content::StoragePartition::REMOVE_DATA_MASK_WEBSQL; 54 return content::StoragePartition::REMOVE_DATA_MASK_WEBSQL;
45 return 0; 55 return 0;
46 } 56 }
47 57
58 HostID GenerateHostID(const extensions::Extension* extension,
59 const content::WebContents* web_contents,
60 const content::RenderViewHost* rvh) {
61 if (extension)
62 return HostID(HostID::EXTENSIONS, extension->id());
63
64 if (web_contents && web_contents->GetWebUI()) {
65 const GURL& url = rvh->GetSiteInstance()->GetSiteURL();
66 return HostID(HostID::WEBUI, url.spec());
67 }
68 NOTREACHED();
69 return HostID();
70 }
71
72 bool Parse(const ContentScriptDetails& script_value,
73 const extensions::Extension* extension,
74 const GURL& owner_base_url,
75 UserScript* script,
76 std::string* error) {
77 // matches (required):
78 const std::vector<std::string>& matches = script_value.matches;
79 if (matches.size() == 0) {
80 return false;
81 }
82
83 for (const std::string& match : matches) {
84 URLPattern pattern(UserScript::ValidUserScriptSchemes(
85 true /* canExecuteScriptEverywhere */));
86 if (pattern.Parse(match) != URLPattern::PARSE_SUCCESS) {
87 *error = errors::kInvalidMatches;
88 return false;
89 }
90 script->add_url_pattern(pattern);
91 }
92
93 // exclude_matches:
94 if (script_value.exclude_matches) {
95 const std::vector<std::string>& exclude_matches =
96 *(script_value.exclude_matches.get());
97 for (const std::string& exclude_match : exclude_matches) {
98 URLPattern pattern(UserScript::ValidUserScriptSchemes(
99 true /* canExecuteScriptEverywhere */));
100
101 if (pattern.Parse(exclude_match) != URLPattern::PARSE_SUCCESS) {
102 *error = errors::kInvalidExcludeMatches;
103 return false;
104 }
105 script->add_exclude_url_pattern(pattern);
106 }
107 }
108 // run_at:
109 if (script_value.run_at) {
110 UserScript::RunLocation run_at = UserScript::UNDEFINED;
111 switch (script_value.run_at) {
112 case ContentScriptDetails::RUN_AT_NONE:
113 case ContentScriptDetails::RUN_AT_DOCUMENT_IDLE:
114 run_at = UserScript::DOCUMENT_IDLE;
115 break;
116 case ContentScriptDetails::RUN_AT_DOCUMENT_START:
117 run_at = UserScript::DOCUMENT_START;
118 break;
119 case ContentScriptDetails::RUN_AT_DOCUMENT_END:
120 run_at = UserScript::DOCUMENT_END;
121 break;
122 }
123 script->set_run_location(run_at);
124 }
125
126 // match_about_blank:
127 if (script_value.match_about_blank)
128 script->set_match_about_blank(*script_value.match_about_blank);
129
130 // css:
131 if (script_value.css) {
132 const std::vector<std::string>& css_files = *(script_value.css.get());
133 for (const std::string& relative : css_files) {
134 GURL url = owner_base_url.Resolve(relative);
135 if (extension) {
136 ExtensionResource resource = extension->GetResource(relative);
137 script->css_scripts().push_back(UserScript::File(
138 resource.extension_root(), resource.relative_path(), url));
139 } else {
140 script->css_scripts().push_back(extensions::UserScript::File(
141 base::FilePath(), base::FilePath(), url));
142 }
143 }
144 }
145
146 // js:
147 if (script_value.js) {
148 const std::vector<std::string>& js_files = *(script_value.js.get());
149 for (const std::string& relative : js_files) {
150 GURL url = owner_base_url.Resolve(relative);
151 if (extension) {
152 ExtensionResource resource = extension->GetResource(relative);
153 script->js_scripts().push_back(UserScript::File(
154 resource.extension_root(), resource.relative_path(), url));
155 } else {
156 script->js_scripts().push_back(extensions::UserScript::File(
157 base::FilePath(), base::FilePath(), url));
158 }
159 }
160 }
161
162 // all_frames:
163 if (script_value.all_frames) {
164 script->set_match_all_frames(*(script_value.all_frames));
165 }
166
167 // include_globs:
168 if (script_value.include_globs) {
169 const std::vector<std::string>& include_globs =
170 *(script_value.include_globs.get());
171 for (const std::string& glob : include_globs)
172 script->add_glob(glob);
173 }
174
175 // exclude_globs:
176 if (script_value.exclude_globs) {
177 const std::vector<std::string>& exclude_globs =
178 *(script_value.exclude_globs.get());
179 for (const std::string& glob : exclude_globs)
180 script->add_exclude_glob(glob);
181 }
182
183 return true;
184 }
185
186 bool Parse(std::vector<linked_ptr<ContentScriptDetails>> content_script_list,
187 const extensions::Extension* extension,
188 const GURL& owner_base_url,
189 std::map<std::string, UserScript>* result,
190 std::string* error) {
191 if (content_script_list.size() == 0)
192 return false;
193 for (size_t i = 0; i < content_script_list.size(); ++i) {
194 const ContentScriptDetails& script_value = *content_script_list[i];
195 const std::string& name = script_value.name;
196 UserScript script;
197 if (!Parse(script_value, extension, owner_base_url, &script, error))
198 return false;
199 else
200 result->insert(std::pair<std::string, UserScript>(name, script));
201 }
202 return true;
203 }
204
205 // Initialize the user script.
206 void InitUserScript(UserScript* script, std::string name, HostID host_id) {
207 if (!script)
208 return;
209 script->set_id(UserScript::GenerateUserScriptID());
210 script->set_name(name);
211 script->set_host_id(host_id);
212 script->set_consumer_instance_type(UserScript::WEBVIEW);
213 }
214
48 } // namespace 215 } // namespace
49 216
50 namespace extensions { 217 namespace extensions {
51 218
52 bool WebViewInternalExtensionFunction::RunAsync() { 219 bool WebViewInternalExtensionFunction::RunAsync() {
53 int instance_id = 0; 220 int instance_id = 0;
54 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id)); 221 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
55 WebViewGuest* guest = WebViewGuest::From( 222 WebViewGuest* guest = WebViewGuest::From(
56 render_view_host()->GetProcess()->GetID(), instance_id); 223 render_view_host()->GetProcess()->GetID(), instance_id);
57 if (!guest) 224 if (!guest)
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 error, on_url, result); 325 error, on_url, result);
159 } 326 }
160 327
161 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() { 328 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() {
162 } 329 }
163 330
164 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const { 331 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const {
165 return true; 332 return true;
166 } 333 }
167 334
335 WebViewInternalAddContentScriptsFunction::
336 WebViewInternalAddContentScriptsFunction() {
337 if (extension()) {
338 set_host_id(HostID(HostID::EXTENSIONS, extension()->id()));
339 return;
340 }
341
342 WebContents* web_contents = GetSenderWebContents();
343 if (web_contents && web_contents->GetWebUI()) {
344 const GURL& url = render_view_host()->GetSiteInstance()->GetSiteURL();
345 set_host_id(HostID(HostID::WEBUI, url.spec()));
346 }
347 }
348
349 WebViewInternalAddContentScriptsFunction::
350 ~WebViewInternalAddContentScriptsFunction() {
351 }
352
353 bool WebViewInternalAddContentScriptsFunction::RunAsync() {
354 scoped_ptr<webview::AddContentScripts::Params> params(
355 webview::AddContentScripts::Params::Create(*args_));
356 EXTENSION_FUNCTION_VALIDATE(params.get());
357
358 int guest_view_instance_id = 0;
359 if (!args_->GetInteger(0, &guest_view_instance_id) ||
360 !guest_view_instance_id) {
361 SendResponse(false);
362 return false;
363 }
364
365 if (!render_view_host() || !render_view_host()->GetProcess()) {
366 SendResponse(false);
367 return false;
368 }
369
370 GURL owner_base_url(
371 render_view_host()->GetSiteInstance()->GetSiteURL().GetWithEmptyPath());
372 std::map<std::string, UserScript> result;
373 if (!Parse(params->content_script_list, extension(), owner_base_url, &result,
374 &error_)) {
375 SendResponse(false);
376 return false;
377 }
378
379 WebViewContentScriptManager* manager =
380 WebViewContentScriptManager::Get(browser_context());
381 if (!manager) {
382 SendResponse(false);
383 return false;
384 }
385
386 int embedder_process_id = render_view_host()->GetProcess()->GetID();
387 HostID host_id =
388 GenerateHostID(extension(), GetSenderWebContents(), render_view_host());
389 for (auto& iter : result)
390 InitUserScript(&iter.second, iter.first, host_id);
391 manager->AddContentScripts(embedder_process_id, guest_view_instance_id,
392 host_id, result);
393 SendResponse(true);
394 return true;
395 }
396
397 WebViewInternalRemoveContentScriptsFunction::
398 WebViewInternalRemoveContentScriptsFunction() {
399 }
400
401 WebViewInternalRemoveContentScriptsFunction::
402 ~WebViewInternalRemoveContentScriptsFunction() {
403 }
404
405 bool WebViewInternalRemoveContentScriptsFunction::RunAsync() {
406 scoped_ptr<webview::RemoveContentScripts::Params> params(
407 webview::RemoveContentScripts::Params::Create(*args_));
408 EXTENSION_FUNCTION_VALIDATE(params.get());
409
410 int guest_view_instance_id = 0;
411 if (!args_->GetInteger(0, &guest_view_instance_id) ||
412 !guest_view_instance_id) {
413 SendResponse(false);
414 return false;
415 }
416
417 WebViewContentScriptManager* manager =
418 WebViewContentScriptManager::Get(browser_context());
419 if (!manager) {
420 SendResponse(false);
421 return false;
422 }
423
424 if (!render_view_host() || !render_view_host()->GetProcess()) {
425 SendResponse(false);
426 return false;
427 }
428
429 int embedder_process_id = render_view_host()->GetProcess()->GetID();
430 manager->RemoveContentScripts(embedder_process_id, guest_view_instance_id,
431 (params->script_name_list).get());
432
433 SendResponse(true);
434 return true;
435 }
436
168 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() { 437 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() {
169 } 438 }
170 439
171 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() { 440 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() {
172 } 441 }
173 442
174 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest* guest) { 443 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest* guest) {
175 scoped_ptr<webview::SetName::Params> params( 444 scoped_ptr<webview::SetName::Params> params(
176 webview::SetName::Params::Create(*args_)); 445 webview::SetName::Params::Create(*args_));
177 EXTENSION_FUNCTION_VALIDATE(params.get()); 446 EXTENSION_FUNCTION_VALIDATE(params.get());
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 // Will finish asynchronously. 791 // Will finish asynchronously.
523 return true; 792 return true;
524 } 793 }
525 794
526 void WebViewInternalClearDataFunction::ClearDataDone() { 795 void WebViewInternalClearDataFunction::ClearDataDone() {
527 Release(); // Balanced in RunAsync(). 796 Release(); // Balanced in RunAsync().
528 SendResponse(true); 797 SendResponse(true);
529 } 798 }
530 799
531 } // namespace extensions 800 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698