• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
6 
7 #include "base/lazy_instance.h"
8 #include "chrome/browser/autocomplete_history_manager.h"
9 #include "chrome/browser/autofill/autofill_manager.h"
10 #include "chrome/browser/automation/automation_tab_helper.h"
11 #include "chrome/browser/bookmarks/bookmark_model.h"
12 #include "chrome/browser/custom_handlers/protocol_handler_registry.h"
13 #include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h"
14 #include "chrome/browser/extensions/extension_tab_helper.h"
15 #include "chrome/browser/extensions/extension_webnavigation_api.h"
16 #include "chrome/browser/file_select_helper.h"
17 #include "chrome/browser/history/history.h"
18 #include "chrome/browser/history/top_sites.h"
19 #include "chrome/browser/password_manager/password_manager.h"
20 #include "chrome/browser/password_manager_delegate_impl.h"
21 #include "chrome/browser/prefs/pref_service.h"
22 #include "chrome/browser/prerender/prerender_observer.h"
23 #include "chrome/browser/printing/print_preview_message_handler.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h"
26 #include "chrome/browser/translate/translate_tab_helper.h"
27 #include "chrome/browser/ui/download/download_tab_helper.h"
28 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
29 #include "chrome/browser/ui/search_engines/search_engine_tab_helper.h"
30 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper_delegate.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/common/render_messages.h"
33 #include "content/browser/tab_contents/tab_contents.h"
34 #include "content/common/notification_service.h"
35 #include "content/common/view_messages.h"
36 #include "grit/generated_resources.h"
37 #include "grit/locale_settings.h"
38 #include "grit/platform_locale_settings.h"
39 #include "ui/base/l10n/l10n_util.h"
40 #include "webkit/glue/webpreferences.h"
41 
42 static base::LazyInstance<PropertyAccessor<TabContentsWrapper*> >
43     g_tab_contents_wrapper_property_accessor(base::LINKER_INITIALIZED);
44 
45 ////////////////////////////////////////////////////////////////////////////////
46 // TabContentsWrapper, public:
47 
TabContentsWrapper(TabContents * contents)48 TabContentsWrapper::TabContentsWrapper(TabContents* contents)
49     : TabContentsObserver(contents),
50       delegate_(NULL),
51       is_starred_(false),
52       tab_contents_(contents) {
53   DCHECK(contents);
54   // Stash this in the property bag so it can be retrieved without having to
55   // go to a Browser.
56   property_accessor()->SetProperty(contents->property_bag(), this);
57 
58   // Create the tab helpers.
59   autocomplete_history_manager_.reset(new AutocompleteHistoryManager(contents));
60   autofill_manager_.reset(new AutofillManager(contents));
61   automation_tab_helper_.reset(new AutomationTabHelper(contents));
62   download_tab_helper_.reset(new DownloadTabHelper(contents));
63   extension_tab_helper_.reset(new ExtensionTabHelper(this));
64   find_tab_helper_.reset(new FindTabHelper(contents));
65   password_manager_delegate_.reset(new PasswordManagerDelegateImpl(contents));
66   password_manager_.reset(
67       new PasswordManager(contents, password_manager_delegate_.get()));
68   search_engine_tab_helper_.reset(new SearchEngineTabHelper(contents));
69   translate_tab_helper_.reset(new TranslateTabHelper(contents));
70   print_view_manager_.reset(new printing::PrintViewManager(contents));
71 
72   // Register for notifications about URL starredness changing on any profile.
73   registrar_.Add(this, NotificationType::URLS_STARRED,
74                  NotificationService::AllSources());
75   registrar_.Add(this, NotificationType::BOOKMARK_MODEL_LOADED,
76                  NotificationService::AllSources());
77 
78   // Create the per-tab observers.
79   file_select_observer_.reset(new FileSelectObserver(contents));
80   prerender_observer_.reset(new prerender::PrerenderObserver(contents));
81   print_preview_.reset(new printing::PrintPreviewMessageHandler(contents));
82   webnavigation_observer_.reset(
83       new ExtensionWebNavigationTabObserver(contents));
84 }
85 
~TabContentsWrapper()86 TabContentsWrapper::~TabContentsWrapper() {
87   // We don't want any notifications while we're running our destructor.
88   registrar_.RemoveAll();
89 }
90 
property_accessor()91 PropertyAccessor<TabContentsWrapper*>* TabContentsWrapper::property_accessor() {
92   return g_tab_contents_wrapper_property_accessor.Pointer();
93 }
94 
RegisterUserPrefs(PrefService * prefs)95 void TabContentsWrapper::RegisterUserPrefs(PrefService* prefs) {
96   prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled, true);
97 
98   WebPreferences pref_defaults;
99   prefs->RegisterBooleanPref(prefs::kWebKitJavascriptEnabled,
100                              pref_defaults.javascript_enabled);
101   prefs->RegisterBooleanPref(prefs::kWebKitWebSecurityEnabled,
102                              pref_defaults.web_security_enabled);
103   prefs->RegisterBooleanPref(
104       prefs::kWebKitJavascriptCanOpenWindowsAutomatically, true);
105   prefs->RegisterBooleanPref(prefs::kWebKitLoadsImagesAutomatically,
106                              pref_defaults.loads_images_automatically);
107   prefs->RegisterBooleanPref(prefs::kWebKitPluginsEnabled,
108                              pref_defaults.plugins_enabled);
109   prefs->RegisterBooleanPref(prefs::kWebKitDomPasteEnabled,
110                              pref_defaults.dom_paste_enabled);
111   prefs->RegisterBooleanPref(prefs::kWebKitShrinksStandaloneImagesToFit,
112                              pref_defaults.shrinks_standalone_images_to_fit);
113   prefs->RegisterDictionaryPref(prefs::kWebKitInspectorSettings);
114   prefs->RegisterBooleanPref(prefs::kWebKitTextAreasAreResizable,
115                              pref_defaults.text_areas_are_resizable);
116   prefs->RegisterBooleanPref(prefs::kWebKitJavaEnabled,
117                              pref_defaults.java_enabled);
118   prefs->RegisterBooleanPref(prefs::kWebkitTabsToLinks,
119                              pref_defaults.tabs_to_links);
120 
121   prefs->RegisterLocalizedStringPref(prefs::kAcceptLanguages,
122                                      IDS_ACCEPT_LANGUAGES);
123   prefs->RegisterLocalizedStringPref(prefs::kDefaultCharset,
124                                      IDS_DEFAULT_ENCODING);
125   prefs->RegisterLocalizedStringPref(prefs::kWebKitStandardFontFamily,
126                                      IDS_STANDARD_FONT_FAMILY);
127   prefs->RegisterLocalizedStringPref(prefs::kWebKitFixedFontFamily,
128                                      IDS_FIXED_FONT_FAMILY);
129   prefs->RegisterLocalizedStringPref(prefs::kWebKitSerifFontFamily,
130                                      IDS_SERIF_FONT_FAMILY);
131   prefs->RegisterLocalizedStringPref(prefs::kWebKitSansSerifFontFamily,
132                                      IDS_SANS_SERIF_FONT_FAMILY);
133   prefs->RegisterLocalizedStringPref(prefs::kWebKitCursiveFontFamily,
134                                      IDS_CURSIVE_FONT_FAMILY);
135   prefs->RegisterLocalizedStringPref(prefs::kWebKitFantasyFontFamily,
136                                      IDS_FANTASY_FONT_FAMILY);
137   prefs->RegisterLocalizedIntegerPref(prefs::kWebKitDefaultFontSize,
138                                       IDS_DEFAULT_FONT_SIZE);
139   prefs->RegisterLocalizedIntegerPref(prefs::kWebKitDefaultFixedFontSize,
140                                       IDS_DEFAULT_FIXED_FONT_SIZE);
141   prefs->RegisterLocalizedIntegerPref(prefs::kWebKitMinimumFontSize,
142                                       IDS_MINIMUM_FONT_SIZE);
143   prefs->RegisterLocalizedIntegerPref(prefs::kWebKitMinimumLogicalFontSize,
144                                       IDS_MINIMUM_LOGICAL_FONT_SIZE);
145   prefs->RegisterLocalizedBooleanPref(prefs::kWebKitUsesUniversalDetector,
146                                       IDS_USES_UNIVERSAL_DETECTOR);
147   prefs->RegisterLocalizedStringPref(prefs::kStaticEncodings,
148                                      IDS_STATIC_ENCODING_LIST);
149   prefs->RegisterStringPref(prefs::kRecentlySelectedEncoding, "");
150 }
151 
GetDefaultTitle()152 string16 TabContentsWrapper::GetDefaultTitle() {
153   return l10n_util::GetStringUTF16(IDS_DEFAULT_TAB_TITLE);
154 }
155 
GetStatusText() const156 string16 TabContentsWrapper::GetStatusText() const {
157   if (!tab_contents()->is_loading() ||
158       tab_contents()->load_state() == net::LOAD_STATE_IDLE) {
159     return string16();
160   }
161 
162   switch (tab_contents()->load_state()) {
163     case net::LOAD_STATE_WAITING_FOR_CACHE:
164       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_WAITING_FOR_CACHE);
165     case net::LOAD_STATE_ESTABLISHING_PROXY_TUNNEL:
166       return
167           l10n_util::GetStringUTF16(IDS_LOAD_STATE_ESTABLISHING_PROXY_TUNNEL);
168     case net::LOAD_STATE_RESOLVING_PROXY_FOR_URL:
169       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_RESOLVING_PROXY_FOR_URL);
170     case net::LOAD_STATE_RESOLVING_HOST:
171       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_RESOLVING_HOST);
172     case net::LOAD_STATE_CONNECTING:
173       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_CONNECTING);
174     case net::LOAD_STATE_SSL_HANDSHAKE:
175       return l10n_util::GetStringUTF16(IDS_LOAD_STATE_SSL_HANDSHAKE);
176     case net::LOAD_STATE_SENDING_REQUEST:
177       if (tab_contents()->upload_size())
178         return l10n_util::GetStringFUTF16Int(
179                     IDS_LOAD_STATE_SENDING_REQUEST_WITH_PROGRESS,
180                     static_cast<int>((100 * tab_contents()->upload_position()) /
181                         tab_contents()->upload_size()));
182       else
183         return l10n_util::GetStringUTF16(IDS_LOAD_STATE_SENDING_REQUEST);
184     case net::LOAD_STATE_WAITING_FOR_RESPONSE:
185       return l10n_util::GetStringFUTF16(IDS_LOAD_STATE_WAITING_FOR_RESPONSE,
186                                         tab_contents()->load_state_host());
187     // Ignore net::LOAD_STATE_READING_RESPONSE and net::LOAD_STATE_IDLE
188     case net::LOAD_STATE_IDLE:
189     case net::LOAD_STATE_READING_RESPONSE:
190       break;
191   }
192 
193   return string16();
194 }
195 
Clone()196 TabContentsWrapper* TabContentsWrapper::Clone() {
197   TabContents* new_contents = tab_contents()->Clone();
198   TabContentsWrapper* new_wrapper = new TabContentsWrapper(new_contents);
199 
200   new_wrapper->extension_tab_helper()->CopyStateFrom(
201       *extension_tab_helper_.get());
202   return new_wrapper;
203 }
204 
GetCurrentWrapperForContents(TabContents * contents)205 TabContentsWrapper* TabContentsWrapper::GetCurrentWrapperForContents(
206     TabContents* contents) {
207   TabContentsWrapper** wrapper =
208       property_accessor()->GetProperty(contents->property_bag());
209 
210   return wrapper ? *wrapper : NULL;
211 }
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 // TabContentsWrapper, TabContentsObserver implementation:
215 
DidNavigateMainFramePostCommit(const NavigationController::LoadCommittedDetails &,const ViewHostMsg_FrameNavigate_Params &)216 void TabContentsWrapper::DidNavigateMainFramePostCommit(
217     const NavigationController::LoadCommittedDetails& /*details*/,
218     const ViewHostMsg_FrameNavigate_Params& /*params*/) {
219   UpdateStarredStateForCurrentURL();
220 }
221 
OnMessageReceived(const IPC::Message & message)222 bool TabContentsWrapper::OnMessageReceived(const IPC::Message& message) {
223   bool handled = true;
224   IPC_BEGIN_MESSAGE_MAP(TabContentsWrapper, message)
225     IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents)
226     IPC_MESSAGE_HANDLER(ViewHostMsg_JSOutOfMemory, OnJSOutOfMemory)
227     IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterProtocolHandler,
228                         OnRegisterProtocolHandler)
229     IPC_MESSAGE_HANDLER(ViewHostMsg_Thumbnail, OnMsgThumbnail)
230     IPC_MESSAGE_UNHANDLED(handled = false)
231   IPC_END_MESSAGE_MAP()
232   return handled;
233 }
234 
235 ////////////////////////////////////////////////////////////////////////////////
236 // TabContentsWrapper, NotificationObserver implementation:
237 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)238 void TabContentsWrapper::Observe(NotificationType type,
239                                  const NotificationSource& source,
240                                  const NotificationDetails& details) {
241   switch (type.value) {
242     case NotificationType::BOOKMARK_MODEL_LOADED:
243       // BookmarkModel finished loading, fall through to update starred state.
244     case NotificationType::URLS_STARRED: {
245       // Somewhere, a URL has been starred.
246       // Ignore notifications for profiles other than our current one.
247       Profile* source_profile = Source<Profile>(source).ptr();
248       if (!source_profile || !source_profile->IsSameProfile(profile()))
249         return;
250 
251       UpdateStarredStateForCurrentURL();
252       break;
253     }
254 
255     default:
256       NOTREACHED();
257   }
258 }
259 
260 ////////////////////////////////////////////////////////////////////////////////
261 // Internal helpers
262 
OnPageContents(const GURL & url,int32 page_id,const string16 & contents)263 void TabContentsWrapper::OnPageContents(const GURL& url,
264                                         int32 page_id,
265                                         const string16& contents) {
266   // Don't index any https pages. People generally don't want their bank
267   // accounts, etc. indexed on their computer, especially since some of these
268   // things are not marked cachable.
269   // TODO(brettw) we may want to consider more elaborate heuristics such as
270   // the cachability of the page. We may also want to consider subframes (this
271   // test will still index subframes if the subframe is SSL).
272   // TODO(zelidrag) bug chromium-os:2808 - figure out if we want to reenable
273   // content indexing for chromeos in some future releases.
274 #if !defined(OS_CHROMEOS)
275   if (!url.SchemeIsSecure()) {
276     Profile* p = profile();
277     if (p && !p->IsOffTheRecord()) {
278       HistoryService* hs = p->GetHistoryService(Profile::IMPLICIT_ACCESS);
279       if (hs)
280         hs->SetPageContents(url, contents);
281     }
282   }
283 #endif
284 }
285 
OnJSOutOfMemory()286 void TabContentsWrapper::OnJSOutOfMemory() {
287   tab_contents()->AddInfoBar(new SimpleAlertInfoBarDelegate(tab_contents(),
288       NULL, l10n_util::GetStringUTF16(IDS_JS_OUT_OF_MEMORY_PROMPT), true));
289 }
290 
OnRegisterProtocolHandler(const std::string & protocol,const GURL & url,const string16 & title)291 void TabContentsWrapper::OnRegisterProtocolHandler(const std::string& protocol,
292                                                    const GURL& url,
293                                                    const string16& title) {
294   ProtocolHandlerRegistry* registry = profile()->GetProtocolHandlerRegistry();
295   ProtocolHandler* handler =
296       ProtocolHandler::CreateProtocolHandler(protocol, url, title);
297   if ((handler != NULL) &&
298       registry->CanSchemeBeOverridden(handler->protocol())) {
299     tab_contents()->AddInfoBar(registry->IsAlreadyRegistered(handler) ?
300       static_cast<InfoBarDelegate*>(new SimpleAlertInfoBarDelegate(
301           tab_contents(), NULL, l10n_util::GetStringFUTF16(
302               IDS_REGISTER_PROTOCOL_HANDLER_ALREADY_REGISTERED,
303               handler->title(), UTF8ToUTF16(handler->protocol())), true)) :
304       new RegisterProtocolHandlerInfoBarDelegate(tab_contents(), registry,
305                                                  handler));
306   }
307 }
308 
OnMsgThumbnail(const GURL & url,const ThumbnailScore & score,const SkBitmap & bitmap)309 void TabContentsWrapper::OnMsgThumbnail(const GURL& url,
310                                         const ThumbnailScore& score,
311                                         const SkBitmap& bitmap) {
312   if (profile()->IsOffTheRecord())
313     return;
314 
315   // Tell History about this thumbnail
316   history::TopSites* ts = profile()->GetTopSites();
317   if (ts)
318     ts->SetPageThumbnail(url, bitmap, score);
319 }
320 
UpdateStarredStateForCurrentURL()321 void TabContentsWrapper::UpdateStarredStateForCurrentURL() {
322   BookmarkModel* model = tab_contents()->profile()->GetBookmarkModel();
323   const bool old_state = is_starred_;
324   is_starred_ = (model && model->IsBookmarked(tab_contents()->GetURL()));
325 
326   if (is_starred_ != old_state && delegate())
327     delegate()->URLStarredChanged(this, is_starred_);
328 }
329