blob: 6f68583eee307ab6f50f6539ffd10f74fb0b00ff [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// 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
3// found in the LICENSE file.
4
5// This code is used in conjunction with the Google Translate Element script.
6// It is injected in a page to translate it from one language to another.
7// It should be included in the page before the Translate Element script.
8
9var cr = {};
10
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000011cr.googleTranslate = (function(key) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010012 /**
13 * The Translate Element library's instance.
14 * @type {object}
15 */
Torne (Richard Coles)58218062012-11-14 11:43:16 +000016 var lib;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010017
18 /**
19 * A flag representing if the Translate Element library is initialized.
20 * @type {boolean}
21 */
Torne (Richard Coles)58218062012-11-14 11:43:16 +000022 var libReady = false;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010023
24 /**
25 * A flag representing if the Translate Element library returns error while
26 * performing translation. Also it is set to true when the Translate Element
27 * library is not initialized in 600 msec from the library is loaded.
28 * @type {boolean}
29 */
Torne (Richard Coles)58218062012-11-14 11:43:16 +000030 var error = false;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010031
32 /**
33 * A flag representing if the Translate Element has finished a translation.
34 * @type {boolean}
35 */
Torne (Richard Coles)58218062012-11-14 11:43:16 +000036 var finished = false;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010037
38 /**
39 * Counts how many times the checkLibReady function is called. The function
40 * is called in every 100 msec and counted up to 6.
41 * @type {number}
42 */
Torne (Richard Coles)58218062012-11-14 11:43:16 +000043 var checkReadyCount = 0;
44
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010045 /**
46 * Time in msec when this script is injected.
47 * @type {number}
48 */
49 var injectedTime = performance.now();
50
51 /**
52 * Time in msec when the Translate Element library is loaded completely.
53 * @type {number}
54 */
55 var loadedTime = 0.0;
56
57 /**
58 * Time in msec when the Translate Element library is initialized and ready
59 * for performing translation.
60 * @type {number}
61 */
62 var readyTime = 0.0;
63
64 /**
65 * Time in msec when the Translate Element library starts a translation.
66 * @type {number}
67 */
68 var startTime = 0.0;
69
70 /**
71 * Time in msec when the Translate Element library ends a translation.
72 * @type {number}
73 */
74 var endTime = 0.0;
75
Torne (Richard Coles)58218062012-11-14 11:43:16 +000076 function checkLibReady() {
77 if (lib.isAvailable()) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010078 readyTime = performance.now();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000079 libReady = true;
80 return;
81 }
82 if (checkReadyCount++ > 5) {
83 error = true;
84 return;
85 }
86 setTimeout(checkLibReady, 100);
87 }
88
89 function onTranslateProgress(progress, opt_finished, opt_error) {
90 finished = opt_finished;
91 // opt_error can be 'undefined'.
92 if (typeof opt_error == 'boolean' && opt_error) {
93 error = true;
94 // We failed to translate, restore so the page is in a consistent state.
95 lib.restore();
96 }
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010097 if (finished)
98 endTime = performance.now();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000099 }
100
101 // Public API.
102 return {
103 /**
104 * Whether the library is ready.
105 * The translate function should only be called when |libReady| is true.
106 * @type {boolean}
107 */
108 get libReady() {
109 return libReady;
110 },
111
112 /**
113 * Whether the current translate has finished successfully.
114 * @type {boolean}
115 */
116 get finished() {
117 return finished;
118 },
119
120 /**
121 * Whether an error occured initializing the library of translating the
122 * page.
123 * @type {boolean}
124 */
125 get error() {
126 return error;
127 },
128
129 /**
130 * The language the page translated was in. Is valid only after the page
131 * has been successfully translated and the original language specified to
132 * the translate function was 'auto'. Is empty otherwise.
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100133 * Some versions of Element library don't provide |getDetectedLanguage|
134 * function. In that case, this function returns 'und'.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000135 * @type {boolean}
136 */
137 get sourceLang() {
138 if (!libReady || !finished || error)
139 return '';
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100140 if (!lib.getDetectedLanguage)
141 return 'und'; // defined as chrome::kUnknownLanguageCode in C++ world.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000142 return lib.getDetectedLanguage();
143 },
144
145 /**
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100146 * Time in msec from this script being injected to all server side scripts
147 * being loaded.
148 * @type {number}
149 */
150 get loadTime() {
151 if (loadedTime == 0)
152 return 0;
153 return loadedTime - injectedTime;
154 },
155
156 /**
157 * Time in msec from this script being injected to the Translate Element
158 * library being ready.
159 * @type {number}
160 */
161 get readyTime() {
162 if (!libReady)
163 return 0;
164 return readyTime - injectedTime;
165 },
166
167 /**
168 * Time in msec to perform translation.
169 * @type {number}
170 */
171 get translationTime() {
172 if (!finished)
173 return 0;
174 return endTime - startTime;
175 },
176
177 /**
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000178 * Translate the page contents. Note that the translation is asynchronous.
179 * You need to regularly check the state of |finished| and |error| to know
180 * if the translation finished or if there was an error.
181 * @param {string} originalLang The language the page is in.
182 * @param {string} targetLang The language the page should be translated to.
183 * @return {boolean} False if the translate library was not ready, in which
184 * case the translation is not started. True otherwise.
185 */
186 translate: function(originalLang, targetLang) {
187 finished = false;
188 error = false;
189 if (!libReady)
190 return false;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100191 startTime = performance.now();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000192 lib.translatePage(originalLang, targetLang, onTranslateProgress);
193 return true;
194 },
195
196 /**
197 * Reverts the page contents to its original value, effectively reverting
198 * any performed translation. Does nothing if the page was not translated.
199 */
200 revert: function() {
201 lib.restore();
202 },
203
204 /**
205 * Entry point called by the Translate Element once it has been injected in
206 * the page.
207 */
208 onTranslateElementLoad: function() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100209 loadedTime = performance.now();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000210 try {
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +0100211 lib = google.translate.TranslateService({
212 'key': key,
213 'useSecureConnection': true
214 });
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000215 } catch (err) {
216 error = true;
217 return;
218 }
219 // The TranslateService is not available immediately as it needs to start
220 // Flash. Let's wait until it is ready.
221 checkLibReady();
222 }
223 };
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000224})/* Calling code '(|key|);' will be appended by TranslateHelper in C++ here. */