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 bool Parse(const ContentScriptDetails& script_value, | |
71 UserScript* script, | |
72 extensions::WebViewGuest* guest, | |
73 const extensions::Extension* extension) { | |
74 // matches (required): | |
75 const std::vector<std::string>& matches = script_value.matches; | |
76 if (matches.size() == 0) { | |
77 return false; | |
78 } | |
79 | |
80 for (const std::string& match : matches) { | |
81 URLPattern pattern(UserScript::ValidUserScriptSchemes( | |
82 true /* canExecuteScriptEverywhere*/)); | |
83 if (pattern.Parse(match) != URLPattern::PARSE_SUCCESS) | |
84 return false; | |
85 script->add_url_pattern(pattern); | |
86 } | |
87 | |
88 // exclude_matches: | |
89 if (script_value.exclude_matches) { | |
90 const std::vector<std::string>& exclude_matches = | |
91 *(script_value.exclude_matches.get()); | |
92 for (const std::string& exclude_match : exclude_matches) { | |
93 URLPattern pattern(UserScript::ValidUserScriptSchemes( | |
94 true /* canExecuteScriptEverywhere*/)); | |
Fady Samuel
2015/03/04 02:02:10
Use unix_hacker style.
Xi Han
2015/03/06 17:29:07
Done.
| |
95 | |
96 if (pattern.Parse(exclude_match) != URLPattern::PARSE_SUCCESS) | |
97 return false; | |
98 script->add_exclude_url_pattern(pattern); | |
99 } | |
100 } | |
101 // run_at: | |
102 if (script_value.run_at) { | |
103 UserScript::RunLocation run_at = UserScript::UNDEFINED; | |
104 switch (script_value.run_at) { | |
105 case ContentScriptDetails::RUN_AT_NONE: | |
106 case ContentScriptDetails::RUN_AT_DOCUMENT_IDLE: | |
107 run_at = UserScript::DOCUMENT_IDLE; | |
108 break; | |
109 case ContentScriptDetails::RUN_AT_DOCUMENT_START: | |
110 run_at = UserScript::DOCUMENT_START; | |
111 break; | |
112 case ContentScriptDetails::RUN_AT_DOCUMENT_END: | |
113 run_at = UserScript::DOCUMENT_END; | |
114 break; | |
115 } | |
116 script->set_run_location(run_at); | |
117 } | |
118 | |
119 // match_about_blank | |
120 if (script_value.match_about_blank) | |
121 script->set_match_about_blank(*script_value.match_about_blank); | |
122 | |
123 GURL owner_base_url(guest->GetOwnerSiteURL().GetWithEmptyPath()); | |
124 | |
125 // css: | |
126 if (script_value.css) { | |
127 const std::vector<std::string>& css_files = *(script_value.css.get()); | |
128 for (const std::string& relative : css_files) { | |
129 GURL url = owner_base_url.Resolve(relative); | |
130 if (extension) { | |
131 ExtensionResource resource = extension->GetResource(relative); | |
132 script->css_scripts().push_back(UserScript::File( | |
133 resource.extension_root(), resource.relative_path(), url)); | |
134 } else { | |
135 script->css_scripts().push_back(extensions::UserScript::File( | |
136 base::FilePath(), base::FilePath(), url)); | |
137 } | |
138 } | |
139 } | |
140 | |
141 // js: | |
142 if (script_value.js) { | |
143 const std::vector<std::string>& js_files = *(script_value.js.get()); | |
144 for (const std::string& relative: js_files) { | |
145 GURL url = owner_base_url.Resolve(relative); | |
146 if (extension) { | |
147 ExtensionResource resource = extension->GetResource(relative); | |
148 script->js_scripts().push_back(UserScript::File( | |
149 resource.extension_root(), resource.relative_path(), url)); | |
150 } else { | |
151 script->js_scripts().push_back(extensions::UserScript::File( | |
152 base::FilePath(), base::FilePath(), url)); | |
153 } | |
154 } | |
155 } | |
156 | |
157 // all_frames: | |
158 if (script_value.all_frames) { | |
159 script->set_match_all_frames(*(script_value.all_frames)); | |
160 } | |
161 | |
162 // include_globs: | |
Fady Samuel
2015/03/04 02:02:10
Remind me what these are?
Xi Han
2015/03/06 17:29:07
Include_globs can be used to limit which pages are
| |
163 if (script_value.include_globs) { | |
164 const std::vector<std::string>& include_globs = | |
165 *(script_value.include_globs.get()); | |
166 for (const std::string& glob: include_globs) | |
167 script->add_glob(glob); | |
168 } | |
169 | |
170 // exclude_globs: | |
Fady Samuel
2015/03/04 02:02:10
Same here. What is this?
Xi Han
2015/03/06 17:29:07
Applied after "matches" to exclude URLs that match
| |
171 if (script_value.exclude_globs) { | |
172 const auto& exclude_globs = *(script_value.exclude_globs.get()); | |
173 for (const std::string& glob: exclude_globs) | |
174 script->add_exclude_glob(glob); | |
175 } | |
176 return true; | |
177 } | |
178 | |
48 } // namespace | 179 } // namespace |
49 | 180 |
50 namespace extensions { | 181 namespace extensions { |
51 | 182 |
52 bool WebViewInternalExtensionFunction::RunAsync() { | 183 bool WebViewInternalExtensionFunction::RunAsync() { |
53 int instance_id = 0; | 184 int instance_id = 0; |
54 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id)); | 185 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id)); |
55 WebViewGuest* guest = WebViewGuest::From( | 186 WebViewGuest* guest = WebViewGuest::From( |
56 render_view_host()->GetProcess()->GetID(), instance_id); | 187 render_view_host()->GetProcess()->GetID(), instance_id); |
57 if (!guest) | 188 if (!guest) |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 error, on_url, result); | 277 error, on_url, result); |
147 } | 278 } |
148 | 279 |
149 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() { | 280 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() { |
150 } | 281 } |
151 | 282 |
152 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const { | 283 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const { |
153 return true; | 284 return true; |
154 } | 285 } |
155 | 286 |
287 WebViewInternalAddContentScriptsFunction:: | |
288 WebViewInternalAddContentScriptsFunction() { | |
289 } | |
290 | |
291 WebViewInternalAddContentScriptsFunction:: | |
292 ~WebViewInternalAddContentScriptsFunction() { | |
293 } | |
294 | |
295 bool WebViewInternalAddContentScriptsFunction::RunAsyncSafe( | |
296 WebViewGuest* guest) { | |
297 scoped_ptr<webview::AddContentScripts::Params> params( | |
298 webview::AddContentScripts::Params::Create(*args_)); | |
299 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
300 auto script_list = params->content_script_list; | |
301 if (guest->IsHostIDEmpty()) | |
302 guest->set_host_id(GenerateHostID(extension(), render_view_host())); | |
303 | |
304 for (size_t i = 0; i < script_list.size(); ++i) { | |
305 const ContentScriptDetails& script_value = *script_list[i]; | |
306 const std::string& name = script_value.name; | |
307 UserScript script; | |
308 if (Parse(script_value, &script, guest, extension())) { | |
309 script.set_id(UserScript::GenerateUserScriptID()); | |
310 script.set_host_id(guest->host_id()); | |
311 guest->AddContentScripts(name, script); | |
312 } else { | |
313 SendResponse(false); | |
314 return false; | |
315 } | |
316 } | |
317 SendResponse(true); | |
318 return true; | |
319 } | |
320 | |
321 WebViewInternalRemoveContentScriptsFunction:: | |
322 WebViewInternalRemoveContentScriptsFunction() { | |
323 } | |
324 | |
325 WebViewInternalRemoveContentScriptsFunction:: | |
326 ~WebViewInternalRemoveContentScriptsFunction() { | |
327 } | |
328 | |
329 bool WebViewInternalRemoveContentScriptsFunction::RunAsyncSafe( | |
330 WebViewGuest* guest) { | |
331 scoped_ptr<webview::RemoveContentScripts::Params> params( | |
332 webview::RemoveContentScripts::Params::Create(*args_)); | |
333 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
334 if (!params->script_name_list) { | |
335 guest->RemoveAllContentScripts(); | |
336 } else { | |
337 for (const std::string& name: *params->script_name_list) | |
338 guest->RemoveContentScripts(name); | |
339 } | |
340 SendResponse(true); | |
341 return true; | |
342 } | |
156 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() { | 343 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() { |
157 } | 344 } |
158 | 345 |
159 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() { | 346 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() { |
160 } | 347 } |
161 | 348 |
162 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest* guest) { | 349 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest* guest) { |
163 scoped_ptr<webview::SetName::Params> params( | 350 scoped_ptr<webview::SetName::Params> params( |
164 webview::SetName::Params::Create(*args_)); | 351 webview::SetName::Params::Create(*args_)); |
165 EXTENSION_FUNCTION_VALIDATE(params.get()); | 352 EXTENSION_FUNCTION_VALIDATE(params.get()); |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
510 // Will finish asynchronously. | 697 // Will finish asynchronously. |
511 return true; | 698 return true; |
512 } | 699 } |
513 | 700 |
514 void WebViewInternalClearDataFunction::ClearDataDone() { | 701 void WebViewInternalClearDataFunction::ClearDataDone() { |
515 Release(); // Balanced in RunAsync(). | 702 Release(); // Balanced in RunAsync(). |
516 SendResponse(true); | 703 SendResponse(true); |
517 } | 704 } |
518 | 705 |
519 } // namespace extensions | 706 } // namespace extensions |
OLD | NEW |