1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_ 6 #define CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_ 7 #pragma once 8 9 #include "base/basictypes.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/string16.h" 12 #include "base/timer.h" 13 #include "chrome/browser/instant/instant_commit_type.h" 14 #include "chrome/browser/search_engines/template_url_id.h" 15 #include "chrome/common/instant_types.h" 16 #include "content/common/notification_observer.h" 17 #include "content/common/notification_registrar.h" 18 #include "content/common/page_transition_types.h" 19 #include "googleurl/src/gurl.h" 20 #include "ui/gfx/rect.h" 21 22 class InstantLoaderDelegate; 23 class InstantLoaderManagerTest; 24 class TabContents; 25 class TabContentsWrapper; 26 class TemplateURL; 27 28 // InstantLoader does the loading of a particular URL for InstantController. 29 // InstantLoader notifies its delegate, which is typically InstantController, of 30 // all interesting events. 31 // 32 // InstantLoader is created with a TemplateURLID. If non-zero InstantLoader 33 // first determines if the site actually supports instant. If it doesn't, the 34 // delegate is notified by way of |InstantLoaderDoesntSupportInstant|. 35 // 36 // If the TemplateURLID supplied to the constructor is zero, then the url is 37 // loaded as is. 38 class InstantLoader : public NotificationObserver { 39 public: 40 InstantLoader(InstantLoaderDelegate* delegate, TemplateURLID id); 41 virtual ~InstantLoader(); 42 43 // Invoked to load a URL. |tab_contents| is the TabContents the preview is 44 // going to be shown on top of and potentially replace. Returns true if the 45 // arguments differ from the last call to |Update|. 46 bool Update(TabContentsWrapper* tab_contents, 47 const TemplateURL* template_url, 48 const GURL& url, 49 PageTransition::Type transition_type, 50 const string16& user_text, 51 bool verbatim, 52 string16* suggested_text); 53 54 // Sets the bounds of the omnibox (in screen coordinates). The bounds are 55 // remembered until the preview is committed or destroyed. This is only used 56 // when showing results for a search provider that supports instant. 57 void SetOmniboxBounds(const gfx::Rect& bounds); 58 59 // Returns true if the mouse is down as the result of activating the preview 60 // content. 61 bool IsMouseDownFromActivate(); 62 63 // Releases the preview TabContents passing ownership to the caller. This is 64 // intended to be called when the preview TabContents is committed. This does 65 // not notify the delegate. 66 TabContentsWrapper* ReleasePreviewContents(InstantCommitType type); 67 68 // Calls through to method of same name on delegate. 69 bool ShouldCommitInstantOnMouseUp(); 70 void CommitInstantLoader(); 71 72 // NotificationObserver: 73 virtual void Observe(NotificationType type, 74 const NotificationSource& source, 75 const NotificationDetails& details) OVERRIDE; 76 77 // The preview TabContents; may be null. 78 TabContentsWrapper* preview_contents() const { 79 return preview_contents_.get(); 80 } 81 82 // Returns true if the preview TabContents is ready to be shown. 83 bool ready() const { return ready_; } 84 85 // Returns true if the current load returned a 200. 86 bool http_status_ok() const { return http_status_ok_; } 87 88 // Returns true if the url needs to be reloaded. This is set to true for 89 // downloads. 90 bool needs_reload() const { return needs_reload_; } 91 92 const GURL& url() const { return url_; } 93 94 bool verbatim() const { return verbatim_; } 95 96 // Are we showing instant results? 97 bool is_showing_instant() const { return template_url_id_ != 0; } 98 99 // If we're showing instant this returns non-zero. 100 TemplateURLID template_url_id() const { return template_url_id_; } 101 102 // See description above field. 103 const string16& user_text() const { return user_text_; } 104 105 private: 106 friend class InstantLoaderManagerTest; 107 friend class InstantTest; 108 class FrameLoadObserver; 109 class PaintObserverImpl; 110 class TabContentsDelegateImpl; 111 112 // Invoked when the page wants to update the suggested text. If |user_text_| 113 // starts with |suggested_text|, then the delegate is notified of the change, 114 // which results in updating the omnibox. 115 void SetCompleteSuggestedText(const string16& suggested_text, 116 InstantCompleteBehavior behavior); 117 118 // Invoked when the page paints. 119 void PreviewPainted(); 120 121 // Invoked when the http status code changes. This may notify the delegate. 122 void SetHTTPStatusOK(bool is_ok); 123 124 // Invoked to show the preview. This is invoked in two possible cases: when 125 // the renderer paints, or when an auth dialog is shown. This notifies the 126 // delegate the preview is ready to be shown. 127 void ShowPreview(); 128 129 // Invoked once the page has finished loading and the script has been sent. 130 void PageFinishedLoading(); 131 132 // Returns the bounds of the omnibox in terms of the preview tab contents. 133 gfx::Rect GetOmniboxBoundsInTermsOfPreview(); 134 135 // Are we waiting for the preview page to finish loading? 136 bool is_waiting_for_load() const { 137 return frame_load_observer_.get() != NULL; 138 } 139 140 // Invoked if it the page doesn't really support instant when we thought it 141 // did. If |needs_reload| is true, the text changed since the first load and 142 // the page needs to be reloaded. 143 void PageDoesntSupportInstant(bool needs_reload); 144 145 // Invokes |SetBoundsToPage(false)|. This is called from the timer. 146 void ProcessBoundsChange(); 147 148 // Notifes the page of the omnibox bounds. If |force_if_loading| is true the 149 // bounds are sent down even if we're waiting on the load, otherwise if we're 150 // waiting on the load and |force_if_loading| is false this does nothing. 151 void SendBoundsToPage(bool force_if_loading); 152 153 // Creates and sets the preview TabContentsWrapper. 154 void CreatePreviewContents(TabContentsWrapper* tab_contents); 155 156 InstantLoaderDelegate* delegate_; 157 158 // If we're showing instant results this is the ID of the TemplateURL driving 159 // the results. A value of 0 means there is no TemplateURL. 160 const TemplateURLID template_url_id_; 161 162 // The url we're displaying. 163 GURL url_; 164 165 // Delegate of the preview TabContents. Used to detect when the user does some 166 // gesture on the TabContents and the preview needs to be activated. 167 scoped_ptr<TabContentsDelegateImpl> preview_tab_contents_delegate_; 168 169 // The preview TabContents; may be null. 170 scoped_ptr<TabContentsWrapper> preview_contents_; 171 172 // Is the preview_contents ready to be shown? 173 bool ready_; 174 175 // Was the last status code a 200? 176 bool http_status_ok_; 177 178 // The text the user typed in the omnibox, stripped of the leading ?, if any. 179 string16 user_text_; 180 181 // The latest suggestion from the page. 182 string16 complete_suggested_text_; 183 184 // The latest suggestion (suggested text less the user text). 185 string16 last_suggestion_; 186 187 // See description above setter. 188 gfx::Rect omnibox_bounds_; 189 190 // Last bounds passed to the page. 191 gfx::Rect last_omnibox_bounds_; 192 193 scoped_ptr<FrameLoadObserver> frame_load_observer_; 194 195 // Transition type of the match last passed to Update. 196 PageTransition::Type last_transition_type_; 197 198 // Timer used to update the bounds of the omnibox. 199 base::OneShotTimer<InstantLoader> update_bounds_timer_; 200 201 // Used to get notifications about renderers coming and going. 202 NotificationRegistrar registrar_; 203 204 // Last value of verbatim passed to |Update|. 205 bool verbatim_; 206 207 // True if the page needs to be reloaded. 208 bool needs_reload_; 209 210 DISALLOW_COPY_AND_ASSIGN(InstantLoader); 211 }; 212 213 #endif // CHROME_BROWSER_INSTANT_INSTANT_LOADER_H_ 214