Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: chrome/browser/tab_contents/match_preview.cc

Issue 3332022: Bunch of match preview tweaks: (Closed)
Patch Set: Add string16 include Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/tab_contents/match_preview.h" 5 #include "chrome/browser/tab_contents/match_preview.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/autocomplete/autocomplete.h"
12 #include "chrome/browser/favicon_service.h"
13 #include "chrome/browser/history/history_marshaling.h"
14 #include "chrome/browser/profile.h"
15 #include "chrome/browser/renderer_host/render_view_host.h"
16 #include "chrome/browser/renderer_host/render_widget_host.h"
17 #include "chrome/browser/renderer_host/render_widget_host_view.h"
18 #include "chrome/browser/search_engines/template_url.h"
19 #include "chrome/browser/search_engines/template_url_model.h"
20 #include "chrome/browser/tab_contents/match_preview_delegate.h"
10 #include "chrome/browser/tab_contents/navigation_controller.h" 21 #include "chrome/browser/tab_contents/navigation_controller.h"
11 #include "chrome/browser/tab_contents/navigation_entry.h" 22 #include "chrome/browser/tab_contents/navigation_entry.h"
12 #include "chrome/browser/tab_contents/tab_contents.h" 23 #include "chrome/browser/tab_contents/tab_contents.h"
13 #include "chrome/browser/tab_contents/tab_contents_delegate.h" 24 #include "chrome/browser/tab_contents/tab_contents_delegate.h"
25 #include "chrome/browser/tab_contents/tab_contents_view.h"
14 #include "chrome/common/chrome_switches.h" 26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/notification_observer.h"
28 #include "chrome/common/notification_registrar.h"
15 #include "chrome/common/notification_service.h" 29 #include "chrome/common/notification_service.h"
16 #include "chrome/common/page_transition_types.h" 30 #include "chrome/common/page_transition_types.h"
31 #include "chrome/common/render_messages.h"
17 #include "chrome/common/renderer_preferences.h" 32 #include "chrome/common/renderer_preferences.h"
33 #include "gfx/codec/png_codec.h"
18 #include "ipc/ipc_message.h" 34 #include "ipc/ipc_message.h"
19 35
36 namespace {
37
38 const char kUserInputScript[] =
39 "if (window.chrome.userInput) window.chrome.userInput(\"$1\");";
40
41 // Sends the user input script to |tab_contents|. |text| is the text the user
42 // input into the omnibox.
43 void SendUserInputScript(TabContents* tab_contents,
44 const string16& text,
45 bool done) {
46 // TODO: support done.
47 string16 escaped_text(text);
48 ReplaceSubstringsAfterOffset(&escaped_text, 0L, ASCIIToUTF16("\""),
49 ASCIIToUTF16("\\\""));
50 string16 script = ReplaceStringPlaceholders(ASCIIToUTF16(kUserInputScript),
51 escaped_text, NULL);
52 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
53 std::wstring(),
54 UTF16ToWide(script));
55 }
56
57 } // namespace
58
59 // FrameLoadObserver is responsible for waiting for the TabContents to finish
60 // loading and when done sending the necessary script down to the page.
61 class MatchPreview::FrameLoadObserver : public NotificationObserver {
62 public:
63 FrameLoadObserver(MatchPreview* match_preview, const string16& text)
64 : match_preview_(match_preview),
65 tab_contents_(match_preview->preview_contents()),
66 unique_id_(tab_contents_->controller().pending_entry()->unique_id()),
67 text_(text),
68 send_done_(false) {
69 registrar_.Add(this, NotificationType::LOAD_COMPLETED_MAIN_FRAME,
70 Source<TabContents>(tab_contents_));
71 registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED,
72 Source<TabContents>(tab_contents_));
73 }
74
75 // Sets the text to send to the page.
76 void set_text(const string16& text) { text_ = text; }
77
78 // Invoked when the MatchPreview releases ownership of the TabContents and
79 // the page hasn't finished loading.
80 void DetachFromPreview() {
81 match_preview_ = NULL;
82 send_done_ = true;
83 }
84
85 // NotificationObserver:
86 virtual void Observe(NotificationType type,
87 const NotificationSource& source,
88 const NotificationDetails& details) {
89 switch (type.value) {
90 case NotificationType::LOAD_COMPLETED_MAIN_FRAME: {
91 int page_id = *(Details<int>(details).ptr());
92 NavigationEntry* active_entry =
93 tab_contents_->controller().GetActiveEntry();
94 if (!active_entry || active_entry->page_id() != page_id ||
95 active_entry->unique_id() != unique_id_) {
96 return;
97 }
98
99 SendUserInputScript(tab_contents_, text_, send_done_);
100
101 if (match_preview_)
102 match_preview_->PageFinishedLoading();
103
104 delete this;
105 return;
106 }
107
108 case NotificationType::TAB_CONTENTS_DESTROYED:
109 delete this;
110 return;
111
112 default:
113 NOTREACHED();
114 break;
115 }
116 }
117
118 private:
119 // MatchPreview that created us.
120 MatchPreview* match_preview_;
121
122 // The TabContents we're listening for changes on.
123 TabContents* tab_contents_;
124
125 // unique_id of the NavigationEntry we're waiting on.
126 const int unique_id_;
127
128 // Text to send down to the page.
129 string16 text_;
130
131 // Passed to SendScript.
132 bool send_done_;
133
134 // Registers and unregisters us for notifications.
135 NotificationRegistrar registrar_;
136
137 DISALLOW_COPY_AND_ASSIGN(FrameLoadObserver);
138 };
139
140 // PaintObserver implementation. When the RenderWidgetHost paints itself this
141 // notifies MatchPreview, which makes the TabContents active.
142 class MatchPreview::PaintObserverImpl : public RenderWidgetHost::PaintObserver {
143 public:
144 explicit PaintObserverImpl(MatchPreview* preview)
145 : match_preview_(preview) {
146 }
147
148 virtual void RenderWidgetHostWillPaint(RenderWidgetHost* rwh) {
149 }
150
151 virtual void RenderWidgetHostDidPaint(RenderWidgetHost* rwh) {
152 match_preview_->PreviewDidPaint();
153 rwh->set_paint_observer(NULL);
154 // WARNING: we've been deleted.
155 }
156
157 private:
158 MatchPreview* match_preview_;
159
160 DISALLOW_COPY_AND_ASSIGN(PaintObserverImpl);
161 };
162
20 class MatchPreview::TabContentsDelegateImpl : public TabContentsDelegate { 163 class MatchPreview::TabContentsDelegateImpl : public TabContentsDelegate {
21 public: 164 public:
22 explicit TabContentsDelegateImpl(MatchPreview* match_preview) 165 explicit TabContentsDelegateImpl(MatchPreview* match_preview)
23 : match_preview_(match_preview) { 166 : match_preview_(match_preview),
167 installed_paint_observer_(false),
168 waiting_for_new_page_(true) {
169 }
170
171 // Invoked prior to loading a new URL.
172 void PrepareForNewLoad() {
173 waiting_for_new_page_ = true;
174 add_page_vector_.clear();
175 }
176
177 // Invoked when removed as the delegate. Gives a chance to do any necessary
178 // cleanup.
179 void Reset() {
180 installed_paint_observer_ = false;
181 }
182
183 // Commits the currently buffered history.
184 void CommitHistory() {
185 TabContents* tab = match_preview_->preview_contents();
186 if (tab->profile()->IsOffTheRecord())
187 return;
188
189 for (size_t i = 0; i < add_page_vector_.size(); ++i)
190 tab->UpdateHistoryForNavigation(add_page_vector_[i].get());
191
192 NavigationEntry* active_entry = tab->controller().GetActiveEntry();
193 DCHECK(active_entry);
194 tab->UpdateHistoryPageTitle(*active_entry);
195
196 FaviconService* favicon_service =
197 tab->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS);
198
199 if (favicon_service && active_entry->favicon().is_valid() &&
200 !active_entry->favicon().bitmap().empty()) {
201 std::vector<unsigned char> image_data;
202 gfx::PNGCodec::EncodeBGRASkBitmap(active_entry->favicon().bitmap(), false,
203 &image_data);
204 favicon_service->SetFavicon(active_entry->url(),
205 active_entry->favicon().url(),
206 image_data);
207 }
24 } 208 }
25 209
26 virtual void OpenURLFromTab(TabContents* source, 210 virtual void OpenURLFromTab(TabContents* source,
27 const GURL& url, const GURL& referrer, 211 const GURL& url, const GURL& referrer,
28 WindowOpenDisposition disposition, 212 WindowOpenDisposition disposition,
29 PageTransition::Type transition) {} 213 PageTransition::Type transition) {}
30 virtual void NavigationStateChanged(const TabContents* source, 214 virtual void NavigationStateChanged(const TabContents* source,
31 unsigned changed_flags) {} 215 unsigned changed_flags) {
216 if (!installed_paint_observer_ && source->controller().entry_count()) {
217 // The load has been committed. Install an observer that waits for the
218 // first paint then makes the preview active. We wait for the load to be
219 // committed before waiting on paint as there is always an initial paint
220 // when a new renderer is created from the resize so that if we showed the
221 // preview after the first paint we would end up with a white rect.
222 installed_paint_observer_ = true;
223 source->GetRenderWidgetHostView()->GetRenderWidgetHost()->
224 set_paint_observer(new PaintObserverImpl(match_preview_));
225 }
226 }
32 virtual void AddNewContents(TabContents* source, 227 virtual void AddNewContents(TabContents* source,
33 TabContents* new_contents, 228 TabContents* new_contents,
34 WindowOpenDisposition disposition, 229 WindowOpenDisposition disposition,
35 const gfx::Rect& initial_pos, 230 const gfx::Rect& initial_pos,
36 bool user_gesture) {} 231 bool user_gesture) {}
37 virtual void ActivateContents(TabContents* contents) { 232 virtual void ActivateContents(TabContents* contents) {
38 match_preview_->CommitCurrentPreview();
39 } 233 }
40 virtual void DeactivateContents(TabContents* contents) {} 234 virtual void DeactivateContents(TabContents* contents) {}
41 virtual void LoadingStateChanged(TabContents* source) {} 235 virtual void LoadingStateChanged(TabContents* source) {}
42 virtual void CloseContents(TabContents* source) {} 236 virtual void CloseContents(TabContents* source) {}
43 virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {} 237 virtual void MoveContents(TabContents* source, const gfx::Rect& pos) {}
44 virtual void DetachContents(TabContents* source) {} 238 virtual void DetachContents(TabContents* source) {}
45 virtual bool IsPopup(const TabContents* source) const { 239 virtual bool IsPopup(const TabContents* source) const {
46 return false; 240 return false;
47 } 241 }
48 virtual TabContents* GetConstrainingContents(TabContents* source) { 242 virtual TabContents* GetConstrainingContents(TabContents* source) {
49 return NULL; 243 return NULL;
50 } 244 }
51 virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {} 245 virtual void ToolbarSizeChanged(TabContents* source, bool is_animating) {}
52 virtual void URLStarredChanged(TabContents* source, bool starred) {} 246 virtual void URLStarredChanged(TabContents* source, bool starred) {}
53 virtual void UpdateTargetURL(TabContents* source, const GURL& url) {} 247 virtual void UpdateTargetURL(TabContents* source, const GURL& url) {}
54 virtual void ContentsMouseEvent( 248 virtual void ContentsMouseEvent(
55 TabContents* source, const gfx::Point& location, bool motion) {} 249 TabContents* source, const gfx::Point& location, bool motion) {}
56 virtual void ContentsZoomChange(bool zoom_in) {} 250 virtual void ContentsZoomChange(bool zoom_in) {}
57 virtual void OnContentSettingsChange(TabContents* source) {} 251 virtual void OnContentSettingsChange(TabContents* source) {}
58 virtual bool IsApplication() const { return false; } 252 virtual bool IsApplication() const { return false; }
59 virtual void ConvertContentsToApplication(TabContents* source) {} 253 virtual void ConvertContentsToApplication(TabContents* source) {}
60 virtual bool CanReloadContents(TabContents* source) const { return true; } 254 virtual bool CanReloadContents(TabContents* source) const { return true; }
61 virtual gfx::Rect GetRootWindowResizerRect() const { 255 virtual gfx::Rect GetRootWindowResizerRect() const {
62 return match_preview_->host_->delegate() ? 256 return gfx::Rect();
63 match_preview_->host_->delegate()->GetRootWindowResizerRect() :
64 gfx::Rect();
65 } 257 }
66 virtual void ShowHtmlDialog(HtmlDialogUIDelegate* delegate, 258 virtual void ShowHtmlDialog(HtmlDialogUIDelegate* delegate,
67 gfx::NativeWindow parent_window) {} 259 gfx::NativeWindow parent_window) {}
68 virtual void BeforeUnloadFired(TabContents* tab, 260 virtual void BeforeUnloadFired(TabContents* tab,
69 bool proceed, 261 bool proceed,
70 bool* proceed_to_fire_unload) {} 262 bool* proceed_to_fire_unload) {}
71 virtual void ForwardMessageToExternalHost(const std::string& message, 263 virtual void ForwardMessageToExternalHost(const std::string& message,
72 const std::string& origin, 264 const std::string& origin,
73 const std::string& target) {} 265 const std::string& target) {}
74 virtual bool IsExternalTabContainer() const { return false; } 266 virtual bool IsExternalTabContainer() const { return false; }
75 virtual void SetFocusToLocationBar(bool select_all) {} 267 virtual void SetFocusToLocationBar(bool select_all) {}
76 virtual void RenderWidgetShowing() {} 268 virtual void RenderWidgetShowing() {}
77 virtual ExtensionFunctionDispatcher* CreateExtensionFunctionDispatcher( 269 virtual ExtensionFunctionDispatcher* CreateExtensionFunctionDispatcher(
78 RenderViewHost* render_view_host, 270 RenderViewHost* render_view_host,
79 const std::string& extension_id) { 271 const std::string& extension_id) {
80 return NULL; 272 return NULL;
81 } 273 }
82 virtual bool TakeFocus(bool reverse) { return false; } 274 virtual bool TakeFocus(bool reverse) { return false; }
83 virtual void SetTabContentBlocked(TabContents* contents, bool blocked) {} 275 virtual void SetTabContentBlocked(TabContents* contents, bool blocked) {}
84 virtual void TabContentsFocused(TabContents* tab_content) { 276 virtual void TabContentsFocused(TabContents* tab_content) {
85 match_preview_->CommitCurrentPreview();
86 } 277 }
87 virtual int GetExtraRenderViewHeight() const { return 0; } 278 virtual int GetExtraRenderViewHeight() const { return 0; }
88 virtual bool CanDownload(int request_id) { return false; } 279 virtual bool CanDownload(int request_id) { return false; }
89 virtual void OnStartDownload(DownloadItem* download, TabContents* tab) {} 280 virtual void OnStartDownload(DownloadItem* download, TabContents* tab) {}
90 virtual bool HandleContextMenu(const ContextMenuParams& params) { 281 virtual bool HandleContextMenu(const ContextMenuParams& params) {
91 return false; 282 return false;
92 } 283 }
93 virtual bool ExecuteContextMenuCommand(int command) { 284 virtual bool ExecuteContextMenuCommand(int command) {
94 return false; 285 return false;
95 } 286 }
96 virtual void ConfirmAddSearchProvider(const TemplateURL* template_url, 287 virtual void ConfirmAddSearchProvider(const TemplateURL* template_url,
97 Profile* profile) {} 288 Profile* profile) {}
98 virtual void ShowPageInfo(Profile* profile, 289 virtual void ShowPageInfo(Profile* profile,
99 const GURL& url, 290 const GURL& url,
100 const NavigationEntry::SSLStatus& ssl, 291 const NavigationEntry::SSLStatus& ssl,
101 bool show_history) {} 292 bool show_history) {}
102 virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, 293 virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
103 bool* is_keyboard_shortcut) { 294 bool* is_keyboard_shortcut) {
104 return false; 295 return false;
105 } 296 }
106 virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {} 297 virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {}
107 virtual void ShowRepostFormWarningDialog(TabContents* tab_contents) {} 298 virtual void ShowRepostFormWarningDialog(TabContents* tab_contents) {}
108 virtual void ShowContentSettingsWindow(ContentSettingsType content_type) {} 299 virtual void ShowContentSettingsWindow(ContentSettingsType content_type) {}
109 virtual void ShowCollectedCookiesDialog(TabContents* tab_contents) {} 300 virtual void ShowCollectedCookiesDialog(TabContents* tab_contents) {}
110 virtual bool OnGoToEntryOffset(int offset) { return false; } 301 virtual bool OnGoToEntryOffset(int offset) { return false; }
111 virtual bool ShouldAddNavigationToHistory( 302 virtual bool ShouldAddNavigationsToHistory(
112 const history::HistoryAddPageArgs& add_page_args, 303 const history::HistoryAddPageArgs& add_page_args,
113 NavigationType::Type navigation_type) { 304 NavigationType::Type navigation_type) {
305 if (waiting_for_new_page_ && navigation_type == NavigationType::NEW_PAGE)
306 waiting_for_new_page_ = false;
307
308 if (!waiting_for_new_page_) {
309 add_page_vector_.push_back(
310 scoped_refptr<history::HistoryAddPageArgs>(add_page_args.Clone()));
311 }
114 return false; 312 return false;
115 } 313 }
116 virtual void OnDidGetApplicationInfo(TabContents* tab_contents, 314 virtual void OnDidGetApplicationInfo(TabContents* tab_contents,
117 int32 page_id) {} 315 int32 page_id) {}
118 virtual gfx::NativeWindow GetFrameNativeWindow() { 316 virtual gfx::NativeWindow GetFrameNativeWindow() {
119 return match_preview_->host_->delegate() ? 317 return NULL;
120 match_preview_->host_->delegate()->GetFrameNativeWindow() : NULL;
121 } 318 }
122 virtual void TabContentsCreated(TabContents* new_contents) {} 319 virtual void TabContentsCreated(TabContents* new_contents) {}
123 virtual bool infobars_enabled() { return false; } 320 virtual bool infobars_enabled() { return false; }
124 virtual bool ShouldEnablePreferredSizeNotifications() { return false; } 321 virtual bool ShouldEnablePreferredSizeNotifications() { return false; }
125 virtual void UpdatePreferredSize(const gfx::Size& pref_size) {} 322 virtual void UpdatePreferredSize(const gfx::Size& pref_size) {}
126 virtual void ContentTypeChanged(TabContents* source) {} 323 virtual void ContentTypeChanged(TabContents* source) {}
127 324
325 virtual void OnSetSuggestResult(int32 page_id, const std::string& result) {
326 TabContents* source = match_preview_->preview_contents();
327 // TODO: only allow for default search provider.
328 if (source->controller().GetActiveEntry() &&
329 page_id == source->controller().GetActiveEntry()->page_id()) {
330 match_preview_->SetCompleteSuggestedText(UTF8ToUTF16(result));
331 }
332 }
333
128 private: 334 private:
335 typedef std::vector<scoped_refptr<history::HistoryAddPageArgs> >
336 AddPageVector;
337
129 MatchPreview* match_preview_; 338 MatchPreview* match_preview_;
130 339
340 // Has the paint observer been installed? See comment in
341 // NavigationStateChanged for details on this.
342 bool installed_paint_observer_;
343
344 // Used to cache data that needs to be added to history. Normally entries are
345 // added to history as the user types, but for match preview we only want to
346 // add the items to history if the user commits the match preview. So, we
347 // cache them here and if committed then add the items to history.
348 AddPageVector add_page_vector_;
349
350 // Are we we waiting for a NavigationType of NEW_PAGE? If we're waiting for
351 // NEW_PAGE navigation we don't add history items to add_page_vector_.
352 bool waiting_for_new_page_;
353
131 DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl); 354 DISALLOW_COPY_AND_ASSIGN(TabContentsDelegateImpl);
132 }; 355 };
133 356
134 MatchPreview::MatchPreview(TabContents* host) : host_(host) {
135 delegate_.reset(new TabContentsDelegateImpl(this));
136 }
137
138 MatchPreview::~MatchPreview() {
139 // Delete the TabContents before the delegate as the TabContents holds a
140 // reference to the delegate.
141 preview_contents_.reset(NULL);
142 }
143
144 // static 357 // static
145 bool MatchPreview::IsEnabled() { 358 bool MatchPreview::IsEnabled() {
146 static bool enabled = false; 359 static bool enabled = false;
147 static bool checked = false; 360 static bool checked = false;
148 if (!checked) { 361 if (!checked) {
149 checked = true; 362 checked = true;
150 enabled = CommandLine::ForCurrentProcess()->HasSwitch( 363 enabled = CommandLine::ForCurrentProcess()->HasSwitch(
151 switches::kEnableMatchPreview); 364 switches::kEnableMatchPreview);
152 } 365 }
153 return enabled; 366 return enabled;
154 } 367 }
155 368
156 void MatchPreview::Update(const GURL& url) { 369 MatchPreview::MatchPreview(MatchPreviewDelegate* delegate)
157 if (url_ == url) 370 : delegate_(delegate),
371 tab_contents_(NULL),
372 is_active_(false),
373 template_url_id_(0) {
374 preview_tab_contents_delegate_.reset(new TabContentsDelegateImpl(this));
375 }
376
377 MatchPreview::~MatchPreview() {
378 // Delete the TabContents before the delegate as the TabContents holds a
379 // reference to the delegate.
380 preview_contents_.reset(NULL);
381 }
382
383 void MatchPreview::Update(TabContents* tab_contents,
384 const AutocompleteMatch& match,
385 const string16& user_text,
386 string16* suggested_text) {
387 if (tab_contents != tab_contents_)
388 DestroyPreviewContents();
389
390 tab_contents_ = tab_contents;
391
392 if (url_ == match.destination_url)
158 return; 393 return;
159 394
160 url_ = url; 395 url_ = match.destination_url;
161 396
162 if (url_.is_empty() || !url_.is_valid()) { 397 if (url_.is_empty() || !url_.is_valid()) {
163 DestroyPreviewContents(); 398 DestroyPreviewContents();
164 return; 399 return;
165 } 400 }
166 401
167 if (!preview_contents_.get()) { 402 user_text_ = user_text;
403
404 if (preview_contents_.get() == NULL) {
168 preview_contents_.reset( 405 preview_contents_.reset(
169 new TabContents(host_->profile(), NULL, MSG_ROUTING_NONE, NULL, NULL)); 406 new TabContents(tab_contents_->profile(), NULL, MSG_ROUTING_NONE,
170 preview_contents_->set_delegate(delegate_.get()); 407 NULL, NULL));
171 NotificationService::current()->Notify( 408 // Propagate the max page id. That way if we end up merging the two
172 NotificationType::MATCH_PREVIEW_TAB_CONTENTS_CREATED, 409 // NavigationControllers (which happens if we commit) none of the page ids
173 Source<TabContents>(host_), 410 // will overlap.
174 NotificationService::NoDetails()); 411 int32 max_page_id = tab_contents_->GetMaxPageID();
412 if (max_page_id != -1)
413 preview_contents_->controller().set_max_restored_page_id(max_page_id + 1);
414
415 preview_contents_->set_delegate(preview_tab_contents_delegate_.get());
416
417 gfx::Rect tab_bounds;
418 tab_contents_->view()->GetContainerBounds(&tab_bounds);
419 preview_contents_->view()->SizeContents(tab_bounds.size());
420
421 preview_contents_->ShowContents();
422 }
423 preview_tab_contents_delegate_->PrepareForNewLoad();
424
425 const TemplateURL* template_url = match.template_url;
426 if (match.type == AutocompleteMatch::SEARCH_WHAT_YOU_TYPED ||
427 match.type == AutocompleteMatch::SEARCH_HISTORY ||
428 match.type == AutocompleteMatch::SEARCH_SUGGEST) {
429 TemplateURLModel* model = tab_contents->profile()->GetTemplateURLModel();
430 template_url = model ? model->GetDefaultSearchProvider() : NULL;
431 }
432 TemplateURLID template_url_id = template_url ? template_url->id() : 0;
433
434 if (template_url && template_url->supports_instant() &&
435 TemplateURL::SupportsReplacement(template_url)) {
436 if (template_url_id == template_url_id_) {
437 if (frame_load_observer_.get()) {
438 // The page hasn't loaded yet. We'll send the script down when it does.
439 frame_load_observer_->set_text(user_text_);
440 return;
441 }
442 SendUserInputScript(preview_contents_.get(), user_text_, false);
443 if (complete_suggested_text_.size() > user_text_.size() &&
444 !complete_suggested_text_.compare(0, user_text_.size(), user_text_)) {
445 *suggested_text = complete_suggested_text_.substr(user_text_.size());
446 }
447 } else {
448 // TODO: should we use a different url for instant?
449 GURL url = GURL(template_url->url()->ReplaceSearchTerms(
450 *template_url, std::wstring(),
451 TemplateURLRef::NO_SUGGESTIONS_AVAILABLE, std::wstring()));
452 // user_text_ is sent once the page finishes loading by FrameLoadObserver.
453 preview_contents_->controller().LoadURL(url, GURL(), match.transition);
454 frame_load_observer_.reset(new FrameLoadObserver(this, user_text_));
455 }
456 } else {
457 frame_load_observer_.reset(NULL);
458 preview_contents_->controller().LoadURL(url_, GURL(), match.transition);
175 } 459 }
176 460
177 // TODO: figure out transition type. 461 template_url_id_ = template_url_id;
178 preview_contents_->controller().LoadURL(url, GURL(),
179 PageTransition::GENERATED);
180 } 462 }
181 463
182 void MatchPreview::DestroyPreviewContents() { 464 void MatchPreview::DestroyPreviewContents() {
183 url_ = GURL(); 465 delegate_->HideMatchPreview();
184 preview_contents_.reset(NULL); 466 delete ReleasePreviewContents(false);
185 } 467 }
186 468
187 void MatchPreview::CommitCurrentPreview() { 469 void MatchPreview::CommitCurrentPreview() {
188 DCHECK(preview_contents_.get()); 470 DCHECK(preview_contents_.get());
189 if (host_->delegate()) 471 delegate_->CommitMatchPreview();
190 host_->delegate()->CommitMatchPreview(host_);
191 } 472 }
192 473
193 TabContents* MatchPreview::ReleasePreviewContents() { 474 TabContents* MatchPreview::ReleasePreviewContents(bool commit_history) {
475 template_url_id_ = 0;
194 url_ = GURL(); 476 url_ = GURL();
477 user_text_.clear();
478 complete_suggested_text_.clear();
479 if (frame_load_observer_.get()) {
480 frame_load_observer_->DetachFromPreview();
481 // FrameLoadObserver will delete itself either when the TabContents is
482 // deleted, or when the page finishes loading.
483 FrameLoadObserver* unused ALLOW_UNUSED = frame_load_observer_.release();
484 }
485 if (preview_contents_.get()) {
486 if (commit_history)
487 preview_tab_contents_delegate_->CommitHistory();
488 // Destroy the paint observer.
489 if (preview_contents_->GetRenderWidgetHostView()) {
490 // RenderWidgetHostView may be null during shutdown.
491 preview_contents_->GetRenderWidgetHostView()->GetRenderWidgetHost()->
492 set_paint_observer(NULL);
493 }
494 preview_contents_->set_delegate(NULL);
495 preview_tab_contents_delegate_->Reset();
496 is_active_ = false;
497 }
195 return preview_contents_.release(); 498 return preview_contents_.release();
196 } 499 }
500
501 void MatchPreview::SetCompleteSuggestedText(
502 const string16& complete_suggested_text) {
503 if (complete_suggested_text == complete_suggested_text_)
504 return;
505
506 if (user_text_.compare(0, user_text_.size(), complete_suggested_text,
507 0, user_text_.size())) {
508 // The user text no longer contains the suggested text, ignore it.
509 complete_suggested_text_.clear();
510 delegate_->SetSuggestedText(string16());
511 return;
512 }
513
514 complete_suggested_text_ = complete_suggested_text;
515 delegate_->SetSuggestedText(
516 complete_suggested_text_.substr(user_text_.size()));
517 }
518
519 void MatchPreview::PreviewDidPaint() {
520 DCHECK(!is_active_);
521 is_active_ = true;
522 delegate_->ShowMatchPreview();
523 }
524
525 void MatchPreview::PageFinishedLoading() {
526 // FrameLoadObserver deletes itself after this call.
527 FrameLoadObserver* unused ALLOW_UNUSED = frame_load_observer_.release();
528 }
OLDNEW
« no previous file with comments | « chrome/browser/tab_contents/match_preview.h ('k') | chrome/browser/tab_contents/match_preview_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698