| Index: chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
 | 
| diff --git a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
 | 
| index 0ce4df8dabd21d94c623d0ae10d11a73afba8b5d..5dc49ab2cd9379615439830a019f6f79fdba9a53 100644
 | 
| --- a/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
 | 
| +++ b/chrome/browser/ui/cocoa/constrained_web_dialog_delegate_mac.mm
 | 
| @@ -11,7 +11,11 @@
 | 
|  #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_custom_window.h"
 | 
|  #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_mac.h"
 | 
|  #import "chrome/browser/ui/cocoa/constrained_window/constrained_window_web_dialog_sheet.h"
 | 
| +#include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
 | 
| +#include "content/public/browser/render_view_host.h"
 | 
|  #include "content/public/browser/web_contents.h"
 | 
| +#include "content/public/browser/web_contents_observer.h"
 | 
| +#include "ui/base/cocoa/window_size_constants.h"
 | 
|  #include "ui/gfx/geometry/size.h"
 | 
|  #include "ui/web_dialogs/web_dialog_delegate.h"
 | 
|  #include "ui/web_dialogs/web_dialog_ui.h"
 | 
| @@ -23,19 +27,61 @@ using ui::WebDialogWebContentsDelegate;
 | 
|  
 | 
|  namespace {
 | 
|  
 | 
| +class ConstrainedWebDialogDelegateMac;
 | 
| +
 | 
| +// This class is to trigger a resize to the dialog window when
 | 
| +// ResizeDueToAutoResize() is invoked.
 | 
| +class WebDialogWebContentsDelegateMac
 | 
| +    : public ui::WebDialogWebContentsDelegate {
 | 
| + public:
 | 
| +  WebDialogWebContentsDelegateMac(content::BrowserContext* browser_context,
 | 
| +                                  content::WebContentsObserver* observer,
 | 
| +                                  ConstrainedWebDialogDelegateBase* delegate)
 | 
| +      : ui::WebDialogWebContentsDelegate(browser_context,
 | 
| +                                         new ChromeWebContentsHandler()),
 | 
| +        observer_(observer),
 | 
| +        delegate_(delegate) {
 | 
| +  }
 | 
| +  ~WebDialogWebContentsDelegateMac() override {}
 | 
| +
 | 
| +  void ResizeDueToAutoResize(content::WebContents* source,
 | 
| +                             const gfx::Size& preferred_size) override {
 | 
| +    if (!observer_->web_contents())
 | 
| +      return;
 | 
| +    delegate_->ResizeToGivenSize(preferred_size);
 | 
| +  }
 | 
| +
 | 
| + private:
 | 
| +  // These members must outlive the instance.
 | 
| +  content::WebContentsObserver* const observer_;
 | 
| +  ConstrainedWebDialogDelegateBase* delegate_;
 | 
| +
 | 
| +  DISALLOW_COPY_AND_ASSIGN(WebDialogWebContentsDelegateMac);
 | 
| +};
 | 
| +
 | 
|  class ConstrainedWebDialogDelegateMac
 | 
|      : public ConstrainedWebDialogDelegateBase {
 | 
|   public:
 | 
|    ConstrainedWebDialogDelegateMac(
 | 
|        content::BrowserContext* browser_context,
 | 
| -      WebDialogDelegate* delegate)
 | 
| -      : ConstrainedWebDialogDelegateBase(browser_context, delegate, NULL) {}
 | 
| +      WebDialogDelegate* delegate,
 | 
| +      content::WebContentsObserver* observer)
 | 
| +      : ConstrainedWebDialogDelegateBase(browser_context, delegate,
 | 
| +          new WebDialogWebContentsDelegateMac(browser_context, observer,
 | 
| +                                              this)) {}
 | 
|  
 | 
|    // WebDialogWebContentsDelegate interface.
 | 
|    void CloseContents(WebContents* source) override {
 | 
|      window_->CloseWebContentsModalDialog();
 | 
|    }
 | 
|  
 | 
| +  // ConstrainedWebDialogDelegateBase:
 | 
| +  void ResizeToGivenSize(const gfx::Size size) override {
 | 
| +    NSSize updated_preferred_size = NSMakeSize(size.width(),
 | 
| +                                               size.height());
 | 
| +    [window_->sheet() resizeWithNewSize:updated_preferred_size];
 | 
| +  }
 | 
| +
 | 
|    void set_window(ConstrainedWindowMac* window) { window_ = window; }
 | 
|    ConstrainedWindowMac* window() const { return window_; }
 | 
|  
 | 
| @@ -50,13 +96,16 @@ class ConstrainedWebDialogDelegateMac
 | 
|  
 | 
|  class ConstrainedWebDialogDelegateViewMac :
 | 
|      public ConstrainedWindowMacDelegate,
 | 
| -    public ConstrainedWebDialogDelegate {
 | 
| +    public ConstrainedWebDialogDelegate,
 | 
| +    public content::WebContentsObserver {
 | 
|  
 | 
|   public:
 | 
|    ConstrainedWebDialogDelegateViewMac(
 | 
|        content::BrowserContext* browser_context,
 | 
|        WebDialogDelegate* delegate,
 | 
| -      content::WebContents* web_contents);
 | 
| +      content::WebContents* web_contents,
 | 
| +      const gfx::Size& min_size,
 | 
| +      const gfx::Size& max_size);
 | 
|    ~ConstrainedWebDialogDelegateViewMac() override {}
 | 
|  
 | 
|    // ConstrainedWebDialogDelegate interface
 | 
| @@ -75,16 +124,37 @@ class ConstrainedWebDialogDelegateViewMac :
 | 
|    gfx::NativeWindow GetNativeDialog() override { return window_; }
 | 
|    WebContents* GetWebContents() override { return impl_->GetWebContents(); }
 | 
|    gfx::Size GetMinimumSize() const override {
 | 
| -    NOTIMPLEMENTED();
 | 
| -    return gfx::Size();
 | 
| +    return min_size_;
 | 
|    }
 | 
|    gfx::Size GetMaximumSize() const override {
 | 
| -    NOTIMPLEMENTED();
 | 
| -    return gfx::Size();
 | 
| +    return max_size_;
 | 
|    }
 | 
|    gfx::Size GetPreferredSize() const override {
 | 
| -    NOTIMPLEMENTED();
 | 
| -    return gfx::Size();
 | 
| +    gfx::Size size;
 | 
| +    if (!impl_->closed_via_webui()) {
 | 
| +      NSRect frame = [window_ frame];
 | 
| +      size = gfx::Size(frame.size.width, frame.size.height);
 | 
| +    }
 | 
| +    return size;
 | 
| +  }
 | 
| +
 | 
| +  // content::WebContentsObserver:
 | 
| +  void RenderViewCreated(content::RenderViewHost* render_view_host) override {
 | 
| +    if (IsDialogAutoResizable())
 | 
| +      EnableAutoResize();
 | 
| +  }
 | 
| +  void RenderViewHostChanged(content::RenderViewHost* old_host,
 | 
| +                             content::RenderViewHost* new_host) override {
 | 
| +    if (IsDialogAutoResizable())
 | 
| +      EnableAutoResize();
 | 
| +  }
 | 
| +  void DocumentOnLoadCompletedInMainFrame() override {
 | 
| +    if (!IsDialogAutoResizable())
 | 
| +      return;
 | 
| +
 | 
| +    EnableAutoResize();
 | 
| +    if (GetWebContents())
 | 
| +      constrained_window_->ShowWebContentsModalDialog();
 | 
|    }
 | 
|  
 | 
|    // ConstrainedWindowMacDelegate interface
 | 
| @@ -95,25 +165,53 @@ class ConstrainedWebDialogDelegateViewMac :
 | 
|    }
 | 
|  
 | 
|   private:
 | 
| +  void EnableAutoResize() {
 | 
| +    if (!GetWebContents())
 | 
| +      return;
 | 
| +
 | 
| +    content::RenderViewHost* render_view_host =
 | 
| +        GetWebContents()->GetRenderViewHost();
 | 
| +    render_view_host->EnableAutoResize(min_size_, max_size_);
 | 
| +  }
 | 
| +
 | 
| +  // Whether or not the dialog is autoresizable is determined based on whether
 | 
| +  // |max_size_| was specified.
 | 
| +  bool IsDialogAutoResizable() {
 | 
| +    return !max_size_.IsEmpty();
 | 
| +  }
 | 
| +
 | 
|    scoped_ptr<ConstrainedWebDialogDelegateMac> impl_;
 | 
| -  scoped_ptr<ConstrainedWindowMac> constrained_window_;
 | 
| +  std::unique_ptr<ConstrainedWindowMac> constrained_window_;
 | 
|    base::scoped_nsobject<NSWindow> window_;
 | 
|  
 | 
| +  // Minimum and maximum sizes to determine dialog bounds for auto-resizing.
 | 
| +  const gfx::Size min_size_;
 | 
| +  const gfx::Size max_size_;
 | 
| +
 | 
|    DISALLOW_COPY_AND_ASSIGN(ConstrainedWebDialogDelegateViewMac);
 | 
|  };
 | 
|  
 | 
|  ConstrainedWebDialogDelegateViewMac::ConstrainedWebDialogDelegateViewMac(
 | 
|      content::BrowserContext* browser_context,
 | 
|      WebDialogDelegate* delegate,
 | 
| -    content::WebContents* web_contents)
 | 
| -    : impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate)) {
 | 
| +    content::WebContents* web_contents,
 | 
| +    const gfx::Size& min_size,
 | 
| +    const gfx::Size& max_size)
 | 
| +    : content::WebContentsObserver(web_contents),
 | 
| +      impl_(new ConstrainedWebDialogDelegateMac(browser_context, delegate,
 | 
| +            this)),
 | 
| +      min_size_(min_size),
 | 
| +      max_size_(max_size) {
 | 
| +  if (IsDialogAutoResizable())
 | 
| +    Observe(GetWebContents());
 | 
| +
 | 
|    // Create a window to hold web_contents in the constrained sheet:
 | 
|    gfx::Size size;
 | 
|    delegate->GetDialogSize(&size);
 | 
|    NSRect frame = NSMakeRect(0, 0, size.width(), size.height());
 | 
|  
 | 
| -  window_.reset(
 | 
| -      [[ConstrainedWindowCustomWindow alloc] initWithContentRect:frame]);
 | 
| +  window_.reset([[ConstrainedWindowCustomWindow alloc]
 | 
| +                initWithContentRect:ui::kWindowSizeDeterminedLater]);
 | 
|    [GetWebContents()->GetNativeView() setFrame:frame];
 | 
|    [GetWebContents()->GetNativeView() setAutoresizingMask:
 | 
|        NSViewWidthSizable|NSViewHeightSizable];
 | 
| @@ -122,8 +220,14 @@ ConstrainedWebDialogDelegateViewMac::ConstrainedWebDialogDelegateViewMac(
 | 
|    base::scoped_nsobject<WebDialogConstrainedWindowSheet> sheet(
 | 
|        [[WebDialogConstrainedWindowSheet alloc] initWithCustomWindow:window_
 | 
|                                                    webDialogDelegate:delegate]);
 | 
| -  constrained_window_.reset(new ConstrainedWindowMac(
 | 
| -      this, web_contents, sheet));
 | 
| +
 | 
| +  if (IsDialogAutoResizable()) {
 | 
| +    constrained_window_ = CreateWebModalDialogMac(
 | 
| +          this, web_contents, sheet);
 | 
| +  } else {
 | 
| +    constrained_window_ = CreateAndShowWebModalDialogMac(
 | 
| +          this, web_contents, sheet);
 | 
| +  }
 | 
|  
 | 
|    impl_->set_window(constrained_window_.get());
 | 
|  }
 | 
| @@ -135,6 +239,23 @@ ConstrainedWebDialogDelegate* ShowConstrainedWebDialog(
 | 
|    // Deleted when the dialog closes.
 | 
|    ConstrainedWebDialogDelegateViewMac* constrained_delegate =
 | 
|        new ConstrainedWebDialogDelegateViewMac(
 | 
| -          browser_context, delegate, web_contents);
 | 
| +          browser_context, delegate, web_contents,
 | 
| +          gfx::Size(), gfx::Size());
 | 
| +  return constrained_delegate;
 | 
| +}
 | 
| +
 | 
| +ConstrainedWebDialogDelegate* ShowConstrainedWebDialogWithAutoResize(
 | 
| +    content::BrowserContext* browser_context,
 | 
| +    WebDialogDelegate* delegate,
 | 
| +    content::WebContents* web_contents,
 | 
| +    const gfx::Size& min_size,
 | 
| +    const gfx::Size& max_size) {
 | 
| +  DCHECK(!min_size.IsEmpty());
 | 
| +  DCHECK(!max_size.IsEmpty());
 | 
| +  // Deleted when the dialog closes.
 | 
| +  ConstrainedWebDialogDelegateViewMac* constrained_delegate =
 | 
| +      new ConstrainedWebDialogDelegateViewMac(
 | 
| +          browser_context, delegate, web_contents,
 | 
| +          min_size, max_size);
 | 
|    return constrained_delegate;
 | 
|  }
 | 
| 
 |