Chromium Code Reviews| Index: extensions/browser/api/web_view/web_view_internal_api.cc |
| diff --git a/extensions/browser/api/web_view/web_view_internal_api.cc b/extensions/browser/api/web_view/web_view_internal_api.cc |
| index 4b041e911764efabd574034f0e175b015ffebd65..0ea09794bb1d82565f367c0f462b47f80101d4a9 100644 |
| --- a/extensions/browser/api/web_view/web_view_internal_api.cc |
| +++ b/extensions/browser/api/web_view/web_view_internal_api.cc |
| @@ -4,6 +4,7 @@ |
| #include "extensions/browser/api/web_view/web_view_internal_api.h" |
| +#include "base/strings/string_number_conversions.h" |
| #include "base/strings/stringprintf.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "content/public/browser/render_process_host.h" |
| @@ -12,11 +13,16 @@ |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/common/stop_find_action.h" |
| #include "extensions/common/api/web_view_internal.h" |
| +#include "extensions/common/error_utils.h" |
| +#include "extensions/common/user_script.h" |
| #include "third_party/WebKit/public/web/WebFindOptions.h" |
| using content::WebContents; |
| using extensions::core_api::web_view_internal::SetPermission::Params; |
| using extensions::core_api::extension_types::InjectDetails; |
| +using extensions::core_api::web_view_internal::ContentScriptDetails; |
| +using extensions::ExtensionResource; |
| +using extensions::UserScript; |
| namespace webview = extensions::core_api::web_view_internal; |
| namespace { |
| @@ -45,6 +51,148 @@ int MaskForKey(const char* key) { |
| return 0; |
| } |
| +scoped_ptr<const HostID> GenerateHostID(const extensions::Extension* extension, |
| + const content::RenderViewHost* rvh) { |
| + if (extension) |
| + return scoped_ptr<const HostID>( |
| + new HostID(HostID::EXTENSIONS, extension->id())); |
| + if (rvh) { |
| + WebContents* web_contents = WebContents::FromRenderViewHost(rvh); |
| + if (web_contents && web_contents->GetWebUI()) { |
| + const GURL& url = rvh->GetSiteInstance()->GetSiteURL(); |
| + return scoped_ptr<const HostID>(new HostID(HostID::WEBUI, url.spec())); |
| + } |
| + } |
| + NOTREACHED(); |
| + return scoped_ptr<const HostID>(); |
| +} |
| + |
| +// Initialize the user script. |
| +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
|
| + if (!script) |
| + return; |
| + script->set_id(UserScript::GenerateUserScriptID()); |
| + script->set_host_id(*(guest->host_id())); |
| + script->set_consumer_instance_type(UserScript::WEBVIEW); |
| + content::WebContents* web_contents = guest->web_contents(); |
| + if (web_contents) { |
| + script->set_routing_info( |
| + UserScript::RoutingInfo(web_contents->GetRenderProcessHost()->GetID(), |
| + web_contents->GetRoutingID())); |
| + } |
| +} |
| + |
| +bool Parse(const ContentScriptDetails& script_value, |
| + UserScript* script, |
| + extensions::WebViewGuest* guest, |
| + const extensions::Extension* extension) { |
| + // matches (required): |
| + const std::vector<std::string>& matches = script_value.matches; |
| + if (matches.size() == 0) { |
| + return false; |
| + } |
| + |
| + for (const std::string& match : matches) { |
| + URLPattern pattern(UserScript::ValidUserScriptSchemes( |
| + true /* canExecuteScriptEverywhere */)); |
| + if (pattern.Parse(match) != URLPattern::PARSE_SUCCESS) |
| + return false; |
| + script->add_url_pattern(pattern); |
| + } |
| + |
| + // exclude_matches: |
| + if (script_value.exclude_matches) { |
| + const std::vector<std::string>& exclude_matches = |
| + *(script_value.exclude_matches.get()); |
| + for (const std::string& exclude_match : exclude_matches) { |
| + URLPattern pattern(UserScript::ValidUserScriptSchemes( |
| + true /* canExecuteScriptEverywhere */)); |
| + |
| + if (pattern.Parse(exclude_match) != URLPattern::PARSE_SUCCESS) |
| + return false; |
| + script->add_exclude_url_pattern(pattern); |
| + } |
| + } |
| + // run_at: |
| + if (script_value.run_at) { |
| + UserScript::RunLocation run_at = UserScript::UNDEFINED; |
| + switch (script_value.run_at) { |
| + case ContentScriptDetails::RUN_AT_NONE: |
| + case ContentScriptDetails::RUN_AT_DOCUMENT_IDLE: |
| + run_at = UserScript::DOCUMENT_IDLE; |
| + break; |
| + case ContentScriptDetails::RUN_AT_DOCUMENT_START: |
| + run_at = UserScript::DOCUMENT_START; |
| + break; |
| + case ContentScriptDetails::RUN_AT_DOCUMENT_END: |
| + run_at = UserScript::DOCUMENT_END; |
| + break; |
| + } |
| + script->set_run_location(run_at); |
| + } |
| + |
| + // match_about_blank |
| + if (script_value.match_about_blank) |
| + script->set_match_about_blank(*script_value.match_about_blank); |
| + |
| + GURL owner_base_url(guest->GetOwnerSiteURL().GetWithEmptyPath()); |
| + |
| + // css: |
| + if (script_value.css) { |
| + const std::vector<std::string>& css_files = *(script_value.css.get()); |
| + for (const std::string& relative : css_files) { |
| + GURL url = owner_base_url.Resolve(relative); |
| + if (extension) { |
| + ExtensionResource resource = extension->GetResource(relative); |
| + script->css_scripts().push_back(UserScript::File( |
| + resource.extension_root(), resource.relative_path(), url)); |
| + } else { |
| + script->css_scripts().push_back(extensions::UserScript::File( |
| + base::FilePath(), base::FilePath(), url)); |
| + } |
| + } |
| + } |
| + |
| + // js: |
| + if (script_value.js) { |
| + const std::vector<std::string>& js_files = *(script_value.js.get()); |
| + for (const std::string& relative : js_files) { |
| + GURL url = owner_base_url.Resolve(relative); |
| + if (extension) { |
| + ExtensionResource resource = extension->GetResource(relative); |
| + script->js_scripts().push_back(UserScript::File( |
| + resource.extension_root(), resource.relative_path(), url)); |
| + } else { |
| + script->js_scripts().push_back(extensions::UserScript::File( |
| + base::FilePath(), base::FilePath(), url)); |
| + } |
| + } |
| + } |
| + |
| + // all_frames: |
| + if (script_value.all_frames) { |
| + script->set_match_all_frames(*(script_value.all_frames)); |
| + } |
| + |
| + // include_globs: |
| + if (script_value.include_globs) { |
| + const std::vector<std::string>& include_globs = |
| + *(script_value.include_globs.get()); |
| + for (const std::string& glob : include_globs) |
| + script->add_glob(glob); |
| + } |
| + |
| + // exclude_globs: |
| + if (script_value.exclude_globs) { |
| + const auto& exclude_globs = *(script_value.exclude_globs.get()); |
| + for (const std::string& glob : exclude_globs) |
| + script->add_exclude_glob(glob); |
| + } |
| + |
| + InitUserScript(script, guest); |
| + return true; |
| +} |
| + |
| } // namespace |
| namespace extensions { |
| @@ -153,6 +301,60 @@ bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const { |
| return true; |
| } |
| +WebViewInternalAddContentScriptsFunction:: |
| + WebViewInternalAddContentScriptsFunction() { |
| +} |
| + |
| +WebViewInternalAddContentScriptsFunction:: |
| + ~WebViewInternalAddContentScriptsFunction() { |
| +} |
| + |
| +bool WebViewInternalAddContentScriptsFunction::RunAsyncSafe( |
| + WebViewGuest* guest) { |
| + scoped_ptr<webview::AddContentScripts::Params> params( |
| + webview::AddContentScripts::Params::Create(*args_)); |
| + EXTENSION_FUNCTION_VALIDATE(params.get()); |
| + auto script_list = params->content_script_list; |
| + if (!guest->host_id()) |
| + guest->set_host_id(GenerateHostID(extension(), render_view_host())); |
|
Fady Samuel
2015/03/11 11:43:17
Move this into AddContentScripts?
|
| + |
| + for (size_t i = 0; i < script_list.size(); ++i) { |
| + const ContentScriptDetails& script_value = *script_list[i]; |
| + const std::string& name = script_value.name; |
| + UserScript script; |
| + if (Parse(script_value, &script, guest, extension())) { |
| + guest->AddContentScripts(name, script); |
|
Fady Samuel
2015/03/11 11:43:17
There's too much magic going on at this layer. Thi
|
| + } else { |
| + SendResponse(false); |
| + return false; |
| + } |
| + } |
| + SendResponse(true); |
| + return true; |
| +} |
| + |
| +WebViewInternalRemoveContentScriptsFunction:: |
| + WebViewInternalRemoveContentScriptsFunction() { |
| +} |
| + |
| +WebViewInternalRemoveContentScriptsFunction:: |
| + ~WebViewInternalRemoveContentScriptsFunction() { |
| +} |
| + |
| +bool WebViewInternalRemoveContentScriptsFunction::RunAsyncSafe( |
| + WebViewGuest* guest) { |
| + scoped_ptr<webview::RemoveContentScripts::Params> params( |
| + webview::RemoveContentScripts::Params::Create(*args_)); |
| + EXTENSION_FUNCTION_VALIDATE(params.get()); |
| + 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.
|
| + guest->RemoveAllContentScripts(); |
| + } else { |
| + for (const std::string& name : *params->script_name_list) |
| + guest->RemoveContentScripts(name); |
| + } |
| + SendResponse(true); |
| + return true; |
| +} |
| WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() { |
| } |