Disable TabDragController tests that fail with a real compositor.
[chromium-blink-merge.git] / chrome / browser / extensions / api / execute_code_function.cc
blobab5bf375e068da829afd8ef8d8cc4ae92f19ff46
1 // Copyright (c) 2013 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 "chrome/browser/extensions/api/execute_code_function.h"
7 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
8 #include "chrome/browser/extensions/image_loader.h"
9 #include "chrome/browser/extensions/script_executor.h"
10 #include "chrome/common/extensions/api/i18n/default_locale_handler.h"
11 #include "chrome/common/extensions/extension_file_util.h"
12 #include "chrome/common/extensions/extension_messages.h"
13 #include "chrome/common/extensions/message_bundle.h"
14 #include "extensions/browser/file_reader.h"
15 #include "extensions/common/error_utils.h"
16 #include "net/base/net_util.h"
17 #include "ui/base/resource/resource_bundle.h"
19 namespace extensions {
21 namespace keys = tabs_constants;
22 using api::tabs::InjectDetails;
24 ExecuteCodeFunction::ExecuteCodeFunction() {
27 ExecuteCodeFunction::~ExecuteCodeFunction() {
30 void ExecuteCodeFunction::DidLoadFile(bool success,
31 const std::string& data) {
33 if (!success || !details_->file) {
34 DidLoadAndLocalizeFile(success, data);
35 return;
38 ScriptExecutor::ScriptType script_type =
39 ShouldInsertCSS() ? ScriptExecutor::CSS : ScriptExecutor::JAVASCRIPT;
41 std::string extension_id;
42 base::FilePath extension_path;
43 std::string extension_default_locale;
44 const Extension* extension = GetExtension();
45 if (extension) {
46 extension_id = extension->id();
47 extension_path = extension->path();
48 extension_default_locale = LocaleInfo::GetDefaultLocale(extension);
51 content::BrowserThread::PostTask(
52 content::BrowserThread::FILE, FROM_HERE,
53 base::Bind(&ExecuteCodeFunction::GetFileURLAndLocalizeCSS, this,
54 script_type,
55 data,
56 extension_id,
57 extension_path,
58 extension_default_locale));
61 void ExecuteCodeFunction::GetFileURLAndLocalizeCSS(
62 ScriptExecutor::ScriptType script_type,
63 const std::string& data,
64 const std::string& extension_id,
65 const base::FilePath& extension_path,
66 const std::string& extension_default_locale) {
68 std::string localized_data = data;
69 // Check if the file is CSS and needs localization.
70 if ((script_type == ScriptExecutor::CSS) &&
71 !extension_id.empty() &&
72 (data.find(MessageBundle::kMessageBegin) != std::string::npos)) {
73 scoped_ptr<SubstitutionMap> localization_messages(
74 extension_file_util::LoadMessageBundleSubstitutionMap(
75 extension_path, extension_id, extension_default_locale));
77 // We need to do message replacement on the data, so it has to be mutable.
78 std::string error;
79 MessageBundle::ReplaceMessagesWithExternalDictionary(*localization_messages,
80 &localized_data,
81 &error);
84 file_url_ = net::FilePathToFileURL(resource_.GetFilePath());
86 // Call back DidLoadAndLocalizeFile on the UI thread. The success parameter
87 // is always true, because if loading had failed, we wouldn't have had
88 // anything to localize.
89 content::BrowserThread::PostTask(
90 content::BrowserThread::UI, FROM_HERE,
91 base::Bind(&ExecuteCodeFunction::DidLoadAndLocalizeFile, this,
92 true, localized_data));
95 void ExecuteCodeFunction::DidLoadAndLocalizeFile(bool success,
96 const std::string& data) {
97 if (success) {
98 if (!Execute(data))
99 SendResponse(false);
100 } else {
101 // TODO(viettrungluu): bug: there's no particular reason the path should be
102 // UTF-8, in which case this may fail.
103 error_ = ErrorUtils::FormatErrorMessage(keys::kLoadFileError,
104 resource_.relative_path().AsUTF8Unsafe());
105 SendResponse(false);
109 bool ExecuteCodeFunction::Execute(const std::string& code_string) {
110 ScriptExecutor* executor = GetScriptExecutor();
111 if (!executor)
112 return false;
114 const Extension* extension = GetExtension();
115 if (!extension)
116 return false;
118 ScriptExecutor::ScriptType script_type = ScriptExecutor::JAVASCRIPT;
119 if (ShouldInsertCSS())
120 script_type = ScriptExecutor::CSS;
122 ScriptExecutor::FrameScope frame_scope =
123 details_->all_frames.get() && *details_->all_frames ?
124 ScriptExecutor::ALL_FRAMES :
125 ScriptExecutor::TOP_FRAME;
127 UserScript::RunLocation run_at =
128 UserScript::UNDEFINED;
129 switch (details_->run_at) {
130 case InjectDetails::RUN_AT_NONE:
131 case InjectDetails::RUN_AT_DOCUMENT_IDLE:
132 run_at = UserScript::DOCUMENT_IDLE;
133 break;
134 case InjectDetails::RUN_AT_DOCUMENT_START:
135 run_at = UserScript::DOCUMENT_START;
136 break;
137 case InjectDetails::RUN_AT_DOCUMENT_END:
138 run_at = UserScript::DOCUMENT_END;
139 break;
141 CHECK_NE(UserScript::UNDEFINED, run_at);
143 executor->ExecuteScript(
144 extension->id(),
145 script_type,
146 code_string,
147 frame_scope,
148 run_at,
149 ScriptExecutor::ISOLATED_WORLD,
150 IsWebView() ? ScriptExecutor::WEB_VIEW_PROCESS
151 : ScriptExecutor::DEFAULT_PROCESS,
152 file_url_,
153 has_callback() ? ScriptExecutor::JSON_SERIALIZED_RESULT
154 : ScriptExecutor::NO_RESULT,
155 base::Bind(&ExecuteCodeFunction::OnExecuteCodeFinished, this));
156 return true;
159 bool ExecuteCodeFunction::HasPermission() {
160 return true;
163 bool ExecuteCodeFunction::RunImpl() {
164 EXTENSION_FUNCTION_VALIDATE(Init());
166 if (!details_->code.get() && !details_->file.get()) {
167 error_ = keys::kNoCodeOrFileToExecuteError;
168 return false;
170 if (details_->code.get() && details_->file.get()) {
171 error_ = keys::kMoreThanOneValuesError;
172 return false;
175 if (!CanExecuteScriptOnPage())
176 return false;
178 if (details_->code.get())
179 return Execute(*details_->code);
181 if (!details_->file.get())
182 return false;
183 resource_ = GetExtension()->GetResource(*details_->file);
185 if (resource_.extension_root().empty() || resource_.relative_path().empty()) {
186 error_ = keys::kNoCodeOrFileToExecuteError;
187 return false;
190 int resource_id;
191 if (ImageLoader::IsComponentExtensionResource(
192 resource_.extension_root(), resource_.relative_path(),
193 &resource_id)) {
194 const ResourceBundle& rb = ResourceBundle::GetSharedInstance();
195 DidLoadFile(true, rb.GetRawDataResource(resource_id).as_string());
196 } else {
197 scoped_refptr<FileReader> file_reader(new FileReader(
198 resource_, base::Bind(&ExecuteCodeFunction::DidLoadFile, this)));
199 file_reader->Start();
202 return true;
205 void ExecuteCodeFunction::OnExecuteCodeFinished(
206 const std::string& error,
207 int32 on_page_id,
208 const GURL& on_url,
209 const base::ListValue& result) {
210 if (!error.empty())
211 SetError(error);
213 SendResponse(error.empty());
216 } // namespace extensions