Index: extensions/browser/api/guest_view/web_view/web_view_internal_api.cc |
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc |
index cb685506fd1ea18bfbf9d8a36213da798e42b862..879f96f0dd1b2c22ff2da5efeaab73afc857bb71 100644 |
--- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc |
+++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc |
@@ -4,6 +4,7 @@ |
#include "extensions/browser/api/guest_view/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/browser_context.h" |
@@ -13,17 +14,25 @@ |
#include "content/public/common/stop_find_action.h" |
#include "content/public/common/url_fetcher.h" |
#include "extensions/browser/guest_view/web_view/web_view_constants.h" |
+#include "extensions/browser/guest_view/web_view/web_view_content_script_manager.h" |
#include "extensions/common/api/web_view_internal.h" |
#include "extensions/common/error_utils.h" |
+#include "extensions/common/manifest_constants.h" |
+#include "extensions/common/user_script.h" |
#include "net/base/load_flags.h" |
#include "net/url_request/url_fetcher.h" |
#include "net/url_request/url_fetcher_delegate.h" |
#include "third_party/WebKit/public/web/WebFindOptions.h" |
using content::WebContents; |
+using extensions::ExtensionResource; |
+using extensions::core_api::web_view_internal::ContentScriptDetails; |
using extensions::core_api::web_view_internal::SetPermission::Params; |
using extensions::core_api::extension_types::InjectDetails; |
+using extensions::UserScript; |
using ui_zoom::ZoomController; |
+// error messages for content scripts: |
+namespace errors = extensions::manifest_errors; |
namespace web_view_internal = extensions::core_api::web_view_internal; |
namespace { |
@@ -56,6 +65,162 @@ uint32 MaskForKey(const char* key) { |
return 0; |
} |
+HostID GenerateHostID(const extensions::Extension* extension, |
+ const content::WebContents* web_contents) { |
+ if (extension) |
+ return HostID(HostID::EXTENSIONS, extension->id()); |
+ |
+ if (web_contents && web_contents->GetWebUI()) { |
+ const GURL& url = web_contents->GetSiteInstance()->GetSiteURL(); |
+ return HostID(HostID::WEBUI, url.spec()); |
+ } |
+ NOTREACHED(); |
+ return HostID(); |
+} |
+ |
+bool Parse(const ContentScriptDetails& script_value, |
+ const extensions::Extension* extension, |
+ const GURL& owner_base_url, |
+ UserScript* script, |
+ std::string* error) { |
+ // 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) { |
+ *error = errors::kInvalidMatches; |
+ 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) { |
+ *error = errors::kInvalidExcludeMatches; |
+ 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); |
+ |
+ // 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 std::vector<std::string>& exclude_globs = |
+ *(script_value.exclude_globs.get()); |
+ for (const std::string& glob : exclude_globs) |
+ script->add_exclude_glob(glob); |
+ } |
+ |
+ return true; |
+} |
+ |
+bool Parse(std::vector<linked_ptr<ContentScriptDetails>> content_script_list, |
+ const extensions::Extension* extension, |
+ const GURL& owner_base_url, |
+ std::map<std::string, UserScript>* result, |
+ std::string* error) { |
+ if (content_script_list.size() == 0) |
+ return false; |
+ for (size_t i = 0; i < content_script_list.size(); ++i) { |
+ const ContentScriptDetails& script_value = *content_script_list[i]; |
+ const std::string& name = script_value.name; |
+ UserScript script; |
+ if (!Parse(script_value, extension, owner_base_url, &script, error)) |
+ return false; |
+ else |
+ result->insert(std::pair<std::string, UserScript>(name, script)); |
+ } |
+ return true; |
+} |
+ |
+// Initialize the user script. |
+void InitUserScript(UserScript* script, std::string name, HostID host_id) { |
+ if (!script) |
+ return; |
+ script->set_id(UserScript::GenerateUserScriptID()); |
+ script->set_name(name); |
+ script->set_host_id(host_id); |
+ script->set_consumer_instance_type(UserScript::WEBVIEW); |
+} |
+ |
} // namespace |
namespace extensions { |
@@ -256,6 +421,90 @@ bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const { |
return true; |
} |
+WebViewInternalAddContentScriptsFunction:: |
+ WebViewInternalAddContentScriptsFunction() { |
+} |
+ |
+WebViewInternalAddContentScriptsFunction:: |
+ ~WebViewInternalAddContentScriptsFunction() { |
+} |
+ |
+bool WebViewInternalAddContentScriptsFunction::RunAsync() { |
+ scoped_ptr<web_view_internal::AddContentScripts::Params> params( |
+ web_view_internal::AddContentScripts::Params::Create(*args_)); |
+ EXTENSION_FUNCTION_VALIDATE(params.get()); |
+ |
+ int view_instance_id = 0; |
+ if (!args_->GetInteger(0, &view_instance_id) || !view_instance_id) { |
+ SendResponse(false); |
+ return false; |
+ } |
+ |
+ GURL owner_base_url( |
+ render_view_host()->GetSiteInstance()->GetSiteURL().GetWithEmptyPath()); |
+ std::map<std::string, UserScript> result; |
+ if (!Parse(params->content_script_list, extension(), owner_base_url, &result, |
+ &error_)) { |
+ SendResponse(false); |
+ return false; |
+ } |
+ |
+ WebViewContentScriptManager* manager = |
+ WebViewContentScriptManager::Get(browser_context()); |
+ if (!manager) { |
+ SendResponse(false); |
+ return false; |
+ } |
+ |
+ int embedder_process_id = |
+ GetSenderWebContents()->GetRenderProcessHost()->GetID(); |
+ HostID host_id = GenerateHostID(extension(), GetSenderWebContents()); |
+ for (auto& iter : result) |
+ InitUserScript(&iter.second, iter.first, host_id); |
+ manager->AddContentScripts(embedder_process_id, view_instance_id, host_id, |
+ result); |
+ |
+ SendResponse(true); |
+ return true; |
+} |
+ |
+WebViewInternalRemoveContentScriptsFunction:: |
+ WebViewInternalRemoveContentScriptsFunction() { |
+} |
+ |
+WebViewInternalRemoveContentScriptsFunction:: |
+ ~WebViewInternalRemoveContentScriptsFunction() { |
+} |
+ |
+bool WebViewInternalRemoveContentScriptsFunction::RunAsync() { |
+ scoped_ptr<web_view_internal::RemoveContentScripts::Params> params( |
+ web_view_internal::RemoveContentScripts::Params::Create(*args_)); |
+ EXTENSION_FUNCTION_VALIDATE(params.get()); |
+ |
+ int view_instance_id = 0; |
+ if (!args_->GetInteger(0, &view_instance_id) || !view_instance_id) { |
+ SendResponse(false); |
+ return false; |
+ } |
+ |
+ WebViewContentScriptManager* manager = |
+ WebViewContentScriptManager::Get(browser_context()); |
+ DCHECK(manager); |
+ |
+ int embedder_process_id = |
+ GetSenderWebContents()->GetRenderProcessHost()->GetID(); |
+ HostID host_id = GenerateHostID(extension(), GetSenderWebContents()); |
+ if (!params->script_name_list) { |
+ manager->RemoveContentScripts(embedder_process_id, view_instance_id, |
+ host_id, std::vector<std::string>()); |
+ } else { |
+ manager->RemoveContentScripts(embedder_process_id, view_instance_id, |
+ host_id, *(params->script_name_list)); |
+ } |
+ SendResponse(true); |
+ return true; |
+} |
+ |
WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() { |
} |