summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/instant/instant_controller.cc74
-rw-r--r--chrome/browser/instant/instant_controller.h11
2 files changed, 50 insertions, 35 deletions
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc
index 99bed68..e364749 100644
--- a/chrome/browser/instant/instant_controller.cc
+++ b/chrome/browser/instant/instant_controller.cc
@@ -37,7 +37,7 @@ InstantController::InstantController(Profile* profile,
: delegate_(delegate),
tab_contents_(NULL),
is_active_(false),
- is_displayable_(false),
+ displayable_loader_(NULL),
commit_on_mouse_up_(false),
last_transition_type_(PageTransition::LINK),
ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)) {
@@ -214,9 +214,11 @@ void InstantController::DestroyPreviewContents() {
}
void InstantController::DestroyPreviewContentsAndLeaveActive() {
- is_displayable_ = false;
commit_on_mouse_up_ = false;
- delegate_->HideInstant();
+ if (displayable_loader_) {
+ displayable_loader_ = NULL;
+ delegate_->HideInstant();
+ }
// TODO(sky): this shouldn't nuke the loader. It should just nuke non-instant
// loaders and hide instant loaders.
@@ -318,7 +320,7 @@ TabContentsWrapper* InstantController::ReleasePreviewContents(
ClearBlacklist();
is_active_ = false;
- is_displayable_ = false;
+ displayable_loader_ = NULL;
commit_on_mouse_up_ = false;
omnibox_bounds_ = gfx::Rect();
loader_manager_.reset();
@@ -352,17 +354,17 @@ GURL InstantController::GetCurrentURL() {
void InstantController::ShowInstantLoader(InstantLoader* loader) {
DCHECK(loader_manager_.get());
- if (loader_manager_->current_loader() == loader) {
- is_displayable_ = true;
- delegate_->ShowInstant(loader->preview_contents());
- } else if (loader_manager_->pending_loader() == loader) {
- scoped_ptr<InstantLoader> old_loader;
+ scoped_ptr<InstantLoader> old_loader;
+ if (loader == loader_manager_->pending_loader()) {
loader_manager_->MakePendingCurrent(&old_loader);
- delegate_->ShowInstant(loader->preview_contents());
- } else {
- // The loader supports instant but isn't active yet. Nothing to do.
+ } else if (loader != loader_manager_->current_loader()) {
+ // Notification from a loader that is no longer the current (either we have
+ // a pending, or its an instant loader). Ignore it.
+ return;
}
+ UpdateDisplayableLoader();
+
NotificationService::current()->Notify(
NotificationType::INSTANT_CONTROLLER_SHOWN,
Source<InstantController>(this),
@@ -408,14 +410,9 @@ void InstantController::InstantLoaderDoesntSupportInstant(
// The loader is active, hide all.
DestroyPreviewContentsAndLeaveActive();
} else {
- if (loader_manager_->current_loader() == loader && is_displayable_) {
- // There is a pending loader and we're active. Hide the preview. When then
- // pending loader finishes loading we'll notify the delegate to show.
- DCHECK(loader_manager_->pending_loader());
- is_displayable_ = false;
- delegate_->HideInstant();
- }
- loader_manager_->DestroyLoader(loader);
+ scoped_ptr<InstantLoader> owned_loader(
+ loader_manager_->ReleaseLoader(loader));
+ UpdateDisplayableLoader();
}
}
@@ -435,13 +432,31 @@ void InstantController::AddToBlacklist(InstantLoader* loader, const GURL& url) {
ScheduleDestroy(loader);
loader_manager_->ReleaseLoader(loader);
- if (is_displayable_ &&
- (!loader_manager_->active_loader() ||
- !loader_manager_->current_loader()->ready())) {
- // Hide instant. When the pending loader finishes loading we'll go active
- // again.
- is_displayable_ = false;
+
+ UpdateDisplayableLoader();
+}
+
+void InstantController::UpdateDisplayableLoader() {
+ InstantLoader* loader = NULL;
+ // As soon as the pending loader is displayable it becomes the current loader,
+ // so we need only concern ourselves with the current loader here.
+ if (loader_manager_.get() && loader_manager_->current_loader() &&
+ loader_manager_->current_loader()->ready()) {
+ loader = loader_manager_->current_loader();
+ }
+ if (loader == displayable_loader_)
+ return;
+
+ displayable_loader_ = loader;
+
+ if (!displayable_loader_) {
delegate_->HideInstant();
+ } else {
+ delegate_->ShowInstant(displayable_loader_->preview_contents());
+ NotificationService::current()->Notify(
+ NotificationType::INSTANT_CONTROLLER_SHOWN,
+ Source<InstantController>(this),
+ NotificationService::NoDetails());
}
}
@@ -482,8 +497,7 @@ bool InstantController::ShouldUpdateNow(TemplateURLID instant_id,
void InstantController::ScheduleUpdate(const GURL& url) {
scheduled_url_ = url;
- if (update_timer_.IsRunning())
- update_timer_.Stop();
+ update_timer_.Stop();
update_timer_.Start(base::TimeDelta::FromMilliseconds(kUpdateDelayMS),
this, &InstantController::ProcessScheduledUpdate);
}
@@ -506,7 +520,6 @@ void InstantController::UpdateLoader(const TemplateURL* template_url,
string16* suggested_text) {
update_timer_.Stop();
- InstantLoader* old_loader = loader_manager_->current_loader();
scoped_ptr<InstantLoader> owned_loader;
TemplateURLID template_url_id = template_url ? template_url->id() : 0;
InstantLoader* new_loader =
@@ -515,8 +528,7 @@ void InstantController::UpdateLoader(const TemplateURL* template_url,
new_loader->SetOmniboxBounds(omnibox_bounds_);
new_loader->Update(tab_contents_, template_url, url, transition_type,
user_text, verbatim, suggested_text);
- if (old_loader != new_loader && new_loader->ready())
- delegate_->ShowInstant(new_loader->preview_contents());
+ UpdateDisplayableLoader();
}
bool InstantController::ShouldShowPreviewFor(const AutocompleteMatch& match,
diff --git a/chrome/browser/instant/instant_controller.h b/chrome/browser/instant/instant_controller.h
index 5596910..bc535f8 100644
--- a/chrome/browser/instant/instant_controller.h
+++ b/chrome/browser/instant/instant_controller.h
@@ -143,7 +143,7 @@ class InstantController : public InstantLoaderDelegate {
// Returns true if the preview TabContents is ready to be displayed. In some
// situations this may return false yet GetPreviewContents() returns non-NULL.
- bool is_displayable() const { return is_displayable_; }
+ bool is_displayable() const { return displayable_loader_ != NULL; }
// Returns the transition type of the last AutocompleteMatch passed to Update.
PageTransition::Type last_transition_type() const {
@@ -188,6 +188,9 @@ class InstantController : public InstantLoaderDelegate {
typedef std::set<std::string> HostBlacklist;
+ // Updates |displayable_loader_| and if necessary notifies the delegate.
+ void UpdateDisplayableLoader();
+
// Returns the TabContents of the pending loader (or NULL). This is only used
// for testing.
TabContentsWrapper* GetPendingPreviewContents();
@@ -247,9 +250,8 @@ class InstantController : public InstantLoaderDelegate {
// See description above getter for details.
bool is_active_;
- // Has notification been sent out that the preview TabContents is ready to be
- // shown?
- bool is_displayable_;
+ // The loader that is ready to be displayed.
+ InstantLoader* displayable_loader_;
// See description above setter.
gfx::Rect omnibox_bounds_;
@@ -268,6 +270,7 @@ class InstantController : public InstantLoaderDelegate {
// reset/commit.
std::set<TemplateURLID> blacklisted_ids_;
+ // Timer used to delay calls to |UpdateLoader|.
base::OneShotTimer<InstantController> update_timer_;
// Used by ScheduleForDestroy; see it for details.