diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-22 03:32:47 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-22 03:32:47 +0000 |
commit | 46fe8e9ecede8772df308ae083fec770998d1ecc (patch) | |
tree | 81d030fd53d613f49f24e286fe4c933eac06f587 /chrome | |
parent | 5746640f419fe2b493ed4e97aa473e96f73c8d73 (diff) | |
download | chromium_src-46fe8e9ecede8772df308ae083fec770998d1ecc.zip chromium_src-46fe8e9ecede8772df308ae083fec770998d1ecc.tar.gz chromium_src-46fe8e9ecede8772df308ae083fec770998d1ecc.tar.bz2 |
Makes match preview send the dimensions of the omnibox to the page.
BUG=54833
TEST=none
Review URL: http://codereview.chromium.org/3417011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60153 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
24 files changed, 170 insertions, 4 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit.cc b/chrome/browser/autocomplete/autocomplete_edit.cc index fa8d600..3201f2a 100644 --- a/chrome/browser/autocomplete/autocomplete_edit.cc +++ b/chrome/browser/autocomplete/autocomplete_edit.cc @@ -672,6 +672,12 @@ bool AutocompleteEditModel::OnAfterPossibleChange(const std::wstring& new_text, return true; } +void AutocompleteEditModel::PopupBoundsChangedTo(const gfx::Rect& bounds) { +#if defined(TOOLKIT_VIEWS) + controller_->OnPopupBoundsChanged(bounds); +#endif +} + // Return true if the suggestion type warrants a TCP/IP preconnection. // i.e., it is now highly likely that the user will select the related domain. static bool IsPreconnectable(AutocompleteMatch::Type type) { diff --git a/chrome/browser/autocomplete/autocomplete_edit.h b/chrome/browser/autocomplete/autocomplete_edit.h index 1454111..caca730 100644 --- a/chrome/browser/autocomplete/autocomplete_edit.h +++ b/chrome/browser/autocomplete/autocomplete_edit.h @@ -22,6 +22,10 @@ class AutocompleteEditController; class AutocompleteEditModel; class AutocompleteEditView; +namespace gfx { +class Rect; +} + // TODO(pkasting): The names and contents of the classes in // this file are temporary. I am in hack-and-slash mode right now. // http://code.google.com/p/chromium/issues/detail?id=6772 @@ -40,6 +44,9 @@ class AutocompleteEditController { // Sent prior to OnAutoCompleteAccept and before the model has been reverted. virtual void OnAutocompleteWillAccept() = 0; + + // Invoked when the popup is going to change its bounds to |bounds|. + virtual void OnPopupBoundsChanged(const gfx::Rect& bounds) = 0; #else // TODO: port. #endif @@ -308,6 +315,9 @@ class AutocompleteEditModel : public NotificationObserver { bool just_deleted_text, bool at_end_of_edit); + // Invoked when the popup is going to change its bounds to |bounds|. + void PopupBoundsChangedTo(const gfx::Rect& bounds); + private: enum PasteState { NONE, // Most recent edit was not a paste that replaced all text. diff --git a/chrome/browser/autocomplete/autocomplete_edit_unittest.cc b/chrome/browser/autocomplete/autocomplete_edit_unittest.cc index cc8c6049..bca3c54 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_unittest.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_unittest.cc @@ -64,6 +64,7 @@ class TestingAutocompleteEditController : public AutocompleteEditController { virtual void OnAutocompleteWillClosePopup() {} virtual void OnAutocompleteLosingFocus(gfx::NativeView view_gaining_focus) {} virtual void OnAutocompleteWillAccept() {} + virtual void OnPopupBoundsChanged(const gfx::Rect& bounds) {} virtual void OnAutocompleteAccept(const GURL& url, WindowOpenDisposition disposition, PageTransition::Type transition, diff --git a/chrome/browser/autocomplete/autocomplete_popup_model.cc b/chrome/browser/autocomplete/autocomplete_popup_model.cc index 74cbb1f..7456ccd 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_model.cc +++ b/chrome/browser/autocomplete/autocomplete_popup_model.cc @@ -14,6 +14,7 @@ #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/common/notification_service.h" +#include "gfx/rect.h" /////////////////////////////////////////////////////////////////////////////// // AutocompletePopupModel @@ -291,6 +292,12 @@ void AutocompletePopupModel::Observe(NotificationType type, SetHoveredLine(kNoMatch); view_->UpdatePopupAppearance(); + +#if defined(TOOLKIT_VIEWS) + edit_model_->PopupBoundsChangedTo(view_->GetTargetBounds()); +#else + // TODO: port +#endif } const SkBitmap* AutocompletePopupModel::GetSpecialIconForMatch( diff --git a/chrome/browser/autocomplete/autocomplete_popup_view.h b/chrome/browser/autocomplete/autocomplete_popup_view.h index 5eb8c82..279d63d 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view.h +++ b/chrome/browser/autocomplete/autocomplete_popup_view.h @@ -30,6 +30,13 @@ class AutocompletePopupView { // mean opening or closing the window. virtual void UpdatePopupAppearance() = 0; +#if defined(TOOLKIT_VIEWS) + // Returns the target bounds for the popup. This returns the popup's current + // bounds when not animating, or the desired target bounds when animating. + // The return value is in screen coordinates. + virtual gfx::Rect GetTargetBounds() = 0; +#endif + // Paint any pending updates. virtual void PaintUpdatesNow() = 0; diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 8334742..d636310 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -3288,6 +3288,10 @@ void Browser::SetSuggestedText(const string16& text) { window()->GetLocationBar()->SetSuggestedText(text); } +gfx::Rect Browser::GetMatchPreviewBounds() { + return window()->GetMatchPreviewBounds(); +} + /////////////////////////////////////////////////////////////////////////////// // Browser, Command and state updating (private): diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 6b57e25..0982959 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -776,6 +776,7 @@ class Browser : public TabStripModelDelegate, virtual void HideMatchPreview(); virtual void CommitMatchPreview(); virtual void SetSuggestedText(const string16& text); + virtual gfx::Rect GetMatchPreviewBounds(); // Command and state updating /////////////////////////////////////////////// diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h index 9009327..4ff6d5e 100644 --- a/chrome/browser/browser_window.h +++ b/chrome/browser/browser_window.h @@ -318,6 +318,11 @@ class BrowserWindow { // Invoked when the match preview's tab contents should be hidden. virtual void HideMatchPreview() = 0; + // Returns the desired bounds for match preview in screen coordinates. Note + // that if match preview isn't currently visible this returns the bounds the + // match preview would be placed at. + virtual gfx::Rect GetMatchPreviewBounds() = 0; + // Construct a BrowserWindow implementation for the specified |browser|. static BrowserWindow* CreateBrowserWindow(Browser* browser); diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h index 226e573..2fe7b8f 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.h +++ b/chrome/browser/cocoa/browser_window_cocoa.h @@ -108,6 +108,7 @@ class BrowserWindowCocoa : public BrowserWindow, virtual void OpenTabpose(); virtual void ShowMatchPreview(); virtual void HideMatchPreview(); + virtual gfx::Rect GetMatchPreviewBounds(); // Overridden from NotificationObserver virtual void Observe(NotificationType type, diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index f889a3c..168300e 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -574,6 +574,12 @@ void BrowserWindowCocoa::HideMatchPreview() { NOTIMPLEMENTED(); } +gfx::Rect BrowserWindowCocoa::GetMatchPreviewBounds() { + // TODO: implement me + NOTIMPLEMENTED(); + return gfx::Rect(); +} + void BrowserWindowCocoa::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 954a664..e6062c1 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -1143,6 +1143,12 @@ void BrowserWindowGtk::HideMatchPreview() { NOTIMPLEMENTED(); } +gfx::Rect BrowserWindowGtk::GetMatchPreviewBounds() { + // TODO: implement me + NOTIMPLEMENTED(); + return gfx::Rect(); +} + void BrowserWindowGtk::ConfirmBrowserCloseWithPendingDownloads() { new DownloadInProgressDialogGtk(browser()); } diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h index 70bd91c..b032a96 100644 --- a/chrome/browser/gtk/browser_window_gtk.h +++ b/chrome/browser/gtk/browser_window_gtk.h @@ -125,6 +125,7 @@ class BrowserWindowGtk : public BrowserWindow, virtual void ToggleTabStripMode() {} virtual void ShowMatchPreview(); virtual void HideMatchPreview(); + virtual gfx::Rect GetMatchPreviewBounds(); // Overridden from NotificationObserver: virtual void Observe(NotificationType type, diff --git a/chrome/browser/tab_contents/match_preview.cc b/chrome/browser/tab_contents/match_preview.cc index d167ceb..1d24287 100644 --- a/chrome/browser/tab_contents/match_preview.cc +++ b/chrome/browser/tab_contents/match_preview.cc @@ -7,6 +7,7 @@ #include <algorithm> #include "base/command_line.h" +#include "base/string_number_conversions.h" #include "base/utf_string_conversions.h" #include "chrome/browser/autocomplete/autocomplete.h" #include "chrome/browser/favicon_service.h" @@ -37,18 +38,41 @@ namespace { const char kUserInputScript[] = "if (window.chrome.userInput) window.chrome.userInput(\"$1\");"; +const char kUserDoneScript[] = + "if (window.chrome.userWantsQuery) window.chrome.userWantsQuery(\"$1\");"; +const char kSetOmniboxBoundsScript[] = + "if (window.chrome.setOmniboxDimensions) " + "window.chrome.setOmniboxDimensions($1, $2, $3, $4);"; // Sends the user input script to |tab_contents|. |text| is the text the user // input into the omnibox. void SendUserInputScript(TabContents* tab_contents, const string16& text, bool done) { - // TODO: support done. string16 escaped_text(text); ReplaceSubstringsAfterOffset(&escaped_text, 0L, ASCIIToUTF16("\""), ASCIIToUTF16("\\\"")); - string16 script = ReplaceStringPlaceholders(ASCIIToUTF16(kUserInputScript), - escaped_text, NULL); + string16 script = ReplaceStringPlaceholders( + ASCIIToUTF16(done ? kUserDoneScript : kUserInputScript), + escaped_text, + NULL); + tab_contents->render_view_host()->ExecuteJavascriptInWebFrame( + std::wstring(), + UTF16ToWide(script)); +} + +// Sends the script for setting the bounds of the omnibox to |tab_contents|. +void SendOmniboxBoundsScript(TabContents* tab_contents, + const gfx::Rect& bounds) { + std::vector<string16> bounds_vector; + bounds_vector.push_back(base::IntToString16(bounds.x())); + bounds_vector.push_back(base::IntToString16(bounds.y())); + bounds_vector.push_back(base::IntToString16(bounds.width())); + bounds_vector.push_back(base::IntToString16(bounds.height())); + string16 script = ReplaceStringPlaceholders( + ASCIIToUTF16(kSetOmniboxBoundsScript), + bounds_vector, + NULL); tab_contents->render_view_host()->ExecuteJavascriptInWebFrame( std::wstring(), UTF16ToWide(script)); @@ -96,6 +120,12 @@ class MatchPreview::FrameLoadObserver : public NotificationObserver { return; } + if (match_preview_) { + gfx::Rect bounds = match_preview_->GetOmniboxBoundsInTermsOfPreview(); + if (!bounds.IsEmpty()) + SendOmniboxBoundsScript(tab_contents_, bounds); + } + SendUserInputScript(tab_contents_, text_, send_done_); if (match_preview_) @@ -434,7 +464,7 @@ void MatchPreview::Update(TabContents* tab_contents, if (template_url && template_url->supports_instant() && TemplateURL::SupportsReplacement(template_url)) { if (template_url_id == template_url_id_) { - if (frame_load_observer_.get()) { + if (is_waiting_for_load()) { // The page hasn't loaded yet. We'll send the script down when it does. frame_load_observer_->set_text(user_text_); return; @@ -454,6 +484,7 @@ void MatchPreview::Update(TabContents* tab_contents, frame_load_observer_.reset(new FrameLoadObserver(this, user_text_)); } } else { + template_url_id_ = 0; frame_load_observer_.reset(NULL); preview_contents_->controller().LoadURL(url_, GURL(), match.transition); } @@ -461,6 +492,18 @@ void MatchPreview::Update(TabContents* tab_contents, template_url_id_ = template_url_id; } +void MatchPreview::SetOmniboxBounds(const gfx::Rect& bounds) { + if (omnibox_bounds_ == bounds) + return; + + omnibox_bounds_ = bounds; + if (preview_contents_.get() && is_showing_instant() && + !is_waiting_for_load()) { + SendOmniboxBoundsScript(preview_contents_.get(), + GetOmniboxBoundsInTermsOfPreview()); + } +} + void MatchPreview::DestroyPreviewContents() { delegate_->HideMatchPreview(); delete ReleasePreviewContents(false); @@ -472,6 +515,7 @@ void MatchPreview::CommitCurrentPreview() { } TabContents* MatchPreview::ReleasePreviewContents(bool commit_history) { + omnibox_bounds_ = gfx::Rect(); template_url_id_ = 0; url_ = GURL(); user_text_.clear(); @@ -526,3 +570,14 @@ void MatchPreview::PageFinishedLoading() { // FrameLoadObserver deletes itself after this call. FrameLoadObserver* unused ALLOW_UNUSED = frame_load_observer_.release(); } + +gfx::Rect MatchPreview::GetOmniboxBoundsInTermsOfPreview() { + if (omnibox_bounds_.IsEmpty()) + return omnibox_bounds_; + + gfx::Rect preview_bounds(delegate_->GetMatchPreviewBounds()); + return gfx::Rect(omnibox_bounds_.x() - preview_bounds.x(), + omnibox_bounds_.y() - preview_bounds.y(), + omnibox_bounds_.width(), + omnibox_bounds_.height()); +} diff --git a/chrome/browser/tab_contents/match_preview.h b/chrome/browser/tab_contents/match_preview.h index f699f89..25bb8b7 100644 --- a/chrome/browser/tab_contents/match_preview.h +++ b/chrome/browser/tab_contents/match_preview.h @@ -12,6 +12,7 @@ #include "base/timer.h" #include "chrome/browser/search_engines/template_url_id.h" #include "chrome/common/page_transition_types.h" +#include "gfx/rect.h" #include "googleurl/src/gurl.h" struct AutocompleteMatch; @@ -43,6 +44,11 @@ class MatchPreview { const string16& user_text, 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); + // Destroys the preview TabContents. Does nothing if the preview TabContents // has not been created. void DestroyPreviewContents(); @@ -85,6 +91,17 @@ class MatchPreview { // 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; + } + + // Are we showing instant results? + bool is_showing_instant() const { return template_url_id_ != 0; } + MatchPreviewDelegate* delegate_; // The TabContents last passed to |Update|. @@ -114,6 +131,9 @@ class MatchPreview { // the results. A value of 0 means there is no TemplateURL. TemplateURLID template_url_id_; + // See description above setter. + gfx::Rect omnibox_bounds_; + scoped_ptr<FrameLoadObserver> frame_load_observer_; DISALLOW_COPY_AND_ASSIGN(MatchPreview); diff --git a/chrome/browser/tab_contents/match_preview_delegate.h b/chrome/browser/tab_contents/match_preview_delegate.h index 9d12cf8..5839198 100644 --- a/chrome/browser/tab_contents/match_preview_delegate.h +++ b/chrome/browser/tab_contents/match_preview_delegate.h @@ -8,6 +8,10 @@ #include "base/string16.h" +namespace gfx { +class Rect; +} + // MatchPreview's delegate. Normally the Browser implements this. See // MatchPreview for details. class MatchPreviewDelegate { @@ -25,6 +29,10 @@ class MatchPreviewDelegate { // Invoked when the suggested text is to change to |text|. virtual void SetSuggestedText(const string16& text) = 0; + // Returns the bounds the match preview will be placed in, in screen + // coordinates. + virtual gfx::Rect GetMatchPreviewBounds() = 0; + protected: virtual ~MatchPreviewDelegate() {} }; diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc index 45c3779..7db0e42 100644 --- a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc +++ b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc @@ -730,6 +730,10 @@ void AutocompletePopupContentsView::UpdatePopupAppearance() { SchedulePaint(); } +gfx::Rect AutocompletePopupContentsView::GetTargetBounds() { + return target_bounds_; +} + void AutocompletePopupContentsView::PaintUpdatesNow() { // TODO(beng): remove this from the interface. } diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h index 3115787..5253004 100644 --- a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h +++ b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h @@ -61,6 +61,7 @@ class AutocompletePopupContentsView : public views::View, virtual bool IsOpen() const; virtual void InvalidateLine(size_t line); virtual void UpdatePopupAppearance(); + virtual gfx::Rect GetTargetBounds(); virtual void PaintUpdatesNow(); virtual void OnDragCanceled(); virtual AutocompletePopupModel* GetModel(); diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc index 4ff696c..66a5bae 100644 --- a/chrome/browser/views/frame/browser_view.cc +++ b/chrome/browser/views/frame/browser_view.cc @@ -1375,6 +1375,10 @@ void BrowserView::HideMatchPreview() { preview_container_ = NULL; } +gfx::Rect BrowserView::GetMatchPreviewBounds() { + return contents_->GetPreviewBounds(); +} + /////////////////////////////////////////////////////////////////////////////// // BrowserView, BrowserWindowTesting implementation: diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h index fdb2381..5703274 100644 --- a/chrome/browser/views/frame/browser_view.h +++ b/chrome/browser/views/frame/browser_view.h @@ -323,6 +323,7 @@ class BrowserView : public BrowserBubbleHost, virtual void ToggleTabStripMode(); virtual void ShowMatchPreview(); virtual void HideMatchPreview(); + virtual gfx::Rect GetMatchPreviewBounds(); // Overridden from BrowserWindowTesting: virtual BookmarkBarView* GetBookmarkBarView() const; diff --git a/chrome/browser/views/frame/contents_container.cc b/chrome/browser/views/frame/contents_container.cc index 3d455ef..fd80e3b 100644 --- a/chrome/browser/views/frame/contents_container.cc +++ b/chrome/browser/views/frame/contents_container.cc @@ -110,6 +110,12 @@ void ContentsContainer::SetActiveTopMargin(int margin) { InvalidateLayout(); } +gfx::Rect ContentsContainer::GetPreviewBounds() { + gfx::Point screen_loc; + ConvertPointToScreen(this, &screen_loc); + return gfx::Rect(screen_loc, size()); +} + void ContentsContainer::Layout() { // The active view always gets the full bounds. active_->SetBounds(0, active_top_margin_, width(), diff --git a/chrome/browser/views/frame/contents_container.h b/chrome/browser/views/frame/contents_container.h index 533ad36..9a03c38 100644 --- a/chrome/browser/views/frame/contents_container.h +++ b/chrome/browser/views/frame/contents_container.h @@ -36,6 +36,10 @@ class ContentsContainer : public views::View { // Sets the active top margin. void SetActiveTopMargin(int margin); + // Returns the bounds of the preview. If the preview isn't active this + // retuns the bounds the preview would be shown at. + gfx::Rect GetPreviewBounds(); + // View overrides: virtual void Layout(); diff --git a/chrome/browser/views/location_bar/location_bar_view.cc b/chrome/browser/views/location_bar/location_bar_view.cc index e970485..193408a 100644 --- a/chrome/browser/views/location_bar/location_bar_view.cc +++ b/chrome/browser/views/location_bar/location_bar_view.cc @@ -746,6 +746,12 @@ void LocationBarView::OnAutocompleteWillAccept() { update_match_preview_ = false; } +void LocationBarView::OnPopupBoundsChanged(const gfx::Rect& bounds) { + MatchPreview* match_preview = delegate_->GetMatchPreview(); + if (match_preview) + match_preview->SetOmniboxBounds(bounds); +} + void LocationBarView::OnAutocompleteAccept( const GURL& url, WindowOpenDisposition disposition, diff --git a/chrome/browser/views/location_bar/location_bar_view.h b/chrome/browser/views/location_bar/location_bar_view.h index d8c7976..dd01100 100644 --- a/chrome/browser/views/location_bar/location_bar_view.h +++ b/chrome/browser/views/location_bar/location_bar_view.h @@ -178,6 +178,7 @@ class LocationBarView : public LocationBar, virtual void OnAutocompleteWillClosePopup(); virtual void OnAutocompleteLosingFocus(gfx::NativeView view_gaining_focus); virtual void OnAutocompleteWillAccept(); + virtual void OnPopupBoundsChanged(const gfx::Rect& bounds); virtual void OnAutocompleteAccept(const GURL& url, WindowOpenDisposition disposition, PageTransition::Type transition, diff --git a/chrome/test/test_browser_window.h b/chrome/test/test_browser_window.h index 6acf901..d488dd0 100644 --- a/chrome/test/test_browser_window.h +++ b/chrome/test/test_browser_window.h @@ -105,6 +105,7 @@ class TestBrowserWindow : public BrowserWindow { virtual void OpenTabpose() {} virtual void ShowMatchPreview() {} virtual void HideMatchPreview() {} + virtual gfx::Rect GetMatchPreviewBounds() { return gfx::Rect(); } protected: virtual void DestroyBrowser() {} |