|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 this.EXPORTED_SYMBOLS = ["Translation"]; |
|
8 |
|
9 const {classes: Cc, interfaces: Ci, utils: Cu} = Components; |
|
10 |
|
11 Cu.import("resource://gre/modules/Promise.jsm"); |
|
12 Cu.import("resource://gre/modules/Services.jsm"); |
|
13 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
14 |
|
15 this.Translation = { |
|
16 supportedSourceLanguages: ["en", "zh", "ja", "es", "de", "fr", "ru", "ar", "ko", "pt"], |
|
17 supportedTargetLanguages: ["en", "pl", "tr", "vi"], |
|
18 |
|
19 _defaultTargetLanguage: "", |
|
20 get defaultTargetLanguage() { |
|
21 if (!this._defaultTargetLanguage) { |
|
22 this._defaultTargetLanguage = Cc["@mozilla.org/chrome/chrome-registry;1"] |
|
23 .getService(Ci.nsIXULChromeRegistry) |
|
24 .getSelectedLocale("global") |
|
25 .split("-")[0]; |
|
26 } |
|
27 return this._defaultTargetLanguage; |
|
28 }, |
|
29 |
|
30 languageDetected: function(aBrowser, aDetectedLanguage) { |
|
31 if (this.supportedSourceLanguages.indexOf(aDetectedLanguage) != -1 && |
|
32 aDetectedLanguage != this.defaultTargetLanguage) { |
|
33 if (!aBrowser.translationUI) |
|
34 aBrowser.translationUI = new TranslationUI(aBrowser); |
|
35 |
|
36 aBrowser.translationUI.showTranslationUI(aDetectedLanguage); |
|
37 } |
|
38 } |
|
39 }; |
|
40 |
|
41 /* TranslationUI objects keep the information related to translation for |
|
42 * a specific browser. This object is passed to the translation |
|
43 * infobar so that it can initialize itself. The properties exposed to |
|
44 * the infobar are: |
|
45 * - detectedLanguage, code of the language detected on the web page. |
|
46 * - state, the state in which the infobar should be displayed |
|
47 * - STATE_{OFFER,TRANSLATING,TRANSLATED,ERROR} constants. |
|
48 * - translatedFrom, if already translated, source language code. |
|
49 * - translatedTo, if already translated, target language code. |
|
50 * - translate, method starting the translation of the current page. |
|
51 * - showOriginalContent, method showing the original page content. |
|
52 * - showTranslatedContent, method showing the translation for an |
|
53 * already translated page whose original content is shown. |
|
54 * - originalShown, boolean indicating if the original or translated |
|
55 * version of the page is shown. |
|
56 */ |
|
57 function TranslationUI(aBrowser) { |
|
58 this.browser = aBrowser; |
|
59 } |
|
60 |
|
61 TranslationUI.prototype = { |
|
62 STATE_OFFER: 0, |
|
63 STATE_TRANSLATING: 1, |
|
64 STATE_TRANSLATED: 2, |
|
65 STATE_ERROR: 3, |
|
66 |
|
67 get doc() this.browser.contentDocument, |
|
68 |
|
69 translate: function(aFrom, aTo) { |
|
70 this.state = this.STATE_TRANSLATING; |
|
71 this.translatedFrom = aFrom; |
|
72 this.translatedTo = aTo; |
|
73 }, |
|
74 |
|
75 showURLBarIcon: function(aTranslated) { |
|
76 let chromeWin = this.browser.ownerGlobal; |
|
77 let PopupNotifications = chromeWin.PopupNotifications; |
|
78 let removeId = aTranslated ? "translate" : "translated"; |
|
79 let notification = |
|
80 PopupNotifications.getNotification(removeId, this.browser); |
|
81 if (notification) |
|
82 PopupNotifications.remove(notification); |
|
83 |
|
84 let callback = aTopic => { |
|
85 if (aTopic != "showing") |
|
86 return false; |
|
87 if (!this.notificationBox.getNotificationWithValue("translation")) |
|
88 this.showTranslationInfoBar(); |
|
89 return true; |
|
90 }; |
|
91 |
|
92 let addId = aTranslated ? "translated" : "translate"; |
|
93 PopupNotifications.show(this.browser, addId, null, |
|
94 addId + "-notification-icon", null, null, |
|
95 {dismissed: true, eventCallback: callback}); |
|
96 }, |
|
97 |
|
98 _state: 0, |
|
99 get state() this._state, |
|
100 set state(val) { |
|
101 let notif = this.notificationBox.getNotificationWithValue("translation"); |
|
102 if (notif) |
|
103 notif.state = val; |
|
104 this._state = val; |
|
105 }, |
|
106 |
|
107 originalShown: true, |
|
108 showOriginalContent: function() { |
|
109 this.showURLBarIcon(); |
|
110 this.originalShown = true; |
|
111 }, |
|
112 |
|
113 showTranslatedContent: function() { |
|
114 this.showURLBarIcon(true); |
|
115 this.originalShown = false; |
|
116 }, |
|
117 |
|
118 get notificationBox() this.browser.ownerGlobal.gBrowser.getNotificationBox(), |
|
119 |
|
120 showTranslationInfoBar: function() { |
|
121 let notificationBox = this.notificationBox; |
|
122 let notif = notificationBox.appendNotification("", "translation", null, |
|
123 notificationBox.PRIORITY_INFO_HIGH); |
|
124 notif.init(this); |
|
125 return notif; |
|
126 }, |
|
127 |
|
128 showTranslationUI: function(aDetectedLanguage) { |
|
129 this.detectedLanguage = aDetectedLanguage; |
|
130 |
|
131 // Reset all values before showing a new translation infobar. |
|
132 this.state = 0; |
|
133 this.translatedFrom = ""; |
|
134 this.translatedTo = ""; |
|
135 this.originalShown = true; |
|
136 |
|
137 this.showURLBarIcon(); |
|
138 return this.showTranslationInfoBar(); |
|
139 } |
|
140 }; |