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

Side by Side Diff: chrome/browser/extensions/execute_code_in_tab_function.cc

Issue 10544023: Moving the tabs_module API into a separate directory in api/ (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Correcting the order of includes. Created 8 years, 6 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "chrome/browser/extensions/execute_code_in_tab_function.h"
6
7 #include "base/bind.h"
8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/extensions/extension_tab_util.h"
12 #include "chrome/browser/extensions/extension_tab_helper.h"
13 #include "chrome/browser/extensions/extension_tabs_module.h"
14 #include "chrome/browser/extensions/extension_tabs_module_constants.h"
15 #include "chrome/browser/extensions/file_reader.h"
16 #include "chrome/browser/extensions/script_executor.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
20 #include "chrome/common/extensions/extension.h"
21 #include "chrome/common/extensions/extension_constants.h"
22 #include "chrome/common/extensions/extension_error_utils.h"
23 #include "chrome/common/extensions/extension_file_util.h"
24 #include "chrome/common/extensions/extension_l10n_util.h"
25 #include "chrome/common/extensions/extension_manifest_constants.h"
26 #include "chrome/common/extensions/extension_message_bundle.h"
27 #include "chrome/common/extensions/extension_messages.h"
28 #include "content/public/browser/render_view_host.h"
29 #include "content/public/browser/web_contents.h"
30
31 using content::BrowserThread;
32 using extensions::ScriptExecutor;
33
34 namespace keys = extension_tabs_module_constants;
35
36 ExecuteCodeInTabFunction::ExecuteCodeInTabFunction()
37 : execute_tab_id_(-1),
38 all_frames_(false),
39 run_at_(UserScript::DOCUMENT_IDLE) {
40 }
41
42 ExecuteCodeInTabFunction::~ExecuteCodeInTabFunction() {}
43
44 bool ExecuteCodeInTabFunction::RunImpl() {
45 DictionaryValue* script_info;
46 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &script_info));
47 size_t number_of_value = script_info->size();
48 if (number_of_value == 0) {
49 error_ = keys::kNoCodeOrFileToExecuteError;
50 return false;
51 } else {
52 bool has_code = script_info->HasKey(keys::kCodeKey);
53 bool has_file = script_info->HasKey(keys::kFileKey);
54 if (has_code && has_file) {
55 error_ = keys::kMoreThanOneValuesError;
56 return false;
57 } else if (!has_code && !has_file) {
58 error_ = keys::kNoCodeOrFileToExecuteError;
59 return false;
60 }
61 }
62
63 execute_tab_id_ = -1;
64 Browser* browser = NULL;
65 TabContentsWrapper* contents = NULL;
66
67 // If |tab_id| is specified, look for it. Otherwise default to selected tab
68 // in the current window.
69 Value* tab_value = NULL;
70 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value));
71 if (tab_value->IsType(Value::TYPE_NULL)) {
72 browser = GetCurrentBrowser();
73 if (!browser) {
74 error_ = keys::kNoCurrentWindowError;
75 return false;
76 }
77 if (!ExtensionTabUtil::GetDefaultTab(browser, &contents, &execute_tab_id_))
78 return false;
79 } else {
80 EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&execute_tab_id_));
81 if (!ExtensionTabUtil::GetTabById(execute_tab_id_, profile(),
82 include_incognito(),
83 &browser, NULL, &contents, NULL)) {
84 return false;
85 }
86 }
87
88 // NOTE: This can give the wrong answer due to race conditions, but it is OK,
89 // we check again in the renderer.
90 CHECK(browser);
91 CHECK(contents);
92 if (!GetExtension()->CanExecuteScriptOnPage(
93 contents->web_contents()->GetURL(), NULL, &error_)) {
94 return false;
95 }
96
97 if (script_info->HasKey(keys::kAllFramesKey)) {
98 if (!script_info->GetBoolean(keys::kAllFramesKey, &all_frames_))
99 return false;
100 }
101
102 if (script_info->HasKey(keys::kRunAtKey)) {
103 std::string run_string;
104 EXTENSION_FUNCTION_VALIDATE(script_info->GetString(
105 keys::kRunAtKey, &run_string));
106
107 if (run_string == extension_manifest_values::kRunAtDocumentStart)
108 run_at_ = UserScript::DOCUMENT_START;
109 else if (run_string == extension_manifest_values::kRunAtDocumentEnd)
110 run_at_ = UserScript::DOCUMENT_END;
111 else if (run_string == extension_manifest_values::kRunAtDocumentIdle)
112 run_at_ = UserScript::DOCUMENT_IDLE;
113 else
114 EXTENSION_FUNCTION_VALIDATE(false);
115 }
116
117 std::string code_string;
118 if (script_info->HasKey(keys::kCodeKey)) {
119 if (!script_info->GetString(keys::kCodeKey, &code_string))
120 return false;
121 }
122
123 if (!code_string.empty()) {
124 if (!Execute(code_string))
125 return false;
126 return true;
127 }
128
129 std::string relative_path;
130 if (script_info->HasKey(keys::kFileKey)) {
131 if (!script_info->GetString(keys::kFileKey, &relative_path))
132 return false;
133 resource_ = GetExtension()->GetResource(relative_path);
134 }
135 if (resource_.extension_root().empty() || resource_.relative_path().empty()) {
136 error_ = keys::kNoCodeOrFileToExecuteError;
137 return false;
138 }
139
140 scoped_refptr<FileReader> file_reader(new FileReader(
141 resource_, base::Bind(&ExecuteCodeInTabFunction::DidLoadFile, this)));
142 file_reader->Start();
143
144 return true;
145 }
146
147 void ExecuteCodeInTabFunction::OnExecuteCodeFinished(bool success,
148 int32 page_id,
149 const std::string& error) {
150 if (!error.empty()) {
151 CHECK(!success);
152 error_ = error;
153 }
154
155 SendResponse(success);
156 }
157
158 void ExecuteCodeInTabFunction::DidLoadFile(bool success,
159 const std::string& data) {
160 std::string function_name = name();
161 const extensions::Extension* extension = GetExtension();
162
163 // Check if the file is CSS and needs localization.
164 if (success &&
165 function_name == TabsInsertCSSFunction::function_name() &&
166 extension != NULL &&
167 data.find(ExtensionMessageBundle::kMessageBegin) != std::string::npos) {
168 BrowserThread::PostTask(
169 BrowserThread::FILE, FROM_HERE,
170 base::Bind(&ExecuteCodeInTabFunction::LocalizeCSS, this,
171 data,
172 extension->id(),
173 extension->path(),
174 extension->default_locale()));
175 } else {
176 DidLoadAndLocalizeFile(success, data);
177 }
178 }
179
180 void ExecuteCodeInTabFunction::LocalizeCSS(
181 const std::string& data,
182 const std::string& extension_id,
183 const FilePath& extension_path,
184 const std::string& extension_default_locale) {
185 scoped_ptr<SubstitutionMap> localization_messages(
186 extension_file_util::LoadExtensionMessageBundleSubstitutionMap(
187 extension_path, extension_id, extension_default_locale));
188
189 // We need to do message replacement on the data, so it has to be mutable.
190 std::string css_data = data;
191 std::string error;
192 ExtensionMessageBundle::ReplaceMessagesWithExternalDictionary(
193 *localization_messages, &css_data, &error);
194
195 // Call back DidLoadAndLocalizeFile on the UI thread. The success parameter
196 // is always true, because if loading had failed, we wouldn't have had
197 // anything to localize.
198 BrowserThread::PostTask(
199 BrowserThread::UI, FROM_HERE,
200 base::Bind(&ExecuteCodeInTabFunction::DidLoadAndLocalizeFile, this,
201 true, css_data));
202 }
203
204 void ExecuteCodeInTabFunction::DidLoadAndLocalizeFile(bool success,
205 const std::string& data) {
206 if (success) {
207 Execute(data);
208 } else {
209 #if defined(OS_POSIX)
210 // TODO(viettrungluu): bug: there's no particular reason the path should be
211 // UTF-8, in which case this may fail.
212 error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kLoadFileError,
213 resource_.relative_path().value());
214 #elif defined(OS_WIN)
215 error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kLoadFileError,
216 WideToUTF8(resource_.relative_path().value()));
217 #endif // OS_WIN
218 SendResponse(false);
219 }
220 }
221
222 bool ExecuteCodeInTabFunction::Execute(const std::string& code_string) {
223 TabContentsWrapper* contents = NULL;
224 Browser* browser = NULL;
225
226 bool success = ExtensionTabUtil::GetTabById(
227 execute_tab_id_, profile(), include_incognito(), &browser, NULL,
228 &contents, NULL) && contents && browser;
229
230 if (!success) {
231 SendResponse(false);
232 return false;
233 }
234
235 const extensions::Extension* extension = GetExtension();
236 if (!extension) {
237 SendResponse(false);
238 return false;
239 }
240
241 ScriptExecutor::ScriptType script_type = ScriptExecutor::JAVASCRIPT;
242 std::string function_name = name();
243 if (function_name == TabsInsertCSSFunction::function_name()) {
244 script_type = ScriptExecutor::CSS;
245 } else if (function_name != TabsExecuteScriptFunction::function_name()) {
246 NOTREACHED();
247 }
248
249 contents->extension_tab_helper()->script_executor()->ExecuteScript(
250 extension->id(),
251 script_type,
252 code_string,
253 all_frames_ ? ScriptExecutor::ALL_FRAMES : ScriptExecutor::TOP_FRAME,
254 run_at_,
255 ScriptExecutor::ISOLATED_WORLD,
256 base::Bind(&ExecuteCodeInTabFunction::OnExecuteCodeFinished, this));
257 return true;
258 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/execute_code_in_tab_function.h ('k') | chrome/browser/extensions/extension_browser_event_router.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698