Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(751)

Side by Side Diff: components/translate/content/renderer/translate_helper.cc

Issue 2577203002: Remove use of WebNode/WebElement in translate_helper (Closed)
Patch Set: Move translate specific DOM operations into separate file Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/core/common/translate_constants.h" 17 #include "components/translate/core/common/translate_constants.h"
18 #include "components/translate/core/common/translate_metrics.h" 18 #include "components/translate/core/common/translate_metrics.h"
19 #include "components/translate/core/common/translate_util.h" 19 #include "components/translate/core/common/translate_util.h"
20 #include "components/translate/core/language_detection/language_detection_util.h " 20 #include "components/translate/core/language_detection/language_detection_util.h "
21 #include "content/public/common/content_constants.h" 21 #include "content/public/common/content_constants.h"
22 #include "content/public/common/url_constants.h" 22 #include "content/public/common/url_constants.h"
23 #include "content/public/renderer/render_frame.h" 23 #include "content/public/renderer/render_frame.h"
24 #include "content/public/renderer/render_thread.h" 24 #include "content/public/renderer/render_thread.h"
25 #include "services/service_manager/public/cpp/interface_provider.h" 25 #include "services/service_manager/public/cpp/interface_provider.h"
26 #include "third_party/WebKit/public/web/WebDocument.h" 26 #include "third_party/WebKit/public/web/WebDocument.h"
27 #include "third_party/WebKit/public/web/WebElement.h" 27 #include "third_party/WebKit/public/web/WebLanguageDetectionDetails.h"
28 #include "third_party/WebKit/public/web/WebLocalFrame.h" 28 #include "third_party/WebKit/public/web/WebLocalFrame.h"
29 #include "third_party/WebKit/public/web/WebNode.h"
30 #include "third_party/WebKit/public/web/WebScriptSource.h" 29 #include "third_party/WebKit/public/web/WebScriptSource.h"
31 #include "url/gurl.h" 30 #include "url/gurl.h"
32 #include "v8/include/v8.h" 31 #include "v8/include/v8.h"
33 32
34 using base::ASCIIToUTF16; 33 using base::ASCIIToUTF16;
35 using blink::WebDocument; 34 using blink::WebDocument;
36 using blink::WebElement; 35 using blink::WebLanguageDetectionDetails;
37 using blink::WebLocalFrame; 36 using blink::WebLocalFrame;
38 using blink::WebNode;
39 using blink::WebScriptSource; 37 using blink::WebScriptSource;
40 using blink::WebSecurityOrigin; 38 using blink::WebSecurityOrigin;
41 using blink::WebString; 39 using blink::WebString;
42 using blink::WebVector; 40 using blink::WebVector;
43 41
44 namespace { 42 namespace {
45 43
46 // The delay in milliseconds that we'll wait before checking to see if the 44 // The delay in milliseconds that we'll wait before checking to see if the
47 // translate library injected in the page is ready. 45 // translate library injected in the page is ready.
48 const int kTranslateInitCheckDelayMs = 150; 46 const int kTranslateInitCheckDelayMs = 150;
49 47
50 // The maximum number of times we'll check to see if the translate library 48 // The maximum number of times we'll check to see if the translate library
51 // injected in the page is ready. 49 // injected in the page is ready.
52 const int kMaxTranslateInitCheckAttempts = 5; 50 const int kMaxTranslateInitCheckAttempts = 5;
53 51
54 // The delay we wait in milliseconds before checking whether the translation has 52 // The delay we wait in milliseconds before checking whether the translation has
55 // finished. 53 // finished.
56 const int kTranslateStatusCheckDelayMs = 400; 54 const int kTranslateStatusCheckDelayMs = 400;
57 55
58 // Language name passed to the Translate element for it to detect the language. 56 // Language name passed to the Translate element for it to detect the language.
59 const char kAutoDetectionLanguage[] = "auto"; 57 const char kAutoDetectionLanguage[] = "auto";
60 58
61 // Isolated world sets following content-security-policy. 59 // Isolated world sets following content-security-policy.
62 const char kContentSecurityPolicy[] = "script-src 'self' 'unsafe-eval'"; 60 const char kContentSecurityPolicy[] = "script-src 'self' 'unsafe-eval'";
63 61
64 // Returns whether the page associated with |document| is a candidate for
65 // translation. Some pages can explictly specify (via a meta-tag) that they
66 // should not be translated.
67 // TODO(dglazkov): This logic should be moved into Blink.
68 bool HasNoTranslateMeta(WebDocument* document) {
69 WebElement head = document->head();
70 if (head.isNull() || head.firstChild().isNull())
71 return false;
72
73 const WebString meta(ASCIIToUTF16("meta"));
74 const WebString name(ASCIIToUTF16("name"));
75 const WebString google(ASCIIToUTF16("google"));
76 const WebString value(ASCIIToUTF16("value"));
77 const WebString content(ASCIIToUTF16("content"));
78
79 for (WebNode child = head.firstChild(); !child.isNull();
80 child = child.nextSibling()) {
81 if (!child.isElementNode())
82 continue;
83 WebElement element = child.to<WebElement>();
84 // Check if a tag is <meta>.
85 if (!element.hasHTMLTagName(meta))
86 continue;
87 // Check if the tag contains name="google".
88 WebString attribute = element.getAttribute(name);
89 if (attribute.isNull() || attribute != google)
90 continue;
91 // Check if the tag contains value="notranslate", or content="notranslate".
92 attribute = element.getAttribute(value);
93 if (attribute.isNull())
94 attribute = element.getAttribute(content);
95 if (attribute.isNull())
96 continue;
97 if (base::LowerCaseEqualsASCII(base::StringPiece16(attribute),
98 "notranslate"))
99 return true;
100 }
101 return false;
102 }
103
104 } // namespace 62 } // namespace
105 63
106 namespace translate { 64 namespace translate {
107 65
108 //////////////////////////////////////////////////////////////////////////////// 66 ////////////////////////////////////////////////////////////////////////////////
109 // TranslateHelper, public: 67 // TranslateHelper, public:
110 TranslateHelper::TranslateHelper(content::RenderFrame* render_frame, 68 TranslateHelper::TranslateHelper(content::RenderFrame* render_frame,
111 int world_id, 69 int world_id,
112 int extension_group, 70 int extension_group,
113 const std::string& extension_scheme) 71 const std::string& extension_scheme)
114 : content::RenderFrameObserver(render_frame), 72 : content::RenderFrameObserver(render_frame),
115 world_id_(world_id), 73 world_id_(world_id),
116 extension_group_(extension_group), 74 extension_group_(extension_group),
117 extension_scheme_(extension_scheme), 75 extension_scheme_(extension_scheme),
118 binding_(this), 76 binding_(this),
119 weak_method_factory_(this) {} 77 weak_method_factory_(this) {}
120 78
121 TranslateHelper::~TranslateHelper() { 79 TranslateHelper::~TranslateHelper() {}
122 }
123 80
124 void TranslateHelper::PrepareForUrl(const GURL& url) { 81 void TranslateHelper::PrepareForUrl(const GURL& url) {
125 // Navigated to a new url, reset current page translation. 82 // Navigated to a new url, reset current page translation.
126 ResetPage(); 83 ResetPage();
127 } 84 }
128 85
129 void TranslateHelper::PageCaptured(const base::string16& contents) { 86 void TranslateHelper::PageCaptured(const base::string16& contents) {
130 // Get the document language as set by WebKit from the http-equiv 87 // Get the document language as set by WebKit from the http-equiv
131 // meta tag for "content-language". This may or may not also 88 // meta tag for "content-language". This may or may not also
132 // have a value derived from the actual Content-Language HTTP 89 // have a value derived from the actual Content-Language HTTP
133 // header. The two actually have different meanings (despite the 90 // header. The two actually have different meanings (despite the
134 // original intent of http-equiv to be an equivalent) with the former 91 // original intent of http-equiv to be an equivalent) with the former
135 // being the language of the document and the latter being the 92 // being the language of the document and the latter being the
136 // language of the intended audience (a distinction really only 93 // language of the intended audience (a distinction really only
137 // relevant for things like langauge textbooks). This distinction 94 // relevant for things like langauge textbooks). This distinction
138 // shouldn't affect translation. 95 // shouldn't affect translation.
139 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); 96 WebLocalFrame* main_frame = render_frame()->GetWebFrame();
140 if (!main_frame) 97 if (!main_frame)
141 return; 98 return;
142 99
143 WebDocument document = main_frame->document(); 100 WebDocument document = main_frame->document();
144 std::string content_language = document.contentLanguage().utf8(); 101 WebLanguageDetectionDetails web_detection_details =
145 WebElement html_element = document.documentElement(); 102 WebLanguageDetectionDetails::collectLanguageDetectionDetails(document);
146 std::string html_lang; 103
147 // |html_element| can be null element, e.g. in 104 std::string content_language = web_detection_details.contentLanguage.utf8();
148 // BrowserTest.WindowOpenClose. 105 std::string html_lang = web_detection_details.htmlLanguage.utf8();
149 if (!html_element.isNull())
150 html_lang = html_element.getAttribute("lang").utf8();
151 std::string cld_language; 106 std::string cld_language;
152 bool is_cld_reliable; 107 bool is_cld_reliable;
153 std::string language = DeterminePageLanguage( 108 std::string language = DeterminePageLanguage(
154 content_language, html_lang, contents, &cld_language, &is_cld_reliable); 109 content_language, html_lang, contents, &cld_language, &is_cld_reliable);
155 110
156 if (language.empty()) 111 if (language.empty())
157 return; 112 return;
158 113
159 language_determined_time_ = base::TimeTicks::Now(); 114 language_determined_time_ = base::TimeTicks::Now();
160 115
161 GURL url(document.url());
162 LanguageDetectionDetails details; 116 LanguageDetectionDetails details;
163 details.time = base::Time::Now(); 117 details.time = base::Time::Now();
164 details.url = url; 118 details.url = web_detection_details.url;
165 details.content_language = content_language; 119 details.content_language = content_language;
166 details.cld_language = cld_language; 120 details.cld_language = cld_language;
167 details.is_cld_reliable = is_cld_reliable; 121 details.is_cld_reliable = is_cld_reliable;
168 details.has_notranslate = HasNoTranslateMeta(&document); 122 details.has_notranslate = web_detection_details.hasNoTranslateMeta;
169 details.html_root_language = html_lang; 123 details.html_root_language = html_lang;
170 details.adopted_language = language; 124 details.adopted_language = language;
171 125
172 // TODO(hajimehoshi): If this affects performance, it should be set only if 126 // TODO(hajimehoshi): If this affects performance, it should be set only if
173 // translate-internals tab exists. 127 // translate-internals tab exists.
174 details.contents = contents; 128 details.contents = contents;
175 129
176 // For the same render frame with the same url, each time when its texts are 130 // For the same render frame with the same url, each time when its texts are
177 // captured, it should be treated as a new page to do translation. 131 // captured, it should be treated as a new page to do translation.
178 ResetPage(); 132 ResetPage();
(...skipping 12 matching lines...) Expand all
191 } 145 }
192 source_lang_.clear(); 146 source_lang_.clear();
193 target_lang_.clear(); 147 target_lang_.clear();
194 } 148 }
195 149
196 //////////////////////////////////////////////////////////////////////////////// 150 ////////////////////////////////////////////////////////////////////////////////
197 // TranslateHelper, protected: 151 // TranslateHelper, protected:
198 bool TranslateHelper::IsTranslateLibAvailable() { 152 bool TranslateHelper::IsTranslateLibAvailable() {
199 return ExecuteScriptAndGetBoolResult( 153 return ExecuteScriptAndGetBoolResult(
200 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && " 154 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && "
201 "typeof cr.googleTranslate.translate == 'function'", false); 155 "typeof cr.googleTranslate.translate == 'function'",
156 false);
202 } 157 }
203 158
204 bool TranslateHelper::IsTranslateLibReady() { 159 bool TranslateHelper::IsTranslateLibReady() {
205 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.libReady", false); 160 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.libReady", false);
206 } 161 }
207 162
208 bool TranslateHelper::HasTranslationFinished() { 163 bool TranslateHelper::HasTranslationFinished() {
209 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.finished", true); 164 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.finished", true);
210 } 165 }
211 166
212 bool TranslateHelper::HasTranslationFailed() { 167 bool TranslateHelper::HasTranslationFailed() {
213 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.error", true); 168 return ExecuteScriptAndGetBoolResult("cr.googleTranslate.error", true);
214 } 169 }
215 170
216 bool TranslateHelper::StartTranslation() { 171 bool TranslateHelper::StartTranslation() {
217 std::string script = "cr.googleTranslate.translate('" + 172 std::string script = "cr.googleTranslate.translate('" + source_lang_ + "','" +
218 source_lang_ + 173 target_lang_ + "')";
219 "','" +
220 target_lang_ +
221 "')";
222 return ExecuteScriptAndGetBoolResult(script, false); 174 return ExecuteScriptAndGetBoolResult(script, false);
223 } 175 }
224 176
225 std::string TranslateHelper::GetOriginalPageLanguage() { 177 std::string TranslateHelper::GetOriginalPageLanguage() {
226 return ExecuteScriptAndGetStringResult("cr.googleTranslate.sourceLang"); 178 return ExecuteScriptAndGetStringResult("cr.googleTranslate.sourceLang");
227 } 179 }
228 180
229 base::TimeDelta TranslateHelper::AdjustDelay(int delayInMs) { 181 base::TimeDelta TranslateHelper::AdjustDelay(int delayInMs) {
230 // Just converts |delayInMs| without any modification in practical cases. 182 // Just converts |delayInMs| without any modification in practical cases.
231 // Tests will override this function to return modified value. 183 // Tests will override this function to return modified value.
232 return base::TimeDelta::FromMilliseconds(delayInMs); 184 return base::TimeDelta::FromMilliseconds(delayInMs);
233 } 185 }
234 186
235 void TranslateHelper::ExecuteScript(const std::string& script) { 187 void TranslateHelper::ExecuteScript(const std::string& script) {
236 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); 188 WebLocalFrame* main_frame = render_frame()->GetWebFrame();
237 if (!main_frame) 189 if (!main_frame)
238 return; 190 return;
239 191
240 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); 192 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script));
241 main_frame->executeScriptInIsolatedWorld( 193 main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1,
242 world_id_, &source, 1, extension_group_); 194 extension_group_);
243 } 195 }
244 196
245 bool TranslateHelper::ExecuteScriptAndGetBoolResult(const std::string& script, 197 bool TranslateHelper::ExecuteScriptAndGetBoolResult(const std::string& script,
246 bool fallback) { 198 bool fallback) {
247 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); 199 WebLocalFrame* main_frame = render_frame()->GetWebFrame();
248 if (!main_frame) 200 if (!main_frame)
249 return fallback; 201 return fallback;
250 202
251 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); 203 v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
252 WebVector<v8::Local<v8::Value> > results; 204 WebVector<v8::Local<v8::Value>> results;
253 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); 205 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script));
254 main_frame->executeScriptInIsolatedWorld( 206 main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1,
255 world_id_, &source, 1, extension_group_, &results); 207 extension_group_, &results);
256 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsBoolean()) { 208 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsBoolean()) {
257 NOTREACHED(); 209 NOTREACHED();
258 return fallback; 210 return fallback;
259 } 211 }
260 212
261 return results[0]->BooleanValue(); 213 return results[0]->BooleanValue();
262 } 214 }
263 215
264 std::string TranslateHelper::ExecuteScriptAndGetStringResult( 216 std::string TranslateHelper::ExecuteScriptAndGetStringResult(
265 const std::string& script) { 217 const std::string& script) {
266 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); 218 WebLocalFrame* main_frame = render_frame()->GetWebFrame();
267 if (!main_frame) 219 if (!main_frame)
268 return std::string(); 220 return std::string();
269 221
270 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); 222 v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
271 WebVector<v8::Local<v8::Value> > results; 223 WebVector<v8::Local<v8::Value>> results;
272 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); 224 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script));
273 main_frame->executeScriptInIsolatedWorld( 225 main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1,
274 world_id_, &source, 1, extension_group_, &results); 226 extension_group_, &results);
275 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsString()) { 227 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsString()) {
276 NOTREACHED(); 228 NOTREACHED();
277 return std::string(); 229 return std::string();
278 } 230 }
279 231
280 v8::Local<v8::String> v8_str = results[0].As<v8::String>(); 232 v8::Local<v8::String> v8_str = results[0].As<v8::String>();
281 int length = v8_str->Utf8Length() + 1; 233 int length = v8_str->Utf8Length() + 1;
282 std::unique_ptr<char[]> str(new char[length]); 234 std::unique_ptr<char[]> str(new char[length]);
283 v8_str->WriteUtf8(str.get(), length); 235 v8_str->WriteUtf8(str.get(), length);
284 return std::string(str.get()); 236 return std::string(str.get());
285 } 237 }
286 238
287 double TranslateHelper::ExecuteScriptAndGetDoubleResult( 239 double TranslateHelper::ExecuteScriptAndGetDoubleResult(
288 const std::string& script) { 240 const std::string& script) {
289 WebLocalFrame* main_frame = render_frame()->GetWebFrame(); 241 WebLocalFrame* main_frame = render_frame()->GetWebFrame();
290 if (!main_frame) 242 if (!main_frame)
291 return 0.0; 243 return 0.0;
292 244
293 v8::HandleScope handle_scope(v8::Isolate::GetCurrent()); 245 v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
294 WebVector<v8::Local<v8::Value> > results; 246 WebVector<v8::Local<v8::Value>> results;
295 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script)); 247 WebScriptSource source = WebScriptSource(ASCIIToUTF16(script));
296 main_frame->executeScriptInIsolatedWorld( 248 main_frame->executeScriptInIsolatedWorld(world_id_, &source, 1,
297 world_id_, &source, 1, extension_group_, &results); 249 extension_group_, &results);
298 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsNumber()) { 250 if (results.size() != 1 || results[0].IsEmpty() || !results[0]->IsNumber()) {
299 NOTREACHED(); 251 NOTREACHED();
300 return 0.0; 252 return 0.0;
301 } 253 }
302 254
303 return results[0]->NumberValue(); 255 return results[0]->NumberValue();
304 } 256 }
305 257
306 // mojom::Page implementations. 258 // mojom::Page implementations.
307 void TranslateHelper::Translate(const std::string& translate_script, 259 void TranslateHelper::Translate(const std::string& translate_script,
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 binding_.Close(); 426 binding_.Close();
475 translate_callback_pending_.Reset(); 427 translate_callback_pending_.Reset();
476 CancelPendingTranslation(); 428 CancelPendingTranslation();
477 } 429 }
478 430
479 void TranslateHelper::OnDestruct() { 431 void TranslateHelper::OnDestruct() {
480 delete this; 432 delete this;
481 } 433 }
482 434
483 } // namespace translate 435 } // namespace translate
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/web/BUILD.gn » ('j') | third_party/WebKit/Source/web/WebLanguageDetectionDetails.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698