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/chromeos/login/account_screen.h"
6
7#include "base/string_util.h"
8#include "base/utf_string_conversions.h"
9#include "chrome/browser/browser_process.h"
10#include "chrome/browser/chromeos/input_method/input_method_util.h"
11#include "chrome/browser/chromeos/login/account_creation_view.h"
12#include "chrome/browser/chromeos/login/screen_observer.h"
13#include "chrome/browser/profiles/profile_manager.h"
14#include "content/browser/renderer_host/render_view_host.h"
15#include "content/browser/site_instance.h"
16#include "content/browser/tab_contents/tab_contents.h"
17#include "googleurl/src/gurl.h"
18#include "views/events/event.h"
19#include "views/widget/widget_gtk.h"
20
21namespace chromeos {
22
23namespace {
24
25const char kCreateAccountPageUrl[] =
26    "https://www.google.com/accounts/NewAccount?service=mail&hl=en";
27
28const char kCreateAccountDoneUrl[] =
29    "http://mail.google.com/mail/help/intro.html";
30
31const char kCreateAccountBackUrl[] =
32    "about:blank";
33
34const char kCreateAccountCSS[] =
35    "body > table, div.body > h3, div.body > table, a, "
36    "#cookieWarning1, #cookieWarning2 {\n"
37    " display: none !important;\n"
38    "}\n"
39    "tbody tr:nth-child(7), tbody tr:nth-child(8), tbody tr:nth-child(9),"
40    "tbody tr:nth-child(13), tbody tr:nth-child(16), tbody tr:nth-child(17),"
41    "tbody tr:nth-child(18) {\n"
42    " display: none !important;\n"
43    "}\n"
44    "body {\n"
45    " padding: 0;\n"
46    "}\n";
47
48const char kCreateAccountJS[] =
49  "try {\n"
50  " var smhck = document.getElementById('smhck');\n"
51  " smhck.checked = false;\n"
52  " smhck.value = 0;\n"
53  " var tables = document.getElementsByTagName('table');\n"
54  " for (var i = 0; i < tables.length; i++) {\n"
55  "   if (tables[i].bgColor == '#cbdced') tables[i].cellPadding = 0;\n"
56  " }\n"
57  " var submitbtn = document.getElementById('submitbutton');\n"
58  " submitbtn.value = 'Create Account';\n"
59  " submitbtn.parentNode.parentNode.firstElementChild.innerHTML ="
60  "   \"<input type='button' style='width:8em' value='<< Back'"
61  "      onclick='window.location=\\\"about:blank\\\";'/>\";\n"
62  "} catch(err) {\n"
63  "}\n";
64
65}  // namespace
66
67///////////////////////////////////////////////////////////////////////////////
68// AccountScreen, public:
69AccountScreen::AccountScreen(WizardScreenDelegate* delegate)
70    : ViewScreen<AccountCreationView>(delegate) {
71  if (!new_account_page_url_.get())
72    new_account_page_url_.reset(new GURL(kCreateAccountPageUrl));
73}
74
75AccountScreen::~AccountScreen() {
76}
77
78// static
79void AccountScreen::set_new_account_page_url(const GURL& url) {
80  new_account_page_url_.reset(new GURL(url));
81}
82
83// static
84scoped_ptr<GURL> AccountScreen::new_account_page_url_;
85// static
86bool AccountScreen::check_for_https_ = true;
87
88///////////////////////////////////////////////////////////////////////////////
89// AccountScreen, ViewScreen implementation:
90void AccountScreen::CreateView() {
91  ViewScreen<AccountCreationView>::CreateView();
92  view()->SetWebPageDelegate(this);
93  view()->SetAccountCreationViewDelegate(this);
94}
95
96void AccountScreen::Refresh() {
97  StartTimeoutTimer();
98  GURL url(*new_account_page_url_);
99  Profile* profile = ProfileManager::GetDefaultProfile();
100  view()->InitDOM(profile,
101                  SiteInstance::CreateSiteInstanceForURL(profile, url));
102  view()->SetTabContentsDelegate(this);
103  view()->LoadURL(url);
104}
105
106AccountCreationView* AccountScreen::AllocateView() {
107  return new AccountCreationView();
108}
109
110///////////////////////////////////////////////////////////////////////////////
111// AccountScreen, TabContentsDelegate implementation:
112void AccountScreen::LoadingStateChanged(TabContents* source) {
113  std::string url = source->GetURL().spec();
114  if (url == kCreateAccountDoneUrl) {
115    source->Stop();
116    CloseScreen(ScreenObserver::ACCOUNT_CREATED);
117  } else if (url == kCreateAccountBackUrl) {
118    CloseScreen(ScreenObserver::ACCOUNT_CREATE_BACK);
119  } else if (check_for_https_ && !source->GetURL().SchemeIsSecure()) {
120    CloseScreen(ScreenObserver::CONNECTION_FAILED);
121  }
122}
123
124void AccountScreen::NavigationStateChanged(const TabContents* source,
125                                           unsigned changed_flags) {
126  if (source->render_view_host()) {
127    source->render_view_host()->InsertCSSInWebFrame(
128        L"", kCreateAccountCSS, "");
129    source->render_view_host()->ExecuteJavascriptInWebFrame(
130        string16(), ASCIIToUTF16(kCreateAccountJS));
131  }
132}
133
134void AccountScreen::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {
135  views::Widget* widget = view()->GetWidget();
136  if (widget && event.os_event && !event.skip_in_browser) {
137    views::KeyEvent views_event(reinterpret_cast<GdkEvent*>(event.os_event));
138    static_cast<views::WidgetGtk*>(widget)->HandleKeyboardEvent(views_event);
139  }
140}
141
142///////////////////////////////////////////////////////////////////////////////
143// AccountScreen, WebPageDelegate implementation:
144void AccountScreen::OnPageLoaded() {
145  StopTimeoutTimer();
146  // Enable input methods (e.g. Chinese, Japanese) so that users could input
147  // their first and last names.
148  if (g_browser_process) {
149    const std::string locale = g_browser_process->GetApplicationLocale();
150    input_method::EnableInputMethods(
151        locale, input_method::kAllInputMethods, "");
152  }
153  view()->ShowPageContent();
154}
155
156void AccountScreen::OnPageLoadFailed(const std::string& url) {
157  CloseScreen(ScreenObserver::CONNECTION_FAILED);
158}
159
160///////////////////////////////////////////////////////////////////////////////
161// AccountScreen, AccountCreationViewDelegate implementation:
162void AccountScreen::OnUserCreated(const std::string& username,
163                                  const std::string& password) {
164  delegate()->GetObserver(this)->OnSetUserNamePassword(username, password);
165}
166
167///////////////////////////////////////////////////////////////////////////////
168// AccountScreen, private:
169void AccountScreen::CloseScreen(ScreenObserver::ExitCodes code) {
170  StopTimeoutTimer();
171  // Disable input methods since they are not necessary to input username and
172  // password.
173  if (g_browser_process) {
174    const std::string locale = g_browser_process->GetApplicationLocale();
175    input_method::EnableInputMethods(
176        locale, input_method::kKeyboardLayoutsOnly, "");
177  }
178  delegate()->GetObserver(this)->OnExit(code);
179}
180
181}  // namespace chromeos
182