summaryrefslogtreecommitdiffstats
path: root/chrome/browser/instant/instant_controller.cc
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-07 20:52:36 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-07 20:52:36 +0000
commit2b15fc8c218b7d9a589fceb98e744603b86fc796 (patch)
tree5822f788fe3e6ca70f10863bd1331488a8051944 /chrome/browser/instant/instant_controller.cc
parent45452a9bd62d6878414aa8387d26a225a220aaea (diff)
downloadchromium_src-2b15fc8c218b7d9a589fceb98e744603b86fc796.zip
chromium_src-2b15fc8c218b7d9a589fceb98e744603b86fc796.tar.gz
chromium_src-2b15fc8c218b7d9a589fceb98e744603b86fc796.tar.bz2
Make instant only load searches for the default provider.
BUG=99266 TEST=make sure instant does search only. R=sreeram@chromium.org Review URL: http://codereview.chromium.org/8176005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@104553 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/instant/instant_controller.cc')
-rw-r--r--chrome/browser/instant/instant_controller.cc433
1 files changed, 87 insertions, 346 deletions
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc
index bad0184..0ade80a 100644
--- a/chrome/browser/instant/instant_controller.cc
+++ b/chrome/browser/instant/instant_controller.cc
@@ -13,7 +13,6 @@
#include "chrome/browser/instant/instant_delegate.h"
#include "chrome/browser/instant/instant_field_trial.h"
#include "chrome/browser/instant/instant_loader.h"
-#include "chrome/browser/instant/instant_loader_manager.h"
#include "chrome/browser/instant/promo_counter.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/prefs/pref_service.h"
@@ -26,7 +25,6 @@
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
-#include "chrome/common/url_constants.h"
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_service.h"
@@ -37,33 +35,12 @@
#include "views/widget/widget.h"
#endif
-namespace {
-
-// Number of ms to delay between loading urls.
-const int kUpdateDelayMS = 200;
-
-// Amount of time we delay before showing pages that have a non-200 status.
-const int kShowDelayMS = 800;
-
-bool IsBlacklistedUrl(const GURL& url) {
- for (int i = 0; i < chrome::kNumberOfChromeDebugURLs; ++i) {
- if (url == GURL(chrome::kChromeDebugURLs[i]))
- return true;
- }
- return false;
-}
-
-}
-
-// static
-InstantController::HostBlacklist* InstantController::host_blacklist_ = NULL;
-
InstantController::InstantController(Profile* profile,
InstantDelegate* delegate)
: delegate_(delegate),
tab_contents_(NULL),
is_active_(false),
- displayable_loader_(NULL),
+ is_displayable_(false),
commit_on_mouse_up_(false),
last_transition_type_(PageTransition::LINK),
ALLOW_THIS_IN_INITIALIZER_LIST(destroy_factory_(this)) {
@@ -179,44 +156,26 @@ bool InstantController::Update(TabContentsWrapper* tab_contents,
string16* suggested_text) {
suggested_text->clear();
- const GURL& url = match.destination_url;
tab_contents_ = tab_contents;
commit_on_mouse_up_ = false;
last_transition_type_ = match.transition;
- const TemplateURL* template_url = NULL;
-
- // The url should not normally be empty or invalid.
- if (url.is_empty() || !url.is_valid()) {
- DestroyPreviewContentsAndLeaveActive();
- return false;
- }
-
- PreviewCondition preview_condition = GetPreviewConditionFor(match,
- &template_url);
- if (preview_condition != PREVIEW_CONDITION_SUCCESS) {
- // Just destroy the preview and cancel the update.
+ if (!ShouldUseInstant(match)) {
DestroyPreviewContentsAndLeaveActive();
return false;
}
- if (!loader_manager_.get())
- loader_manager_.reset(new InstantLoaderManager(this));
+ const TemplateURL* template_url = match.template_url;
+ DCHECK(template_url); // ShouldUseInstant returns false if no turl.
+ if (!loader_.get())
+ loader_.reset(new InstantLoader(this, template_url->id()));
if (!is_active_) {
is_active_ = true;
delegate_->PrepareForInstant();
}
- TemplateURLID template_url_id = template_url ? template_url->id() : 0;
- // Verbatim only makes sense if the search engines supports instant.
- bool real_verbatim = template_url_id ? verbatim : false;
-
- if (ShouldUpdateNow(template_url_id, match.destination_url)) {
- UpdateLoader(template_url, match.destination_url, match.transition,
- user_text, real_verbatim, suggested_text);
- } else {
- ScheduleUpdate(match.destination_url);
- }
+ UpdateLoader(template_url, match.destination_url, match.transition, user_text,
+ verbatim, suggested_text);
NotificationService::current()->Notify(
chrome::NOTIFICATION_INSTANT_CONTROLLER_UPDATED,
@@ -232,16 +191,12 @@ void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) {
// Always track the omnibox bounds. That way if Update is later invoked the
// bounds are in sync.
omnibox_bounds_ = bounds;
- if (loader_manager_.get()) {
- if (loader_manager_->current_loader())
- loader_manager_->current_loader()->SetOmniboxBounds(bounds);
- if (loader_manager_->pending_loader())
- loader_manager_->pending_loader()->SetOmniboxBounds(bounds);
- }
+ if (loader_.get())
+ loader_->SetOmniboxBounds(bounds);
}
void InstantController::DestroyPreviewContents() {
- if (!loader_manager_.get()) {
+ if (!loader_.get()) {
// We're not showing anything, nothing to do.
return;
}
@@ -256,38 +211,22 @@ void InstantController::DestroyPreviewContents() {
void InstantController::DestroyPreviewContentsAndLeaveActive() {
commit_on_mouse_up_ = false;
- if (displayable_loader_) {
- displayable_loader_ = NULL;
+ if (is_displayable_) {
+ is_displayable_ = false;
delegate_->HideInstant();
}
-
- if (loader_manager_.get())
- loader_manager_->DestroyNonInstantLoaders();
- show_timer_.Stop();
- update_timer_.Stop();
}
bool InstantController::IsCurrent() {
// TODO(mmenke): See if we can do something more intelligent in the
// navigation pending case.
- return loader_manager_.get() && loader_manager_->active_loader() &&
- loader_manager_->active_loader()->ready() &&
- !loader_manager_->active_loader()->IsNavigationPending() &&
- !loader_manager_->active_loader()->needs_reload() &&
- !update_timer_.IsRunning();
+ return is_displayable_ && !loader_->IsNavigationPending() &&
+ !loader_->needs_reload();
}
TabContentsWrapper* InstantController::CommitCurrentPreview(
InstantCommitType type) {
- if (type == INSTANT_COMMIT_PRESSED_ENTER && show_timer_.IsRunning()) {
- // The user pressed enter and the show timer is running. This means the
- // pending_loader returned an error code and we're not showing it. Force it
- // to be shown.
- show_timer_.Stop();
- ShowTimerFired();
- }
- DCHECK(loader_manager_.get());
- DCHECK(loader_manager_->current_loader());
+ DCHECK(loader_.get());
TabContentsWrapper* tab = ReleasePreviewContents(type);
tab->controller().CopyStateFromAndPrune(&tab_contents_->controller());
delegate_->CommitInstant(tab);
@@ -300,9 +239,8 @@ void InstantController::SetCommitOnMouseUp() {
}
bool InstantController::IsMouseDownFromActivate() {
- DCHECK(loader_manager_.get());
- DCHECK(loader_manager_->current_loader());
- return loader_manager_->current_loader()->IsMouseDownFromActivate();
+ DCHECK(loader_.get());
+ return loader_->IsMouseDownFromActivate();
}
#if defined(OS_MACOSX)
@@ -311,21 +249,15 @@ void InstantController::OnAutocompleteLostFocus(
// If |IsMouseDownFromActivate()| returns false, the RenderWidgetHostView did
// not receive a mouseDown event. Therefore, we should destroy the preview.
// Otherwise, the RWHV was clicked, so we commit the preview.
- if (!is_displayable() || !GetPreviewContents() ||
- !IsMouseDownFromActivate() ||
- loader_manager_->active_loader()->IsNavigationPending()) {
+ if (!IsCurrent() || !IsMouseDownFromActivate())
DestroyPreviewContents();
- } else if (IsShowingInstant()) {
+ else
SetCommitOnMouseUp();
- } else {
- CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST);
- }
}
#else
void InstantController::OnAutocompleteLostFocus(
gfx::NativeView view_gaining_focus) {
- if (!is_active() || !GetPreviewContents() ||
- loader_manager_->active_loader()->IsNavigationPending()) {
+ if (!IsCurrent()) {
DestroyPreviewContents();
return;
}
@@ -368,15 +300,10 @@ void InstantController::OnAutocompleteLostFocus(
return;
}
- if (IsShowingInstant()) {
- // We're showing instant results. As instant results may shift when
- // committing we commit on the mouse up. This way a slow click still
- // works fine.
- SetCommitOnMouseUp();
- return;
- }
-
- CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST);
+ // We're showing instant results. As instant results may shift when
+ // committing we commit on the mouse up. This way a slow click still works
+ // fine.
+ SetCommitOnMouseUp();
return;
}
@@ -414,49 +341,28 @@ void InstantController::OnAutocompleteGotFocus(
return;
const TemplateURL* template_url = model->GetDefaultSearchProvider();
- if (!template_url || !template_url->instant_url() || !template_url->id())
+ if (!IsValidInstantTemplateURL(template_url))
return;
tab_contents_ = tab_contents;
- if (!loader_manager_.get())
- loader_manager_.reset(new InstantLoaderManager(this));
- loader_manager_->GetInstantLoader(template_url->id())
- ->MaybeLoadInstantURL(tab_contents, template_url);
+ if (!loader_.get())
+ loader_.reset(new InstantLoader(this, template_url->id()));
+ loader_->MaybeLoadInstantURL(tab_contents, template_url);
}
TabContentsWrapper* InstantController::ReleasePreviewContents(
InstantCommitType type) {
- if (!loader_manager_.get())
+ if (!loader_.get())
return NULL;
- // Make sure the pending loader is active. Ideally we would call
- // ShowTimerFired, but if Release is invoked from the browser we don't want to
- // attempt to show the tab contents (since its being added to a new tab).
- if (type == INSTANT_COMMIT_PRESSED_ENTER && show_timer_.IsRunning()) {
- InstantLoader* loader = loader_manager_->active_loader();
- if (loader && loader->ready() &&
- loader == loader_manager_->pending_loader()) {
- scoped_ptr<InstantLoader> old_loader;
- loader_manager_->MakePendingCurrent(&old_loader);
- }
- }
-
- // Loader may be null if the url blacklisted instant.
- scoped_ptr<InstantLoader> loader;
- if (loader_manager_->current_loader())
- loader.reset(loader_manager_->ReleaseCurrentLoader());
- TabContentsWrapper* tab = loader.get() ?
- loader->ReleasePreviewContents(type) : NULL;
-
+ TabContentsWrapper* tab = loader_->ReleasePreviewContents(type);
ClearBlacklist();
is_active_ = false;
- displayable_loader_ = NULL;
+ is_displayable_ = false;
commit_on_mouse_up_ = false;
omnibox_bounds_ = gfx::Rect();
- loader_manager_.reset();
- update_timer_.Stop();
- show_timer_.Stop();
+ loader_.reset();
return tab;
}
@@ -465,46 +371,19 @@ void InstantController::CompleteRelease(TabContentsWrapper* tab) {
}
TabContentsWrapper* InstantController::GetPreviewContents() {
- return loader_manager_.get() && loader_manager_->current_loader() ?
- loader_manager_->current_loader()->preview_contents() : NULL;
-}
-
-bool InstantController::IsShowingInstant() {
- return loader_manager_.get() && loader_manager_->current_loader() &&
- loader_manager_->current_loader()->is_showing_instant();
-}
-
-bool InstantController::MightSupportInstant() {
- return loader_manager_.get() && loader_manager_->active_loader() &&
- loader_manager_->active_loader()->is_showing_instant();
-}
-
-GURL InstantController::GetCurrentURL() {
- return loader_manager_.get() && loader_manager_->active_loader() ?
- loader_manager_->active_loader()->url() : GURL();
+ return loader_.get() ? loader_->preview_contents() : NULL;
}
void InstantController::InstantStatusChanged(InstantLoader* loader) {
- if (!loader->http_status_ok()) {
- // Status isn't ok, start a timer that when fires shows the result. This
- // delays showing 403 pages and the like.
- show_timer_.Stop();
- show_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kShowDelayMS),
- this, &InstantController::ShowTimerFired);
- UpdateDisplayableLoader();
- return;
- }
-
- ProcessInstantStatusChanged(loader);
+ DCHECK(loader_.get());
+ UpdateIsDisplayable();
}
void InstantController::SetSuggestedTextFor(
InstantLoader* loader,
const string16& text,
InstantCompleteBehavior behavior) {
- if (loader_manager_->current_loader() == loader)
- delegate_->SetSuggestedText(text, behavior);
+ delegate_->SetSuggestedText(text, behavior);
}
gfx::Rect InstantController::GetInstantBounds() {
@@ -516,7 +395,7 @@ bool InstantController::ShouldCommitInstantOnMouseUp() {
}
void InstantController::CommitInstantLoader(InstantLoader* loader) {
- if (loader_manager_.get() && loader_manager_->current_loader() == loader) {
+ if (loader_.get() && loader_.get() == loader) {
CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST);
} else {
// This can happen if the mouse was down, we swapped out the preview and
@@ -528,71 +407,37 @@ void InstantController::CommitInstantLoader(InstantLoader* loader) {
void InstantController::InstantLoaderDoesntSupportInstant(
InstantLoader* loader) {
- DCHECK(!loader->ready()); // We better not be showing this loader.
- DCHECK(loader->template_url_id());
-
VLOG(1) << "provider does not support instant";
// Don't attempt to use instant for this search engine again.
- BlacklistFromInstant(loader->template_url_id());
-
- // Because of the state of the stack we can't destroy the loader now.
- bool was_pending = loader_manager_->pending_loader() == loader;
- ScheduleDestroy(loader_manager_->ReleaseLoader(loader));
- if (was_pending) {
- // |loader| was the pending loader. We may be showing another TabContents to
- // the user (what was current). Destroy it.
- DestroyPreviewContentsAndLeaveActive();
- } else {
- // |loader| wasn't pending, yet it may still be the displayed loader.
- UpdateDisplayableLoader();
- }
+ BlacklistFromInstant();
}
void InstantController::AddToBlacklist(InstantLoader* loader, const GURL& url) {
- std::string host = url.host();
- if (host.empty())
- return;
-
- if (!host_blacklist_)
- host_blacklist_ = new HostBlacklist;
- host_blacklist_->insert(host);
-
- if (!loader_manager_.get())
- return;
+ // Don't attempt to use instant for this search engine again.
+ BlacklistFromInstant();
// Because of the state of the stack we can't destroy the loader now.
- ScheduleDestroy(loader);
-
- loader_manager_->ReleaseLoader(loader);
-
- UpdateDisplayableLoader();
+ ScheduleDestroy(loader_.release());
+ UpdateIsDisplayable();
}
void InstantController::SwappedTabContents(InstantLoader* loader) {
- if (displayable_loader_ == loader)
- delegate_->ShowInstant(displayable_loader_->preview_contents());
-}
-
-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() &&
- (!show_timer_.IsRunning() ||
- loader_manager_->current_loader()->http_status_ok())) {
- loader = loader_manager_->current_loader();
- }
- if (loader == displayable_loader_)
- return;
+ if (is_displayable_)
+ delegate_->ShowInstant(loader->preview_contents());
+}
- displayable_loader_ = loader;
+void InstantController::UpdateIsDisplayable() {
+ bool displayable =
+ (loader_.get() && loader_->ready() && loader_->http_status_ok());
+ if (displayable == is_displayable_)
+ return;
- if (!displayable_loader_) {
+ is_displayable_ = displayable;
+ if (!is_displayable_) {
delegate_->HideInstant();
} else {
- delegate_->ShowInstant(displayable_loader_->preview_contents());
+ delegate_->ShowInstant(loader_->preview_contents());
NotificationService::current()->Notify(
chrome::NOTIFICATION_INSTANT_CONTROLLER_SHOWN,
Source<InstantController>(this),
@@ -600,153 +445,49 @@ void InstantController::UpdateDisplayableLoader() {
}
}
-TabContentsWrapper* InstantController::GetPendingPreviewContents() {
- return loader_manager_.get() && loader_manager_->pending_loader() ?
- loader_manager_->pending_loader()->preview_contents() : NULL;
-}
-
-bool InstantController::ShouldUpdateNow(TemplateURLID instant_id,
- const GURL& url) {
- DCHECK(loader_manager_.get());
-
- if (instant_id) {
- // Update sites that support instant immediately, they can do their own
- // throttling.
- return true;
- }
-
- if (url.SchemeIsFile())
- return true; // File urls should load quickly, so don't delay loading them.
-
- if (loader_manager_->WillUpdateChangeActiveLoader(instant_id)) {
- // If Update would change loaders, update now. This indicates transitioning
- // from an instant to non-instant loader.
- return true;
- }
-
- InstantLoader* active_loader = loader_manager_->active_loader();
- // WillUpdateChangeActiveLoader should return true if no active loader, so
- // we know there will be an active loader if we get here.
- DCHECK(active_loader);
- // Immediately update if the url is the same (which should result in nothing
- // happening) or the hosts differ, otherwise we'll delay the update.
- return (active_loader->url() == url) ||
- (active_loader->url().host() != url.host());
-}
-
-void InstantController::ScheduleUpdate(const GURL& url) {
- scheduled_url_ = url;
-
- update_timer_.Stop();
- update_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kUpdateDelayMS),
- this, &InstantController::ProcessScheduledUpdate);
+void InstantController::UpdateLoader(const TemplateURL* template_url,
+ const GURL& url,
+ PageTransition::Type transition_type,
+ const string16& user_text,
+ bool verbatim,
+ string16* suggested_text) {
+ loader_->SetOmniboxBounds(omnibox_bounds_);
+ loader_->Update(tab_contents_, template_url, url, transition_type, user_text,
+ verbatim, suggested_text);
+ UpdateIsDisplayable();
}
-void InstantController::ProcessScheduledUpdate() {
- DCHECK(loader_manager_.get());
+bool InstantController::ShouldUseInstant(const AutocompleteMatch& match) {
+ TemplateURLService* model = TemplateURLServiceFactory::GetForProfile(
+ tab_contents_->profile());
+ if (!model)
+ return false;
- // We only delay loading of sites that don't support instant, so we can ignore
- // suggested_text here.
- string16 suggested_text;
- UpdateLoader(NULL, scheduled_url_, last_transition_type_, string16(), false,
- &suggested_text);
+ const TemplateURL* default_t_url = model->GetDefaultSearchProvider();
+ const TemplateURL* match_t_url = match.template_url;
+ return IsValidInstantTemplateURL(default_t_url) &&
+ IsValidInstantTemplateURL(match_t_url) &&
+ (match_t_url->id() == default_t_url->id());
}
-void InstantController::ProcessInstantStatusChanged(InstantLoader* loader) {
- DCHECK(loader_manager_.get());
- scoped_ptr<InstantLoader> old_loader;
- if (loader == loader_manager_->pending_loader()) {
- loader_manager_->MakePendingCurrent(&old_loader);
- } 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();
+// Returns true if |template_url| is a valid TemplateURL for use by instant.
+bool InstantController::IsValidInstantTemplateURL(
+ const TemplateURL* template_url) {
+ return template_url && template_url->instant_url() && template_url->id() &&
+ template_url->instant_url()->SupportsReplacement() &&
+ !IsBlacklistedFromInstant(template_url->id());
}
-void InstantController::ShowTimerFired() {
- if (!loader_manager_.get())
+void InstantController::BlacklistFromInstant() {
+ if (!loader_.get())
return;
- InstantLoader* loader = loader_manager_->active_loader();
- if (loader && loader->ready())
- ProcessInstantStatusChanged(loader);
-}
+ DCHECK(loader_->template_url_id());
+ blacklisted_ids_.insert(loader_->template_url_id());
-void InstantController::UpdateLoader(const TemplateURL* template_url,
- const GURL& url,
- PageTransition::Type transition_type,
- const string16& user_text,
- bool verbatim,
- string16* suggested_text) {
- update_timer_.Stop();
-
- scoped_ptr<InstantLoader> owned_loader;
- TemplateURLID template_url_id = template_url ? template_url->id() : 0;
- InstantLoader* new_loader =
- loader_manager_->UpdateLoader(template_url_id, &owned_loader);
-
- new_loader->SetOmniboxBounds(omnibox_bounds_);
- if (new_loader->Update(tab_contents_, template_url, url, transition_type,
- user_text, verbatim, suggested_text)) {
- show_timer_.Stop();
- if (!new_loader->http_status_ok()) {
- show_timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kShowDelayMS),
- this, &InstantController::ShowTimerFired);
- }
- }
- UpdateDisplayableLoader();
-}
-
-InstantController::PreviewCondition InstantController::GetPreviewConditionFor(
- const AutocompleteMatch& match, const TemplateURL** template_url) {
- const TemplateURL* t_url = match.template_url;
- if (t_url) {
- if (!t_url->id() ||
- !t_url->instant_url() ||
- IsBlacklistedFromInstant(t_url->id()) ||
- !t_url->instant_url()->SupportsReplacement()) {
- // To avoid extra load on other search engines we only enable previews if
- // they support the instant API.
- return PREVIEW_CONDITION_INVALID_TEMPLATE_URL;
- }
- }
- *template_url = t_url;
-
- if (match.destination_url.SchemeIs(chrome::kJavaScriptScheme))
- return PREVIEW_CONDITION_JAVASCRIPT_SCHEME;
-
- // Extension keywords don't have a real destination URL.
- if (match.template_url && match.template_url->IsExtensionKeyword())
- return PREVIEW_CONDITION_EXTENSION_KEYWORD;
-
- // Was the host blacklisted?
- if (host_blacklist_ && host_blacklist_->count(match.destination_url.host()))
- return PREVIEW_CONDITION_BLACKLISTED_HOST;
-
- // Was the URL blacklisted?
- if (IsBlacklistedUrl(match.destination_url))
- return PREVIEW_CONDITION_BLACKLISTED_URL;
-
- const CommandLine* cl = CommandLine::ForCurrentProcess();
- if ((cl->HasSwitch(switches::kRestrictInstantToSearch) ||
- InstantFieldTrial::IsExperimentGroup(tab_contents_->profile())) &&
- match.type != AutocompleteMatch::SEARCH_WHAT_YOU_TYPED &&
- match.type != AutocompleteMatch::SEARCH_HISTORY &&
- match.type != AutocompleteMatch::SEARCH_SUGGEST &&
- match.type != AutocompleteMatch::SEARCH_OTHER_ENGINE) {
- return PREVIEW_CONDITION_INSTANT_SEARCH_ONLY;
- }
-
- return PREVIEW_CONDITION_SUCCESS;
-}
-
-void InstantController::BlacklistFromInstant(TemplateURLID id) {
- blacklisted_ids_.insert(id);
+ // Because of the state of the stack we can't destroy the loader now.
+ ScheduleDestroy(loader_.release());
+ UpdateIsDisplayable();
}
bool InstantController::IsBlacklistedFromInstant(TemplateURLID id) {