OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |