summaryrefslogtreecommitdiffstats
path: root/chrome/browser/instant/instant_controller.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/instant/instant_controller.cc')
-rw-r--r--chrome/browser/instant/instant_controller.cc197
1 files changed, 197 insertions, 0 deletions
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc
new file mode 100644
index 0000000..a095696
--- /dev/null
+++ b/chrome/browser/instant/instant_controller.cc
@@ -0,0 +1,197 @@
+// Copyright (c) 2010 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 "chrome/browser/instant/instant_controller.h"
+
+#include "base/command_line.h"
+#include "chrome/browser/autocomplete/autocomplete.h"
+#include "chrome/browser/instant/instant_delegate.h"
+#include "chrome/browser/instant/instant_loader.h"
+#include "chrome/browser/instant/instant_loader_manager.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/search_engines/template_url.h"
+#include "chrome/browser/search_engines/template_url_model.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/url_constants.h"
+
+// static
+bool InstantController::IsEnabled() {
+ static bool enabled = false;
+ static bool checked = false;
+ if (!checked) {
+ checked = true;
+ enabled = CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kEnableMatchPreview);
+ }
+ return enabled;
+}
+
+InstantController::InstantController(InstantDelegate* delegate)
+ : delegate_(delegate),
+ tab_contents_(NULL),
+ is_active_(false),
+ commit_on_mouse_up_(false),
+ last_transition_type_(PageTransition::LINK) {
+}
+
+InstantController::~InstantController() {
+}
+
+void InstantController::Update(TabContents* tab_contents,
+ const AutocompleteMatch& match,
+ const string16& user_text,
+ string16* suggested_text) {
+ if (tab_contents != tab_contents_)
+ DestroyPreviewContents();
+
+ const GURL& url = match.destination_url;
+
+ tab_contents_ = tab_contents;
+ commit_on_mouse_up_ = false;
+ last_transition_type_ = match.transition;
+
+ if (loader_manager_.get() && loader_manager_->active_loader()->url() == url)
+ return;
+
+ if (url.is_empty() || !url.is_valid() || !ShouldShowPreviewFor(url)) {
+ DestroyPreviewContents();
+ return;
+ }
+
+ if (!loader_manager_.get())
+ loader_manager_.reset(new InstantLoaderManager(this));
+
+ const TemplateURL* template_url = match.template_url;
+ if (match.type == AutocompleteMatch::SEARCH_WHAT_YOU_TYPED ||
+ match.type == AutocompleteMatch::SEARCH_HISTORY ||
+ match.type == AutocompleteMatch::SEARCH_SUGGEST) {
+ TemplateURLModel* model = tab_contents->profile()->GetTemplateURLModel();
+ template_url = model ? model->GetDefaultSearchProvider() : NULL;
+ }
+ // TODO(sky): remove the id check. It's only necessary because the search
+ // engine saved to prefs doesn't have an id. Jean-luc is fixing separately.
+ if (template_url && (!template_url->supports_instant() ||
+ !template_url->id() ||
+ !TemplateURL::SupportsReplacement(template_url))) {
+ template_url = NULL;
+ }
+ TemplateURLID template_url_id = template_url ? template_url->id() : 0;
+
+ InstantLoader* old_loader = loader_manager_->current_loader();
+ scoped_ptr<InstantLoader> owned_loader;
+ InstantLoader* new_loader =
+ loader_manager_->UpdateLoader(template_url_id, &owned_loader);
+
+ new_loader->SetOmniboxBounds(omnibox_bounds_);
+ new_loader->Update(tab_contents, match, user_text, template_url,
+ suggested_text);
+ if (old_loader != new_loader && new_loader->ready())
+ delegate_->ShowInstant(new_loader->preview_contents());
+}
+
+void InstantController::SetOmniboxBounds(const gfx::Rect& bounds) {
+ if (omnibox_bounds_ == bounds)
+ return;
+
+ 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);
+ }
+}
+
+void InstantController::DestroyPreviewContents() {
+ if (!loader_manager_.get()) {
+ // We're not showing anything, nothing to do.
+ return;
+ }
+
+ delegate_->HideInstant();
+ delete ReleasePreviewContents(INSTANT_COMMIT_DESTROY);
+}
+
+void InstantController::CommitCurrentPreview(InstantCommitType type) {
+ DCHECK(loader_manager_.get());
+ DCHECK(loader_manager_->current_loader());
+ delegate_->CommitInstant(ReleasePreviewContents(type));
+}
+
+void InstantController::SetCommitOnMouseUp() {
+ commit_on_mouse_up_ = true;
+}
+
+bool InstantController::IsMouseDownFromActivate() {
+ DCHECK(loader_manager_.get());
+ DCHECK(loader_manager_->current_loader());
+ return loader_manager_->current_loader()->IsMouseDownFromActivate();
+}
+
+TabContents* InstantController::ReleasePreviewContents(InstantCommitType type) {
+ if (!loader_manager_.get())
+ return NULL;
+
+ scoped_ptr<InstantLoader> loader(loader_manager_->ReleaseCurrentLoader());
+ TabContents* tab = loader->ReleasePreviewContents(type);
+
+ is_active_ = false;
+ omnibox_bounds_ = gfx::Rect();
+ commit_on_mouse_up_ = false;
+ loader_manager_.reset(NULL);
+ return tab;
+}
+
+TabContents* InstantController::GetPreviewContents() {
+ return loader_manager_.get() ?
+ loader_manager_->current_loader()->preview_contents() : NULL;
+}
+
+bool InstantController::IsShowingInstant() {
+ return loader_manager_.get() &&
+ loader_manager_->current_loader()->is_showing_instant();
+}
+
+void InstantController::ShowInstantLoader(InstantLoader* loader) {
+ DCHECK(loader_manager_.get());
+ if (loader_manager_->current_loader() == loader) {
+ is_active_ = true;
+ delegate_->ShowInstant(loader->preview_contents());
+ } else if (loader_manager_->pending_loader() == loader) {
+ scoped_ptr<InstantLoader> old_loader;
+ loader_manager_->MakePendingCurrent(&old_loader);
+ delegate_->ShowInstant(loader->preview_contents());
+ } else {
+ NOTREACHED();
+ }
+}
+
+void InstantController::SetSuggestedTextFor(InstantLoader* loader,
+ const string16& text) {
+ if (loader_manager_->current_loader() == loader)
+ delegate_->SetSuggestedText(text);
+}
+
+gfx::Rect InstantController::GetInstantBounds() {
+ return delegate_->GetInstantBounds();
+}
+
+bool InstantController::ShouldCommitInstantOnMouseUp() {
+ return commit_on_mouse_up_;
+}
+
+void InstantController::CommitInstantLoader(InstantLoader* loader) {
+ if (loader_manager_.get() && loader_manager_->current_loader() == loader) {
+ CommitCurrentPreview(INSTANT_COMMIT_FOCUS_LOST);
+ } else {
+ // This can happen if the mouse was down, we swapped out the preview and
+ // the mouse was released. Generally this shouldn't happen, but if it does
+ // revert.
+ DestroyPreviewContents();
+ }
+}
+
+bool InstantController::ShouldShowPreviewFor(const GURL& url) {
+ return !url.SchemeIs(chrome::kJavaScriptScheme);
+}