// Copyright (c) 2011 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 CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_
#define CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_
#pragma once
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "base/timer.h"
#include "chrome/browser/instant/instant_commit_type.h"
#include "chrome/browser/search_engines/template_url_id.h"
#include "chrome/common/instant_types.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "content/common/page_transition_types.h"
#include "googleurl/src/gurl.h"
#include "ui/gfx/rect.h"
class InstantLoaderDelegate;
class InstantLoaderManagerTest;
class TabContents;
class TabContentsWrapper;
class TemplateURL;
// InstantLoader does the loading of a particular URL for InstantController.
// InstantLoader notifies its delegate, which is typically InstantController, of
// all interesting events.
//
// InstantLoader is created with a TemplateURLID. If non-zero InstantLoader
// first determines if the site actually supports instant. If it doesn't, the
// delegate is notified by way of |InstantLoaderDoesntSupportInstant|.
//
// If the TemplateURLID supplied to the constructor is zero, then the url is
// loaded as is.
class InstantLoader : public NotificationObserver {
public:
InstantLoader(InstantLoaderDelegate* delegate, TemplateURLID id);
virtual ~InstantLoader();
// Invoked to load a URL. |tab_contents| is the TabContents the preview is
// going to be shown on top of and potentially replace. Returns true if the
// arguments differ from the last call to |Update|.
bool Update(TabContentsWrapper* tab_contents,
const TemplateURL* template_url,
const GURL& url,
PageTransition::Type transition_type,
const string16& user_text,
bool verbatim,
string16* suggested_text);
// Sets the bounds of the omnibox (in screen coordinates). The bounds are
// remembered until the preview is committed or destroyed. This is only used
// when showing results for a search provider that supports instant.
void SetOmniboxBounds(const gfx::Rect& bounds);
// Returns true if the mouse is down as the result of activating the preview
// content.
bool IsMouseDownFromActivate();
// Releases the preview TabContents passing ownership to the caller. This is
// intended to be called when the preview TabContents is committed. This does
// not notify the delegate.
TabContentsWrapper* ReleasePreviewContents(InstantCommitType type);
// Calls through to method of same name on delegate.
bool ShouldCommitInstantOnMouseUp();
void CommitInstantLoader();
// NotificationObserver:
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) OVERRIDE;
// The preview TabContents; may be null.
TabContentsWrapper* preview_contents() const {
return preview_contents_.get();
}
// Returns true if the preview TabContents is ready to be shown.
bool ready() const { return ready_; }
// Returns true if the current load returned a 200.
bool http_status_ok() const { return http_status_ok_; }
// Returns true if the url needs to be reloaded. This is set to true for
// downloads.
bool needs_reload() const { return needs_reload_; }
const GURL& url() const { return url_; }
bool verbatim() const { return verbatim_; }
// Are we showing instant results?
bool is_showing_instant() const { return template_url_id_ != 0; }
// If we're showing instant this returns non-zero.
TemplateURLID template_url_id() const { return template_url_id_; }
// See description above field.
const string16& user_text() const { return user_text_; }
private:
friend class InstantLoaderManagerTest;
friend class InstantTest;
class FrameLoadObserver;
class PaintObserverImpl;
class TabContentsDelegateImpl;
// Invoked when the page wants to update the suggested text. If |user_text_|
// starts with |suggested_text|, then the delegate is notified of the change,
// which results in updating the omnibox.
void SetCompleteSuggestedText(const string16& suggested_text,
InstantCompleteBehavior behavior);
// Invoked when the page paints.
void PreviewPainted();
// Invoked when the http status code changes. This may notify the delegate.
void SetHTTPStatusOK(bool is_ok);
// Invoked to show the preview. This is invoked in two possible cases: when
// the renderer paints, or when an auth dialog is shown. This notifies the
// delegate the preview is ready to be shown.
void ShowPreview();
// Invoked once the page has finished loading and the script has been sent.
void PageFinishedLoading();
// Returns the bounds of the omnibox in terms of the preview tab contents.
gfx::Rect GetOmniboxBoundsInTermsOfPreview();
// Are we waiting for the preview page to finish loading?
bool is_waiting_for_load() const {
return frame_load_observer_.get() != NULL;
}
// Invoked if it the page doesn't really support instant when we thought it
// did. If |needs_reload| is true, the text changed since the first load and
// the page needs to be reloaded.
void PageDoesntSupportInstant(bool needs_reload);
// Invokes |SetBoundsToPage(false)|. This is called from the timer.
void ProcessBoundsChange();
// Notifes the page of the omnibox bounds. If |force_if_loading| is true the
// bounds are sent down even if we're waiting on the load, otherwise if we're
// waiting on the load and |force_if_loading| is false this does nothing.
void SendBoundsToPage(bool force_if_loading);
// Creates and sets the preview TabContentsWrapper.
void CreatePreviewContents(TabContentsWrapper* tab_contents);
InstantLoaderDelegate* delegate_;
// If we're showing instant results this is the ID of the TemplateURL driving
// the results. A value of 0 means there is no TemplateURL.
const TemplateURLID template_url_id_;
// The url we're displaying.
GURL url_;
// Delegate of the preview TabContents. Used to detect when the user does some
// gesture on the TabContents and the preview needs to be activated.
scoped_ptr<TabContentsDelegateImpl> preview_tab_contents_delegate_;
// The preview TabContents; may be null.
scoped_ptr<TabContentsWrapper> preview_contents_;
// Is the preview_contents ready to be shown?
bool ready_;
// Was the last status code a 200?
bool http_status_ok_;
// The text the user typed in the omnibox, stripped of the leading ?, if any.
string16 user_text_;
// The latest suggestion from the page.
string16 complete_suggested_text_;
// The latest suggestion (suggested text less the user text).
string16 last_suggestion_;
// See description above setter.
gfx::Rect omnibox_bounds_;
// Last bounds passed to the page.
gfx::Rect last_omnibox_bounds_;
scoped_ptr<FrameLoadObserver> frame_load_observer_;
// Transition type of the match last passed to Update.
PageTransition::Type last_transition_type_;
// Timer used to update the bounds of the omnibox.
base::OneShotTimer<InstantLoader> update_bounds_timer_;
// Used to get notifications about renderers coming and going.
NotificationRegistrar registrar_;
// Last value of verbatim passed to |Update|.
bool verbatim_;
// True if the page needs to be reloaded.
bool needs_reload_;
DISALLOW_COPY_AND_ASSIGN(InstantLoader);
};
#endif // CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_