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
3 // found in the LICENSE file.
5 #include "extensions/renderer/programmatic_script_injector.h"
9 #include "base/values.h"
10 #include "content/public/renderer/render_view.h"
11 #include "extensions/common/error_utils.h"
12 #include "extensions/common/extension_messages.h"
13 #include "extensions/common/manifest_constants.h"
14 #include "extensions/common/permissions/permissions_data.h"
15 #include "extensions/renderer/injection_host.h"
16 #include "extensions/renderer/script_context.h"
17 #include "third_party/WebKit/public/platform/WebString.h"
18 #include "third_party/WebKit/public/web/WebDocument.h"
19 #include "third_party/WebKit/public/web/WebFrame.h"
20 #include "third_party/WebKit/public/web/WebScriptSource.h"
22 namespace extensions
{
24 ProgrammaticScriptInjector::ProgrammaticScriptInjector(
25 const ExtensionMsg_ExecuteCode_Params
& params
,
26 blink::WebFrame
* web_frame
)
27 : params_(new ExtensionMsg_ExecuteCode_Params(params
)),
28 url_(ScriptContext::GetDataSourceURLForFrame(web_frame
)),
29 render_view_(content::RenderView::FromWebView(web_frame
->view())),
30 results_(new base::ListValue()),
34 ProgrammaticScriptInjector::~ProgrammaticScriptInjector() {
37 UserScript::InjectionType
ProgrammaticScriptInjector::script_type()
39 return UserScript::PROGRAMMATIC_SCRIPT
;
42 bool ProgrammaticScriptInjector::ShouldExecuteInChildFrames() const {
43 return params_
->all_frames
;
46 bool ProgrammaticScriptInjector::ShouldExecuteInMainWorld() const {
47 return params_
->in_main_world
;
50 bool ProgrammaticScriptInjector::IsUserGesture() const {
51 return params_
->user_gesture
;
54 bool ProgrammaticScriptInjector::ExpectsResults() const {
55 return params_
->wants_result
;
58 bool ProgrammaticScriptInjector::ShouldInjectJs(
59 UserScript::RunLocation run_location
) const {
60 return GetRunLocation() == run_location
&& params_
->is_javascript
;
63 bool ProgrammaticScriptInjector::ShouldInjectCss(
64 UserScript::RunLocation run_location
) const {
65 return GetRunLocation() == run_location
&& !params_
->is_javascript
;
68 PermissionsData::AccessType
ProgrammaticScriptInjector::CanExecuteOnFrame(
69 const InjectionHost
* injection_host
,
70 blink::WebFrame
* frame
,
72 const GURL
& top_url
) const {
73 GURL effective_document_url
= ScriptContext::GetEffectiveDocumentURL(
74 frame
, frame
->document().url(), params_
->match_about_blank
);
75 if (params_
->is_web_view
) {
76 if (frame
->parent()) {
77 // This is a subframe inside <webview>, so allow it.
78 return PermissionsData::ACCESS_ALLOWED
;
81 return effective_document_url
== params_
->webview_src
82 ? PermissionsData::ACCESS_ALLOWED
83 : PermissionsData::ACCESS_DENIED
;
86 return injection_host
->CanExecuteOnFrame(
87 effective_document_url
, top_url
, tab_id
, true /* is_declarative */);
90 std::vector
<blink::WebScriptSource
> ProgrammaticScriptInjector::GetJsSources(
91 UserScript::RunLocation run_location
) const {
92 DCHECK_EQ(GetRunLocation(), run_location
);
93 DCHECK(params_
->is_javascript
);
95 return std::vector
<blink::WebScriptSource
>(
97 blink::WebScriptSource(
98 blink::WebString::fromUTF8(params_
->code
), params_
->file_url
));
101 std::vector
<std::string
> ProgrammaticScriptInjector::GetCssSources(
102 UserScript::RunLocation run_location
) const {
103 DCHECK_EQ(GetRunLocation(), run_location
);
104 DCHECK(!params_
->is_javascript
);
106 return std::vector
<std::string
>(1, params_
->code
);
109 void ProgrammaticScriptInjector::OnInjectionComplete(
110 scoped_ptr
<base::ListValue
> execution_results
,
111 ScriptsRunInfo
* scripts_run_info
,
112 UserScript::RunLocation run_location
) {
113 results_
= execution_results
.Pass();
114 Finish(std::string());
117 void ProgrammaticScriptInjector::OnWillNotInject(InjectFailureReason reason
) {
121 error
= ErrorUtils::FormatErrorMessage(manifest_errors::kCannotAccessPage
,
124 case EXTENSION_REMOVED
: // no special error here.
131 UserScript::RunLocation
ProgrammaticScriptInjector::GetRunLocation() const {
132 return static_cast<UserScript::RunLocation
>(params_
->run_at
);
135 void ProgrammaticScriptInjector::Finish(const std::string
& error
) {
139 render_view_
->Send(new ExtensionHostMsg_ExecuteCodeFinished(
140 render_view_
->GetRoutingID(),
147 } // namespace extensions