blob: deb9a9c3835ae0cc712d525765827ea90a870d24 [file] [log] [blame]
[email protected]fd2b9ce2010-08-11 04:03:571// 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]46fe8e92010-09-22 03:32:4710#include "base/string_number_conversions.h"
[email protected]03bb953d2010-09-14 21:38:3011#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]fd2b9ce2010-08-11 04:03:5722#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]03bb953d2010-09-14 21:38:3026#include "chrome/browser/tab_contents/tab_contents_view.h"
[email protected]fd2b9ce2010-08-11 04:03:5727#include "chrome/common/chrome_switches.h"
[email protected]03bb953d2010-09-14 21:38:3028#include "chrome/common/notification_observer.h"
29#include "chrome/common/notification_registrar.h"
[email protected]fd2b9ce2010-08-11 04:03:5730#include "chrome/common/notification_service.h"
31#include "chrome/common/page_transition_types.h"
[email protected]03bb953d2010-09-14 21:38:3032#include "chrome/common/render_messages.h"
[email protected]fd2b9ce2010-08-11 04:03:5733#include "chrome/common/renderer_preferences.h"
[email protected]03bb953d2010-09-14 21:38:3034#include "gfx/codec/png_codec.h"
[email protected]fd2b9ce2010-08-11 04:03:5735#include "ipc/ipc_message.h"
36
[email protected]03bb953d2010-09-14 21:38:3037namespace {
38
[email protected]3aac77a2010-09-24 17:00:1339// 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]03bb953d2010-09-14 21:38:3043const char kUserInputScript[] =
[email protected]3aac77a2010-09-24 17:00:1344 "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]46fe8e92010-09-22 03:32:4750const char kUserDoneScript[] =
[email protected]3aac77a2010-09-24 17:00:1351 "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]46fe8e92010-09-22 03:32:4757const char kSetOmniboxBoundsScript[] =
58 "if (window.chrome.setOmniboxDimensions) "
59 "window.chrome.setOmniboxDimensions($1, $2, $3, $4);";
[email protected]03bb953d2010-09-14 21:38:3060
[email protected]3aac77a2010-09-24 17:00:1361// Escapes quotes in the |text| so that it be passed to JavaScript as a quoted
62// string.
63string16 EscapeUserText(const string16& text) {
[email protected]03bb953d2010-09-14 21:38:3064 string16 escaped_text(text);
65 ReplaceSubstringsAfterOffset(&escaped_text, 0L, ASCIIToUTF16("\""),
66 ASCIIToUTF16("\\\""));
[email protected]3aac77a2010-09-24 17:00:1367 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.
72void 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.
89void SendUserInputScript(TabContents* tab_contents, const string16& text) {
90 string16 script = ReplaceStringPlaceholders(ASCIIToUTF16(kUserInputScript),
91 EscapeUserText(text),
92 NULL);
[email protected]46fe8e92010-09-22 03:32:4793 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|.
99void 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]03bb953d2010-09-14 21:38:30110 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.
119class 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]3aac77a2010-09-24 17:00:13126 pressed_enter_(false) {
[email protected]03bb953d2010-09-14 21:38:30127 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]3aac77a2010-09-24 17:00:13138 void DetachFromPreview(bool pressed_enter) {
[email protected]03bb953d2010-09-14 21:38:30139 match_preview_ = NULL;
[email protected]3aac77a2010-09-24 17:00:13