diff options
author | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-07 04:43:45 +0000 |
---|---|---|
committer | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-07 04:43:45 +0000 |
commit | 5cbb809a7203d91c05021aae74e16fdcefff9352 (patch) | |
tree | 0627479ed7960568638b118d8e01c0aac41d5a25 /chrome | |
parent | b00e86cf9afb44beb3f8fd51e85318505cabaa89 (diff) | |
download | chromium_src-5cbb809a7203d91c05021aae74e16fdcefff9352.zip chromium_src-5cbb809a7203d91c05021aae74e16fdcefff9352.tar.gz chromium_src-5cbb809a7203d91c05021aae74e16fdcefff9352.tar.bz2 |
This reverts: HTML Pack Extension Dialog / Linux & Mac Packaging Support.
original issue: http://codereview.chromium.org/207062/
TBR=sky
Review URL: http://codereview.chromium.org/270001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28234 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser_init.cc | 27 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service_unittest.cc | 2 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_ui.cc | 138 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_ui.h | 23 | ||||
-rw-r--r-- | chrome/browser/extensions/pack_extension_job.h | 8 | ||||
-rw-r--r-- | chrome/browser/net/chrome_url_request_context.cc | 3 | ||||
-rw-r--r-- | chrome/browser/resources/extensions_ui.html | 188 | ||||
-rw-r--r-- | chrome/browser/views/extensions/extension_pack_dialog.cc | 233 | ||||
-rwxr-xr-x | chrome/chrome.gyp | 8 |
9 files changed, 275 insertions, 355 deletions
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc index ce0c7f4..b551bcf 100644 --- a/chrome/browser/browser_init.cc +++ b/chrome/browser/browser_init.cc @@ -28,7 +28,9 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/defaults.h" +#if defined(OS_WIN) // TODO(port) #include "chrome/browser/extensions/extension_creator.h" +#endif #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/first_run.h" @@ -365,20 +367,6 @@ GURL GetWelcomePageURL() { return GURL(welcome_url); } -void ShowPackExtensionMessage(const std::wstring caption, - const std::wstring message) { -#if defined(OS_WIN) - win_util::MessageBox(NULL, message, caption, MB_OK | MB_SETFOREGROUND); -#else - // Just send caption & text to stdout on mac & linux. - std::string out_text = WideToASCII(caption); - out_text.append("\n\n"); - out_text.append(WideToASCII(message)); - out_text.append("\n"); - printf(out_text.c_str()); -#endif -} - } // namespace // static @@ -763,6 +751,7 @@ bool BrowserInit::ProcessCmdLineImpl(const CommandLine& command_line, // ExtensionCreator depends on base/crypto/rsa_private_key and // base/crypto/signature_creator, both of which only have windows // implementations. +#if defined(OS_WIN) scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); if (creator->Run(src_dir, crx_path, private_key_path, output_private_key_path)) { @@ -780,12 +769,16 @@ bool BrowserInit::ProcessCmdLineImpl(const CommandLine& command_line, message = StringPrintf(L"Created the extension:\n\n%ls", crx_path.ToWStringHack().c_str()); } - ShowPackExtensionMessage(L"Extension Packaging Success", message); + win_util::MessageBox(NULL, message, L"Extension Packaging Success", + MB_OK | MB_SETFOREGROUND); } else { - ShowPackExtensionMessage(L"Extension Packaging Error", - UTF8ToWide(creator->error_message())); + win_util::MessageBox(NULL, UTF8ToWide(creator->error_message()), + L"Extension Packaging Error", MB_OK | MB_SETFOREGROUND); return false; } +#else + NOTIMPLEMENTED() << " extension creation not implemented on POSIX."; +#endif // defined(OS_WIN) return false; } } diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc index 57ae6f6..fa257e0 100644 --- a/chrome/browser/extensions/extensions_service_unittest.cc +++ b/chrome/browser/extensions/extensions_service_unittest.cc @@ -727,6 +727,7 @@ TEST_F(ExtensionsServiceTest, InstallExtension) { // TODO(erikkay): add tests for upgrade cases. } +#if defined(OS_WIN) // TODO(port) // Test Packaging and installing an extension. // TODO(rafaelw): add more tests for failure cases. TEST_F(ExtensionsServiceTest, PackExtension) { @@ -790,6 +791,7 @@ TEST_F(ExtensionsServiceTest, PackExtensionOpenSSLKey) { file_util::Delete(crx_path, false); } +#endif // defined(OS_WIN) TEST_F(ExtensionsServiceTest, InstallTheme) { InitializeEmptyExtensionsService(); diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc index 96de8e3..db10a9a 100644 --- a/chrome/browser/extensions/extensions_ui.cc +++ b/chrome/browser/extensions/extensions_ui.cc @@ -9,7 +9,6 @@ #include "base/string_util.h" #include "base/thread.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/chrome_thread.h" #include "chrome/browser/debugger/devtools_manager.h" #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extensions_service.h" @@ -48,14 +47,6 @@ void ExtensionsUIHTMLSource::StartDataRequest(const std::string& path, DictionaryValue localized_strings; localized_strings.SetString(L"title", l10n_util::GetString(IDS_EXTENSIONS_TITLE)); - localized_strings.SetString(L"packDialogHeading", - l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_HEADING)); - localized_strings.SetString(L"rootDirectoryLabel", - l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL)); - localized_strings.SetString(L"packDialogBrowse", - l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_BROWSE)); - localized_strings.SetString(L"privateKeyLabel", - l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL)); static const base::StringPiece extensions_html( ResourceBundle::GetSharedInstance().GetRawDataResource( @@ -100,8 +91,6 @@ void ExtensionsDOMHandler::RegisterMessages() { NewCallback(this, &ExtensionsDOMHandler::HandlePackMessage)); dom_ui_->RegisterMessageCallback("autoupdate", NewCallback(this, &ExtensionsDOMHandler::HandleAutoUpdateMessage)); - dom_ui_->RegisterMessageCallback("selectFilePath", - NewCallback(this, &ExtensionsDOMHandler::HandleSelectFilePathMessage)); } void ExtensionsDOMHandler::HandleRequestExtensionsData(const Value* value) { @@ -198,77 +187,18 @@ void ExtensionsDOMHandler::HandleUninstallMessage(const Value* value) { } void ExtensionsDOMHandler::HandleLoadMessage(const Value* value) { - std::string string_path; - CHECK(value->IsType(Value::TYPE_LIST)); - const ListValue* list = static_cast<const ListValue*>(value); - CHECK(list->GetSize() == 1) << list->GetSize(); - CHECK(list->GetString(0, &string_path)); - FilePath file_path = FilePath::FromWStringHack(ASCIIToWide(string_path)); - extensions_service_->LoadExtension(file_path); -} - -void ExtensionsDOMHandler::ShowAlert(const std::string& message) { - ListValue arguments; - arguments.Append(Value::CreateStringValue(message)); - dom_ui_->CallJavascriptFunction(L"alert", arguments); + load_extension_dialog_ = SelectFileDialog::Create(this); + load_extension_dialog_->SelectFile( + SelectFileDialog::SELECT_FOLDER, + l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY), + FilePath(), NULL, 0, FILE_PATH_LITERAL(""), + dom_ui_->tab_contents()->view()->GetTopLevelNativeWindow(), NULL); } void ExtensionsDOMHandler::HandlePackMessage(const Value* value) { - std::string extension_path; - std::string private_key_path; - CHECK(value->IsType(Value::TYPE_LIST)); - const ListValue* list = static_cast<const ListValue*>(value); - CHECK(list->GetSize() == 2); - CHECK(list->GetString(0, &extension_path)); - CHECK(list->GetString(1, &private_key_path)); - - FilePath root_directory = FilePath::FromWStringHack(ASCIIToWide( - extension_path)); - FilePath key_file = FilePath::FromWStringHack(ASCIIToWide(private_key_path)); - - if (root_directory.empty()) { - if (extension_path.empty()) { - ShowAlert(l10n_util::GetStringUTF8( - IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED)); - } else { - ShowAlert(l10n_util::GetStringUTF8( - IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID)); - } - - return; - } - - if (!private_key_path.empty() && key_file.empty()) { - ShowAlert(l10n_util::GetStringUTF8( - IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID)); - return; - } - - pack_job_ = new PackExtensionJob(this, root_directory, key_file, - ChromeThread::GetMessageLoop(ChromeThread::FILE)); -} - -void ExtensionsDOMHandler::OnPackSuccess(const FilePath& crx_file, - const FilePath& pem_file) { - std::string message; - if (!pem_file.empty()) { - message = WideToASCII(l10n_util::GetStringF( - IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_NEW, - crx_file.ToWStringHack(), - pem_file.ToWStringHack())); - } else { - message = WideToASCII(l10n_util::GetStringF( - IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_UPDATE, - crx_file.ToWStringHack())); - } - ShowAlert(message); - - ListValue results; - dom_ui_->CallJavascriptFunction(L"hidePackDialog", results); -} - -void ExtensionsDOMHandler::OnPackFailure(const std::wstring& error) { - ShowAlert(WideToASCII(error)); +#if defined(OS_WIN) + ShowPackDialog(); +#endif } void ExtensionsDOMHandler::HandleAutoUpdateMessage(const Value* value) { @@ -278,55 +208,9 @@ void ExtensionsDOMHandler::HandleAutoUpdateMessage(const Value* value) { } } -void ExtensionsDOMHandler::HandleSelectFilePathMessage(const Value* value) { - std::string select_type; - std::string operation; - CHECK(value->IsType(Value::TYPE_LIST)); - const ListValue* list = static_cast<const ListValue*>(value); - CHECK(list->GetSize() == 2); - CHECK(list->GetString(0, &select_type)); - CHECK(list->GetString(1, &operation)); - - SelectFileDialog::Type type = SelectFileDialog::SELECT_FOLDER; - static SelectFileDialog::FileTypeInfo info; - int file_type_index = 0; - if (select_type == "file") - type = SelectFileDialog::SELECT_OPEN_FILE; - - string16 select_title; - if (operation == "load") - select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY); - else if (operation == "packRoot") - select_title = l10n_util::GetStringUTF16( - IDS_EXTENSION_PACK_DIALOG_SELECT_ROOT); - else if (operation == "pem") { - select_title = l10n_util::GetStringUTF16( - IDS_EXTENSION_PACK_DIALOG_SELECT_KEY); - info.extensions.push_back(std::vector<FilePath::StringType>()); - info.extensions.front().push_back(FILE_PATH_LITERAL("pem")); - info.extension_description_overrides.push_back(WideToUTF16( - l10n_util::GetString( - IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION))); - info.include_all_files = true; - file_type_index = 1; - } else { - NOTREACHED(); - return; - } - - load_extension_dialog_ = SelectFileDialog::Create(this); - load_extension_dialog_->SelectFile(type, select_title, FilePath(), &info, - file_type_index, FILE_PATH_LITERAL(""), - dom_ui_->tab_contents()->view()->GetTopLevelNativeWindow(), NULL); -} - - void ExtensionsDOMHandler::FileSelected(const FilePath& path, int index, void* params) { - // Add the extensions to the results structure. - ListValue results; - results.Append(Value::CreateStringValue(path.value())); - dom_ui_->CallJavascriptFunction(L"window.handleFilePathSelected", results); + extensions_service_->LoadExtension(path); } void ExtensionsDOMHandler::Observe(NotificationType type, @@ -459,8 +343,6 @@ std::vector<ExtensionPage> ExtensionsDOMHandler::GetActivePagesForExtension( } ExtensionsDOMHandler::~ExtensionsDOMHandler() { - if (pack_job_.get()) - pack_job_->ClearClient(); } // ExtensionsDOMHandler, public: ----------------------------------------------- diff --git a/chrome/browser/extensions/extensions_ui.h b/chrome/browser/extensions/extensions_ui.h index 908c9f3..80ddf4d 100644 --- a/chrome/browser/extensions/extensions_ui.h +++ b/chrome/browser/extensions/extensions_ui.h @@ -10,7 +10,6 @@ #include "chrome/browser/dom_ui/chrome_url_data_manager.h" #include "chrome/browser/dom_ui/dom_ui.h" -#include "chrome/browser/extensions/pack_extension_job.h" #include "chrome/browser/shell_dialogs.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" @@ -53,7 +52,6 @@ class ExtensionsUIHTMLSource : public ChromeURLDataManager::DataSource { class ExtensionsDOMHandler : public DOMMessageHandler, public NotificationObserver, - public PackExtensionJob::Client, public SelectFileDialog::Listener { public: explicit ExtensionsDOMHandler(ExtensionsService* extension_service); @@ -73,13 +71,13 @@ class ExtensionsDOMHandler const UserScript& script, const FilePath& extension_path); - // ExtensionPackJob::Client - virtual void OnPackSuccess(const FilePath& crx_file, - const FilePath& key_file); - - virtual void OnPackFailure(const std::wstring& message); - private: +#if defined(OS_WIN) + // The implementation of this method is platform-specific and defined + // elsewhere. + static void ShowPackDialog(); +#endif + // Callback for "requestExtensionsData" message. void HandleRequestExtensionsData(const Value* value); @@ -104,12 +102,6 @@ class ExtensionsDOMHandler // Callback for "autoupdate" message. void HandleAutoUpdateMessage(const Value* value); - // Utility for calling javascript window.alert in the page. - void ShowAlert(const std::string& message); - - // Callback for "selectFilePath" message. - void HandleSelectFilePathMessage(const Value* value); - // SelectFileDialog::Listener virtual void FileSelected(const FilePath& path, int index, void* params); @@ -134,9 +126,6 @@ class ExtensionsDOMHandler // Used to pick the directory when loading an extension. scoped_refptr<SelectFileDialog> load_extension_dialog_; - // Used to package the extension. - scoped_refptr<PackExtensionJob> pack_job_; - // We monitor changes to the extension system so that we can reload when // necessary. NotificationRegistrar registrar_; diff --git a/chrome/browser/extensions/pack_extension_job.h b/chrome/browser/extensions/pack_extension_job.h index 8c3cf26..ec00f21 100644 --- a/chrome/browser/extensions/pack_extension_job.h +++ b/chrome/browser/extensions/pack_extension_job.h @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_EXTENSIONS_PACK_EXTENSION_JOB_UI_H_ -#define CHROME_BROWSER_EXTENSIONS_PACK_EXTENSION_JOB_UI_H_ - #include <string> #include "base/file_path.h" @@ -14,7 +11,7 @@ class MessageLoop; // Manages packing an extension on the file thread and reporting the result // back to the UI. -class PackExtensionJob : public base::RefCountedThreadSafe<PackExtensionJob> { +class PackExtensionJob : public base::RefCounted<PackExtensionJob> { public: // Interface for people who want to use PackExtensionJob to implement. @@ -49,6 +46,3 @@ class PackExtensionJob : public base::RefCountedThreadSafe<PackExtensionJob> { DISALLOW_COPY_AND_ASSIGN(PackExtensionJob); }; - -#endif // CHROME_BROWSER_EXTENSIONS_PACK_EXTENSION_JOB_UI_H_ - diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index 2918b1f..2c68419 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -520,8 +520,9 @@ void ChromeURLRequestContext::OnDefaultCharsetChange( void ChromeURLRequestContext::OnNewExtensions(const std::string& id, const FilePath& path) { - if (!is_off_the_record_) + if (!is_off_the_record_) { extension_paths_[id] = path; + } } void ChromeURLRequestContext::OnUnloadedExtension(const std::string& id) { diff --git a/chrome/browser/resources/extensions_ui.html b/chrome/browser/resources/extensions_ui.html index 99076f8..0c9273b 100644 --- a/chrome/browser/resources/extensions_ui.html +++ b/chrome/browser/resources/extensions_ui.html @@ -111,87 +111,6 @@ button { font-size:100%; } -#dialogBackground, #dialogBackground div { - display: -webkit-box; - -webkit-box-align: center; -} - -#dialog input[type="button"] { - font-size: 12px; - height: 25px; - width: 100px; -} - -#dialog input[type="text"] { - width: 220px; - font-size: 12px; - font-family: Arial, Helvetica, sans-serif; -} - -#dialogBackground { - background-color: rgba(0, 0, 0, .2); - display: none; - height: 100%; - left: 0; - position: fixed; - top: 0; - width: 100%; - z-index: 1; - -webkit-box-orient: vertical; - -webkit-user-select:none; -} - -#dialogHBackground { - height: 100%; - -webkit-box-orient: horizontal; -} - -#dialog { - background-color: #5296DE; - border: 1px solid #3A75BD; - border-radius: 6px 6px; - font-size: 12px; - width: 500px; - -webkit-box-orient: vertical; -} - -#dialogHeader { - background-color: rgba(0,0,0,0); - color: white; - margin: 4px; - width: 100%; -} - -#dialogBody { - background-color: rgb(240, 240, 240); - border: 1px solid #3A75BD; - border-bottom-left-radius: 4px 4px; - border-bottom-right-radius: 4px 4px; - margin: 0px 2px 2px 2px; - -webkit-box-orient: vertical; -} - -#dialogContentHeader { - margin: 16px; -} - -.dialogBrowseRow { - margin-left: -24px; - width: 100%; - -webkit-box-orient: horizontal; - -webkit-box-pack: end; -} - -.dialogBrowseRow>* { - margin: 2px -} - -#dialogContentFooter { - margin-bottom: 6px; - margin-left: -12px; - margin-top: 20px; -} - </style> <script> /** @@ -345,69 +264,17 @@ function handleUninstallExtension(node) { } /** - * Utility function which asks the C++ to show a platform-specific file select - * dialog, and fire |callback| with the |filePath| that resulted. |selectType| - * can be either 'file' or 'folder'. |operation| can be 'load', 'packRoot', - * or 'pem' which are signals to the C++ to do some operation-specific - * configuration. - */ -function showFileDialog(selectType, operation, callback) { - handleFilePathSelected = function(filePath) { - callback(filePath); - handleFilePathSelected = function() {}; - }; - - chrome.send('selectFilePath', [selectType, operation]); -} - -/** * Handles the "Load extension..." button being pressed. */ function loadExtension() { - showFileDialog('folder', 'load', function(filePath) { - chrome.send('load', [String(filePath)]); - }); + chrome.send('load', []); } /** * Handles the "Pack extension..." button being pressed. */ function packExtension() { - var extensionPath = document.getElementById('extensionPathText').value; - var privateKeyPath = document.getElementById('privateKeyPath').value; - chrome.send('pack', [extensionPath, privateKeyPath]); -} - -/** - * Shows to modal HTML pack dialog. - */ -function showPackDialog() { - document.getElementById('dialogBackground').style.display="-webkit-box"; -} - -/** - * Hides the pack dialog. - */ -function hidePackDialog() { - document.getElementById('dialogBackground').style.display="none" -} - -/** - * Pop up a select dialog to capture the extension path. - */ -function selectExtensionPath() { - showFileDialog('folder', 'packRoot', function(filePath) { - document.getElementById('extensionPathText').value = filePath; - }); -} - -/** - * Pop up a select dialog to capture the private key path. - */ -function selectPrivateKeyPath() { - showFileDialog('file', 'pem', function(filePath) { - document.getElementById('privateKeyPath').value = filePath; - }); + chrome.send('pack', []); } /** @@ -420,55 +287,6 @@ function autoUpdate() { </script> </head> <body onload="requestExtensionsData();"> - <div id="dialogBackground"> - <div id="dialogHBackground"> - <div id="dialog"> - <div id="dialogHeader"> - Pack Extension - </div> - <div id="dialogBody"> - <div id="dialogContentHeader" i18n-content="packDialogHeading"> - HEADING - </div> - <div class="dialogBrowseRow"> - <div i18n-content="rootDirectoryLabel"> - ROOT_DIR - </div> - <div> - <input type="text" id="extensionPathText"> - </div> - <div> - <input type="button" value="BROWSE" - i18n-values="value:packDialogBrowse" - onclick="selectExtensionPath();"> - </div> - </div> - <div class="dialogBrowseRow"> - <div i18n-content="privateKeyLabel"> - PRIVATE_KEY - </div> - <div> - <input type="text" id="privateKeyPath"> - </div> - <div> - <input type="button" value="BROWSE" - i18n-values="value:packDialogBrowse" - onclick="selectPrivateKeyPath();"> - </div> - </div> - <div class="dialogBrowseRow" id="dialogContentFooter"> - <div> - <input type="button" value="OK" onclick="packExtension();"> - </div> - <div> - <input type="button" value="Cancel" onclick="hidePackDialog();"> - </div> - </div> - </div> - </div> - </div> - </div> - <div id="body-container" style="display:none;"> <div id="header"><h1>About extensions</h1></div> @@ -538,7 +356,7 @@ function autoUpdate() { <div class="sidebar-content"> <button onclick="loadExtension()">Load unpacked extension...</button><br /> - <button onclick="showPackDialog()">Pack extension...</button><br /> + <button onclick="packExtension()">Pack extension...</button><br /> <button onclick="autoUpdate()">Update extensions now</button> </div> </td> diff --git a/chrome/browser/views/extensions/extension_pack_dialog.cc b/chrome/browser/views/extensions/extension_pack_dialog.cc new file mode 100644 index 0000000..3b66cc7 --- /dev/null +++ b/chrome/browser/views/extensions/extension_pack_dialog.cc @@ -0,0 +1,233 @@ +// 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 "app/gfx/font.h" +#include "app/l10n_util.h" +#include "app/win_util.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_window.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/extensions/extensions_ui.h" +#include "chrome/browser/extensions/pack_extension_job.h" +#include "chrome/browser/shell_dialogs.h" +#include "grit/generated_resources.h" +#include "views/controls/label.h" +#include "views/controls/button/native_button.h" +#include "views/controls/textfield/textfield.h" +#include "views/standard_layout.h" +#include "views/view.h" +#include "views/window/dialog_client_view.h" +#include "views/window/dialog_delegate.h" +#include "views/window/window.h" + +namespace { + +// Puts up the the pack dialog, which has this basic layout: +// +// Select the extension to pack. +// +// Extension root: [ ] [browse] +// Extension key file: [ ] [browse] +// +// [ok] [cancel] +class PackDialogContent + : public views::View, + public PackExtensionJob::Client, + public SelectFileDialog::Listener, + public views::ButtonListener, + public views::DialogDelegate { + public: + PackDialogContent() : ok_button_(NULL) { + using views::GridLayout; + + // Setup the layout. + views::GridLayout* layout = CreatePanelGridLayout(this); + SetLayoutManager(layout); + + views::ColumnSet* columns = layout->AddColumnSet(0); + columns->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, + GridLayout::USE_PREF, 0, 0); + columns->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); + columns->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1, + GridLayout::USE_PREF, 0, 0); + columns->AddPaddingColumn(0, kRelatedControlHorizontalSpacing); + columns->AddColumn(GridLayout::LEADING, GridLayout::FILL, 1, + GridLayout::USE_PREF, 0, 0); + + layout->StartRow(0, 0); + views::Label* heading = new views::Label( + l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_HEADING)); + heading->SetMultiLine(true); + heading->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + layout->AddView(heading, 5, 1, GridLayout::FILL, GridLayout::LEADING); + + layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing); + + layout->StartRow(0, 0); + layout->AddView(new views::Label(l10n_util::GetString( + IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL))); + extension_root_textbox_ = new views::Textfield(); + extension_root_textbox_->set_default_width_in_chars(32); + layout->AddView(extension_root_textbox_); + extension_root_button_ = new views::NativeButton(this, l10n_util::GetString( + IDS_EXTENSION_PACK_DIALOG_BROWSE)); + layout->AddView(extension_root_button_); + + layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); + + layout->StartRow(0, 0); + layout->AddView(new views::Label(l10n_util::GetString( + IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL))); + private_key_textbox_ = new views::Textfield(); + private_key_textbox_->set_default_width_in_chars(32); + layout->AddView(private_key_textbox_); + private_key_button_ = new views::NativeButton(this, l10n_util::GetString( + IDS_EXTENSION_PACK_DIALOG_BROWSE)); + layout->AddView(private_key_button_); + } + + // PackExtensionJob::Client + virtual void OnPackSuccess(const FilePath& crx_file, + const FilePath& pem_file) { + ok_button_->SetEnabled(true); + std::wstring message; + if (!pem_file.empty()) { + message = l10n_util::GetStringF( + IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_NEW, + crx_file.ToWStringHack(), + pem_file.ToWStringHack()); + } else { + message = l10n_util::GetStringF( + IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_UPDATE, + crx_file.ToWStringHack()); + } + win_util::MessageBox(GetWindow()->GetNativeWindow(), message, + l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_SUCCESS_TITLE), + MB_OK | MB_SETFOREGROUND); + GetWindow()->Close(); + } + + void OnPackFailure(const std::wstring& error) { + ok_button_->SetEnabled(true); + win_util::MessageBox(GetWindow()->GetNativeWindow(), error, + l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_FAILURE_TITLE), + MB_OK | MB_SETFOREGROUND); + } + + private: + // DialogDelegate + virtual bool Accept() { + FilePath root_directory = FilePath::FromWStringHack( + extension_root_textbox_->text()); + FilePath key_file = FilePath::FromWStringHack(private_key_textbox_->text()); + + if (root_directory.empty()) { + if (extension_root_textbox_->text().empty()) { + OnPackFailure(l10n_util::GetString( + IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED)); + } else { + OnPackFailure(l10n_util::GetString( + IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID)); + } + + return false; + } + + if (!private_key_textbox_->text().empty() && key_file.empty()) { + OnPackFailure(l10n_util::GetString( + IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID)); + return false; + } + + pack_job_ = new PackExtensionJob(this, root_directory, key_file, + ChromeThread::GetMessageLoop(ChromeThread::FILE)); + + // Prevent the dialog from closing because PackExtensionJob is asynchronous. + // We need to wait to find out if it succeeded before closing the window. + // + // Also disable the OK button while this is going so the user understands + // that something is happening. + views::DialogClientView* dialog = static_cast<views::DialogClientView*>( + GetWindow()->GetClientView()); + ok_button_ = dialog->ok_button(); + ok_button_->SetEnabled(false); + return false; + } + + virtual void OnClose() { + if (pack_job_) + pack_job_->ClearClient(); + } + + // WindowDelegate + virtual std::wstring GetWindowTitle() const { + return l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_TITLE); + } + virtual views::View* GetContentsView() { + return this; + } + + // ButtonListener + virtual void ButtonPressed(views::Button* sender, const views::Event& event) { + file_dialog_ = SelectFileDialog::Create(this); + + if (sender == extension_root_button_) { + file_dialog_->SelectFile(SelectFileDialog::SELECT_FOLDER, + l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_SELECT_ROOT), + FilePath::FromWStringHack(extension_root_textbox_->text()), + NULL, 0, FILE_PATH_LITERAL(""), + GetWindow()->GetNativeWindow(), + extension_root_textbox_); + } else { + static SelectFileDialog::FileTypeInfo info; + info.extensions.push_back(std::vector<FilePath::StringType>()); + info.extensions.front().push_back(FILE_PATH_LITERAL("pem")); + info.extension_description_overrides.push_back(l10n_util::GetString( + IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION)); + info.include_all_files = true; + + file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE, + l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_SELECT_KEY), + FilePath::FromWStringHack(private_key_textbox_->text()), + &info, 1, FILE_PATH_LITERAL(""), + GetWindow()->GetNativeWindow(), + private_key_textbox_); + } + } + + // SelectFileDialog::Listener + virtual void MultiFilesSelected( + const std::vector<FilePath>& files, void* params) {}; + virtual void FileSelectionCanceled(void* params) {}; + virtual void FileSelected(const FilePath& path, int index, void* params) { + static_cast<views::Textfield*>(params)->SetText(path.ToWStringHack()); + } + + views::Textfield* extension_root_textbox_; + views::Textfield* private_key_textbox_; + views::NativeButton* extension_root_button_; + views::NativeButton* private_key_button_; + views::NativeButton* ok_button_; + + scoped_refptr<SelectFileDialog> file_dialog_; + scoped_refptr<PackExtensionJob> pack_job_; + + DISALLOW_COPY_AND_ASSIGN(PackDialogContent); +}; + +} // namespace + +// static +void ExtensionsDOMHandler::ShowPackDialog() { + Browser* browser = BrowserList::GetLastActive(); + if (!browser) + return; + + BrowserWindow* window = browser->window(); + if (!window) + return; + + views::Window::CreateChromeWindow(window->GetNativeHandle(), + gfx::Rect(400, 0), new PackDialogContent())->Show(); +} diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index e4addf0..5e97e00 100755 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -2098,6 +2098,7 @@ 'browser/views/event_utils.cc', 'browser/views/event_utils.h', 'browser/views/extensions/extension_install_prompt.cc', + 'browser/views/extensions/extension_pack_dialog.cc', 'browser/views/extensions/extension_popup.cc', 'browser/views/extensions/extension_popup.h', 'browser/views/extensions/extension_shelf.cc', @@ -2751,6 +2752,11 @@ ['exclude', '^browser/tab_contents/tab_contents_view_gtk.h'], ['exclude', '^browser/tab_contents/render_view_context_menu_gtk.cc'], ['exclude', '^browser/tab_contents/render_view_context_menu_gtk.h'], + # This compiles but has Linux shared build linking issues due to + # missing rsa_private_key functions. + ['exclude', '^browser/extensions/extension_creator.cc'], + # This compiles but it needs extension_creator. + ['exclude', '^browser/extensions/pack_extension_job.cc'], ], }], ['OS=="linux" and toolkit_views==0', { @@ -2836,6 +2842,8 @@ 'browser/bookmarks/bookmark_menu_controller.h', 'browser/browser_accessibility.cc', 'browser/browser_accessibility_manager.cc', + 'browser/extensions/extension_creator.cc', + 'browser/extensions/pack_extension_job.cc', 'browser/dom_ui/html_dialog_contents.cc', 'browser/external_tab_container.cc', 'browser/google_update.cc', |