| Index: chrome/browser/extensions/api/tabs/tabs_api.cc | 
| diff --git a/chrome/browser/extensions/api/tabs/tabs.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc | 
| similarity index 85% | 
| rename from chrome/browser/extensions/api/tabs/tabs.cc | 
| rename to chrome/browser/extensions/api/tabs/tabs_api.cc | 
| index 342b6307572382bdbc0a34901e6344c6a771eb88..441f4221875776e3e7289624cdabc30fca17936f 100644 | 
| --- a/chrome/browser/extensions/api/tabs/tabs.cc | 
| +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc | 
| @@ -2,7 +2,7 @@ | 
| // Use of this source code is governed by a BSD-style license that can be | 
| // found in the LICENSE file. | 
|  | 
| -#include "chrome/browser/extensions/api/tabs/tabs.h" | 
| +#include "chrome/browser/extensions/api/tabs/tabs_api.h" | 
|  | 
| #include <algorithm> | 
| #include <limits> | 
| @@ -26,6 +26,7 @@ | 
| #include "chrome/browser/extensions/extension_host.h" | 
| #include "chrome/browser/extensions/extension_service.h" | 
| #include "chrome/browser/extensions/extension_tab_util.h" | 
| +#include "chrome/browser/extensions/file_reader.h" | 
| #include "chrome/browser/extensions/script_executor.h" | 
| #include "chrome/browser/extensions/tab_helper.h" | 
| #include "chrome/browser/extensions/window_controller.h" | 
| @@ -50,10 +51,15 @@ | 
| #include "chrome/browser/web_applications/web_app.h" | 
| #include "chrome/common/chrome_notification_types.h" | 
| #include "chrome/common/chrome_switches.h" | 
| +#include "chrome/common/extensions/api/tabs.h" | 
| #include "chrome/common/extensions/api/windows.h" | 
| #include "chrome/common/extensions/extension.h" | 
| +#include "chrome/common/extensions/extension_constants.h" | 
| +#include "chrome/common/extensions/extension_file_util.h" | 
| +#include "chrome/common/extensions/extension_l10n_util.h" | 
| #include "chrome/common/extensions/extension_manifest_constants.h" | 
| #include "chrome/common/extensions/extension_messages.h" | 
| +#include "chrome/common/extensions/message_bundle.h" | 
| #include "chrome/common/extensions/user_script.h" | 
| #include "chrome/common/pref_names.h" | 
| #include "chrome/common/url_constants.h" | 
| @@ -87,6 +93,7 @@ namespace GetLastFocused = extensions::api::windows::GetLastFocused; | 
| namespace errors = extension_manifest_errors; | 
| namespace keys = extensions::tabs_constants; | 
|  | 
| +using content::BrowserThread; | 
| using content::NavigationController; | 
| using content::NavigationEntry; | 
| using content::OpenURLParams; | 
| @@ -95,10 +102,12 @@ using content::RenderViewHost; | 
| using content::WebContents; | 
| using extensions::ErrorUtils; | 
| using extensions::ScriptExecutor; | 
| +using extensions::UserScript; | 
| using extensions::WindowController; | 
| using extensions::WindowControllerList; | 
| +using extensions::api::tabs::InjectDetails; | 
|  | 
| -const int CaptureVisibleTabFunction::kDefaultQuality = 90; | 
| +const int TabsCaptureVisibleTabFunction::kDefaultQuality = 90; | 
|  | 
| namespace { | 
|  | 
| @@ -249,7 +258,7 @@ Browser* CreateBrowserWindow(const Browser::CreateParams& params, | 
|  | 
| // Windows --------------------------------------------------------------------- | 
|  | 
| -bool GetWindowFunction::RunImpl() { | 
| +bool WindowsGetFunction::RunImpl() { | 
| scoped_ptr<Get::Params> params(Get::Params::Create(*args_)); | 
| EXTENSION_FUNCTION_VALIDATE(params.get()); | 
|  | 
| @@ -268,7 +277,7 @@ bool GetWindowFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool GetCurrentWindowFunction::RunImpl() { | 
| +bool WindowsGetCurrentFunction::RunImpl() { | 
| scoped_ptr<GetCurrent::Params> params(GetCurrent::Params::Create(*args_)); | 
| EXTENSION_FUNCTION_VALIDATE(params.get()); | 
|  | 
| @@ -289,7 +298,7 @@ bool GetCurrentWindowFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool GetLastFocusedWindowFunction::RunImpl() { | 
| +bool WindowsGetLastFocusedFunction::RunImpl() { | 
| scoped_ptr<GetLastFocused::Params> params( | 
| GetLastFocused::Params::Create(*args_)); | 
| EXTENSION_FUNCTION_VALIDATE(params.get()); | 
| @@ -316,7 +325,7 @@ bool GetLastFocusedWindowFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool GetAllWindowsFunction::RunImpl() { | 
| +bool WindowsGetAllFunction::RunImpl() { | 
| scoped_ptr<GetAll::Params> params(GetAll::Params::Create(*args_)); | 
| EXTENSION_FUNCTION_VALIDATE(params.get()); | 
|  | 
| @@ -341,7 +350,7 @@ bool GetAllWindowsFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool CreateWindowFunction::ShouldOpenIncognitoWindow( | 
| +bool WindowsCreateFunction::ShouldOpenIncognitoWindow( | 
| const base::DictionaryValue* args, | 
| std::vector<GURL>* urls, | 
| bool* is_error) { | 
| @@ -391,7 +400,7 @@ bool CreateWindowFunction::ShouldOpenIncognitoWindow( | 
| return incognito; | 
| } | 
|  | 
| -bool CreateWindowFunction::RunImpl() { | 
| +bool WindowsCreateFunction::RunImpl() { | 
| DictionaryValue* args = NULL; | 
| std::vector<GURL> urls; | 
| WebContents* contents = NULL; | 
| @@ -660,7 +669,7 @@ bool CreateWindowFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool UpdateWindowFunction::RunImpl() { | 
| +bool WindowsUpdateFunction::RunImpl() { | 
| int window_id = extension_misc::kUnknownWindowId; | 
| EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &window_id)); | 
| DictionaryValue* update_props; | 
| @@ -804,7 +813,7 @@ bool UpdateWindowFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool RemoveWindowFunction::RunImpl() { | 
| +bool WindowsRemoveFunction::RunImpl() { | 
| int window_id = -1; | 
| EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &window_id)); | 
|  | 
| @@ -831,7 +840,7 @@ bool RemoveWindowFunction::RunImpl() { | 
|  | 
| // Tabs ------------------------------------------------------------------------ | 
|  | 
| -bool GetSelectedTabFunction::RunImpl() { | 
| +bool TabsGetSelectedFunction::RunImpl() { | 
| // windowId defaults to "current" window. | 
| int window_id = extension_misc::kCurrentWindowId; | 
|  | 
| @@ -855,7 +864,7 @@ bool GetSelectedTabFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool GetAllTabsInWindowFunction::RunImpl() { | 
| +bool TabsGetAllInWindowFunction::RunImpl() { | 
| // windowId defaults to "current" window. | 
| int window_id = extension_misc::kCurrentWindowId; | 
| if (HasOptionalArgument(0)) | 
| @@ -870,7 +879,7 @@ bool GetAllTabsInWindowFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool QueryTabsFunction::RunImpl() { | 
| +bool TabsQueryFunction::RunImpl() { | 
| DictionaryValue* query = NULL; | 
| EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &query)); | 
|  | 
| @@ -983,7 +992,7 @@ bool QueryTabsFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool CreateTabFunction::RunImpl() { | 
| +bool TabsCreateFunction::RunImpl() { | 
| DictionaryValue* args = NULL; | 
| EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args)); | 
|  | 
| @@ -1117,7 +1126,7 @@ bool CreateTabFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool DuplicateTabFunction::RunImpl() { | 
| +bool TabsDuplicateFunction::RunImpl() { | 
| int tab_id = -1; | 
| EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id)); | 
|  | 
| @@ -1143,7 +1152,7 @@ bool DuplicateTabFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool GetTabFunction::RunImpl() { | 
| +bool TabsGetFunction::RunImpl() { | 
| int tab_id = -1; | 
| EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id)); | 
|  | 
| @@ -1161,7 +1170,7 @@ bool GetTabFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool GetCurrentTabFunction::RunImpl() { | 
| +bool TabsGetCurrentFunction::RunImpl() { | 
| DCHECK(dispatcher()); | 
|  | 
| WebContents* contents = dispatcher()->delegate()->GetAssociatedWebContents(); | 
| @@ -1171,7 +1180,7 @@ bool GetCurrentTabFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool HighlightTabsFunction::RunImpl() { | 
| +bool TabsHighlightFunction::RunImpl() { | 
| DictionaryValue* info = NULL; | 
| EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &info)); | 
|  | 
| @@ -1228,10 +1237,10 @@ bool HighlightTabsFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -UpdateTabFunction::UpdateTabFunction() : web_contents_(NULL) { | 
| +TabsUpdateFunction::TabsUpdateFunction() : web_contents_(NULL) { | 
| } | 
|  | 
| -bool UpdateTabFunction::RunImpl() { | 
| +bool TabsUpdateFunction::RunImpl() { | 
| DictionaryValue* update_props = NULL; | 
| EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &update_props)); | 
|  | 
| @@ -1335,7 +1344,7 @@ bool UpdateTabFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool UpdateTabFunction::UpdateURLIfPresent(DictionaryValue* update_props, | 
| +bool TabsUpdateFunction::UpdateURLIfPresent(DictionaryValue* update_props, | 
| int tab_id, | 
| bool* is_async) { | 
| if (!update_props->HasKey(keys::kUrlKey)) | 
| @@ -1379,7 +1388,7 @@ bool UpdateTabFunction::UpdateURLIfPresent(DictionaryValue* update_props, | 
| ScriptExecutor::TOP_FRAME, | 
| extensions::UserScript::DOCUMENT_IDLE, | 
| ScriptExecutor::MAIN_WORLD, | 
| -            base::Bind(&UpdateTabFunction::OnExecuteCodeFinished, this)); | 
| +            base::Bind(&TabsUpdateFunction::OnExecuteCodeFinished, this)); | 
|  | 
| *is_async = true; | 
| return true; | 
| @@ -1396,14 +1405,14 @@ bool UpdateTabFunction::UpdateURLIfPresent(DictionaryValue* update_props, | 
| return true; | 
| } | 
|  | 
| -void UpdateTabFunction::PopulateResult() { | 
| +void TabsUpdateFunction::PopulateResult() { | 
| if (!has_callback()) | 
| return; | 
|  | 
| SetResult(ExtensionTabUtil::CreateTabValue(web_contents_, GetExtension())); | 
| } | 
|  | 
| -void UpdateTabFunction::OnExecuteCodeFinished(const std::string& error, | 
| +void TabsUpdateFunction::OnExecuteCodeFinished(const std::string& error, | 
| int32 on_page_id, | 
| const GURL& url, | 
| const ListValue& script_result) { | 
| @@ -1414,7 +1423,7 @@ void UpdateTabFunction::OnExecuteCodeFinished(const std::string& error, | 
| SendResponse(error.empty()); | 
| } | 
|  | 
| -bool MoveTabsFunction::RunImpl() { | 
| +bool TabsMoveFunction::RunImpl() { | 
| Value* tab_value = NULL; | 
| EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value)); | 
|  | 
| @@ -1535,7 +1544,7 @@ bool MoveTabsFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool ReloadTabFunction::RunImpl() { | 
| +bool TabsReloadFunction::RunImpl() { | 
| bool bypass_cache = false; | 
| if (HasOptionalArgument(1)) { | 
| DictionaryValue* reload_props = NULL; | 
| @@ -1590,7 +1599,7 @@ bool ReloadTabFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool RemoveTabsFunction::RunImpl() { | 
| +bool TabsRemoveFunction::RunImpl() { | 
| Value* tab_value = NULL; | 
| EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value)); | 
|  | 
| @@ -1620,7 +1629,8 @@ bool RemoveTabsFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -bool CaptureVisibleTabFunction::GetTabToCapture(WebContents** web_contents) { | 
| +bool TabsCaptureVisibleTabFunction::GetTabToCapture( | 
| +    WebContents** web_contents) { | 
| Browser* browser = NULL; | 
| // windowId defaults to "current" window. | 
| int window_id = extension_misc::kCurrentWindowId; | 
| @@ -1640,7 +1650,7 @@ bool CaptureVisibleTabFunction::GetTabToCapture(WebContents** web_contents) { | 
| return true; | 
| }; | 
|  | 
| -bool CaptureVisibleTabFunction::RunImpl() { | 
| +bool TabsCaptureVisibleTabFunction::RunImpl() { | 
| PrefServiceBase* service = profile()->GetPrefs(); | 
| if (service->GetBoolean(prefs::kDisableScreenshots)) { | 
| error_ = keys::kScreenshotsDisabled; | 
| @@ -1699,14 +1709,14 @@ bool CaptureVisibleTabFunction::RunImpl() { | 
| render_view_host->CopyFromBackingStore( | 
| gfx::Rect(), | 
| view->GetViewBounds().size(), | 
| -      base::Bind(&CaptureVisibleTabFunction::CopyFromBackingStoreComplete, | 
| +      base::Bind(&TabsCaptureVisibleTabFunction::CopyFromBackingStoreComplete, | 
| this, | 
| base::Owned(temp_bitmap)), | 
| temp_bitmap); | 
| return true; | 
| } | 
|  | 
| -void CaptureVisibleTabFunction::CopyFromBackingStoreComplete( | 
| +void TabsCaptureVisibleTabFunction::CopyFromBackingStoreComplete( | 
| skia::PlatformBitmap* bitmap, | 
| bool succeeded) { | 
| if (succeeded) { | 
| @@ -1726,14 +1736,14 @@ void CaptureVisibleTabFunction::CopyFromBackingStoreComplete( | 
| registrar_.Add(this, | 
| chrome::NOTIFICATION_TAB_SNAPSHOT_TAKEN, | 
| content::Source<WebContents>(web_contents)); | 
| -  AddRef();  // Balanced in CaptureVisibleTabFunction::Observe(). | 
| +  AddRef();  // Balanced in TabsCaptureVisibleTabFunction::Observe(). | 
| SnapshotTabHelper::FromWebContents(web_contents)->CaptureSnapshot(); | 
| } | 
|  | 
| -// If a backing store was not available in CaptureVisibleTabFunction::RunImpl, | 
| -// than the renderer was asked for a snapshot.  Listen for a notification | 
| -// that the snapshot is available. | 
| -void CaptureVisibleTabFunction::Observe( | 
| +// If a backing store was not available in | 
| +// TabsCaptureVisibleTabFunction::RunImpl, than the renderer was asked for a | 
| +// snapshot.  Listen for a notification that the snapshot is available. | 
| +void TabsCaptureVisibleTabFunction::Observe( | 
| int type, | 
| const content::NotificationSource& source, | 
| const content::NotificationDetails& details) { | 
| @@ -1751,12 +1761,12 @@ void CaptureVisibleTabFunction::Observe( | 
| SendResultFromBitmap(*screen_capture); | 
| } | 
|  | 
| -  Release();  // Balanced in CaptureVisibleTabFunction::RunImpl(). | 
| +  Release();  // Balanced in TabsCaptureVisibleTabFunction::RunImpl(). | 
| } | 
|  | 
| // Turn a bitmap of the screen into an image, set that image as the result, | 
| // and call SendResponse(). | 
| -void CaptureVisibleTabFunction::SendResultFromBitmap( | 
| +void TabsCaptureVisibleTabFunction::SendResultFromBitmap( | 
| const SkBitmap& screen_capture) { | 
| std::vector<unsigned char> data; | 
| SkAutoLockPixels screen_capture_lock(screen_capture); | 
| @@ -1802,13 +1812,13 @@ void CaptureVisibleTabFunction::SendResultFromBitmap( | 
| SendResponse(true); | 
| } | 
|  | 
| -void CaptureVisibleTabFunction::RegisterUserPrefs( | 
| +void TabsCaptureVisibleTabFunction::RegisterUserPrefs( | 
| PrefServiceSyncable* service) { | 
| service->RegisterBooleanPref(prefs::kDisableScreenshots, false, | 
| PrefServiceSyncable::UNSYNCABLE_PREF); | 
| } | 
|  | 
| -bool DetectTabLanguageFunction::RunImpl() { | 
| +bool TabsDetectLanguageFunction::RunImpl() { | 
| int tab_id = 0; | 
| Browser* browser = NULL; | 
| WebContents* contents = NULL; | 
| @@ -1846,7 +1856,7 @@ bool DetectTabLanguageFunction::RunImpl() { | 
| // Delay the callback invocation until after the current JS call has | 
| // returned. | 
| MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 
| -        &DetectTabLanguageFunction::GotLanguage, this, | 
| +        &TabsDetectLanguageFunction::GotLanguage, this, | 
| translate_tab_helper->language_state().original_language())); | 
| return true; | 
| } | 
| @@ -1863,7 +1873,7 @@ bool DetectTabLanguageFunction::RunImpl() { | 
| return true; | 
| } | 
|  | 
| -void DetectTabLanguageFunction::Observe( | 
| +void TabsDetectLanguageFunction::Observe( | 
| int type, | 
| const content::NotificationSource& source, | 
| const content::NotificationDetails& details) { | 
| @@ -1878,9 +1888,249 @@ void DetectTabLanguageFunction::Observe( | 
| GotLanguage(language); | 
| } | 
|  | 
| -void DetectTabLanguageFunction::GotLanguage(const std::string& language) { | 
| +void TabsDetectLanguageFunction::GotLanguage(const std::string& language) { | 
| SetResult(Value::CreateStringValue(language.c_str())); | 
| SendResponse(true); | 
|  | 
| Release();  // Balanced in Run() | 
| } | 
| + | 
| +ExecuteCodeInTabFunction::ExecuteCodeInTabFunction() | 
| +    : execute_tab_id_(-1) { | 
| +} | 
| + | 
| +ExecuteCodeInTabFunction::~ExecuteCodeInTabFunction() {} | 
| + | 
| +bool ExecuteCodeInTabFunction::HasPermission() { | 
| +  if (Init() && | 
| +      extension_->HasAPIPermissionForTab(execute_tab_id_, | 
| +                                         extensions::APIPermission::kTab)) { | 
| +    return true; | 
| +  } | 
| +  return ExtensionFunction::HasPermission(); | 
| +} | 
| + | 
| +bool ExecuteCodeInTabFunction::RunImpl() { | 
| +  EXTENSION_FUNCTION_VALIDATE(Init()); | 
| + | 
| +  if (!details_->code.get() && !details_->file.get()) { | 
| +    error_ = keys::kNoCodeOrFileToExecuteError; | 
| +    return false; | 
| +  } | 
| +  if (details_->code.get() && details_->file.get()) { | 
| +    error_ = keys::kMoreThanOneValuesError; | 
| +    return false; | 
| +  } | 
| + | 
| +  content::WebContents* contents = NULL; | 
| + | 
| +  // If |tab_id| is specified, look for the tab. Otherwise default to selected | 
| +  // tab in the current window. | 
| +  CHECK_GE(execute_tab_id_, 0); | 
| +  if (!ExtensionTabUtil::GetTabById(execute_tab_id_, profile(), | 
| +                                    include_incognito(), | 
| +                                    NULL, NULL, &contents, NULL)) { | 
| +    return false; | 
| +  } | 
| + | 
| +  // NOTE: This can give the wrong answer due to race conditions, but it is OK, | 
| +  // we check again in the renderer. | 
| +  CHECK(contents); | 
| +  if (!GetExtension()->CanExecuteScriptOnPage(contents->GetURL(), | 
| +                                              contents->GetURL(), | 
| +                                              execute_tab_id_, | 
| +                                              NULL, | 
| +                                              &error_)) { | 
| +    return false; | 
| +  } | 
| + | 
| +  if (details_->code.get()) | 
| +    return Execute(*details_->code); | 
| + | 
| +  CHECK(details_->file.get()); | 
| +  resource_ = GetExtension()->GetResource(*details_->file); | 
| + | 
| +  if (resource_.extension_root().empty() || resource_.relative_path().empty()) { | 
| +    error_ = keys::kNoCodeOrFileToExecuteError; | 
| +    return false; | 
| +  } | 
| + | 
| +  scoped_refptr<FileReader> file_reader(new FileReader( | 
| +      resource_, base::Bind(&ExecuteCodeInTabFunction::DidLoadFile, this))); | 
| +  file_reader->Start(); | 
| + | 
| +  return true; | 
| +} | 
| + | 
| +void ExecuteCodeInTabFunction::OnExecuteCodeFinished(const std::string& error, | 
| +                                                     int32 on_page_id, | 
| +                                                     const GURL& on_url, | 
| +                                                     const ListValue& result) { | 
| +  if (!error.empty()) | 
| +    SetError(error); | 
| + | 
| +  SendResponse(error.empty()); | 
| +} | 
| + | 
| +void TabsExecuteScriptFunction::OnExecuteCodeFinished(const std::string& error, | 
| +                                                      int32 on_page_id, | 
| +                                                      const GURL& on_url, | 
| +                                                      const ListValue& result) { | 
| +  if (error.empty()) | 
| +    SetResult(result.DeepCopy()); | 
| +  ExecuteCodeInTabFunction::OnExecuteCodeFinished(error, on_page_id, on_url, | 
| +                                                  result); | 
| +} | 
| + | 
| +bool ExecuteCodeInTabFunction::Init() { | 
| +  if (details_.get()) | 
| +    return true; | 
| + | 
| +  // |tab_id| is optional so it's ok if it's not there. | 
| +  int tab_id = -1; | 
| +  args_->GetInteger(0, &tab_id); | 
| + | 
| +  // |details| are not optional. | 
| +  DictionaryValue* details_value = NULL; | 
| +  if (!args_->GetDictionary(1, &details_value)) | 
| +    return false; | 
| +  scoped_ptr<InjectDetails> details(new InjectDetails()); | 
| +  if (!InjectDetails::Populate(*details_value, details.get())) | 
| +    return false; | 
| + | 
| +  // If the tab ID is -1 then it needs to be converted to the currently active | 
| +  // tab's ID. | 
| +  if (tab_id == -1) { | 
| +    Browser* browser = GetCurrentBrowser(); | 
| +    if (!browser) | 
| +      return false; | 
| +    content::WebContents* web_contents = NULL; | 
| +    if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, &tab_id)) | 
| +      return false; | 
| +  } | 
| + | 
| +  execute_tab_id_ = tab_id; | 
| +  details_ = details.Pass(); | 
| +  return true; | 
| +} | 
| + | 
| +void ExecuteCodeInTabFunction::DidLoadFile(bool success, | 
| +                                           const std::string& data) { | 
| +  std::string function_name = name(); | 
| +  const extensions::Extension* extension = GetExtension(); | 
| + | 
| +  // Check if the file is CSS and needs localization. | 
| +  if (success && | 
| +      function_name == TabsInsertCSSFunction::function_name() && | 
| +      extension != NULL && | 
| +      data.find( | 
| +          extensions::MessageBundle::kMessageBegin) != std::string::npos) { | 
| +    BrowserThread::PostTask( | 
| +        BrowserThread::FILE, FROM_HERE, | 
| +        base::Bind(&ExecuteCodeInTabFunction::LocalizeCSS, this, | 
| +                   data, | 
| +                   extension->id(), | 
| +                   extension->path(), | 
| +                   extension->default_locale())); | 
| +  } else { | 
| +    DidLoadAndLocalizeFile(success, data); | 
| +  } | 
| +} | 
| + | 
| +void ExecuteCodeInTabFunction::LocalizeCSS( | 
| +    const std::string& data, | 
| +    const std::string& extension_id, | 
| +    const FilePath& extension_path, | 
| +    const std::string& extension_default_locale) { | 
| +  scoped_ptr<SubstitutionMap> localization_messages( | 
| +      extension_file_util::LoadMessageBundleSubstitutionMap( | 
| +          extension_path, extension_id, extension_default_locale)); | 
| + | 
| +  // We need to do message replacement on the data, so it has to be mutable. | 
| +  std::string css_data = data; | 
| +  std::string error; | 
| +  extensions::MessageBundle::ReplaceMessagesWithExternalDictionary( | 
| +      *localization_messages, &css_data, &error); | 
| + | 
| +  // Call back DidLoadAndLocalizeFile on the UI thread. The success parameter | 
| +  // is always true, because if loading had failed, we wouldn't have had | 
| +  // anything to localize. | 
| +  BrowserThread::PostTask( | 
| +      BrowserThread::UI, FROM_HERE, | 
| +      base::Bind(&ExecuteCodeInTabFunction::DidLoadAndLocalizeFile, this, | 
| +                 true, css_data)); | 
| +} | 
| + | 
| +void ExecuteCodeInTabFunction::DidLoadAndLocalizeFile(bool success, | 
| +                                                      const std::string& data) { | 
| +  if (success) { | 
| +    if (!Execute(data)) | 
| +      SendResponse(false); | 
| +  } else { | 
| +#if defined(OS_POSIX) | 
| +    // TODO(viettrungluu): bug: there's no particular reason the path should be | 
| +    // UTF-8, in which case this may fail. | 
| +    error_ = ErrorUtils::FormatErrorMessage(keys::kLoadFileError, | 
| +        resource_.relative_path().value()); | 
| +#elif defined(OS_WIN) | 
| +    error_ = ErrorUtils::FormatErrorMessage(keys::kLoadFileError, | 
| +        WideToUTF8(resource_.relative_path().value())); | 
| +#endif  // OS_WIN | 
| +    SendResponse(false); | 
| +  } | 
| +} | 
| + | 
| +bool ExecuteCodeInTabFunction::Execute(const std::string& code_string) { | 
| +  content::WebContents* contents = NULL; | 
| +  Browser* browser = NULL; | 
| + | 
| +  bool success = ExtensionTabUtil::GetTabById( | 
| +      execute_tab_id_, profile(), include_incognito(), &browser, NULL, | 
| +      &contents, NULL) && contents && browser; | 
| + | 
| +  if (!success) | 
| +    return false; | 
| + | 
| +  const extensions::Extension* extension = GetExtension(); | 
| +  if (!extension) | 
| +    return false; | 
| + | 
| +  ScriptExecutor::ScriptType script_type = ScriptExecutor::JAVASCRIPT; | 
| +  std::string function_name = name(); | 
| +  if (function_name == TabsInsertCSSFunction::function_name()) { | 
| +    script_type = ScriptExecutor::CSS; | 
| +  } else if (function_name != TabsExecuteScriptFunction::function_name()) { | 
| +    NOTREACHED(); | 
| +  } | 
| + | 
| +  ScriptExecutor::FrameScope frame_scope = | 
| +      details_->all_frames.get() && *details_->all_frames ? | 
| +          ScriptExecutor::ALL_FRAMES : | 
| +          ScriptExecutor::TOP_FRAME; | 
| + | 
| +  UserScript::RunLocation run_at = UserScript::UNDEFINED; | 
| +  switch (details_->run_at) { | 
| +    case InjectDetails::RUN_AT_NONE: | 
| +    case InjectDetails::RUN_AT_DOCUMENT_IDLE: | 
| +      run_at = UserScript::DOCUMENT_IDLE; | 
| +      break; | 
| +    case InjectDetails::RUN_AT_DOCUMENT_START: | 
| +      run_at = UserScript::DOCUMENT_START; | 
| +      break; | 
| +    case InjectDetails::RUN_AT_DOCUMENT_END: | 
| +      run_at = UserScript::DOCUMENT_END; | 
| +      break; | 
| +  } | 
| +  CHECK_NE(UserScript::UNDEFINED, run_at); | 
| + | 
| +  extensions::TabHelper::FromWebContents(contents)-> | 
| +      script_executor()->ExecuteScript( | 
| +          extension->id(), | 
| +          script_type, | 
| +          code_string, | 
| +          frame_scope, | 
| +          run_at, | 
| +          ScriptExecutor::ISOLATED_WORLD, | 
| +          base::Bind(&ExecuteCodeInTabFunction::OnExecuteCodeFinished, this)); | 
| +  return true; | 
| +} | 
|  |