diff options
Diffstat (limited to 'chrome/browser/extensions')
8 files changed, 257 insertions, 2 deletions
diff --git a/chrome/browser/extensions/execute_code_in_tab_function.cc b/chrome/browser/extensions/execute_code_in_tab_function.cc new file mode 100755 index 0000000..bd62799 --- /dev/null +++ b/chrome/browser/extensions/execute_code_in_tab_function.cc @@ -0,0 +1,156 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/execute_code_in_tab_function.h" + +#include "base/thread.h" +#include "base/file_util.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/extensions/extension_tabs_module.h" +#include "chrome/browser/extensions/extension_tabs_module_constants.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_error_utils.h" + +namespace keys = extension_tabs_module_constants; + +const wchar_t* kCodeKey = L"code"; +const wchar_t* kFileKey = L"file"; + +bool ExecuteCodeInTabFunction::RunImpl() { + EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST)); + const ListValue* args = static_cast<const ListValue*>(args_); + + DictionaryValue* script_info; + EXTENSION_FUNCTION_VALIDATE(args->GetDictionary(1, &script_info)); + size_t number_of_value = script_info->GetSize(); + if (number_of_value == 0) { + error_ = keys::kNoCodeOrFileToExecuteError; + return false; + } else if (number_of_value > 1) { + error_ = keys::kMoreThanOneValuesError; + return false; + } + + execute_tab_id_ = -1; + Browser* browser = NULL; + TabContents* contents = NULL; + + // If |tab_id| is specified, look for it. Otherwise default to selected tab + // in the current window. + Value* tab_value = NULL; + EXTENSION_FUNCTION_VALIDATE(args->Get(0, &tab_value)); + if (tab_value->IsType(Value::TYPE_NULL)) { + browser = dispatcher()->GetBrowser(); + if (!browser) { + error_ = keys::kNoCurrentWindowError; + return false; + } + if (!ExtensionTabUtil::GetDefaultTab(browser, &contents, &execute_tab_id_)) + return false; + } else { + EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&execute_tab_id_)); + if (!ExtensionTabUtil::GetTabById(execute_tab_id_, profile(), &browser, + NULL, &contents, NULL)) { + return false; + } + } + + DCHECK(browser); + DCHECK(contents); + + if (!GetExtension()->CanAccessHost(contents->GetURL())) { + error_ = ExtensionErrorUtils::FormatErrorMessage( + keys::kCannotAccessPageError, contents->GetURL().spec()); + return false; + } + + if (script_info->HasKey(kCodeKey)) { + if (!script_info->GetString(kCodeKey, &code_string_)) + return false; + } + + if (!code_string_.empty()) { + Execute(); + return true; + } + + std::string relative_path; + if (script_info->HasKey(kFileKey)) { + if (!script_info->GetString(kFileKey, &relative_path)) + return false; + file_path_ = GetExtension()->GetResourcePath(relative_path); + } + if (file_path_.empty()) { + error_ = keys::kNoCodeOrFileToExecuteError; + return false; + } + + ui_loop_ = MessageLoop::current(); + MessageLoop* work_loop = g_browser_process->file_thread()->message_loop(); + work_loop->PostTask(FROM_HERE, + NewRunnableMethod(this, &ExecuteCodeInTabFunction::LoadFile)); + + return true; +} + +void ExecuteCodeInTabFunction::LoadFile() { + DCHECK(ui_loop_); + std::string content; + if (!file_util::ReadFileToString(file_path_, &content)) { + +#if defined(OS_POSIX) + error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kLoadFileError, + file_path_.value()); +#elif defined(OS_WIN) + error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kLoadFileError, + WideToUTF8(file_path_.value())); +#endif // OS_WIN + + ui_loop_->PostTask(FROM_HERE, + NewRunnableMethod(this, &ExecuteCodeInTabFunction::SendResponse, + false)); + } else { + code_string_ = content; + ui_loop_->PostTask(FROM_HERE, + NewRunnableMethod(this, &ExecuteCodeInTabFunction::Execute)); + } + + return; +} + +void ExecuteCodeInTabFunction::Execute() { + TabContents* contents = NULL; + Browser* browser = NULL; + if (!ExtensionTabUtil::GetTabById(execute_tab_id_, profile(), &browser, NULL, + &contents, NULL) && contents && browser) { + SendResponse(false); + return; + } + + bool is_js_code = true; + std::string function_name = name(); + if (function_name == keys::kInsertCSSFunction) { + is_js_code = false; + } else if (function_name != keys::kExecuteScriptFunction) { + DCHECK(false); + } + registrar_.Add(this, NotificationType::TAB_CODE_EXECUTED, + NotificationService::AllSources()); + AddRef(); // balanced in Observe() + contents->ExecuteCode(request_id(), extension_id(), is_js_code, + code_string_); +} + +void ExecuteCodeInTabFunction::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + std::pair<int, bool>* result_details = + Details<std::pair<int, bool> >(details).ptr(); + if (result_details->first == request_id()) { + SendResponse(result_details->second); + Release(); // balanced in Execute() + } +} diff --git a/chrome/browser/extensions/execute_code_in_tab_function.h b/chrome/browser/extensions/execute_code_in_tab_function.h new file mode 100755 index 0000000..c1a1579 --- /dev/null +++ b/chrome/browser/extensions/execute_code_in_tab_function.h @@ -0,0 +1,52 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_EXECUTE_CODE_IN_TAB_FUNCTION_H__ +#define CHROME_BROWSER_EXTENSIONS_EXECUTE_CODE_IN_TAB_FUNCTION_H__ + +#include <string> +#include <vector> + +#include "base/file_path.h" +#include "chrome/browser/extensions/extension_function.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_registrar.h" + +class MessageLoop; + +// Implement API call tabs.executeScript and tabs.insertCSS. +class ExecuteCodeInTabFunction : public AsyncExtensionFunction, + public NotificationObserver { + public: + ExecuteCodeInTabFunction() : execute_tab_id_(-1), ui_loop_(NULL) {} + + private: + virtual bool RunImpl(); + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Load contents from file whose path is specified in JSON arguments. Run + // in file thread. + void LoadFile(); + + // Run in UI thread. + void Execute(); + + NotificationRegistrar registrar_; + + // Id of tab which executes code. + int execute_tab_id_; + + MessageLoop* ui_loop_; + + // Contain path of file which is specified in JSON arguments. + FilePath file_path_; + + // Contain code to be executed. + std::string code_string_; +}; + +#endif // CHROME_BROWSER_EXTENSIONS_EXECUTE_CODE_IN_TAB_FUNCTION_H__ diff --git a/chrome/browser/extensions/execute_script_apitest.cc b/chrome/browser/extensions/execute_script_apitest.cc new file mode 100755 index 0000000..f519702 --- /dev/null +++ b/chrome/browser/extensions/execute_script_apitest.cc @@ -0,0 +1,13 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/extension_apitest.h" + +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ExecuteScript) { + host_resolver()->AddRule("a.com", "127.0.0.1"); + host_resolver()->AddRule("b.com", "127.0.0.1"); + StartHTTPServer(); + + ASSERT_TRUE(RunExtensionTest("executescript")) << message_; +} diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 36f4192..a9de221 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -7,6 +7,7 @@ #include "base/process_util.h" #include "base/singleton.h" #include "base/values.h" +#include "chrome/browser/extensions/execute_code_in_tab_function.h" #include "chrome/browser/extensions/extension_bookmarks_module.h" #include "chrome/browser/extensions/extension_bookmarks_module_constants.h" #include "chrome/browser/extensions/extension_function.h" @@ -111,6 +112,10 @@ void FactoryRegistry::ResetFunctions() { &NewExtensionFunction<DetectTabLanguageFunction>; factories_[tabs::kCaptureVisibleTabFunction] = &NewExtensionFunction<CaptureVisibleTabFunction>; + factories_[tabs::kExecuteScriptFunction] = + &NewExtensionFunction<ExecuteCodeInTabFunction>; + factories_[tabs::kInsertCSSFunction] = + &NewExtensionFunction<ExecuteCodeInTabFunction>; // Page Actions. factories_[page_actions::kEnablePageActionFunction] = diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index 5cd4242..12028c2 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -27,7 +27,6 @@ #include "skia/ext/platform_canvas.h" #include "third_party/skia/include/core/SkBitmap.h" - namespace keys = extension_tabs_module_constants; // Forward declare static helper functions defined below. @@ -157,6 +156,22 @@ DictionaryValue* ExtensionTabUtil::CreateWindowValue(const Browser* browser, return result; } +bool ExtensionTabUtil::GetDefaultTab(Browser* browser, TabContents** contents, + int* tab_id) { + DCHECK(browser); + DCHECK(contents); + DCHECK(tab_id); + + *contents = browser->tabstrip_model()->GetSelectedTabContents(); + if (*contents) { + if (tab_id) + *tab_id = ExtensionTabUtil::GetTabId(*contents); + return true; + } + + return false; +} + bool ExtensionTabUtil::GetTabById(int tab_id, Profile* profile, Browser** browser, TabStripModel** tab_strip, diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h index eccd823..0914758 100644 --- a/chrome/browser/extensions/extension_tabs_module.h +++ b/chrome/browser/extensions/extension_tabs_module.h @@ -39,6 +39,8 @@ class ExtensionTabUtil { static DictionaryValue* CreateWindowValue(const Browser* browser, bool populate_tabs); + static bool GetDefaultTab(Browser* browser, TabContents** contents, + int* tab_id); // Any out parameter (|browser|, |tab_strip|, |contents|, & |tab_index|) may // be NULL and will not be set within the function. static bool GetTabById(int tab_id, Profile* profile, Browser** browser, @@ -94,9 +96,9 @@ class RemoveTabFunction : public SyncExtensionFunction { }; class DetectTabLanguageFunction : public AsyncExtensionFunction, public NotificationObserver { + private: virtual bool RunImpl(); - private: virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); diff --git a/chrome/browser/extensions/extension_tabs_module_constants.cc b/chrome/browser/extensions/extension_tabs_module_constants.cc index 7f28314..8c9e153 100644 --- a/chrome/browser/extensions/extension_tabs_module_constants.cc +++ b/chrome/browser/extensions/extension_tabs_module_constants.cc @@ -64,4 +64,11 @@ const char kRemoveTabFunction[] = "tabs.remove"; const char kDetectTabLanguageFunction[] = "tabs.detectLanguage"; const char kCaptureVisibleTabFunction[] = "tabs.captureVisibleTab"; +const char kExecuteScriptFunction[] = "tabs.executeScript"; +const char kInsertCSSFunction[] = "tabs.insertCSS"; +const char kNoCodeOrFileToExecuteError[] = "No source code or file specified."; +const char kMoreThanOneValuesError[] = "There should be only one value (either" + "code or file) in the second argument."; +const char kLoadFileError[] = "Failed to load file: \"*\". "; + } // namespace extension_tabs_module_constants diff --git a/chrome/browser/extensions/extension_tabs_module_constants.h b/chrome/browser/extensions/extension_tabs_module_constants.h index f22b48d..cfb3412 100644 --- a/chrome/browser/extensions/extension_tabs_module_constants.h +++ b/chrome/browser/extensions/extension_tabs_module_constants.h @@ -69,6 +69,11 @@ extern const char kMoveTabFunction[]; extern const char kRemoveTabFunction[]; extern const char kDetectTabLanguageFunction[]; extern const char kCaptureVisibleTabFunction[]; +extern const char kExecuteScriptFunction[]; +extern const char kInsertCSSFunction[]; +extern const char kNoCodeOrFileToExecuteError[]; +extern const char kMoreThanOneValuesError[]; +extern const char kLoadFileError[]; }; // namespace extension_tabs_module_constants |