diff options
author | droger@chromium.org <droger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-18 15:09:41 +0000 |
---|---|---|
committer | droger@chromium.org <droger@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-18 15:09:41 +0000 |
commit | 051655ad35d7b3c442ba1df8880da91123bf9bc9 (patch) | |
tree | 25d7d1fa8cb99621c927f1deb2707e1d7b3d0fc6 /components | |
parent | 8e37bf2199e37e270163eb407fab789c4ba77846 (diff) | |
download | chromium_src-051655ad35d7b3c442ba1df8880da91123bf9bc9.zip chromium_src-051655ad35d7b3c442ba1df8880da91123bf9bc9.tar.gz chromium_src-051655ad35d7b3c442ba1df8880da91123bf9bc9.tar.bz2 |
Move Infobars core files to the Infobars component
This CL sets up the directory structure for the Infobars component and the
infobars_core target. It also does a simple code move to the compoonent.
This CL does not move ConfirmInfoBarDelegate because it still has a
dependency on chrome/ (for strings).
BUG=354379
TBR=sky, reed
Review URL: https://codereview.chromium.org/240193003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@264792 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components')
-rw-r--r-- | components/OWNERS | 2 | ||||
-rw-r--r-- | components/components.gyp | 1 | ||||
-rw-r--r-- | components/infobars.gypi | 32 | ||||
-rw-r--r-- | components/infobars/DEPS | 8 | ||||
-rw-r--r-- | components/infobars/OWNERS | 1 | ||||
-rw-r--r-- | components/infobars/README | 7 | ||||
-rw-r--r-- | components/infobars/core/infobar.cc | 179 | ||||
-rw-r--r-- | components/infobars/core/infobar.h | 153 | ||||
-rw-r--r-- | components/infobars/core/infobar_container.cc | 178 | ||||
-rw-r--r-- | components/infobars/core/infobar_container.h | 137 | ||||
-rw-r--r-- | components/infobars/core/infobar_delegate.cc | 111 | ||||
-rw-r--r-- | components/infobars/core/infobar_delegate.h | 148 | ||||
-rw-r--r-- | components/infobars/core/infobar_manager.cc | 141 | ||||
-rw-r--r-- | components/infobars/core/infobar_manager.h | 124 | ||||
-rw-r--r-- | components/infobars/core/infobars_switches.cc | 14 | ||||
-rw-r--r-- | components/infobars/core/infobars_switches.h | 16 |
16 files changed, 1252 insertions, 0 deletions
diff --git a/components/OWNERS b/components/OWNERS index 5024899..6f9da6d 100644 --- a/components/OWNERS +++ b/components/OWNERS @@ -43,6 +43,8 @@ per-file favicon*=blundell@chromium.org # Temporary for the duration of the favicon componentization. per-file favicon*=droger@chromium.org +per-file infobars.gypi=pkasting@chromium.org + per-file json_schema.gypi=asargent@chromium.org per-file json_schema.gypi=calamity@chromium.org per-file json_schema.gypi=kalman@chromium.org diff --git a/components/components.gyp b/components/components.gyp index cb2052a..aa4c7ac 100644 --- a/components/components.gyp +++ b/components/components.gyp @@ -21,6 +21,7 @@ 'domain_reliability.gypi', 'favicon.gypi', 'favicon_base.gypi', + 'infobars.gypi', 'json_schema.gypi', 'keyed_service.gypi', 'language_usage_metrics.gypi', diff --git a/components/infobars.gypi b/components/infobars.gypi new file mode 100644 index 0000000..7ca15b5 --- /dev/null +++ b/components/infobars.gypi @@ -0,0 +1,32 @@ +# 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. + +{ + 'targets': [ + { + 'target_name': 'infobars_core', + 'type': 'static_library', + 'include_dirs': [ + '..', + ], + 'dependencies': [ + '../base/base.gyp:base', + '../skia/skia.gyp:skia', + '../ui/gfx/gfx.gyp:gfx', + ], + 'sources': [ + 'infobars/core/infobar.cc', + 'infobars/core/infobar.h', + 'infobars/core/infobar_container.cc', + 'infobars/core/infobar_container.h', + 'infobars/core/infobar_delegate.cc', + 'infobars/core/infobar_delegate.h', + 'infobars/core/infobar_manager.cc', + 'infobars/core/infobar_manager.h', + 'infobars/core/infobars_switches.cc', + 'infobars/core/infobars_switches.h', + ], + }, + ], +} diff --git a/components/infobars/DEPS b/components/infobars/DEPS new file mode 100644 index 0000000..4f66f6c --- /dev/null +++ b/components/infobars/DEPS @@ -0,0 +1,8 @@ +include_rules = [ + # Infobars is a layered component; subdirectories must explicitly introduce + # the ability to use the content layer as appropriate. + "-content", + + "+ui", + "+third_party/skia" +] diff --git a/components/infobars/OWNERS b/components/infobars/OWNERS new file mode 100644 index 0000000..bf426d6 --- /dev/null +++ b/components/infobars/OWNERS @@ -0,0 +1 @@ +pkasting@chromium.org diff --git a/components/infobars/README b/components/infobars/README new file mode 100644 index 0000000..8b736f1 --- /dev/null +++ b/components/infobars/README @@ -0,0 +1,7 @@ +- Infobars is a layered component +(https://sites.google.com/a/chromium.org/dev/developers/design-documents/layered-components-design) +to enable it to be shared cleanly on iOS. + +Directory structure: +core/: shared code that does not depend on src/content/ +content/: Driver for the shared code based on the content layer. diff --git a/components/infobars/core/infobar.cc b/components/infobars/core/infobar.cc new file mode 100644 index 0000000..1ddfffd --- /dev/null +++ b/components/infobars/core/infobar.cc @@ -0,0 +1,179 @@ +// 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/infobar.h" + +#include <cmath> + +#include "base/logging.h" +#include "build/build_config.h" +#include "components/infobars/core/infobar_container.h" +#include "components/infobars/core/infobar_manager.h" +#include "ui/gfx/animation/slide_animation.h" + +namespace infobars { + +InfoBar::InfoBar(scoped_ptr<InfoBarDelegate> delegate) + : owner_(NULL), + delegate_(delegate.Pass()), + container_(NULL), + animation_(this), + arrow_height_(0), + arrow_target_height_(kDefaultArrowTargetHeight), + arrow_half_width_(0), + bar_height_(0), + bar_target_height_(kDefaultBarTargetHeight) { + DCHECK(delegate_ != NULL); + animation_.SetTweenType(gfx::Tween::LINEAR); + delegate_->set_infobar(this); +} + +InfoBar::~InfoBar() { + DCHECK(!owner_); +} + +// static +SkColor InfoBar::GetTopColor(InfoBarDelegate::Type infobar_type) { + static const SkColor kWarningBackgroundColorTop = + SkColorSetRGB(255, 242, 183); // Yellow + static const SkColor kPageActionBackgroundColorTop = + SkColorSetRGB(237, 237, 237); // Gray + return (infobar_type == InfoBarDelegate::WARNING_TYPE) ? + kWarningBackgroundColorTop : kPageActionBackgroundColorTop; +} + +// static +SkColor InfoBar::GetBottomColor(InfoBarDelegate::Type infobar_type) { + static const SkColor kWarningBackgroundColorBottom = + SkColorSetRGB(250, 230, 145); // Yellow + static const SkColor kPageActionBackgroundColorBottom = + SkColorSetRGB(217, 217, 217); // Gray + return (infobar_type == InfoBarDelegate::WARNING_TYPE) ? + kWarningBackgroundColorBottom : kPageActionBackgroundColorBottom; +} + +void InfoBar::SetOwner(InfoBarManager* owner) { + DCHECK(!owner_); + owner_ = owner; + delegate_->StoreActiveEntryUniqueID(); + PlatformSpecificSetOwner(); +} + +void InfoBar::Show(bool animate) { + PlatformSpecificShow(animate); + if (animate) { + animation_.Show(); + } else { + animation_.Reset(1.0); + RecalculateHeights(true); + } +} + +void InfoBar::Hide(bool animate) { + PlatformSpecificHide(animate); + if (animate) { + animation_.Hide(); + } else { + animation_.Reset(0.0); + // We want to remove ourselves from the container immediately even if we + // still have an owner, which MaybeDelete() won't do. + DCHECK(container_); + container_->RemoveInfoBar(this); + MaybeDelete(); // Necessary if the infobar was already closing. + } +} + +void InfoBar::SetArrowTargetHeight(int height) { + DCHECK_LE(height, kMaximumArrowTargetHeight); + // Once the closing animation starts, we ignore further requests to change the + // target height. + if ((arrow_target_height_ != height) && !animation_.IsClosing()) { + arrow_target_height_ = height; + RecalculateHeights(false); + } +} + +void InfoBar::CloseSoon() { + owner_ = NULL; + PlatformSpecificOnCloseSoon(); + MaybeDelete(); +} + +void InfoBar::RemoveSelf() { + if (owner_) + owner_->RemoveInfoBar(this); +} + +void InfoBar::SetBarTargetHeight(int height) { + if (bar_target_height_ != height) { + bar_target_height_ = height; + RecalculateHeights(false); + } +} + +void InfoBar::AnimationProgressed(const gfx::Animation* animation) { + RecalculateHeights(false); +} + +void InfoBar::AnimationEnded(const gfx::Animation* animation) { + // When the animation ends, we must ensure the container is notified even if + // the heights haven't changed, lest it never get an "animation finished" + // notification. (If the browser doesn't get this notification, it will not + // bother to re-layout the content area for the new infobar size.) + RecalculateHeights(true); + MaybeDelete(); +} + +void InfoBar::RecalculateHeights(bool force_notify) { + int old_arrow_height = arrow_height_; + int old_bar_height = bar_height_; + + // Find the desired arrow height/half-width. The arrow area is + // |arrow_height_| * |arrow_half_width_|. When the bar is opening or closing, + // scaling each of these with the square root of the animation value causes a + // linear animation of the area, which matches the perception of the animation + // of the bar portion. + double scale_factor = sqrt(animation_.GetCurrentValue()); + arrow_height_ = static_cast<int>(arrow_target_height_ * scale_factor); + if (animation_.is_animating()) { + arrow_half_width_ = static_cast<int>(std::min(arrow_target_height_, + kMaximumArrowTargetHalfWidth) * scale_factor); + } else { + // When the infobar is not animating (i.e. fully open), we set the + // half-width to be proportionally the same distance between its default and + // maximum values as the height is between its. + arrow_half_width_ = kDefaultArrowTargetHalfWidth + + ((kMaximumArrowTargetHalfWidth - kDefaultArrowTargetHalfWidth) * + ((arrow_height_ - kDefaultArrowTargetHeight) / + (kMaximumArrowTargetHeight - kDefaultArrowTargetHeight))); + } + // Add pixels for the stroke, if the arrow is to be visible at all. Without + // this, changing the arrow height from 0 to kSeparatorLineHeight would + // produce no visible effect, because the stroke would paint atop the divider + // line above the infobar. + if (arrow_height_) + arrow_height_ += kSeparatorLineHeight; + + bar_height_ = animation_.CurrentValueBetween(0, bar_target_height_); + + // Don't re-layout if nothing has changed, e.g. because the animation step was + // not large enough to actually change the heights by at least a pixel. + bool heights_differ = + (old_arrow_height != arrow_height_) || (old_bar_height != bar_height_); + if (heights_differ) + PlatformSpecificOnHeightsRecalculated(); + + if (container_ && (heights_differ || force_notify)) + container_->OnInfoBarStateChanged(animation_.is_animating()); +} + +void InfoBar::MaybeDelete() { + if (!owner_ && (animation_.GetCurrentValue() == 0.0)) { + if (container_) + container_->RemoveInfoBar(this); + delete this; + } +} + +} // namespace infobars diff --git a/components/infobars/core/infobar.h b/components/infobars/core/infobar.h new file mode 100644 index 0000000..9aef299 --- /dev/null +++ b/components/infobars/core/infobar.h @@ -0,0 +1,153 @@ +// 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. + +#ifndef COMPONENTS_INFOBARS_CORE_INFOBAR_H_ +#define COMPONENTS_INFOBARS_CORE_INFOBAR_H_ + +#include <utility> + +#include "base/memory/scoped_ptr.h" +#include "components/infobars/core/infobar_delegate.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/animation/animation_delegate.h" +#include "ui/gfx/animation/slide_animation.h" +#include "ui/gfx/size.h" + +namespace infobars { + +class InfoBarContainer; +class InfoBarManager; + +// InfoBar is a cross-platform base class for an infobar "view" (in the MVC +// sense), which owns a corresponding InfoBarDelegate "model". Typically, +// a caller will call XYZInfoBarDelegate::Create() and pass in the +// InfoBarManager for the relevant tab. This will create an XYZInfoBarDelegate, +// create a platform-specific subclass of InfoBar to own it, and then call +// InfoBarManager::AddInfoBar() to give it ownership of the infobar. +// During its life, the InfoBar may be shown and hidden as the owning tab is +// switched between the foreground and background. Eventually, InfoBarManager +// will instruct the InfoBar to close itself. At this point, the InfoBar will +// optionally animate closed; once it's no longer visible, it deletes itself, +// destroying the InfoBarDelegate in the process. +// +// Thus, InfoBarDelegate and InfoBar implementations can assume they share +// lifetimes, and not NULL-check each other; but if one needs to reach back into +// the owning InfoBarManager, it must check whether that's still possible. +class InfoBar : public gfx::AnimationDelegate { + public: + // These are the types passed as Details for infobar-related notifications. + typedef InfoBar AddedDetails; + typedef std::pair<InfoBar*, bool> RemovedDetails; + typedef std::pair<InfoBar*, InfoBar*> ReplacedDetails; + + // Platforms must define these. + static const int kDefaultBarTargetHeight; + static const int kSeparatorLineHeight; + static const int kDefaultArrowTargetHeight; + static const int kMaximumArrowTargetHeight; + // The half-width (see comments on |arrow_half_width_| below) scales to its + // default and maximum values proportionally to how the height scales to its. + static const int kDefaultArrowTargetHalfWidth; + static const int kMaximumArrowTargetHalfWidth; + + explicit InfoBar(scoped_ptr<InfoBarDelegate> delegate); + virtual ~InfoBar(); + + static SkColor GetTopColor(InfoBarDelegate::Type infobar_type); + static SkColor GetBottomColor(InfoBarDelegate::Type infobar_type); + + InfoBarManager* owner() { return owner_; } + InfoBarDelegate* delegate() { return delegate_.get(); } + const InfoBarDelegate* delegate() const { return delegate_.get(); } + void set_container(InfoBarContainer* container) { container_ = container; } + + // Sets |owner_|. This also calls StoreActiveEntryUniqueID() on |delegate_|. + // This must only be called once as there's no way to extract an infobar from + // its owner without deleting it, for reparenting in another tab. + void SetOwner(InfoBarManager* owner); + + // Makes the infobar visible. If |animate| is true, the infobar is then + // animated to full size. + void Show(bool animate); + + // Makes the infobar hidden. If |animate| is false, the infobar is + // immediately removed from the container, and, if now unowned, deleted. If + // |animate| is true, the infobar is animated to zero size, ultimately + // triggering a call to AnimationEnded(). + void Hide(bool animate); + + // Changes the target height of the arrow portion of the infobar. This has no + // effect once the infobar is animating closed. + void SetArrowTargetHeight(int height); + + // Notifies the infobar that it is no longer owned and should delete itself + // once it is invisible. + void CloseSoon(); + + // Forwards a close request to our owner. This is a no-op if we're already + // unowned. + void RemoveSelf(); + + // Changes the target height of the main ("bar") portion of the infobar. + void SetBarTargetHeight(int height); + + const gfx::SlideAnimation& animation() const { return animation_; } + int arrow_height() const { return arrow_height_; } + int arrow_target_height() const { return arrow_target_height_; } + int arrow_half_width() const { return arrow_half_width_; } + int total_height() const { return arrow_height_ + bar_height_; } + + protected: + // gfx::AnimationDelegate: + virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; + + const InfoBarContainer* container() const { return container_; } + InfoBarContainer* container() { return container_; } + gfx::SlideAnimation* animation() { return &animation_; } + int bar_height() const { return bar_height_; } + int bar_target_height() const { return bar_target_height_; } + + // Platforms may optionally override these if they need to do work during + // processing of the given calls. + virtual void PlatformSpecificSetOwner() {} + virtual void PlatformSpecificShow(bool animate) {} + virtual void PlatformSpecificHide(bool animate) {} + virtual void PlatformSpecificOnCloseSoon() {} + virtual void PlatformSpecificOnHeightsRecalculated() {} + + private: + // gfx::AnimationDelegate: + virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; + + // Finds the new desired arrow and bar heights, and if they differ from the + // current ones, calls PlatformSpecificOnHeightRecalculated(). Informs our + // container our state has changed if either the heights have changed or + // |force_notify| is set. + void RecalculateHeights(bool force_notify); + + // Checks whether the infobar is unowned and done with all animations. If so, + // notifies the container that it should remove this infobar, and deletes + // itself. + void MaybeDelete(); + + InfoBarManager* owner_; + scoped_ptr<InfoBarDelegate> delegate_; + InfoBarContainer* container_; + gfx::SlideAnimation animation_; + + // The current and target heights of the arrow and bar portions, and half the + // current arrow width. (It's easier to work in half-widths as we draw the + // arrow as two halves on either side of a center point.) + int arrow_height_; // Includes both fill and top stroke. + int arrow_target_height_; + int arrow_half_width_; // Includes only fill. + int bar_height_; // Includes both fill and bottom separator. + int bar_target_height_; + + DISALLOW_COPY_AND_ASSIGN(InfoBar); +}; + +} // namespace infobars + +#endif // COMPONENTS_INFOBARS_CORE_INFOBAR_H_ diff --git a/components/infobars/core/infobar_container.cc b/components/infobars/core/infobar_container.cc new file mode 100644 index 0000000..f435dd7 --- /dev/null +++ b/components/infobars/core/infobar_container.cc @@ -0,0 +1,178 @@ +// 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/infobar_container.h" + +#include <algorithm> + +#include "base/logging.h" +#include "build/build_config.h" +#include "components/infobars/core/infobar.h" +#include "components/infobars/core/infobar_delegate.h" +#include "ui/gfx/animation/slide_animation.h" + +namespace infobars { + +InfoBarContainer::Delegate::~Delegate() { +} + +InfoBarContainer::InfoBarContainer(Delegate* delegate) + : delegate_(delegate), + infobar_manager_(NULL), + top_arrow_target_height_(InfoBar::kDefaultArrowTargetHeight) { +} + +InfoBarContainer::~InfoBarContainer() { + // RemoveAllInfoBarsForDestruction() should have already cleared our infobars. + DCHECK(infobars_.empty()); + if (infobar_manager_) + infobar_manager_->RemoveObserver(this); +} + +void InfoBarContainer::ChangeInfoBarManager(InfoBarManager* infobar_manager) { + if (infobar_manager_) + infobar_manager_->RemoveObserver(this); + + // Hides all infobars in this container without animation. + while (!infobars_.empty()) { + InfoBar* infobar = infobars_.front(); + // Inform the infobar that it's hidden. If it was already closing, this + // deletes it. Otherwise, this ensures the infobar will be deleted if it's + // closed while it's not in an InfoBarContainer. + infobar->Hide(false); + } + + infobar_manager_ = infobar_manager; + if (infobar_manager_) { + infobar_manager_->AddObserver(this); + + for (size_t i = 0; i < infobar_manager_->infobar_count(); ++i) { + // As when we removed the infobars above, we prevent callbacks to + // OnInfoBarStateChanged() for each infobar. + AddInfoBar(infobar_manager_->infobar_at(i), i, false, NO_CALLBACK); + } + } + + // Now that everything is up to date, signal the delegate to re-layout. + OnInfoBarStateChanged(false); +} + +int InfoBarContainer::GetVerticalOverlap(int* total_height) { + // Our |total_height| is the sum of the preferred heights of the InfoBars + // contained within us plus the |vertical_overlap|. + int vertical_overlap = 0; + int next_infobar_y = 0; + + for (InfoBars::iterator i(infobars_.begin()); i != infobars_.end(); ++i) { + InfoBar* infobar = *i; + next_infobar_y -= infobar->arrow_height(); + vertical_overlap = std::max(vertical_overlap, -next_infobar_y); + next_infobar_y += infobar->total_height(); + } + + if (total_height) + *total_height = next_infobar_y + vertical_overlap; + return vertical_overlap; +} + +void InfoBarContainer::SetMaxTopArrowHeight(int height) { + // Decrease the height by the arrow stroke thickness, which is the separator + // line height, because the infobar arrow target heights are without-stroke. + top_arrow_target_height_ = std::min( + std::max(height - InfoBar::kSeparatorLineHeight, 0), + InfoBar::kMaximumArrowTargetHeight); + UpdateInfoBarArrowTargetHeights(); +} + +void InfoBarContainer::OnInfoBarStateChanged(bool is_animating) { + if (delegate_) + delegate_->InfoBarContainerStateChanged(is_animating); + UpdateInfoBarArrowTargetHeights(); + PlatformSpecificInfoBarStateChanged(is_animating); +} + +void InfoBarContainer::RemoveInfoBar(InfoBar* infobar) { + infobar->set_container(NULL); + InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar)); + DCHECK(i != infobars_.end()); + PlatformSpecificRemoveInfoBar(infobar); + infobars_.erase(i); +} + +void InfoBarContainer::RemoveAllInfoBarsForDestruction() { + // Before we remove any children, we reset |delegate_|, so that no removals + // will result in us trying to call + // delegate_->InfoBarContainerStateChanged(). This is important because at + // this point |delegate_| may be shutting down, and it's at best unimportant + // and at worst disastrous to call that. + delegate_ = NULL; + ChangeInfoBarManager(NULL); +} + +void InfoBarContainer::OnInfoBarAdded(InfoBar* infobar) { + AddInfoBar(infobar, infobars_.size(), true, WANT_CALLBACK); +} + +void InfoBarContainer::OnInfoBarRemoved(InfoBar* infobar, bool animate) { + infobar->Hide(animate); + UpdateInfoBarArrowTargetHeights(); +} + +void InfoBarContainer::OnInfoBarReplaced(InfoBar* old_infobar, + InfoBar* new_infobar) { + PlatformSpecificReplaceInfoBar(old_infobar, new_infobar); + InfoBars::const_iterator i(std::find(infobars_.begin(), infobars_.end(), + old_infobar)); + DCHECK(i != infobars_.end()); + size_t position = i - infobars_.begin(); + old_infobar->Hide(false); + AddInfoBar(new_infobar, position, false, WANT_CALLBACK); +} + +void InfoBarContainer::OnManagerShuttingDown(InfoBarManager* manager) { + DCHECK_EQ(infobar_manager_, manager); + infobar_manager_->RemoveObserver(this); + infobar_manager_ = NULL; +} + +void InfoBarContainer::AddInfoBar(InfoBar* infobar, + size_t position, + bool animate, + CallbackStatus callback_status) { + DCHECK(std::find(infobars_.begin(), infobars_.end(), infobar) == + infobars_.end()); + DCHECK_LE(position, infobars_.size()); + infobars_.insert(infobars_.begin() + position, infobar); + UpdateInfoBarArrowTargetHeights(); + PlatformSpecificAddInfoBar(infobar, position); + if (callback_status == WANT_CALLBACK) + infobar->set_container(this); + infobar->Show(animate); + if (callback_status == NO_CALLBACK) + infobar->set_container(this); +} + +void InfoBarContainer::UpdateInfoBarArrowTargetHeights() { + for (size_t i = 0; i < infobars_.size(); ++i) + infobars_[i]->SetArrowTargetHeight(ArrowTargetHeightForInfoBar(i)); +} + +int InfoBarContainer::ArrowTargetHeightForInfoBar(size_t infobar_index) const { + if (!delegate_ || !delegate_->DrawInfoBarArrows(NULL)) + return 0; + if (infobar_index == 0) + return top_arrow_target_height_; + const gfx::SlideAnimation& first_infobar_animation = + const_cast<const InfoBar*>(infobars_.front())->animation(); + if ((infobar_index > 1) || first_infobar_animation.IsShowing()) + return InfoBar::kDefaultArrowTargetHeight; + // When the first infobar is animating closed, we animate the second infobar's + // arrow target height from the default to the top target height. Note that + // the animation values here are going from 1.0 -> 0.0 as the top bar closes. + return top_arrow_target_height_ + static_cast<int>( + (InfoBar::kDefaultArrowTargetHeight - top_arrow_target_height_) * + first_infobar_animation.GetCurrentValue()); +} + +} // namespace infobars diff --git a/components/infobars/core/infobar_container.h b/components/infobars/core/infobar_container.h new file mode 100644 index 0000000..6663821 --- /dev/null +++ b/components/infobars/core/infobar_container.h @@ -0,0 +1,137 @@ +// 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. + +#ifndef COMPONENTS_INFOBARS_CORE_INFOBAR_CONTAINER_H_ +#define COMPONENTS_INFOBARS_CORE_INFOBAR_CONTAINER_H_ + +#include <vector> + +#include "base/compiler_specific.h" +#include "base/time/time.h" +#include "components/infobars/core/infobar_manager.h" +#include "third_party/skia/include/core/SkColor.h" + +namespace infobars { + +class InfoBar; + +// InfoBarContainer is a cross-platform base class to handle the visibility- +// related aspects of InfoBars. While InfoBarManager owns the InfoBars, the +// InfoBarContainer is responsible for telling particular InfoBars that they +// should be hidden or visible. +// +// Platforms need to subclass this to implement a few platform-specific +// functions, which are pure virtual here. +class InfoBarContainer : public InfoBarManager::Observer { + public: + class Delegate { + public: + // The separator color may vary depending on where the container is hosted. + virtual SkColor GetInfoBarSeparatorColor() const = 0; + + // The delegate is notified each time the infobar container changes height, + // as well as when it stops animating. + virtual void InfoBarContainerStateChanged(bool is_animating) = 0; + + // The delegate needs to tell us whether "unspoofable" arrows should be + // drawn, and if so, at what |x| coordinate. |x| may be NULL. + virtual bool DrawInfoBarArrows(int* x) const = 0; + + protected: + virtual ~Delegate(); + }; + + explicit InfoBarContainer(Delegate* delegate); + virtual ~InfoBarContainer(); + + // Changes the InfoBarManager for which this container is showing infobars. + // This will hide all current infobars, remove them from the container, add + // the infobars from |infobar_manager|, and show them all. |infobar_manager| + // may be NULL. + void ChangeInfoBarManager(InfoBarManager* infobar_manager); + + // Returns the amount by which to overlap the toolbar above, and, when + // |total_height| is non-NULL, set it to the height of the InfoBarContainer + // (including overlap). + int GetVerticalOverlap(int* total_height); + + // Called by the delegate when the distance between what the top infobar's + // "unspoofable" arrow would point to and the top infobar itself changes. + // This enables the top infobar to show a longer arrow (e.g. because of a + // visible bookmark bar) or shorter (e.g. due to being in a popup window) if + // desired. + // + // IMPORTANT: This MUST NOT result in a call back to + // Delegate::InfoBarContainerStateChanged() unless it causes an actual + // change, lest we infinitely recurse. + void SetMaxTopArrowHeight(int height); + + // Called when a contained infobar has animated or by some other means changed + // its height, or when it stops animating. The container is expected to do + // anything necessary to respond, e.g. re-layout. + void OnInfoBarStateChanged(bool is_animating); + + // Called by |infobar| to request that it be removed from the container. At + // this point, |infobar| should already be hidden. + void RemoveInfoBar(InfoBar* infobar); + + const Delegate* delegate() const { return delegate_; } + + protected: + // Subclasses must call this during destruction, so that we can remove + // infobars (which will call the pure virtual functions below) while the + // subclass portion of |this| has not yet been destroyed. + void RemoveAllInfoBarsForDestruction(); + + // These must be implemented on each platform to e.g. adjust the visible + // object hierarchy. The first two functions should each be called exactly + // once during an infobar's life (see comments on RemoveInfoBar() and + // AddInfoBar()). + virtual void PlatformSpecificAddInfoBar(InfoBar* infobar, + size_t position) = 0; + // TODO(miguelg): Remove this; it is only necessary for Android, and only + // until the translate infobar is implemented as three different infobars like + // GTK does. + virtual void PlatformSpecificReplaceInfoBar(InfoBar* old_infobar, + InfoBar* new_infobar) {} + virtual void PlatformSpecificRemoveInfoBar(InfoBar* infobar) = 0; + virtual void PlatformSpecificInfoBarStateChanged(bool is_animating) {} + + private: + typedef std::vector<InfoBar*> InfoBars; + + // InfoBarManager::Observer: + virtual void OnInfoBarAdded(InfoBar* infobar) OVERRIDE; + virtual void OnInfoBarRemoved(InfoBar* infobar, bool animate) OVERRIDE; + virtual void OnInfoBarReplaced(InfoBar* old_infobar, + InfoBar* new_infobar) OVERRIDE; + virtual void OnManagerShuttingDown(InfoBarManager* manager) OVERRIDE; + + // Adds |infobar| to this container before the existing infobar at position + // |position| and calls Show() on it. |animate| is passed along to + // infobar->Show(). Depending on the value of |callback_status|, this calls + // infobar->set_container(this) either before or after the call to Show() so + // that OnInfoBarStateChanged() either will or won't be called as a result. + enum CallbackStatus { NO_CALLBACK, WANT_CALLBACK }; + void AddInfoBar(InfoBar* infobar, + size_t position, + bool animate, + CallbackStatus callback_status); + + void UpdateInfoBarArrowTargetHeights(); + int ArrowTargetHeightForInfoBar(size_t infobar_index) const; + + Delegate* delegate_; + InfoBarManager* infobar_manager_; + InfoBars infobars_; + + // Calculated in SetMaxTopArrowHeight(). + int top_arrow_target_height_; + + DISALLOW_COPY_AND_ASSIGN(InfoBarContainer); +}; + +} // namespace infobars + +#endif // COMPONENTS_INFOBARS_CORE_INFOBAR_CONTAINER_H_ diff --git a/components/infobars/core/infobar_delegate.cc b/components/infobars/core/infobar_delegate.cc new file mode 100644 index 0000000..d3f5165 --- /dev/null +++ b/components/infobars/core/infobar_delegate.cc @@ -0,0 +1,111 @@ +// 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/infobar_delegate.h" + +#include "base/logging.h" +#include "build/build_config.h" +#include "components/infobars/core/infobar.h" +#include "components/infobars/core/infobar_manager.h" +#include "ui/base/resource/resource_bundle.h" + +namespace infobars { + +const int InfoBarDelegate::kNoIconID = 0; + +InfoBarDelegate::~InfoBarDelegate() { +} + +InfoBarDelegate::InfoBarAutomationType + InfoBarDelegate::GetInfoBarAutomationType() const { + return UNKNOWN_INFOBAR; +} + +bool InfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const { + return false; +} + +bool InfoBarDelegate::ShouldExpire(const NavigationDetails& details) const { + if (!details.is_navigation_to_different_page) + return false; + + return ShouldExpireInternal(details); +} + +void InfoBarDelegate::InfoBarDismissed() { +} + +int InfoBarDelegate::GetIconID() const { + return kNoIconID; +} + +InfoBarDelegate::Type InfoBarDelegate::GetInfoBarType() const { + return WARNING_TYPE; +} + +AutoLoginInfoBarDelegate* InfoBarDelegate::AsAutoLoginInfoBarDelegate() { + return NULL; +} + +ConfirmInfoBarDelegate* InfoBarDelegate::AsConfirmInfoBarDelegate() { + return NULL; +} + +ExtensionInfoBarDelegate* InfoBarDelegate::AsExtensionInfoBarDelegate() { + return NULL; +} + +InsecureContentInfoBarDelegate* + InfoBarDelegate::AsInsecureContentInfoBarDelegate() { + return NULL; +} + +MediaStreamInfoBarDelegate* InfoBarDelegate::AsMediaStreamInfoBarDelegate() { + return NULL; +} + +PopupBlockedInfoBarDelegate* InfoBarDelegate::AsPopupBlockedInfoBarDelegate() { + return NULL; +} + +RegisterProtocolHandlerInfoBarDelegate* + InfoBarDelegate::AsRegisterProtocolHandlerInfoBarDelegate() { + return NULL; +} + +ScreenCaptureInfoBarDelegate* + InfoBarDelegate::AsScreenCaptureInfoBarDelegate() { + return NULL; +} + +ThemeInstalledInfoBarDelegate* + InfoBarDelegate::AsThemePreviewInfobarDelegate() { + return NULL; +} + +TranslateInfoBarDelegate* InfoBarDelegate::AsTranslateInfoBarDelegate() { + return NULL; +} + +void InfoBarDelegate::StoreActiveEntryUniqueID() { + contents_unique_id_ = infobar()->owner()->GetActiveEntryID(); +} + +gfx::Image InfoBarDelegate::GetIcon() const { + int icon_id = GetIconID(); + return (icon_id == kNoIconID) ? gfx::Image() : + ResourceBundle::GetSharedInstance().GetNativeImageNamed(icon_id); +} + +InfoBarDelegate::InfoBarDelegate() : contents_unique_id_(0) { +} + +bool InfoBarDelegate::ShouldExpireInternal( + const NavigationDetails& details) const { + // NOTE: If you change this, be sure to check and adjust the behavior of + // anyone who overrides this as necessary! + return (contents_unique_id_ != details.entry_id) || details.is_reload; +} + +} // namespace infobars diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h new file mode 100644 index 0000000..b6d63ac --- /dev/null +++ b/components/infobars/core/infobar_delegate.h @@ -0,0 +1,148 @@ +// 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. + +#ifndef COMPONENTS_INFOBARS_CORE_INFOBAR_DELEGATE_H_ +#define COMPONENTS_INFOBARS_CORE_INFOBAR_DELEGATE_H_ + +#include "base/basictypes.h" +#include "base/strings/string16.h" +#include "ui/base/window_open_disposition.h" + +class AutoLoginInfoBarDelegate; +class ConfirmInfoBarDelegate; +class ExtensionInfoBarDelegate; +class InsecureContentInfoBarDelegate; +class MediaStreamInfoBarDelegate; +class PopupBlockedInfoBarDelegate; +class RegisterProtocolHandlerInfoBarDelegate; +class ScreenCaptureInfoBarDelegate; +class ThemeInstalledInfoBarDelegate; +class ThreeDAPIInfoBarDelegate; +class TranslateInfoBarDelegate; + +namespace gfx { +class Image; +} + +namespace infobars { + +class InfoBar; + +// An interface implemented by objects wishing to control an InfoBar. +// Implementing this interface is not sufficient to use an InfoBar, since it +// does not map to a specific InfoBar type. Instead, you must implement +// ConfirmInfoBarDelegate, or override with your own delegate for your own +// InfoBar variety. +class InfoBarDelegate { + public: + // The type of the infobar. It controls its appearance, such as its background + // color. + enum Type { + WARNING_TYPE, + PAGE_ACTION_TYPE, + }; + + enum InfoBarAutomationType { + CONFIRM_INFOBAR, + PASSWORD_INFOBAR, + RPH_INFOBAR, + UNKNOWN_INFOBAR, + }; + + // Describes navigation events, used to decide whether infobars should be + // dismissed. + struct NavigationDetails { + // Unique identifier for the entry. + int entry_id; + // True if it is a navigation to a different page (as opposed to in-page). + bool is_navigation_to_different_page; + // True if the entry replaced the existing one. + bool did_replace_entry; + // True for the main frame, false for a sub-frame. + bool is_main_frame; + bool is_reload; + bool is_redirect; + }; + + // Value to use when the InfoBar has no icon to show. + static const int kNoIconID; + + // Called when the InfoBar that owns this delegate is being destroyed. At + // this point nothing is visible onscreen. + virtual ~InfoBarDelegate(); + + virtual InfoBarAutomationType GetInfoBarAutomationType() const; + + // Returns true if the supplied |delegate| is equal to this one. Equality is + // left to the implementation to define. This function is called by the + // InfoBarManager when determining whether or not a delegate should be + // added because a matching one already exists. If this function returns true, + // the InfoBarManager will not add the new delegate because it considers + // one to already be present. + virtual bool EqualsDelegate(InfoBarDelegate* delegate) const; + + // Returns true if the InfoBar should be closed automatically after the page + // is navigated. By default this returns true if the navigation is to a new + // page (not including reloads). Subclasses wishing to change this behavior + // can override either this function or ShouldExpireInternal(), depending on + // what level of control they need. + virtual bool ShouldExpire(const NavigationDetails& details) const; + + // Called when the user clicks on the close button to dismiss the infobar. + virtual void InfoBarDismissed(); + + // Return the resource ID of the icon to be shown for this InfoBar. If the + // value is equal to |kNoIconID|, no icon is shown. + virtual int GetIconID() const; + + // Returns the type of the infobar. The type determines the appearance (such + // as background color) of the infobar. + virtual Type GetInfoBarType() const; + + // Type-checking downcast routines: + virtual AutoLoginInfoBarDelegate* AsAutoLoginInfoBarDelegate(); + virtual ConfirmInfoBarDelegate* AsConfirmInfoBarDelegate(); + virtual ExtensionInfoBarDelegate* AsExtensionInfoBarDelegate(); + virtual InsecureContentInfoBarDelegate* AsInsecureContentInfoBarDelegate(); + virtual MediaStreamInfoBarDelegate* AsMediaStreamInfoBarDelegate(); + virtual PopupBlockedInfoBarDelegate* AsPopupBlockedInfoBarDelegate(); + virtual RegisterProtocolHandlerInfoBarDelegate* + AsRegisterProtocolHandlerInfoBarDelegate(); + virtual ScreenCaptureInfoBarDelegate* AsScreenCaptureInfoBarDelegate(); + virtual ThemeInstalledInfoBarDelegate* AsThemePreviewInfobarDelegate(); + virtual TranslateInfoBarDelegate* AsTranslateInfoBarDelegate(); + + void set_infobar(InfoBar* infobar) { infobar_ = infobar; } + + // Store the unique id for the active entry, to be used later upon navigation + // to determine if this InfoBarDelegate should be expired. + void StoreActiveEntryUniqueID(); + + // Return the icon to be shown for this InfoBar. If the returned Image is + // empty, no icon is shown. + virtual gfx::Image GetIcon() const; + + protected: + InfoBarDelegate(); + + // Returns true if the navigation is to a new URL or a reload occured. + virtual bool ShouldExpireInternal(const NavigationDetails& details) const; + + int contents_unique_id() const { return contents_unique_id_; } + InfoBar* infobar() { return infobar_; } + + private: + // The unique id of the active NavigationEntry of the WebContents that we were + // opened for. Used to help expire on navigations. + int contents_unique_id_; + + // The InfoBar associated with us. + InfoBar* infobar_; + + DISALLOW_COPY_AND_ASSIGN(InfoBarDelegate); +}; + +} // namespace infobars + +#endif // COMPONENTS_INFOBARS_CORE_INFOBAR_DELEGATE_H_ diff --git a/components/infobars/core/infobar_manager.cc b/components/infobars/core/infobar_manager.cc new file mode 100644 index 0000000..6525a9a --- /dev/null +++ b/components/infobars/core/infobar_manager.cc @@ -0,0 +1,141 @@ +// 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/infobar_manager.h" + +#include "base/command_line.h" +#include "components/infobars/core/infobar.h" +#include "components/infobars/core/infobars_switches.h" + +namespace infobars { + +InfoBar* InfoBarManager::AddInfoBar(scoped_ptr<InfoBar> infobar) { + DCHECK(infobar); + if (!infobars_enabled_) + return NULL; + + for (InfoBars::const_iterator i(infobars_.begin()); i != infobars_.end(); + ++i) { + if ((*i)->delegate()->EqualsDelegate(infobar->delegate())) { + DCHECK_NE((*i)->delegate(), infobar->delegate()); + return NULL; + } + } + + InfoBar* infobar_ptr = infobar.release(); + infobars_.push_back(infobar_ptr); + infobar_ptr->SetOwner(this); + + NotifyInfoBarAdded(infobar_ptr); + + return infobar_ptr; +} + +void InfoBarManager::RemoveInfoBar(InfoBar* infobar) { + RemoveInfoBarInternal(infobar, true); +} + +void InfoBarManager::RemoveAllInfoBars(bool animate) { + while (!infobars_.empty()) + RemoveInfoBarInternal(infobars_.back(), animate); +} + +InfoBar* InfoBarManager::ReplaceInfoBar(InfoBar* old_infobar, + scoped_ptr<InfoBar> new_infobar) { + DCHECK(old_infobar); + if (!infobars_enabled_) + return AddInfoBar(new_infobar.Pass()); // Deletes the infobar. + DCHECK(new_infobar); + + InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), + old_infobar)); + DCHECK(i != infobars_.end()); + + InfoBar* new_infobar_ptr = new_infobar.release(); + i = infobars_.insert(i, new_infobar_ptr); + new_infobar_ptr->SetOwner(this); + + // Remove the old infobar before notifying, so that if any observers call back + // to AddInfoBar() or similar, we don't dupe-check against this infobar. + infobars_.erase(++i); + + NotifyInfoBarReplaced(old_infobar, new_infobar_ptr); + + old_infobar->CloseSoon(); + return new_infobar_ptr; +} + +void InfoBarManager::AddObserver(Observer* obs) { + observer_list_.AddObserver(obs); +} + +void InfoBarManager::RemoveObserver(Observer* obs) { + observer_list_.RemoveObserver(obs); +} + +InfoBarManager::InfoBarManager() + : infobars_enabled_(true) { + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableInfoBars)) + infobars_enabled_ = false; +} + +InfoBarManager::~InfoBarManager() {} + +void InfoBarManager::ShutDown() { + // Destroy all remaining InfoBars. It's important to not animate here so that + // we guarantee that we'll delete all delegates before we do anything else. + RemoveAllInfoBars(false); + FOR_EACH_OBSERVER(Observer, observer_list_, OnManagerShuttingDown(this)); +} + +void InfoBarManager::OnNavigation( + const InfoBarDelegate::NavigationDetails& details) { + // NOTE: It is not safe to change the following code to count upwards or + // use iterators, as the RemoveInfoBar() call synchronously modifies our + // delegate list. + for (size_t i = infobars_.size(); i > 0; --i) { + InfoBar* infobar = infobars_[i - 1]; + if (infobar->delegate()->ShouldExpire(details)) + RemoveInfoBar(infobar); + } +} + +void InfoBarManager::NotifyInfoBarAdded(InfoBar* infobar) { + FOR_EACH_OBSERVER(Observer, observer_list_, OnInfoBarAdded(infobar)); +} + +void InfoBarManager::NotifyInfoBarRemoved(InfoBar* infobar, bool animate) { + FOR_EACH_OBSERVER(Observer, observer_list_, + OnInfoBarRemoved(infobar, animate)); +} + +void InfoBarManager::NotifyInfoBarReplaced(InfoBar* old_infobar, + InfoBar* new_infobar) { + FOR_EACH_OBSERVER(Observer, + observer_list_, + OnInfoBarReplaced(old_infobar, new_infobar)); +} + +void InfoBarManager::RemoveInfoBarInternal(InfoBar* infobar, bool animate) { + DCHECK(infobar); + if (!infobars_enabled_) { + DCHECK(infobars_.empty()); + return; + } + + InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar)); + DCHECK(i != infobars_.end()); + + // Remove the infobar before notifying, so that if any observers call back to + // AddInfoBar() or similar, we don't dupe-check against this infobar. + infobars_.erase(i); + + // This notification must happen before the call to CloseSoon() below, since + // observers may want to access |infobar| and that call can delete it. + NotifyInfoBarRemoved(infobar, animate); + + infobar->CloseSoon(); +} + +} // namespace infobars diff --git a/components/infobars/core/infobar_manager.h b/components/infobars/core/infobar_manager.h new file mode 100644 index 0000000..747d5ac --- /dev/null +++ b/components/infobars/core/infobar_manager.h @@ -0,0 +1,124 @@ +// 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. + +#ifndef COMPONENTS_INFOBARS_CORE_INFOBAR_MANAGER_H_ +#define COMPONENTS_INFOBARS_CORE_INFOBAR_MANAGER_H_ + +#include <vector> + +#include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" +#include "components/infobars/core/infobar_delegate.h" + +namespace content { +class WebContents; +} + +namespace infobars { + +class InfoBar; + +// Provides access to creating, removing and enumerating info bars +// attached to a tab. +class InfoBarManager { + public: + // Observer class for infobar events. + class Observer { + public: + virtual void OnInfoBarAdded(InfoBar* infobar) = 0; + virtual void OnInfoBarRemoved(InfoBar* infobar, bool animate) = 0; + virtual void OnInfoBarReplaced(InfoBar* old_infobar, + InfoBar* new_infobar) = 0; + virtual void OnManagerShuttingDown(InfoBarManager* manager) = 0; + }; + + InfoBarManager(); + virtual ~InfoBarManager(); + + // Must be called before destruction. + // TODO(droger): Merge this method with the destructor once the virtual calls + // for notifications are removed (see http://crbug.com/354380). + void ShutDown(); + + // Adds the specified |infobar|, which already owns a delegate. + // + // If infobars are disabled for this tab or the tab already has an infobar + // whose delegate returns true for + // InfoBarDelegate::EqualsDelegate(infobar->delegate()), |infobar| is deleted + // immediately without being added. + // + // Returns the infobar if it was successfully added. + InfoBar* AddInfoBar(scoped_ptr<InfoBar> infobar); + + // Removes the specified |infobar|. This in turn may close immediately or + // animate closed; at the end the infobar will delete itself. + // + // If infobars are disabled for this tab, this will do nothing, on the + // assumption that the matching AddInfoBar() call will have already deleted + // the infobar (see above). + void RemoveInfoBar(InfoBar* infobar); + + // Removes all the infobars. + void RemoveAllInfoBars(bool animate); + + // Replaces one infobar with another, without any animation in between. This + // will result in |old_infobar| being synchronously deleted. + // + // If infobars are disabled for this tab, |new_infobar| is deleted immediately + // without being added, and nothing else happens. + // + // Returns the new infobar if it was successfully added. + // + // NOTE: This does not perform any EqualsDelegate() checks like AddInfoBar(). + InfoBar* ReplaceInfoBar(InfoBar* old_infobar, + scoped_ptr<InfoBar> new_infobar); + + // Returns the number of infobars for this tab. + size_t infobar_count() const { return infobars_.size(); } + + // Returns the infobar at the given |index|. The InfoBarManager retains + // ownership. + // + // Warning: Does not sanity check |index|. + InfoBar* infobar_at(size_t index) { return infobars_[index]; } + + // Must be called when a navigation happens. + void OnNavigation(const InfoBarDelegate::NavigationDetails& details); + + void AddObserver(Observer* obs); + void RemoveObserver(Observer* obs); + + // Returns the active entry ID. + virtual int GetActiveEntryID() = 0; + + protected: + // Notifies the observer in |observer_list_|. + // TODO(droger): Absorb these methods back into their callers once virtual + // overrides are removed (see http://crbug.com/354380). + virtual void NotifyInfoBarAdded(InfoBar* infobar); + virtual void NotifyInfoBarRemoved(InfoBar* infobar, bool animate); + virtual void NotifyInfoBarReplaced(InfoBar* old_infobar, + InfoBar* new_infobar); + + private: + // InfoBars associated with this InfoBarManager. We own these pointers. + // However, this is not a ScopedVector, because we don't delete the infobars + // directly once they've been added to this; instead, when we're done with an + // infobar, we instruct it to delete itself and then orphan it. See + // RemoveInfoBarInternal(). + typedef std::vector<InfoBar*> InfoBars; + + void RemoveInfoBarInternal(InfoBar* infobar, bool animate); + + InfoBars infobars_; + bool infobars_enabled_; + + ObserverList<Observer, true> observer_list_; + + DISALLOW_COPY_AND_ASSIGN(InfoBarManager); +}; + +} // namespace infobars + +#endif // COMPONENTS_INFOBARS_CORE_INFOBAR_MANAGER_H_ diff --git a/components/infobars/core/infobars_switches.cc b/components/infobars/core/infobars_switches.cc new file mode 100644 index 0000000..deb21a7 --- /dev/null +++ b/components/infobars/core/infobars_switches.cc @@ -0,0 +1,14 @@ +// 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/infobars_switches.h" + +namespace infobars { +namespace switches { + +// Prevent infobars from appearing. +const char kDisableInfoBars[] = "disable-infobars"; + +} // namespace switches +} // namespace infobars diff --git a/components/infobars/core/infobars_switches.h b/components/infobars/core/infobars_switches.h new file mode 100644 index 0000000..d24a09a --- /dev/null +++ b/components/infobars/core/infobars_switches.h @@ -0,0 +1,16 @@ +// 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. + +#ifndef COMPONENTS_INFOBARS_CORE_INFOBARS_SWITCHES_H_ +#define COMPONENTS_INFOBARS_CORE_INFOBARS_SWITCHES_H_ + +namespace infobars { +namespace switches { + +extern const char kDisableInfoBars[]; + +} // namespace switches +} // namespace infobars + +#endif // COMPONENTS_INFOBARS_CORE_INFOBARS_SWITCHES_H_ |