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

Unified Diff: extensions/browser/api/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: Add a test. 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 side-by-side diff with in-line comments
Download patch
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() {
}

Powered by Google App Engine
This is Rietveld 408576698