summaryrefslogtreecommitdiffstats
path: root/ios
diff options
context:
space:
mode:
authordroger <droger@chromium.org>2014-12-19 00:28:45 -0800
committerCommit bot <commit-bot@chromium.org>2014-12-19 08:29:35 +0000
commit5922f8c9686e4871c61fd276083bc25c9186cad7 (patch)
treeb6b318b580b94b6019c5d0e0a8b706e7374db7ac /ios
parent081bd5578343012915bcb079aba951505352eb37 (diff)
downloadchromium_src-5922f8c9686e4871c61fd276083bc25c9186cad7.zip
chromium_src-5922f8c9686e4871c61fd276083bc25c9186cad7.tar.gz
chromium_src-5922f8c9686e4871c61fd276083bc25c9186cad7.tar.bz2
Upstream ios/chrome/browser/infobars
Review URL: https://codereview.chromium.org/811313002 Cr-Commit-Position: refs/heads/master@{#309167}
Diffstat (limited to 'ios')
-rw-r--r--ios/chrome/DEPS3
-rw-r--r--ios/chrome/browser/infobars/OWNERS2
-rw-r--r--ios/chrome/browser/infobars/confirm_infobar_controller.h14
-rw-r--r--ios/chrome/browser/infobars/confirm_infobar_controller.mm126
-rw-r--r--ios/chrome/browser/infobars/confirm_infobar_delegate.mm21
-rw-r--r--ios/chrome/browser/infobars/infobar.h46
-rw-r--r--ios/chrome/browser/infobars/infobar.mm88
-rw-r--r--ios/chrome/browser/infobars/infobar_container_ios.h45
-rw-r--r--ios/chrome/browser/infobars/infobar_container_ios.mm70
-rw-r--r--ios/chrome/browser/infobars/infobar_container_view.h23
-rw-r--r--ios/chrome/browser/infobars/infobar_container_view.mm57
-rw-r--r--ios/chrome/browser/infobars/infobar_controller.h51
-rw-r--r--ios/chrome/browser/infobars/infobar_controller.mm56
-rw-r--r--ios/chrome/ios_chrome.gyp13
14 files changed, 615 insertions, 0 deletions
diff --git a/ios/chrome/DEPS b/ios/chrome/DEPS
index 81b43aa..fb23515 100644
--- a/ios/chrome/DEPS
+++ b/ios/chrome/DEPS
@@ -1,11 +1,14 @@
include_rules = [
+ "+components/infobars/core",
"+components/keyed_service/core",
"+components/keyed_service/ios",
"+components/leveldb_proto",
"+components/suggestions",
+ "+components/translate/core",
"+ios/public/provider/chrome",
"+ios/web/public",
"+net",
+ "+ui",
# Only parts of skia are compiled on iOS, so we explicitly list the
# files that can be included to avoid bringing in more code.
diff --git a/ios/chrome/browser/infobars/OWNERS b/ios/chrome/browser/infobars/OWNERS
new file mode 100644
index 0000000..5bca21e
--- /dev/null
+++ b/ios/chrome/browser/infobars/OWNERS
@@ -0,0 +1,2 @@
+droger@chromium.org
+jif@chromium.org
diff --git a/ios/chrome/browser/infobars/confirm_infobar_controller.h b/ios/chrome/browser/infobars/confirm_infobar_controller.h
new file mode 100644
index 0000000..22110bb
--- /dev/null
+++ b/ios/chrome/browser/infobars/confirm_infobar_controller.h
@@ -0,0 +1,14 @@
+// Copyright 2012 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 IOS_CHROME_BROWSER_INFOBARS_CONFIRM_INFOBAR_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_INFOBARS_CONFIRM_INFOBAR_CONTROLLER_H_
+
+#include "ios/chrome/browser/infobars/infobar_controller.h"
+
+@interface ConfirmInfoBarController : InfoBarController
+
+@end
+
+#endif // IOS_CHROME_BROWSER_INFOBARS_CONFIRM_INFOBAR_CONTROLLER_H_
diff --git a/ios/chrome/browser/infobars/confirm_infobar_controller.mm b/ios/chrome/browser/infobars/confirm_infobar_controller.mm
new file mode 100644
index 0000000..4ead1c1
--- /dev/null
+++ b/ios/chrome/browser/infobars/confirm_infobar_controller.mm
@@ -0,0 +1,126 @@
+// Copyright 2012 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 "ios/chrome/browser/infobars/confirm_infobar_controller.h"
+
+#include "base/mac/foundation_util.h"
+#include "base/strings/sys_string_conversions.h"
+#include "components/infobars/core/confirm_infobar_delegate.h"
+#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
+#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
+#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#include "ui/gfx/image/image.h"
+
+namespace {
+
+// UI Tags for the infobar buttons
+enum ConfirmInfoBarUITags { OK = 1, CANCEL, CLOSE };
+
+// Converts a UI button tag to the corresponding InfoBarButton.
+ConfirmInfoBarDelegate::InfoBarButton UITagToButton(NSUInteger tag) {
+ switch (tag) {
+ case ConfirmInfoBarUITags::OK:
+ return ConfirmInfoBarDelegate::BUTTON_OK;
+ case ConfirmInfoBarUITags::CANCEL:
+ case ConfirmInfoBarUITags::CLOSE:
+ return ConfirmInfoBarDelegate::BUTTON_CANCEL;
+ default:
+ NOTREACHED();
+ return ConfirmInfoBarDelegate::BUTTON_CANCEL;
+ }
+}
+
+} // namespace
+
+#pragma mark - ConfirmInfoBarController
+
+@interface ConfirmInfoBarController ()
+
+// Action for any of the user defined buttons.
+- (void)infoBarButtonDidPress:(id)sender;
+
+@end
+
+@implementation ConfirmInfoBarController {
+}
+
+#pragma mark -
+#pragma mark InfoBarController
+
+- (void)layoutForDelegate:(infobars::InfoBarDelegate*)delegate
+ frame:(CGRect)frame {
+ ConfirmInfoBarDelegate* infoBarModel = delegate->AsConfirmInfoBarDelegate();
+ DCHECK(!infoBarView_);
+ infoBarView_.reset([ios::GetChromeBrowserProvider()->CreateInfoBarView()
+ initWithFrame:frame
+ delegate:delegate_
+ isWarning:infoBarModel->GetInfoBarType() ==
+ infobars::InfoBarDelegate::WARNING_TYPE]);
+
+ // Model data.
+ NSString* modelMsg = nil;
+ if (infoBarModel->GetMessageText().length())
+ modelMsg = base::SysUTF16ToNSString(infoBarModel->GetMessageText());
+ gfx::Image modelIcon = infoBarModel->GetIcon();
+ int buttons = infoBarModel->GetButtons();
+ NSString* buttonOK = nil;
+ if (buttons & ConfirmInfoBarDelegate::BUTTON_OK) {
+ buttonOK = base::SysUTF16ToNSString(
+ infoBarModel->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_OK));
+ }
+ NSString* buttonCancel = nil;
+ if (buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
+ buttonCancel = base::SysUTF16ToNSString(
+ infoBarModel->GetButtonLabel(ConfirmInfoBarDelegate::BUTTON_CANCEL));
+ }
+
+ [infoBarView_ addCloseButtonWithTag:ConfirmInfoBarUITags::CLOSE
+ target:self
+ action:@selector(infoBarButtonDidPress:)];
+
+ // Optional left icon.
+ if (!modelIcon.IsEmpty())
+ [infoBarView_ addLeftIcon:modelIcon.ToUIImage()];
+
+ // Optional message.
+ if (modelMsg)
+ [infoBarView_ addLabel:modelMsg];
+
+ if (buttonOK && buttonCancel) {
+ [infoBarView_ addButton1:buttonOK
+ tag1:ConfirmInfoBarUITags::OK
+ button2:buttonCancel
+ tag2:ConfirmInfoBarUITags::CANCEL
+ target:self
+ action:@selector(infoBarButtonDidPress:)];
+ } else if (buttonOK) {
+ [infoBarView_ addButton:buttonOK
+ tag:ConfirmInfoBarUITags::OK
+ target:self
+ action:@selector(infoBarButtonDidPress:)];
+ } else {
+ // No buttons, only message.
+ DCHECK(modelMsg && !buttonCancel);
+ }
+}
+
+#pragma mark - Handling of User Events
+
+- (void)infoBarButtonDidPress:(id)sender {
+ // This press might have occurred after the user has already pressed a button,
+ // in which case the view has been detached from the delegate and this press
+ // should be ignored.
+ if (!delegate_) {
+ return;
+ }
+ if ([sender isKindOfClass:[UIButton class]]) {
+ NSUInteger tag = static_cast<UIButton*>(sender).tag;
+ if (tag == ConfirmInfoBarUITags::CLOSE)
+ delegate_->InfoBarDidCancel();
+ else
+ delegate_->InfoBarButtonDidPress(UITagToButton(tag));
+ }
+}
+
+@end
diff --git a/ios/chrome/browser/infobars/confirm_infobar_delegate.mm b/ios/chrome/browser/infobars/confirm_infobar_delegate.mm
new file mode 100644
index 0000000..47493a0
--- /dev/null
+++ b/ios/chrome/browser/infobars/confirm_infobar_delegate.mm
@@ -0,0 +1,21 @@
+// Copyright 2014 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 "components/infobars/core/confirm_infobar_delegate.h"
+
+#include "base/mac/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
+#include "ios/chrome/browser/infobars/confirm_infobar_controller.h"
+#include "ios/chrome/browser/infobars/infobar.h"
+
+// This function is defined in the component, but implemented in the embedder.
+// static
+scoped_ptr<infobars::InfoBar> ConfirmInfoBarDelegate::CreateInfoBar(
+ scoped_ptr<ConfirmInfoBarDelegate> delegate) {
+ scoped_ptr<InfoBarIOS> infobar(new InfoBarIOS(delegate.Pass()));
+ base::scoped_nsobject<ConfirmInfoBarController> controller(
+ [[ConfirmInfoBarController alloc] initWithDelegate:infobar.get()]);
+ infobar->SetController(controller);
+ return infobar.Pass();
+}
diff --git a/ios/chrome/browser/infobars/infobar.h b/ios/chrome/browser/infobars/infobar.h
new file mode 100644
index 0000000..fead437
--- /dev/null
+++ b/ios/chrome/browser/infobars/infobar.h
@@ -0,0 +1,46 @@
+// Copyright 2012 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 IOS_CHROME_BROWSER_INFOBARS_INFOBAR_H_
+#define IOS_CHROME_BROWSER_INFOBARS_INFOBAR_H_
+
+#include "base/mac/scoped_nsobject.h"
+#include "components/infobars/core/infobar.h"
+#include "components/infobars/core/infobar_delegate.h"
+#include "ios/chrome/browser/infobars/infobar_controller.h"
+#import "ios/public/provider/chrome/browser/ui/infobar_view_delegate.h"
+
+// InfoBar for iOS acts as a UIViewController for InfoBarView.
+class InfoBarIOS : public infobars::InfoBar, public InfoBarViewDelegate {
+ public:
+ explicit InfoBarIOS(scoped_ptr<infobars::InfoBarDelegate> delegate);
+ ~InfoBarIOS() override;
+
+ // Layouts the infobar using data from delegate and prepare it for adding to
+ // superview.
+ void Layout(CGRect container_bounds);
+
+ // Returns UIView holding content of this infobar.
+ UIView* view();
+
+ // Remove the infobar view from infobar container view.
+ void RemoveView();
+
+ // Sets the controller. Should be called right after the infobar's creation.
+ void SetController(InfoBarController* controller);
+
+ private:
+ // InfoBar overrides:
+ void PlatformSpecificOnHeightsRecalculated() override;
+
+ // InfoBarViewDelegate:
+ void SetInfoBarTargetHeight(int height) override;
+ void InfoBarDidCancel() override;
+ void InfoBarButtonDidPress(NSUInteger button_id) override;
+
+ base::scoped_nsobject<InfoBarController> controller_;
+ DISALLOW_COPY_AND_ASSIGN(InfoBarIOS);
+};
+
+#endif // IOS_CHROME_BROWSER_INFOBARS_INFOBAR_H_
diff --git a/ios/chrome/browser/infobars/infobar.mm b/ios/chrome/browser/infobars/infobar.mm
new file mode 100644
index 0000000..65f9a89
--- /dev/null
+++ b/ios/chrome/browser/infobars/infobar.mm
@@ -0,0 +1,88 @@
+// Copyright 2012 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 "ios/chrome/browser/infobars/infobar.h"
+
+#include "base/logging.h"
+#include "components/infobars/core/confirm_infobar_delegate.h"
+#include "components/translate/core/browser/translate_infobar_delegate.h"
+#import "ios/chrome/browser/infobars/confirm_infobar_controller.h"
+
+using infobars::InfoBar;
+using infobars::InfoBarDelegate;
+
+InfoBarIOS::InfoBarIOS(scoped_ptr<InfoBarDelegate> delegate)
+ : InfoBar(delegate.Pass()) {
+}
+
+InfoBarIOS::~InfoBarIOS() {
+ DCHECK(controller_);
+ [controller_ detachView];
+ controller_.reset();
+}
+
+void InfoBarIOS::SetController(InfoBarController* controller) {
+ controller_.reset([controller retain]);
+}
+
+void InfoBarIOS::Layout(CGRect container_bounds) {
+ DCHECK(controller_);
+ if ([controller_ view]) {
+ [[controller_ view] setFrame:container_bounds];
+ } else {
+ [controller_ layoutForDelegate:delegate() frame:container_bounds];
+ }
+ SetBarTargetHeight([controller_ barHeight]);
+}
+
+UIView* InfoBarIOS::view() {
+ DCHECK(controller_);
+ return [controller_ view];
+}
+
+void InfoBarIOS::RemoveView() {
+ DCHECK(controller_);
+ [controller_ removeView];
+}
+
+void InfoBarIOS::PlatformSpecificOnHeightsRecalculated() {
+ DCHECK(controller_);
+ [controller_ onHeightsRecalculated:bar_height()];
+}
+
+#pragma mark - InfoBarViewDelegate
+
+void InfoBarIOS::SetInfoBarTargetHeight(int height) {
+ SetBarTargetHeight(height);
+}
+
+// Some infobar button was pressed.
+void InfoBarIOS::InfoBarButtonDidPress(NSUInteger button_id) {
+ // Do not add new logic for specific info bar delegates.
+ // TODO(droger): Move the logic elsewhere, http://crbug.com/307552.
+ // If not owned, the infobar has already been removed.
+ if (!owner())
+ return;
+ if (delegate()->AsConfirmInfoBarDelegate()) {
+ ConfirmInfoBarDelegate* confirmDelegate =
+ delegate()->AsConfirmInfoBarDelegate();
+ if ((button_id == ConfirmInfoBarDelegate::BUTTON_OK &&
+ confirmDelegate->Accept()) ||
+ (button_id == ConfirmInfoBarDelegate::BUTTON_CANCEL &&
+ delegate()->AsConfirmInfoBarDelegate()->Cancel())) {
+ RemoveSelf();
+ }
+ } else if (delegate()->AsTranslateInfoBarDelegate()) {
+ // TODO(droger): Upstream Translate infobars.
+ NOTREACHED() << "Translate infobars not upstreamed yet.";
+ }
+}
+
+void InfoBarIOS::InfoBarDidCancel() {
+ // If not owned, the infobar has already been removed.
+ if (!owner())
+ return;
+ delegate()->InfoBarDismissed();
+ RemoveSelf();
+}
diff --git a/ios/chrome/browser/infobars/infobar_container_ios.h b/ios/chrome/browser/infobars/infobar_container_ios.h
new file mode 100644
index 0000000..44db6c6
--- /dev/null
+++ b/ios/chrome/browser/infobars/infobar_container_ios.h
@@ -0,0 +1,45 @@
+// Copyright 2012 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 IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_IOS_H_
+#define IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_IOS_H_
+
+#include "components/infobars/core/infobar_container.h"
+
+#include "base/mac/scoped_nsobject.h"
+
+@class InfoBarContainerView;
+class InfoBarIOS;
+
+// IOS infobar container specialization, managing infobars visibility so
+// that only the front most one is visible at any time.
+class InfoBarContainerIOS : public infobars::InfoBarContainer {
+ public:
+ explicit InfoBarContainerIOS(infobars::InfoBarContainer::Delegate* delegate);
+ ~InfoBarContainerIOS() override;
+
+ // Returns the UIView container.
+ InfoBarContainerView* view();
+
+ // Hides the current infobar keeping the current state. If a new infobar is
+ // added, it will be hidden as well.
+ void SuspendInfobars();
+
+ // Restores the normal behavior of the infobars.
+ void RestoreInfobars();
+
+ protected:
+ void PlatformSpecificAddInfoBar(infobars::InfoBar* infobar,
+ size_t position) override;
+ void PlatformSpecificRemoveInfoBar(infobars::InfoBar* infobar) override;
+ void PlatformSpecificInfoBarStateChanged(bool is_animating) override;
+
+ private:
+ base::scoped_nsobject<InfoBarContainerView> container_view_;
+ InfoBarContainer::Delegate* delegate_;
+
+ DISALLOW_COPY_AND_ASSIGN(InfoBarContainerIOS);
+};
+
+#endif // IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_IOS_H_
diff --git a/ios/chrome/browser/infobars/infobar_container_ios.mm b/ios/chrome/browser/infobars/infobar_container_ios.mm
new file mode 100644
index 0000000..bd1223b
--- /dev/null
+++ b/ios/chrome/browser/infobars/infobar_container_ios.mm
@@ -0,0 +1,70 @@
+// Copyright 2012 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 "ios/chrome/browser/infobars/infobar_container_ios.h"
+
+#import <UIKit/UIKit.h>
+
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
+#include "ios/chrome/browser/infobars/infobar.h"
+#include "ios/chrome/browser/infobars/infobar_container_view.h"
+
+InfoBarContainerIOS::InfoBarContainerIOS(
+ infobars::InfoBarContainer::Delegate* delegate)
+ : InfoBarContainer(delegate), delegate_(delegate) {
+ DCHECK(delegate);
+ container_view_.reset([[InfoBarContainerView alloc] init]);
+ [container_view_ setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
+ UIViewAutoresizingFlexibleTopMargin];
+}
+
+InfoBarContainerIOS::~InfoBarContainerIOS() {
+ RemoveAllInfoBarsForDestruction();
+}
+
+InfoBarContainerView* InfoBarContainerIOS::view() {
+ return container_view_;
+}
+
+void InfoBarContainerIOS::PlatformSpecificAddInfoBar(infobars::InfoBar* infobar,
+ size_t position) {
+ InfoBarIOS* infobar_ios = static_cast<InfoBarIOS*>(infobar);
+ [container_view_ addInfoBar:infobar_ios position:position];
+}
+
+void InfoBarContainerIOS::PlatformSpecificRemoveInfoBar(
+ infobars::InfoBar* infobar) {
+ InfoBarIOS* infobar_ios = static_cast<InfoBarIOS*>(infobar);
+ infobar_ios->RemoveView();
+ // If total_height() is 0, then the infobar was removed after an animation. In
+ // this case, signal the delegate that the state changed.
+ // Otherwise, the infobar is being replaced by another one. Do not call the
+ // delegate in this case, as the delegate will be updated when the new infobar
+ // is added.
+ if (infobar->total_height() == 0)
+ delegate_->InfoBarContainerStateChanged(false);
+
+ // TODO(rohitrao, jif): [Merge 239355] Upstream InfoBarContainer deletes the
+ // infobar. Avoid deleting it here.
+ // crbug.com/327290
+ // base::MessageLoop::current()->DeleteSoon(FROM_HERE, infobar_ios);
+}
+
+void InfoBarContainerIOS::PlatformSpecificInfoBarStateChanged(
+ bool is_animating) {
+ [container_view_ setUserInteractionEnabled:!is_animating];
+ [container_view_ setNeedsLayout];
+}
+
+void InfoBarContainerIOS::SuspendInfobars() {
+ ios::GetChromeBrowserProvider()->SetUIViewAlphaWithAnimation(container_view_,
+ 0);
+}
+
+void InfoBarContainerIOS::RestoreInfobars() {
+ ios::GetChromeBrowserProvider()->SetUIViewAlphaWithAnimation(container_view_,
+ 1);
+}
diff --git a/ios/chrome/browser/infobars/infobar_container_view.h b/ios/chrome/browser/infobars/infobar_container_view.h
new file mode 100644
index 0000000..4d14f87
--- /dev/null
+++ b/ios/chrome/browser/infobars/infobar_container_view.h
@@ -0,0 +1,23 @@
+// Copyright 2012 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 IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_VIEW_H_
+#define IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_VIEW_H_
+
+#import <UIKit/UIKit.h>
+
+class InfoBarIOS;
+
+@interface InfoBarContainerView : UIView {
+}
+
+// Add a new infobar to the container view at position |position|.
+- (void)addInfoBar:(InfoBarIOS*)infoBarIOS position:(NSInteger)position;
+
+// Height of the frontmost infobar that is not hidden.
+- (CGFloat)topmostVisibleInfoBarHeight;
+
+@end
+
+#endif // IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTAINER_VIEW_H_
diff --git a/ios/chrome/browser/infobars/infobar_container_view.mm b/ios/chrome/browser/infobars/infobar_container_view.mm
new file mode 100644
index 0000000..ccd9f99
--- /dev/null
+++ b/ios/chrome/browser/infobars/infobar_container_view.mm
@@ -0,0 +1,57 @@
+// Copyright 2012 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 "ios/chrome/browser/infobars/infobar_container_view.h"
+
+#include "base/logging.h"
+#include "ios/chrome/browser/infobars/infobar.h"
+#include "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#include "ui/base/device_form_factor.h"
+
+@implementation InfoBarContainerView
+
+- (void)addInfoBar:(InfoBarIOS*)infoBarIOS position:(NSInteger)position {
+ DCHECK_LE((NSUInteger)position, [[self subviews] count]);
+ CGRect containerBounds = [self bounds];
+ infoBarIOS->Layout(containerBounds);
+ UIView* view = infoBarIOS->view();
+ [self insertSubview:view atIndex:position];
+}
+
+- (CGSize)sizeThatFits:(CGSize)size {
+ CGFloat height = 0;
+ if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) {
+ for (UIView* view in self.subviews) {
+ CGSize elementSize = [view sizeThatFits:size];
+ height += elementSize.height;
+ }
+ } else {
+ for (UIView* view in self.subviews) {
+ CGFloat elementHeight = [view sizeThatFits:size].height;
+ if (elementHeight > height)
+ height = elementHeight;
+ }
+ }
+ size.height = height;
+ return size;
+}
+
+- (void)layoutSubviews {
+ for (UIView<InfoBarViewProtocol>* view in self.subviews) {
+ [view sizeToFit];
+ CGRect frame = view.frame;
+ frame.origin.y = CGRectGetHeight(frame) - [view visibleHeight];
+ [view setFrame:frame];
+ }
+}
+
+- (CGFloat)topmostVisibleInfoBarHeight {
+ for (UIView<InfoBarViewProtocol>* view in
+ [self.subviews reverseObjectEnumerator]) {
+ return [view sizeThatFits:self.frame.size].height;
+ }
+ return 0;
+}
+
+@end
diff --git a/ios/chrome/browser/infobars/infobar_controller.h b/ios/chrome/browser/infobars/infobar_controller.h
new file mode 100644
index 0000000..14b6dda
--- /dev/null
+++ b/ios/chrome/browser/infobars/infobar_controller.h
@@ -0,0 +1,51 @@
+// Copyright 2012 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 IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTROLLER_H_
+#define IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTROLLER_H_
+
+#import <UIKit/UIKit.h>
+
+#include "base/basictypes.h"
+#include "base/mac/scoped_nsobject.h"
+#include "base/memory/scoped_ptr.h"
+#include "components/infobars/core/infobar.h"
+
+@protocol InfoBarViewProtocol;
+class InfoBarViewDelegate;
+
+// InfoBar for iOS acts as a UIViewController for InfoBarView.
+@interface InfoBarController : NSObject {
+ @protected
+ base::scoped_nsobject<UIView<InfoBarViewProtocol>> infoBarView_;
+ __weak InfoBarViewDelegate* delegate_;
+}
+
+// Creates a view and lays out all the infobar elements in it. Will not add
+// it as a subview yet. This method must be overriden in subclasses.
+- (void)layoutForDelegate:(infobars::InfoBarDelegate*)delegate
+ frame:(CGRect)bounds;
+
+// Designated initializer.
+- (instancetype)initWithDelegate:(InfoBarViewDelegate*)delegate;
+
+// Detaches view from its delegate.
+// After this function is called, no user interaction can be handled.
+- (void)detachView;
+
+// Returns the actual height in pixels of this infobar instance.
+- (int)barHeight;
+
+// Adjusts visible portion of this infobar.
+- (void)onHeightsRecalculated:(int)newHeight;
+
+// Removes the view.
+- (void)removeView;
+
+// Accesses the view.
+- (UIView*)view;
+
+@end
+
+#endif // IOS_CHROME_BROWSER_INFOBARS_INFOBAR_CONTROLLER_H_
diff --git a/ios/chrome/browser/infobars/infobar_controller.mm b/ios/chrome/browser/infobars/infobar_controller.mm
new file mode 100644
index 0000000..ac999fd
--- /dev/null
+++ b/ios/chrome/browser/infobars/infobar_controller.mm
@@ -0,0 +1,56 @@
+// Copyright 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 "ios/chrome/browser/infobars/infobar_controller.h"
+
+#include "base/mac/foundation_util.h"
+#include "base/strings/sys_string_conversions.h"
+#include "components/infobars/core/confirm_infobar_delegate.h"
+#import "ios/public/provider/chrome/browser/ui/infobar_view_protocol.h"
+#include "ui/gfx/image/image.h"
+
+@implementation InfoBarController
+
+- (instancetype)initWithDelegate:(InfoBarViewDelegate*)delegate {
+ self = [super init];
+ if (self) {
+ DCHECK(delegate);
+ delegate_ = delegate;
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [infoBarView_ removeFromSuperview];
+ [super dealloc];
+}
+
+- (int)barHeight {
+ return CGRectGetHeight([infoBarView_ frame]);
+}
+
+- (void)layoutForDelegate:(infobars::InfoBarDelegate*)delegate
+ frame:(CGRect)bounds {
+ // Must be overriden in subclasses.
+ NOTREACHED();
+}
+
+- (void)onHeightsRecalculated:(int)newHeight {
+ [infoBarView_ setVisibleHeight:newHeight];
+}
+
+- (UIView*)view {
+ return infoBarView_;
+}
+
+- (void)removeView {
+ [infoBarView_ removeFromSuperview];
+}
+
+- (void)detachView {
+ [infoBarView_ resetDelegate];
+ delegate_ = nullptr;
+}
+
+@end
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp
index 7edf066..768b753 100644
--- a/ios/chrome/ios_chrome.gyp
+++ b/ios/chrome/ios_chrome.gyp
@@ -15,10 +15,12 @@
],
'dependencies': [
'../../base/base.gyp:base',
+ '../../components/components.gyp:infobars_core',
'../../components/components.gyp:keyed_service_core',
'../../components/components.gyp:keyed_service_ios',
'../../components/components.gyp:leveldb_proto',
'../../components/components.gyp:suggestions',
+ '../../components/components.gyp:translate_core_browser',
'../../net/net.gyp:net',
'../../skia/skia.gyp:skia',
'../../url/url.gyp:url_lib',
@@ -26,6 +28,17 @@
'../web/ios_web.gyp:ios_web',
],
'sources': [
+ 'browser/infobars/confirm_infobar_controller.h',
+ 'browser/infobars/confirm_infobar_controller.mm',
+ 'browser/infobars/confirm_infobar_delegate.mm',
+ 'browser/infobars/infobar.h',
+ 'browser/infobars/infobar.mm',
+ 'browser/infobars/infobar_container_ios.h',
+ 'browser/infobars/infobar_container_ios.mm',
+ 'browser/infobars/infobar_container_view.h',
+ 'browser/infobars/infobar_container_view.mm',
+ 'browser/infobars/infobar_controller.h',
+ 'browser/infobars/infobar_controller.mm',
'browser/net/image_fetcher.h',
'browser/net/image_fetcher.mm',
'browser/suggestions/image_fetcher_impl.h',