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. 4 5#include "extensions/renderer/programmatic_script_injector.h" 6 7#include <vector> 8 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.h" 13#include "extensions/common/extension_messages.h" 14#include "extensions/common/manifest_constants.h" 15#include "extensions/common/permissions/permissions_data.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" 21 22namespace extensions { 23 24ProgrammaticScriptInjector::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()), 31 finished_(false) { 32} 33 34ProgrammaticScriptInjector::~ProgrammaticScriptInjector() { 35} 36 37UserScript::InjectionType ProgrammaticScriptInjector::script_type() 38 const { 39 return UserScript::PROGRAMMATIC_SCRIPT; 40} 41 42bool ProgrammaticScriptInjector::ShouldExecuteInChildFrames() const { 43 return params_->all_frames; 44} 45 46bool ProgrammaticScriptInjector::ShouldExecuteInMainWorld() const { 47 return params_->in_main_world; 48} 49 50bool ProgrammaticScriptInjector::IsUserGesture() const { 51 return params_->user_gesture; 52} 53 54bool ProgrammaticScriptInjector::ExpectsResults() const { 55 return params_->wants_result; 56} 57 58bool ProgrammaticScriptInjector::ShouldInjectJs( 59 UserScript::RunLocation run_location) const { 60 return GetRunLocation() == run_location && params_->is_javascript; 61} 62 63bool ProgrammaticScriptInjector::ShouldInjectCss( 64 UserScript::RunLocation run_location) const { 65 return GetRunLocation() == run_location && !params_->is_javascript; 66} 67 68PermissionsData::AccessType ProgrammaticScriptInjector::CanExecuteOnFrame( 69 const Extension* extension, 70 blink::WebFrame* frame, 71 int tab_id, 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 return effective_document_url == params_->webview_src 77 ? PermissionsData::ACCESS_ALLOWED 78 : PermissionsData::ACCESS_DENIED; 79 } 80 81 return extension->permissions_data()->GetPageAccess(extension, 82 effective_document_url, 83 top_url, 84 tab_id, 85 -1, // no process ID. 86 NULL /* ignore error */); 87} 88 89std::vector<blink::WebScriptSource> ProgrammaticScriptInjector::GetJsSources( 90 UserScript::RunLocation run_location) const { 91 DCHECK_EQ(GetRunLocation(), run_location); 92 DCHECK(params_->is_javascript); 93 94 return std::vector<blink::WebScriptSource>( 95 1, 96 blink::WebScriptSource( 97 blink::WebString::fromUTF8(params_->code), params_->file_url)); 98} 99 100std::vector<std::string> ProgrammaticScriptInjector::GetCssSources( 101 UserScript::RunLocation run_location) const { 102 DCHECK_EQ(GetRunLocation(), run_location); 103 DCHECK(!params_->is_javascript); 104 105 return std::vector<std::string>(1, params_->code); 106} 107 108void ProgrammaticScriptInjector::OnInjectionComplete( 109 scoped_ptr<base::ListValue> execution_results, 110 ScriptsRunInfo* scripts_run_info, 111 UserScript::RunLocation run_location) { 112 results_ = execution_results.Pass(); 113 Finish(std::string()); 114} 115 116void ProgrammaticScriptInjector::OnWillNotInject(InjectFailureReason reason) { 117 std::string error; 118 switch (reason) { 119 case NOT_ALLOWED: 120 error = ErrorUtils::FormatErrorMessage(manifest_errors::kCannotAccessPage, 121 url_.spec()); 122 break; 123 case EXTENSION_REMOVED: // no special error here. 124 case WONT_INJECT: 125 break; 126 } 127 Finish(error); 128} 129 130UserScript::RunLocation ProgrammaticScriptInjector::GetRunLocation() const { 131 return static_cast<UserScript::RunLocation>(params_->run_at); 132} 133 134void ProgrammaticScriptInjector::Finish(const std::string& error) { 135 DCHECK(!finished_); 136 finished_ = true; 137 138 render_view_->Send(new ExtensionHostMsg_ExecuteCodeFinished( 139 render_view_->GetRoutingID(), 140 params_->request_id, 141 error, 142 url_, 143 *results_)); 144} 145 146} // namespace extensions 147