Commit 0cb2e086 authored by groby@chromium.org's avatar groby@chromium.org

[autofill] First step towards autofill dialog on OSX.

This CL implements a blank tab-modal dialog that gets invoked when
requestAutocomplete is used.

TBR=jhawkins@chromium.org
R=sail@chromium.org, estade@chromium.org
BUG=157274

Review URL: https://chromiumcodereview.appspot.com/13470023

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@195286 0039d316-1c4b-4281-b951-d872f2087c98
parent a9de20a8
...@@ -10,9 +10,8 @@ namespace autofill { ...@@ -10,9 +10,8 @@ namespace autofill {
AutofillDialogView::~AutofillDialogView() {} AutofillDialogView::~AutofillDialogView() {}
#if !defined(TOOLKIT_VIEWS) && !defined(OS_ANDROID) #if defined(TOOLKIT_GTK)
// TODO(estade): implement the dialog on other platforms. See // TODO(estade): implement the dialog on GTK. See http://crbug.com/157275.
// http://crbug.com/157274 http://crbug.com/157275
AutofillDialogView* AutofillDialogView::Create( AutofillDialogView* AutofillDialogView::Create(
AutofillDialogController* controller) { AutofillDialogController* controller) {
return NULL; return NULL;
......
// Copyright (c) 2013 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_UI_COCOA_AUTOFILL_AUTOFILL_DIALOG_COCOA_H_
#define CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_DIALOG_COCOA_H_
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/ui/autofill/autofill_dialog_controller.h"
#include "chrome/browser/ui/autofill/autofill_dialog_view.h"
#include "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
namespace content {
class NavigationController;
}
@class AutofillDialogWindowController;
@class GTMWidthBasedTweaker;
namespace autofill {
class AutofillDialogCocoa : public AutofillDialogView,
public ConstrainedWindowMacDelegate {
public:
explicit AutofillDialogCocoa(AutofillDialogController* controller);
virtual ~AutofillDialogCocoa();
// AutofillDialogView implementation:
virtual void Show() OVERRIDE;
virtual void Hide() OVERRIDE;
virtual void UpdateAccountChooser() OVERRIDE;
virtual void UpdateButtonStrip() OVERRIDE;
virtual void UpdateNotificationArea() OVERRIDE;
virtual void UpdateSection(DialogSection section,
UserInputAction action) OVERRIDE;
virtual void GetUserInput(DialogSection section,
DetailOutputMap* output) OVERRIDE;
virtual string16 GetCvc() OVERRIDE;
virtual bool UseBillingForShipping() OVERRIDE;
virtual bool SaveDetailsLocally() OVERRIDE;
virtual const content::NavigationController* ShowSignIn() OVERRIDE;
virtual void HideSignIn() OVERRIDE;
virtual void UpdateProgressBar(double value) OVERRIDE;
virtual void ModelChanged() OVERRIDE;
virtual void SubmitForTesting() OVERRIDE;
virtual void CancelForTesting() OVERRIDE;
// ConstrainedWindowMacDelegate implementation.
virtual void OnConstrainedWindowClosed(
ConstrainedWindowMac* window) OVERRIDE;
void PerformClose();
private:
scoped_ptr<ConstrainedWindowMac> constrained_window_;
scoped_nsobject<AutofillDialogWindowController> sheet_controller_;
// The controller |this| queries for logic and state.
AutofillDialogController* controller_;
};
} // autofill
@interface AutofillDialogWindowController : NSWindowController
<NSWindowDelegate> {
@private
content::WebContents* webContents_; // weak.
autofill::AutofillDialogCocoa* autofillDialog_; // weak.
scoped_nsobject<GTMWidthBasedTweaker> buttonContainer_;
}
// Designated initializer. The WebContents cannot be NULL.
- (id)initWithWebContents:(content::WebContents*)webContents
autofillDialog:(autofill::AutofillDialogCocoa*)autofillDialog;
// Closes the sheet and ends the modal loop. This will also clean up the memory.
- (IBAction)closeSheet:(id)sender;
@end
#endif // CHROME_BROWSER_UI_COCOA_AUTOFILL_AUTOFILL_DIALOG_COCOA_H_
// Copyright (c) 2013 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/ui/cocoa/autofill/autofill_dialog_cocoa.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_button.h"
#include "chrome/browser/ui/chrome_style.h"
#include "base/mac/bundle_locations.h"
#include "base/memory/scoped_nsobject.h"
#include "chrome/browser/ui/chrome_style.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_sheet.h"
#import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h"
#import "chrome/browser/ui/cocoa/key_equivalent_constants.h"
#include "grit/generated_resources.h"
#import "third_party/GTM/AppKit/GTMUILocalizerAndLayoutTweaker.h"
#include "ui/base/cocoa/window_size_constants.h"
#include "ui/base/l10n/l10n_util.h"
namespace {
const CGFloat kButtonGap = 6;
} // namespace
namespace autofill {
// static
AutofillDialogView* AutofillDialogView::Create(
AutofillDialogController* controller) {
return new AutofillDialogCocoa(controller);
}
AutofillDialogCocoa::AutofillDialogCocoa(AutofillDialogController* controller)
: controller_(controller) {
sheet_controller_.reset([[AutofillDialogWindowController alloc]
initWithWebContents:controller_->web_contents()
autofillDialog:this]);
scoped_nsobject<CustomConstrainedWindowSheet> sheet(
[[CustomConstrainedWindowSheet alloc]
initWithCustomWindow:[sheet_controller_ window]]);
constrained_window_.reset(
new ConstrainedWindowMac(this, controller_->web_contents(), sheet));
}
AutofillDialogCocoa::~AutofillDialogCocoa() {
}
void AutofillDialogCocoa::Show() {
}
void AutofillDialogCocoa::Hide() {
}
void AutofillDialogCocoa::UpdateAccountChooser() {
}
void AutofillDialogCocoa::UpdateButtonStrip() {
}
void AutofillDialogCocoa::UpdateNotificationArea() {
}
void AutofillDialogCocoa::UpdateSection(DialogSection section,
UserInputAction action) {
}
void AutofillDialogCocoa::GetUserInput(DialogSection section,
DetailOutputMap* output) {
}
string16 AutofillDialogCocoa::GetCvc() {
return string16();
}
bool AutofillDialogCocoa::UseBillingForShipping() {
return false;
}
bool AutofillDialogCocoa::SaveDetailsLocally() {
return false;
}
const content::NavigationController* AutofillDialogCocoa::ShowSignIn() {
return NULL;
}
void AutofillDialogCocoa::HideSignIn() {}
void AutofillDialogCocoa::UpdateProgressBar(double value) {}
void AutofillDialogCocoa::ModelChanged() {}
void AutofillDialogCocoa::SubmitForTesting() {}
void AutofillDialogCocoa::CancelForTesting() {
PerformClose();
}
void AutofillDialogCocoa::OnConstrainedWindowClosed(
ConstrainedWindowMac* window) {
constrained_window_.reset();
// |this| belongs to |controller_|, so no self-destruction here.
controller_->ViewClosed();
}
void AutofillDialogCocoa::PerformClose() {
controller_->OnCancel();
constrained_window_->CloseWebContentsModalDialog();
}
} // autofill
#pragma mark Window Controller
@implementation AutofillDialogWindowController
- (id)initWithWebContents:(content::WebContents*)webContents
autofillDialog:(autofill::AutofillDialogCocoa*)autofillDialog {
DCHECK(webContents);
// TODO(groby): Should be ui::kWindowSizeDeterminedLater
NSRect frame = NSMakeRect(0, 0, 550, 600);
scoped_nsobject<ConstrainedWindowCustomWindow> window(
[[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]);
if ((self = [super initWithWindow:window])) {
webContents_ = webContents;
autofillDialog_ = autofillDialog;
[self buildWindowButtons];
[self layoutButtons];
}
return self;
}
- (IBAction)closeSheet:(id)sender {
autofillDialog_->PerformClose();
}
- (void)buildWindowButtons {
if (buttonContainer_.get())
return;
buttonContainer_.reset([[GTMWidthBasedTweaker alloc] initWithFrame:
ui::kWindowSizeDeterminedLater]);
[buttonContainer_
setAutoresizingMask:(NSViewMinXMargin | NSViewMinYMargin)];
scoped_nsobject<NSButton> button(
[[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]);
[button setTitle:l10n_util::GetNSStringWithFixup(IDS_CANCEL)];
[button setKeyEquivalent:kKeyEquivalentEscape];
[button setTarget:self];
[button setAction:@selector(closeSheet:)];
[button sizeToFit];
[buttonContainer_ addSubview:button];
CGFloat nextX = NSMaxX([button frame]) + kButtonGap;
button.reset([[ConstrainedWindowButton alloc] initWithFrame:NSZeroRect]);
[button setFrameOrigin:NSMakePoint(nextX, 0)];
[button setTitle:l10n_util::GetNSStringWithFixup(
IDS_AUTOFILL_DIALOG_SUBMIT_BUTTON)];
[button setKeyEquivalent:kKeyEquivalentReturn];
[button setTarget:self];
[button setAction:@selector(closeSheet:)];
[button sizeToFit];
[buttonContainer_ addSubview:button];
const CGFloat dialogOffset = NSWidth([[self window] frame]) -
chrome_style::kHorizontalPadding - NSMaxX([button frame]);
[buttonContainer_ setFrame:
NSMakeRect(dialogOffset, chrome_style::kClientBottomPadding,
NSMaxX([button frame]), NSMaxY([button frame]))];
[[[self window] contentView] addSubview:buttonContainer_];
}
- (void)layoutButtons {
scoped_nsobject<GTMUILocalizerAndLayoutTweaker> layoutTweaker(
[[GTMUILocalizerAndLayoutTweaker alloc] init]);
[layoutTweaker tweakUI:buttonContainer_];
}
@end
\ No newline at end of file
// Copyright (c) 2013 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.
#import "chrome/browser/ui/cocoa/autofill/autofill_dialog_cocoa.h"
#include "base/bind.h"
#include "base/message_loop.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/autofill/common/form_data.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace autofill {
namespace {
void MockCallback(const FormStructure*, const std::string&) {}
class TestAutofillDialogController : public AutofillDialogControllerImpl {
public:
TestAutofillDialogController(
content::WebContents* contents,
const FormData& form_structure,
const AutofillMetrics& metric_logger,
scoped_refptr<content::MessageLoopRunner> runner,
const DialogType dialog_type)
: AutofillDialogControllerImpl(contents,
form_structure,
GURL(),
dialog_type,
base::Bind(MockCallback)),
metric_logger_(metric_logger) ,
runner_(runner) {
DisableWallet();
}
virtual ~TestAutofillDialogController() {}
virtual void ViewClosed() OVERRIDE {
DCHECK(runner_);
AutofillDialogControllerImpl::ViewClosed();
runner_->Quit();
}
void RunMessageLoop() {
DCHECK(runner_);
runner_->Run();
}
// Increase visibility for testing.
AutofillDialogView* view() { return AutofillDialogControllerImpl::view(); }
private:
// To specify our own metric logger.
virtual const AutofillMetrics& GetMetricLogger() const OVERRIDE {
return metric_logger_;
}
const AutofillMetrics& metric_logger_;
scoped_refptr<content::MessageLoopRunner> runner_;
DISALLOW_COPY_AND_ASSIGN(TestAutofillDialogController);
};
class AutofillDialogCocoaBrowserTest : public InProcessBrowserTest {
public:
AutofillDialogCocoaBrowserTest() : InProcessBrowserTest() {}
virtual ~AutofillDialogCocoaBrowserTest() {}
virtual void SetUpOnMainThread() OVERRIDE {
FormFieldData field;
field.autocomplete_attribute = "cc-number";
FormData form_data;
form_data.fields.push_back(field);
runner_ = new content::MessageLoopRunner;
controller_ = new TestAutofillDialogController(
browser()->tab_strip_model()->GetActiveWebContents(),
form_data,
metric_logger_,
runner_,
DIALOG_TYPE_REQUEST_AUTOCOMPLETE);
}
TestAutofillDialogController* controller() { return controller_; }
private:
// The controller owns itself.
TestAutofillDialogController* controller_;
// The following members must outlive the controller.
AutofillMetrics metric_logger_;
scoped_refptr<content::MessageLoopRunner> runner_;
DISALLOW_COPY_AND_ASSIGN(AutofillDialogCocoaBrowserTest);
};
IN_PROC_BROWSER_TEST_F(AutofillDialogCocoaBrowserTest, DisplayUI) {
controller()->Show();
controller()->view()->CancelForTesting();
controller()->RunMessageLoop();
}
} // namespace
} // namespace autofill
\ No newline at end of file
...@@ -362,6 +362,8 @@ ...@@ -362,6 +362,8 @@
'browser/ui/cocoa/applescript/tab_applescript.mm', 'browser/ui/cocoa/applescript/tab_applescript.mm',
'browser/ui/cocoa/applescript/window_applescript.h', 'browser/ui/cocoa/applescript/window_applescript.h',
'browser/ui/cocoa/applescript/window_applescript.mm', 'browser/ui/cocoa/applescript/window_applescript.mm',
'browser/ui/cocoa/autofill/autofill_dialog_cocoa.h',
'browser/ui/cocoa/autofill/autofill_dialog_cocoa.mm',
'browser/ui/cocoa/autofill/autofill_popup_view_bridge.h', 'browser/ui/cocoa/autofill/autofill_popup_view_bridge.h',
'browser/ui/cocoa/autofill/autofill_popup_view_bridge.mm', 'browser/ui/cocoa/autofill/autofill_popup_view_bridge.mm',
'browser/ui/cocoa/autofill/autofill_popup_view_cocoa.h', 'browser/ui/cocoa/autofill/autofill_popup_view_cocoa.h',
......
...@@ -1502,6 +1502,7 @@ ...@@ -1502,6 +1502,7 @@
'browser/ui/browser_navigator_browsertest_chromeos.cc', 'browser/ui/browser_navigator_browsertest_chromeos.cc',
'browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm', 'browser/ui/cocoa/applescript/browsercrapplication+applescript_test.mm',
'browser/ui/cocoa/applescript/window_applescript_test.mm', 'browser/ui/cocoa/applescript/window_applescript_test.mm',
'browser/ui/cocoa//autofill/autofill_dialog_cocoa_browsertest.mm',
'browser/ui/cocoa/browser_window_cocoa_browsertest.mm', 'browser/ui/cocoa/browser_window_cocoa_browsertest.mm',
'browser/ui/cocoa/browser_window_controller_browsertest.mm', 'browser/ui/cocoa/browser_window_controller_browsertest.mm',
'browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm', 'browser/ui/cocoa/constrained_window/constrained_window_mac_browsertest.mm',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment