diff options
-rw-r--r-- | chrome/browser/instant/instant_controller.cc | 74 | ||||
-rw-r--r-- | chrome/browser/instant/instant_controller.h | 11 |
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. |