[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 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 |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "chrome/browser/tab_contents/match_preview.h" |
| 6 | |
| 7 | #include <algorithm> |
| 8 | |
| 9 | #include "base/command_line.h" |
[email protected] | 46fe8e9 | 2010-09-22 03:32:47 | [diff] [blame] | 10 | #include "base/string_number_conversions.h" |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 11 | #include "base/utf_string_conversions.h" |
| 12 | #include "chrome/browser/autocomplete/autocomplete.h" |
| 13 | #include "chrome/browser/favicon_service.h" |
| 14 | #include "chrome/browser/history/history_marshaling.h" |
| 15 | #include "chrome/browser/profile.h" |
| 16 | #include "chrome/browser/renderer_host/render_view_host.h" |
| 17 | #include "chrome/browser/renderer_host/render_widget_host.h" |
| 18 | #include "chrome/browser/renderer_host/render_widget_host_view.h" |
| 19 | #include "chrome/browser/search_engines/template_url.h" |
| 20 | #include "chrome/browser/search_engines/template_url_model.h" |
| 21 | #include "chrome/browser/tab_contents/match_preview_delegate.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 22 | #include "chrome/browser/tab_contents/navigation_controller.h" |
| 23 | #include "chrome/browser/tab_contents/navigation_entry.h" |
| 24 | #include "chrome/browser/tab_contents/tab_contents.h" |
| 25 | #include "chrome/browser/tab_contents/tab_contents_delegate.h" |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 26 | #include "chrome/browser/tab_contents/tab_contents_view.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 27 | #include "chrome/common/chrome_switches.h" |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 28 | #include "chrome/common/notification_observer.h" |
| 29 | #include "chrome/common/notification_registrar.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 30 | #include "chrome/common/notification_service.h" |
| 31 | #include "chrome/common/page_transition_types.h" |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 32 | #include "chrome/common/render_messages.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 33 | #include "chrome/common/renderer_preferences.h" |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 34 | #include "gfx/codec/png_codec.h" |
[email protected] | fd2b9ce | 2010-08-11 04:03:57 | [diff] [blame] | 35 | #include "ipc/ipc_message.h" |
| 36 | |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 37 | namespace { |
| 38 | |
[email protected] | 3aac77a | 2010-09-24 17:00:13 | [diff] [blame^] | 39 | // Script sent as the user is typing and the provider supports instant. |
| 40 | // Params: |
| 41 | // . the text the user typed. |
| 42 | // TODO: add support for the 2nd and 3rd params. |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 43 | const char kUserInputScript[] = |
[email protected] | 3aac77a | 2010-09-24 17:00:13 | [diff] [blame^] | 44 | "if (window.chrome.userInput) window.chrome.userInput(\"$1\", 0, 0);"; |
| 45 | |
| 46 | // Script sent when the page is committed and the provider supports instant. |
| 47 | // Params: |
| 48 | // . the text the user typed. |
| 49 | // . boolean indicating if the user pressed enter to accept the text. |
[email protected] | 46fe8e9 | 2010-09-22 03:32:47 | [diff] [blame] | 50 | const char kUserDoneScript[] = |
[email protected] | 3aac77a | 2010-09-24 17:00:13 | [diff] [blame^] | 51 | "if (window.chrome.userWantsQuery) " |
| 52 | "window.chrome.userWantsQuery(\"$1\", $2);"; |
| 53 | |
| 54 | // Script sent when the bounds of the omnibox changes and the provider supports |
| 55 | // instant. The params are the bounds relative to the origin of the preview |
| 56 | // (x, y, width, height). |
[email protected] | 46fe8e9 | 2010-09-22 03:32:47 | [diff] [blame] | 57 | const char kSetOmniboxBoundsScript[] = |
| 58 | "if (window.chrome.setOmniboxDimensions) " |
| 59 | "window.chrome.setOmniboxDimensions($1, $2, $3, $4);"; |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 60 | |
[email protected] | 3aac77a | 2010-09-24 17:00:13 | [diff] [blame^] | 61 | // Escapes quotes in the |text| so that it be passed to JavaScript as a quoted |
| 62 | // string. |
| 63 | string16 EscapeUserText(const string16& text) { |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 64 | string16 escaped_text(text); |
| 65 | ReplaceSubstringsAfterOffset(&escaped_text, 0L, ASCIIToUTF16("\""), |
| 66 | ASCIIToUTF16("\\\"")); |
[email protected] | 3aac77a | 2010-09-24 17:00:13 | [diff] [blame^] | 67 | return escaped_text; |
| 68 | } |
| 69 | |
| 70 | // Sends the script for when the user commits the preview. |pressed_enter| is |
| 71 | // true if the user pressed enter to commit. |
| 72 | void SendDoneScript(TabContents* tab_contents, |
| 73 | const string16& text, |
| 74 | bool pressed_enter) { |
| 75 | std::vector<string16> params; |
| 76 | params.push_back(EscapeUserText(text)); |
| 77 | params.push_back(pressed_enter ? ASCIIToUTF16("true") : |
| 78 | ASCIIToUTF16("false")); |
| 79 | string16 script = ReplaceStringPlaceholders(ASCIIToUTF16(kUserDoneScript), |
| 80 | params, |
| 81 | NULL); |
| 82 | tab_contents->render_view_host()->ExecuteJavascriptInWebFrame( |
| 83 | std::wstring(), |
| 84 | UTF16ToWide(script)); |
| 85 | } |
| 86 | |
| 87 | // Sends the user input script to |tab_contents|. |text| is the text the user |
| 88 | // input into the omnibox. |
| 89 | void SendUserInputScript(TabContents* tab_contents, const string16& text) { |
| 90 | string16 script = ReplaceStringPlaceholders(ASCIIToUTF16(kUserInputScript), |
| 91 | EscapeUserText(text), |
| 92 | NULL); |
[email protected] | 46fe8e9 | 2010-09-22 03:32:47 | [diff] [blame] | 93 | tab_contents->render_view_host()->ExecuteJavascriptInWebFrame( |
| 94 | std::wstring(), |
| 95 | UTF16ToWide(script)); |
| 96 | } |
| 97 | |
| 98 | // Sends the script for setting the bounds of the omnibox to |tab_contents|. |
| 99 | void SendOmniboxBoundsScript(TabContents* tab_contents, |
| 100 | const gfx::Rect& bounds) { |
| 101 | std::vector<string16> bounds_vector; |
| 102 | bounds_vector.push_back(base::IntToString16(bounds.x())); |
| 103 | bounds_vector.push_back(base::IntToString16(bounds.y())); |
| 104 | bounds_vector.push_back(base::IntToString16(bounds.width())); |
| 105 | bounds_vector.push_back(base::IntToString16(bounds.height())); |
| 106 | string16 script = ReplaceStringPlaceholders( |
| 107 | ASCIIToUTF16(kSetOmniboxBoundsScript), |
| 108 | bounds_vector, |
| 109 | NULL); |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 110 | tab_contents->render_view_host()->ExecuteJavascriptInWebFrame( |
| 111 | std::wstring(), |
| 112 | UTF16ToWide(script)); |
| 113 | } |
| 114 | |
| 115 | } // namespace |
| 116 | |
| 117 | // FrameLoadObserver is responsible for waiting for the TabContents to finish |
| 118 | // loading and when done sending the necessary script down to the page. |
| 119 | class MatchPreview::FrameLoadObserver : public NotificationObserver { |
| 120 | public: |
| 121 | FrameLoadObserver(MatchPreview* match_preview, const string16& text) |
| 122 | : match_preview_(match_preview), |
| 123 | tab_contents_(match_preview->preview_contents()), |
| 124 | unique_id_(tab_contents_->controller().pending_entry()->unique_id()), |
| 125 | text_(text), |
[email protected] | 3aac77a | 2010-09-24 17:00:13 | [diff] [blame^] | 126 | pressed_enter_(false) { |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 127 | registrar_.Add(this, NotificationType::LOAD_COMPLETED_MAIN_FRAME, |
| 128 | Source<TabContents>(tab_contents_)); |
| 129 | registrar_.Add(this, NotificationType::TAB_CONTENTS_DESTROYED, |
| 130 | Source<TabContents>(tab_contents_)); |
| 131 | } |
| 132 | |
| 133 | // Sets the text to send to the page. |
| 134 | void set_text(const string16& text) { text_ = text; } |
| 135 | |
| 136 | // Invoked when the MatchPreview releases ownership of the TabContents and |
| 137 | // the page hasn't finished loading. |
[email protected] | 3aac77a | 2010-09-24 17:00:13 | [diff] [blame^] | 138 | void DetachFromPreview(bool pressed_enter) { |
[email protected] | 03bb953d | 2010-09-14 21:38:30 | [diff] [blame] | 139 | match_preview_ = NULL; |
[email protected] | 3aac77a | 2010-09-24 17:00:13 | [diff] [
|