OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/translate/content/renderer/translate_helper.h" | 5 #include "components/translate/content/renderer/translate_helper.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
13 #include "base/strings/string16.h" | 13 #include "base/strings/string16.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
16 #include "base/threading/thread_task_runner_handle.h" | 16 #include "base/threading/thread_task_runner_handle.h" |
17 #include "components/translate/content/common/translate_messages.h" | |
18 #include "components/translate/core/common/translate_constants.h" | 17 #include "components/translate/core/common/translate_constants.h" |
19 #include "components/translate/core/common/translate_metrics.h" | 18 #include "components/translate/core/common/translate_metrics.h" |
20 #include "components/translate/core/common/translate_util.h" | 19 #include "components/translate/core/common/translate_util.h" |
21 #include "components/translate/core/language_detection/language_detection_util.h " | 20 #include "components/translate/core/language_detection/language_detection_util.h " |
22 #include "content/public/common/content_constants.h" | 21 #include "content/public/common/content_constants.h" |
23 #include "content/public/common/url_constants.h" | 22 #include "content/public/common/url_constants.h" |
24 #include "content/public/renderer/render_frame.h" | 23 #include "content/public/renderer/render_frame.h" |
25 #include "content/public/renderer/render_thread.h" | 24 #include "content/public/renderer/render_thread.h" |
26 #include "ipc/ipc_platform_file.h" | 25 #include "services/shell/public/cpp/interface_provider.h" |
27 #include "third_party/WebKit/public/web/WebDocument.h" | 26 #include "third_party/WebKit/public/web/WebDocument.h" |
28 #include "third_party/WebKit/public/web/WebElement.h" | 27 #include "third_party/WebKit/public/web/WebElement.h" |
29 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 28 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
30 #include "third_party/WebKit/public/web/WebNode.h" | 29 #include "third_party/WebKit/public/web/WebNode.h" |
31 #include "third_party/WebKit/public/web/WebScriptSource.h" | 30 #include "third_party/WebKit/public/web/WebScriptSource.h" |
32 #include "url/gurl.h" | 31 #include "url/gurl.h" |
33 #include "v8/include/v8.h" | 32 #include "v8/include/v8.h" |
34 | 33 |
35 using base::ASCIIToUTF16; | 34 using base::ASCIIToUTF16; |
36 using blink::WebDocument; | 35 using blink::WebDocument; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 if (head.isNull() || !head.hasChildNodes()) | 70 if (head.isNull() || !head.hasChildNodes()) |
72 return false; | 71 return false; |
73 | 72 |
74 const WebString meta(ASCIIToUTF16("meta")); | 73 const WebString meta(ASCIIToUTF16("meta")); |
75 const WebString name(ASCIIToUTF16("name")); | 74 const WebString name(ASCIIToUTF16("name")); |
76 const WebString google(ASCIIToUTF16("google")); | 75 const WebString google(ASCIIToUTF16("google")); |
77 const WebString value(ASCIIToUTF16("value")); | 76 const WebString value(ASCIIToUTF16("value")); |
78 const WebString content(ASCIIToUTF16("content")); | 77 const WebString content(ASCIIToUTF16("content")); |
79 | 78 |
80 for (WebNode child = head.firstChild(); !child.isNull(); | 79 for (WebNode child = head.firstChild(); !child.isNull(); |
81 child = child.nextSibling()) { | 80 child = child.nextSibling()) { |
82 if (!child.isElementNode()) | 81 if (!child.isElementNode()) |
83 continue; | 82 continue; |
84 WebElement element = child.to<WebElement>(); | 83 WebElement element = child.to<WebElement>(); |
85 // Check if a tag is <meta>. | 84 // Check if a tag is <meta>. |
86 if (!element.hasHTMLTagName(meta)) | 85 if (!element.hasHTMLTagName(meta)) |
87 continue; | 86 continue; |
88 // Check if the tag contains name="google". | 87 // Check if the tag contains name="google". |
89 WebString attribute = element.getAttribute(name); | 88 WebString attribute = element.getAttribute(name); |
90 if (attribute.isNull() || attribute != google) | 89 if (attribute.isNull() || attribute != google) |
91 continue; | 90 continue; |
(...skipping 15 matching lines...) Expand all Loading... | |
107 namespace translate { | 106 namespace translate { |
108 | 107 |
109 //////////////////////////////////////////////////////////////////////////////// | 108 //////////////////////////////////////////////////////////////////////////////// |
110 // TranslateHelper, public: | 109 // TranslateHelper, public: |
111 // | 110 // |
112 TranslateHelper::TranslateHelper(content::RenderFrame* render_frame, | 111 TranslateHelper::TranslateHelper(content::RenderFrame* render_frame, |
113 int world_id, | 112 int world_id, |
114 int extension_group, | 113 int extension_group, |
115 const std::string& extension_scheme) | 114 const std::string& extension_scheme) |
116 : content::RenderFrameObserver(render_frame), | 115 : content::RenderFrameObserver(render_frame), |
117 page_seq_no_(0), | |
118 translation_pending_(false), | |
119 world_id_(world_id), | 116 world_id_(world_id), |
120 extension_group_(extension_group), | 117 extension_group_(extension_group), |
121 extension_scheme_(extension_scheme), | 118 extension_scheme_(extension_scheme), |
119 binding_(this), | |
122 weak_method_factory_(this) {} | 120 weak_method_factory_(this) {} |
123 | 121 |
124 TranslateHelper::~TranslateHelper() { | 122 TranslateHelper::~TranslateHelper() {} |
125 } | |
126 | 123 |
127 void TranslateHelper::PrepareForUrl(const GURL& url) { | 124 void TranslateHelper::PrepareForUrl(const GURL& url) { |
128 ++page_seq_no_; | 125 // Navigated to a new page, close the binding for previous page. |
129 Send(new ChromeFrameHostMsg_TranslateAssignedSequenceNumber(routing_id(), | 126 binding_.Close(); |
130 page_seq_no_)); | 127 translate_callback_pending_.Reset(); |
131 } | 128 } |
132 | 129 |
133 void TranslateHelper::PageCaptured(const base::string16& contents) { | 130 void TranslateHelper::PageCaptured(const base::string16& contents) { |
134 PageCapturedImpl(page_seq_no_, contents); | |
135 } | |
136 | |
137 void TranslateHelper::PageCapturedImpl(int page_seq_no, | |
138 const base::string16& contents) { | |
139 // Get the document language as set by WebKit from the http-equiv | 131 // Get the document language as set by WebKit from the http-equiv |
140 // meta tag for "content-language". This may or may not also | 132 // meta tag for "content-language". This may or may not also |
141 // have a value derived from the actual Content-Language HTTP | 133 // have a value derived from the actual Content-Language HTTP |
142 // header. The two actually have different meanings (despite the | 134 // header. The two actually have different meanings (despite the |
143 // original intent of http-equiv to be an equivalent) with the former | 135 // original intent of http-equiv to be an equivalent) with the former |
144 // being the language of the document and the latter being the | 136 // being the language of the document and the latter being the |
145 // language of the intended audience (a distinction really only | 137 // language of the intended audience (a distinction really only |
146 // relevant for things like langauge textbooks). This distinction | 138 // relevant for things like langauge textbooks). This distinction |
147 // shouldn't affect translation. | 139 // shouldn't affect translation. |
148 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); | 140 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); |
149 if (!main_frame || page_seq_no_ != page_seq_no) | 141 if (!main_frame) |
150 return; | 142 return; |
151 | 143 |
152 WebDocument document = main_frame->document(); | 144 WebDocument document = main_frame->document(); |
153 std::string content_language = document.contentLanguage().utf8(); | 145 std::string content_language = document.contentLanguage().utf8(); |
154 WebElement html_element = document.documentElement(); | 146 WebElement html_element = document.documentElement(); |
155 std::string html_lang; | 147 std::string html_lang; |
156 // |html_element| can be null element, e.g. in | 148 // |html_element| can be null element, e.g. in |
157 // BrowserTest.WindowOpenClose. | 149 // BrowserTest.WindowOpenClose. |
158 if (!html_element.isNull()) | 150 if (!html_element.isNull()) |
159 html_lang = html_element.getAttribute("lang").utf8(); | 151 html_lang = html_element.getAttribute("lang").utf8(); |
(...skipping 15 matching lines...) Expand all Loading... | |
175 details.cld_language = cld_language; | 167 details.cld_language = cld_language; |
176 details.is_cld_reliable = is_cld_reliable; | 168 details.is_cld_reliable = is_cld_reliable; |
177 details.has_notranslate = HasNoTranslateMeta(&document); | 169 details.has_notranslate = HasNoTranslateMeta(&document); |
178 details.html_root_language = html_lang; | 170 details.html_root_language = html_lang; |
179 details.adopted_language = language; | 171 details.adopted_language = language; |
180 | 172 |
181 // TODO(hajimehoshi): If this affects performance, it should be set only if | 173 // TODO(hajimehoshi): If this affects performance, it should be set only if |
182 // translate-internals tab exists. | 174 // translate-internals tab exists. |
183 details.contents = contents; | 175 details.contents = contents; |
184 | 176 |
185 Send(new ChromeFrameHostMsg_TranslateLanguageDetermined( | 177 // For the same render frame with the same url, each time when its texts are |
186 routing_id(), details, !details.has_notranslate && !language.empty())); | 178 // captured, it should be treated as a new page to do translation. |
179 binding_.Close(); | |
180 GetTranslateDriver()->RegisterPage( | |
181 binding_.CreateInterfacePtrAndBind(), details, | |
182 !details.has_notranslate && !language.empty()); | |
187 } | 183 } |
188 | 184 |
189 void TranslateHelper::CancelPendingTranslation() { | 185 void TranslateHelper::CancelPendingTranslation() { |
190 weak_method_factory_.InvalidateWeakPtrs(); | 186 weak_method_factory_.InvalidateWeakPtrs(); |
191 translation_pending_ = false; | 187 // Make sure to send the cancelled response back. |
188 if (translate_callback_pending_) { | |
189 translate_callback_pending_.Run(true, source_lang_, target_lang_, | |
190 TranslateErrors::NONE); | |
191 translate_callback_pending_.Reset(); | |
192 } | |
192 source_lang_.clear(); | 193 source_lang_.clear(); |
193 target_lang_.clear(); | 194 target_lang_.clear(); |
194 } | 195 } |
195 | 196 |
196 //////////////////////////////////////////////////////////////////////////////// | 197 //////////////////////////////////////////////////////////////////////////////// |
197 // TranslateHelper, protected: | 198 // TranslateHelper, protected: |
198 // | 199 // |
199 bool TranslateHelper::IsTranslateLibAvailable() { | 200 bool TranslateHelper::IsTranslateLibAvailable() { |
200 return ExecuteScriptAndGetBoolResult( | 201 return ExecuteScriptAndGetBoolResult( |
201 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && " | 202 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && " |
202 "typeof cr.googleTranslate.translate == 'function'", false); | 203 "typeof cr.googleTranslate.translate == 'function'", |
204 false); | |
203 } | 205 } |
204 | 206 |
205 bool TranslateHelper::IsTranslateLibReady() { | 207 bool TranslateHelper::IsTranslateLibReady() { |
206 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.libReady", false); | 208 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.libReady", false); |
207 } | 209 } |
208 | 210 |
209 bool TranslateHelper::HasTranslationFinished() { | 211 bool TranslateHelper::HasTranslationFinished() { |
210 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.finished", true); | 212 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.finished", true); |
211 } | 213 } |
212 | 214 |
213 bool TranslateHelper::HasTranslationFailed() { | 215 bool TranslateHelper::HasTranslationFailed() { |
214 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.error", true); | 216 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.error", true); |
215 } | 217 } |
216 | 218 |
217 bool TranslateHelper::StartTranslation() { | 219 bool TranslateHelper::StartTranslation() { |
218 std::string script = "cr.googleTranslate.translate('" + | 220 std::string script = "cr.googleTranslate.translate('" + source_lang_ + "','" + |
Tom Sepez
2016/08/01 17:08:17
Note: pre-existing. Although this is invoked in r
leonhsl(Using Gerrit)
2016/08/02 02:52:23
Understood. I filed an issue crbug.com/633460 to d
| |
219 source_lang_ + | 221 target_lang_ + "')"; |
220 "','" + | |
221 target_lang_ + | |
222 "')"; | |
223 return ExecuteScriptAndGetBoolResult(script, false); | 222 return ExecuteScriptAndGetBoolResult(script, false); |
224 } | 223 } |
225 | 224 |
226 std::string TranslateHelper::GetOriginalPageLanguage() { | 225 std::string TranslateHelper::GetOriginalPageLanguage() { |
227 return ExecuteScriptAndGetStringResult("cr.googleTranslate.sourceLang"); | 226 return ExecuteScriptAndGetStringResult("cr.googleTranslate.sourceLang"); |
228 } | 227 } |
229 | 228 |
230 base::TimeDelta TranslateHelper::AdjustDelay(int delayInMs) { | 229 base::TimeDelta TranslateHelper::AdjustDelay(int delayInMs) { |
231 // Just converts |delayInMs| without any modification in practical cases. | 230 // Just converts |delayInMs| without any modification in practical cases. |
232 // Tests will override this function to return modified value. | 231 // Tests will override this function to return modified value. |
233 return base::TimeDelta::FromMilliseconds(delayInMs); | 232 return base::TimeDelta::FromMilliseconds(delayInMs); |
234 } | 233 } |
235 | 234 |
236 void TranslateHelper::ExecuteScript(const std::string& script) { | 235 void TranslateHelper::ExecuteScript(const std::string& script) { |
237 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); | 236 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); |
238 if (!main_frame) | 237 if (!main_frame) |
239 return; | 238 return; |
240 | 239 |
241 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); | 240 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); |
242 main_frame->executeScriptInIsolatedWorld( | 241 main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1, |
243 world_id_, &source, 1, extension_group_); | 242 extension_group_); |
244 } | 243 } |
245 | 244 |
246 bool TranslateHelper::ExecuteScriptAndGetBoolResult(const std::string& script, | 245 bool TranslateHelper::ExecuteScriptAndGetBoolResult(const std::string& script, |
247 bool fallback) { | 246 bool fallback) { |
248 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); | 247 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); |
249 if (!main_frame) | 248 if (!main_frame) |
250 return fallback; | 249 return fallback; |
251 | 250 |
252 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); | 251 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); |
253 WebVector<v8::Local<v8::Value> > results; | 252 WebVector<v8::Local<v8::Value>> results; |
254 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); | 253 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); |
255 main_frame->executeScriptInIsolatedWorld( | 254 main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1, |
256 world_id_, &source, 1, extension_group_, &results); | 255 extension_group_, &results); |
257 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsBoolean()) { | 256 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsBoolean()) { |
258 NOTREACHED(); | 257 NOTREACHED(); |
259 return fallback; | 258 return fallback; |
260 } | 259 } |
261 | 260 |
262 return results[0]->BooleanValue(); | 261 return results[0]->BooleanValue(); |
263 } | 262 } |
264 | 263 |
265 std::string TranslateHelper::ExecuteScriptAndGetStringResult( | 264 std::string TranslateHelper::ExecuteScriptAndGetStringResult( |
266 const std::string& script) { | 265 const std::string& script) { |
267 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); | 266 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); |
268 if (!main_frame) | 267 if (!main_frame) |
269 return std::string(); | 268 return std::string(); |
270 | 269 |
271 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); | 270 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); |
272 WebVector<v8::Local<v8::Value> > results; | 271 WebVector<v8::Local<v8::Value>> results; |
273 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); | 272 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); |
274 main_frame->executeScriptInIsolatedWorld( | 273 main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1, |
275 world_id_, &source, 1, extension_group_, &results); | 274 extension_group_, &results); |
276 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsString()) { | 275 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsString()) { |
277 NOTREACHED(); | 276 NOTREACHED(); |
278 return std::string(); | 277 return std::string(); |
279 } | 278 } |
280 | 279 |
281 v8::Local<v8::String> v8_str = results[0].As<v8::String>(); | 280 v8::Local<v8::String> v8_str = results[0].As<v8::String>(); |
282 int length = v8_str->Utf8Length() + 1; | 281 int length = v8_str->Utf8Length() + 1; |
283 std::unique_ptr<char[]> str(new char[length]); | 282 std::unique_ptr<char[]> str(new char[length]); |
284 v8_str->WriteUtf8(str.get(), length); | 283 v8_str->WriteUtf8(str.get(), length); |
285 return std::string(str.get()); | 284 return std::string(str.get()); |
286 } | 285 } |
287 | 286 |
288 double TranslateHelper::ExecuteScriptAndGetDoubleResult( | 287 double TranslateHelper::ExecuteScriptAndGetDoubleResult( |
289 const std::string& script) { | 288 const std::string& script) { |
290 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); | 289 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); |
291 if (!main_frame) | 290 if (!main_frame) |
292 return 0.0; | 291 return 0.0; |
293 | 292 |
294 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); | 293 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); |
295 WebVector<v8::Local<v8::Value> > results; | 294 WebVector<v8::Local<v8::Value>> results; |
296 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); | 295 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); |
297 main_frame->executeScriptInIsolatedWorld( | 296 main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1, |
298 world_id_, &source, 1, extension_group_, &results); | 297 extension_group_, &results); |
299 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsNumber()) { | 298 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsNumber()) { |
300 NOTREACHED(); | 299 NOTREACHED(); |
301 return 0.0; | 300 return 0.0; |
302 } | 301 } |
303 | 302 |
304 return results[0]->NumberValue(); | 303 return results[0]->NumberValue(); |
305 } | 304 } |
306 | 305 |
307 //////////////////////////////////////////////////////////////////////////////// | 306 // mojom::Page implementations. |
308 // TranslateHelper, private: | 307 void TranslateHelper::Translate(const std::string& translate_script, |
309 // | 308 const std::string& source_lang, |
310 bool TranslateHelper::OnMessageReceived(const IPC::Message& message) { | 309 const std::string& target_lang, |
311 bool handled = true; | 310 const TranslateCallback& callback) { |
312 IPC_BEGIN_MESSAGE_MAP(TranslateHelper, message) | |
313 IPC_MESSAGE_HANDLER(ChromeFrameMsg_TranslatePage, OnTranslatePage) | |
314 IPC_MESSAGE_HANDLER(ChromeFrameMsg_RevertTranslation, OnRevertTranslation) | |
315 IPC_MESSAGE_UNHANDLED(handled = false) | |
316 IPC_END_MESSAGE_MAP() | |
317 return handled; | |
318 } | |
319 | |
320 void TranslateHelper::OnTranslatePage(int page_seq_no, | |
321 const std::string& translate_script, | |
322 const std::string& source_lang, | |
323 const std::string& target_lang) { | |
324 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); | 311 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); |
325 if (!main_frame || page_seq_no_ != page_seq_no) | 312 if (!main_frame) { |
313 // Cancelled. | |
314 callback.Run(true, source_lang, target_lang, TranslateErrors::NONE); | |
326 return; // We navigated away, nothing to do. | 315 return; // We navigated away, nothing to do. |
316 } | |
327 | 317 |
328 // A similar translation is already under way, nothing to do. | 318 // A similar translation is already under way, nothing to do. |
329 if (translation_pending_ && target_lang_ == target_lang) | 319 if (translate_callback_pending_ && target_lang_ == target_lang) { |
320 // This request is ignored. | |
321 callback.Run(true, source_lang, target_lang, TranslateErrors::NONE); | |
330 return; | 322 return; |
323 } | |
331 | 324 |
332 // Any pending translation is now irrelevant. | 325 // Any pending translation is now irrelevant. |
333 CancelPendingTranslation(); | 326 CancelPendingTranslation(); |
334 | 327 |
335 // Set our states. | 328 // Set our states. |
336 translation_pending_ = true; | 329 translate_callback_pending_ = callback; |
337 | 330 |
338 // If the source language is undetermined, we'll let the translate element | 331 // If the source language is undetermined, we'll let the translate element |
339 // detect it. | 332 // detect it. |
340 source_lang_ = (source_lang != kUnknownLanguageCode) ? source_lang | 333 source_lang_ = (source_lang != kUnknownLanguageCode) ? source_lang |
341 : kAutoDetectionLanguage; | 334 : kAutoDetectionLanguage; |
342 target_lang_ = target_lang; | 335 target_lang_ = target_lang; |
343 | 336 |
344 ReportUserActionDuration(language_determined_time_, base::TimeTicks::Now()); | 337 ReportUserActionDuration(language_determined_time_, base::TimeTicks::Now()); |
345 | 338 |
346 GURL url(main_frame->document().url()); | 339 GURL url(main_frame->document().url()); |
347 ReportPageScheme(url.scheme()); | 340 ReportPageScheme(url.scheme()); |
348 | 341 |
349 // Set up v8 isolated world with proper content-security-policy and | 342 // Set up v8 isolated world with proper content-security-policy and |
350 // security-origin. | 343 // security-origin. |
351 main_frame->setIsolatedWorldContentSecurityPolicy( | 344 main_frame->setIsolatedWorldContentSecurityPolicy( |
352 world_id_, WebString::fromUTF8(kContentSecurityPolicy)); | 345 world_id_, WebString::fromUTF8(kContentSecurityPolicy)); |
353 | 346 |
354 GURL security_origin = GetTranslateSecurityOrigin(); | 347 GURL security_origin = GetTranslateSecurityOrigin(); |
355 main_frame->setIsolatedWorldSecurityOrigin( | 348 main_frame->setIsolatedWorldSecurityOrigin( |
356 world_id_, WebSecurityOrigin::create(security_origin)); | 349 world_id_, WebSecurityOrigin::create(security_origin)); |
357 | 350 |
358 if (!IsTranslateLibAvailable()) { | 351 if (!IsTranslateLibAvailable()) { |
359 // Evaluate the script to add the translation related method to the global | 352 // Evaluate the script to add the translation related method to the global |
360 // context of the page. | 353 // context of the page. |
361 ExecuteScript(translate_script); | 354 ExecuteScript(translate_script); |
362 DCHECK(IsTranslateLibAvailable()); | 355 DCHECK(IsTranslateLibAvailable()); |
363 } | 356 } |
364 | 357 |
365 TranslatePageImpl(page_seq_no, 0); | 358 TranslatePageImpl(0); |
366 } | 359 } |
367 | 360 |
368 void TranslateHelper::OnRevertTranslation(int page_seq_no) { | 361 void TranslateHelper::RevertTranslation() { |
369 if (page_seq_no_ != page_seq_no) | |
370 return; // We navigated away, nothing to do. | |
371 | |
372 if (!IsTranslateLibAvailable()) { | 362 if (!IsTranslateLibAvailable()) { |
373 NOTREACHED(); | 363 NOTREACHED(); |
374 return; | 364 return; |
375 } | 365 } |
376 | 366 |
377 CancelPendingTranslation(); | 367 CancelPendingTranslation(); |
378 | 368 |
379 ExecuteScript("cr.googleTranslate.revert()"); | 369 ExecuteScript("cr.googleTranslate.revert()"); |
380 } | 370 } |
381 | 371 |
382 void TranslateHelper::CheckTranslateStatus(int page_seq_no) { | 372 //////////////////////////////////////////////////////////////////////////////// |
383 // If this is not the same page, the translation has been canceled. | 373 // TranslateHelper, private: |
384 if (page_seq_no_ != page_seq_no) | 374 // |
385 return; | 375 void TranslateHelper::CheckTranslateStatus() { |
386 | |
387 // First check if there was an error. | 376 // First check if there was an error. |
388 if (HasTranslationFailed()) { | 377 if (HasTranslationFailed()) { |
389 // TODO(toyoshim): Check |errorCode| of translate.js and notify it here. | 378 // TODO(toyoshim): Check |errorCode| of translate.js and notify it here. |
390 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); | 379 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); |
391 return; // There was an error. | 380 return; // There was an error. |
392 } | 381 } |
393 | 382 |
394 if (HasTranslationFinished()) { | 383 if (HasTranslationFinished()) { |
395 std::string actual_source_lang; | 384 std::string actual_source_lang; |
396 // Translation was successfull, if it was auto, retrieve the source | 385 // Translation was successfull, if it was auto, retrieve the source |
397 // language the Translate Element detected. | 386 // language the Translate Element detected. |
398 if (source_lang_ == kAutoDetectionLanguage) { | 387 if (source_lang_ == kAutoDetectionLanguage) { |
399 actual_source_lang = GetOriginalPageLanguage(); | 388 actual_source_lang = GetOriginalPageLanguage(); |
400 if (actual_source_lang.empty()) { | 389 if (actual_source_lang.empty()) { |
401 NotifyBrowserTranslationFailed(TranslateErrors::UNKNOWN_LANGUAGE); | 390 NotifyBrowserTranslationFailed(TranslateErrors::UNKNOWN_LANGUAGE); |
402 return; | 391 return; |
403 } else if (actual_source_lang == target_lang_) { | 392 } else if (actual_source_lang == target_lang_) { |
404 NotifyBrowserTranslationFailed(TranslateErrors::IDENTICAL_LANGUAGES); | 393 NotifyBrowserTranslationFailed(TranslateErrors::IDENTICAL_LANGUAGES); |
405 return; | 394 return; |
406 } | 395 } |
407 } else { | 396 } else { |
408 actual_source_lang = source_lang_; | 397 actual_source_lang = source_lang_; |
409 } | 398 } |
410 | 399 |
411 if (!translation_pending_) { | 400 if (!translate_callback_pending_) { |
412 NOTREACHED(); | 401 NOTREACHED(); |
413 return; | 402 return; |
414 } | 403 } |
415 | 404 |
416 translation_pending_ = false; | |
417 | |
418 // Check JavaScript performance counters for UMA reports. | 405 // Check JavaScript performance counters for UMA reports. |
419 ReportTimeToTranslate( | 406 ReportTimeToTranslate( |
420 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.translationTime")); | 407 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.translationTime")); |
421 | 408 |
422 // Notify the browser we are done. | 409 // Notify the browser we are done. |
423 render_frame()->Send(new ChromeFrameHostMsg_PageTranslated( | 410 translate_callback_pending_.Run(false, actual_source_lang, target_lang_, |
424 render_frame()->GetRoutingID(), actual_source_lang, target_lang_, | 411 TranslateErrors::NONE); |
425 TranslateErrors::NONE)); | 412 translate_callback_pending_.Reset(); |
426 return; | 413 return; |
427 } | 414 } |
428 | 415 |
429 // The translation is still pending, check again later. | 416 // The translation is still pending, check again later. |
430 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 417 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
431 FROM_HERE, base::Bind(&TranslateHelper::CheckTranslateStatus, | 418 FROM_HERE, base::Bind(&TranslateHelper::CheckTranslateStatus, |
432 weak_method_factory_.GetWeakPtr(), page_seq_no), | 419 weak_method_factory_.GetWeakPtr()), |
433 AdjustDelay(kTranslateStatusCheckDelayMs)); | 420 AdjustDelay(kTranslateStatusCheckDelayMs)); |
434 } | 421 } |
435 | 422 |
436 void TranslateHelper::TranslatePageImpl(int page_seq_no, int count) { | 423 void TranslateHelper::TranslatePageImpl(int count) { |
437 DCHECK_LT(count, kMaxTranslateInitCheckAttempts); | 424 DCHECK_LT(count, kMaxTranslateInitCheckAttempts); |
438 if (page_seq_no_ != page_seq_no) | |
439 return; | |
440 | |
441 if (!IsTranslateLibReady()) { | 425 if (!IsTranslateLibReady()) { |
442 // The library is not ready, try again later, unless we have tried several | 426 // The library is not ready, try again later, unless we have tried several |
443 // times unsuccessfully already. | 427 // times unsuccessfully already. |
444 if (++count >= kMaxTranslateInitCheckAttempts) { | 428 if (++count >= kMaxTranslateInitCheckAttempts) { |
445 NotifyBrowserTranslationFailed(TranslateErrors::INITIALIZATION_ERROR); | 429 NotifyBrowserTranslationFailed(TranslateErrors::INITIALIZATION_ERROR); |
446 return; | 430 return; |
447 } | 431 } |
448 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 432 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
449 FROM_HERE, | 433 FROM_HERE, base::Bind(&TranslateHelper::TranslatePageImpl, |
450 base::Bind(&TranslateHelper::TranslatePageImpl, | 434 weak_method_factory_.GetWeakPtr(), count), |
451 weak_method_factory_.GetWeakPtr(), page_seq_no, count), | |
452 AdjustDelay(count * kTranslateInitCheckDelayMs)); | 435 AdjustDelay(count * kTranslateInitCheckDelayMs)); |
453 return; | 436 return; |
454 } | 437 } |
455 | 438 |
456 // The library is loaded, and ready for translation now. | 439 // The library is loaded, and ready for translation now. |
457 // Check JavaScript performance counters for UMA reports. | 440 // Check JavaScript performance counters for UMA reports. |
458 ReportTimeToBeReady( | 441 ReportTimeToBeReady( |
459 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.readyTime")); | 442 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.readyTime")); |
460 ReportTimeToLoad( | 443 ReportTimeToLoad( |
461 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.loadTime")); | 444 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.loadTime")); |
462 | 445 |
463 if (!StartTranslation()) { | 446 if (!StartTranslation()) { |
464 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); | 447 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); |
465 return; | 448 return; |
466 } | 449 } |
467 // Check the status of the translation. | 450 // Check the status of the translation. |
468 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 451 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
469 FROM_HERE, base::Bind(&TranslateHelper::CheckTranslateStatus, | 452 FROM_HERE, base::Bind(&TranslateHelper::CheckTranslateStatus, |
470 weak_method_factory_.GetWeakPtr(), page_seq_no), | 453 weak_method_factory_.GetWeakPtr()), |
471 AdjustDelay(kTranslateStatusCheckDelayMs)); | 454 AdjustDelay(kTranslateStatusCheckDelayMs)); |
472 } | 455 } |
473 | 456 |
474 void TranslateHelper::NotifyBrowserTranslationFailed( | 457 void TranslateHelper::NotifyBrowserTranslationFailed( |
475 TranslateErrors::Type error) { | 458 TranslateErrors::Type error) { |
476 translation_pending_ = false; | 459 DCHECK(translate_callback_pending_); |
477 // Notify the browser there was an error. | 460 // Notify the browser there was an error. |
478 render_frame()->Send(new ChromeFrameHostMsg_PageTranslated( | 461 translate_callback_pending_.Run(false, source_lang_, target_lang_, error); |
479 render_frame()->GetRoutingID(), source_lang_, target_lang_, error)); | 462 translate_callback_pending_.Reset(); |
463 } | |
464 | |
465 const mojom::ContentTranslateDriverPtr& TranslateHelper::GetTranslateDriver() { | |
466 if (!translate_driver_) { | |
467 render_frame()->GetRemoteInterfaces()->GetInterface( | |
468 mojo::GetProxy(&translate_driver_)); | |
469 } | |
470 | |
471 return translate_driver_; | |
480 } | 472 } |
481 | 473 |
482 void TranslateHelper::OnDestruct() { | 474 void TranslateHelper::OnDestruct() { |
483 delete this; | 475 delete this; |
484 } | 476 } |
485 | 477 |
486 } // namespace translate | 478 } // namespace translate |
OLD | NEW |