"use strict";
const EXPORTED_SYMBOLS = ["core", "resources"];
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
const resources = {
browser: {
styles: ["/native/fx/pagetranslator/pagetranslator.css"],
urlBarItems: {
button: 8000}}};
const core = {
api: null,
init: function PluginTranslator_init(api) {
this.api = api;
this.Prefs = api.Settings;
TranslatorService.init();
this.Prefs.observeChanges(TranslatorService,this.api.componentID);
}
,
finalize: function PluginTranslator_finalize() {
this.Prefs.ignoreChanges(this.api.componentID);
TranslatorService.finalize();
this.Prefs = null;
this.api = null;
}
,
initURLBarItem: function PluginTranslator_initURLBarItem(itemElement, itemClass) {
return new URLBarItem(itemElement, itemClass, this);
}
,
Settings: {
getMainTemplate: function PluginTranslator_getMainTemplate() {
return core.api.Package.getFileInputChannel("/native/fx/pagetranslator/settings.xml").contentStream;
}
},
get translator() {
return TranslatorService;
}
,
Prefs: null,
item: null};
function URLBarItem(itemElement, itemClass, module) {
itemElement.module = module;
itemElement.setAttribute("yb-native-widget-name","http://bar.yandex.ru/packages/yandexbar#pagetranslator");
this.element = itemElement;
}

;
URLBarItem.prototype = {
finalize: function TPluginTranslatorUBItem_finalize() {
this.element.finalize();
this.element = null;
}
};
const kXulChromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
const kWindowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
const TIMEOUT_LOAD = 5000;
const TRANSLATOR_KEY = "yandex.pagetranslator";
const TranslatorService = {
init: function TranslatorService_init() {
var require = {
};
Cu.import(core.api.Package.resolvePath("/native/fx/modules/lang-detector.jsm"),require);
this._langDetector = require.langDetector;
this._langDetector.init(core.api);
}
,
finalize: function TranslatorService_finalize() {
this._langDetector = null;
}
,
onSettingChange: function TranslatorService_onSettingChange(name, variant, instanceID) {
if (name !== "tlang")
return;
var enumerator = kWindowMediator.getEnumerator("navigator:browser");
while (enumerator.hasMoreElements()) {
let tabbrowser = enumerator.getNext().gBrowser;
let event = tabbrowser.contentDocument.createEvent("event");
event.initEvent("PageTranslator_onReset",true,false);
tabbrowser.dispatchEvent(event);
}

}
,
translate: function TranslatorService_translate(doc, lang) {
if (! doc || ! lang || ! doc.wrappedJSObject)
return;
var translator = doc.wrappedJSObject[TRANSLATOR_KEY];
if (translator)
{
let pair = this.getLangPair(lang,this.language);
translator.translate(pair);
}
 else
{
this._injectScripts(doc,lang);
}

}
,
revert: function TranslatorService_revert(doc) {
var translator = doc.wrappedJSObject[TRANSLATOR_KEY];
if (! translator)
return;
translator.undo();
}
,
_injectScripts: function TranslatorService__injectScripts(doc, lang) {
var version = "1.40";
var prefix = "http://translate.yandex.net/v" + version + "/js/";
const urls = [prefix + "lib.js", prefix + "tr-url.js"];
var scriptList = [];
var that = this;
function onload(url) {
var index = scriptList.indexOf(url);
if (~ index)
{
scriptList.splice(index,1);
}

if (! scriptList.length)
{
doc.defaultView.clearTimeout(timeoutLoad);
that._translateStart(doc,lang);
}

}

var timeoutLoad = doc.defaultView.setTimeout(function () {
var event = doc.createEvent("event");
event.initEvent("PageTranslator_onTranslateError",true,false);
doc.dispatchEvent(event);
}
,TIMEOUT_LOAD);
for (let i = urls.length;i--;) {
let url = urls[i];
let script = this._createScriptNode(doc,url);
script.addEventListener("load",function TranslatorService__injectScriptsOnLOad() {
onload(url);
}
,false);
scriptList.push(url);
doc.head.appendChild(script);
}

}
,
_createScriptNode: function TranslatorService__createScriptNode(doc, url) {
var script = doc.createElement("script");
script.setAttribute("type","text/javascript");
script.setAttribute("charset","utf-8");
script.setAttribute("src",url);
return script;
}
,
_translateStart: function TranslatorService__translateStart(doc, slang) {
if (! slang)
return;
var win = doc.defaultView;
var uidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
var uid = uidGenerator.generateUUID().toString();
var Doc = win.wrappedJSObject.Doc;
if (typeof Doc !== "function")
{
win.setTimeout(function () {
var event = doc.createEvent("event");
event.initEvent("PageTranslator_onTranslateError",true,false);
doc.dispatchEvent(event);
}
,0);
return;
}

var translator = new Doc(uid, win.location.href);
translator.trUrl = "http://translate.yandex.net/tr.json";
translator.setListener(new Listener(translator));
translator.__exposedProps__ = {
};
for(let key in translator) {
translator.__exposedProps__[key] = "r";
}

var pair = this.getLangPair(slang,this.language);
translator.translate(pair);
doc.wrappedJSObject[TRANSLATOR_KEY] = translator;
}
,
matchLang: function TranslatorService_matchLang(lang) {
return this.language === lang;
}
,
getLangPair: function TranslatorService_isAvailablePair(slang, tlang) {
return this.getAvailablePair(slang + "-" + tlang);
}
,
detectLang: function TranslatorService_detectLang(doc) {
return doc.body ? this.langDetector.detect(doc.body.innerHTML,false) : null;
}
,
getAvailablePair: function TranslatorService_getAvailablePair(pair) {
return this._availablePairs[pair] || null;
}
,
get localeLanguage() {
var localeString = kXulChromeReg.getSelectedLocale("global");
var lang = localeString.match(this._languagePattern)[0];
return lang;
}
,
get language() {
var lang = core.Prefs.getValue("tlang");
if (! lang)
{
lang = this.localeLanguage;
}

if (! ~ this._availableLocaleLangs.indexOf(lang))
{
return null;
}

if (lang in this._mapLocaleLangs)
{
return this._mapLocaleLangs[lang];
}

return lang;
}
,
get langDetector() {
return this._langDetector;
}
,
_availableLocaleLangs: ["ru", "en", "es", "it", "fr", "de", "uk", "be", "kk", "tr", "pl"],
_availablePairs: {
"ru-en": "ru-en",
"ru-uk": "ru-uk",
"ru-tr": "ru-tr",
"en-ru": "en-ru",
"uk-ru": "uk-ru",
"tr-ru": "tr-ru",
"de-ru": "de-ru",
"fr-ru": "fr-ru",
"it-ru": "it-ru",
"es-ru": "es-ru",
"pl-ru": "pl-ru",
"en-uk": "en-ru",
"tr-uk": "tr-ru",
"de-uk": "de-ru",
"fr-uk": "fr-ru",
"it-uk": "it-ru",
"es-uk": "es-ru",
"pl-uk": "pl-ru",
"en-tr": "en-tr",
"uk-tr": "uk-tr"},
_mapLocaleLangs: {
be: "ru",
kk: "ru",
de: "en",
fr: "en",
it: "en",
es: "en",
pl: "en"},
_languagePattern: /^([a-z]{2})/,
_langDetector: null};
function Listener(Doc) {
this.Doc = Doc;
this.STATE_TR_END = Doc.constructor.STATE_TR_END;
}

;
Listener.prototype = {
onProgressChanged: function Listener_onProgressChanged() {

}
,
onStateChanged: function Listener_onStateChanged() {
var state = this.Doc.getState();
var doc = this.Doc.doc;
if (state == this.STATE_TR_END)
{
let event = doc.createEvent("event");
event.initEvent("PageTranslator_onTranslateFinish",true,false);
doc.dispatchEvent(event);
}

}
,
onError: function Listener_onError(err) {
var doc = this.Doc.doc;
var event = doc.createEvent("event");
event.initEvent("PageTranslator_onTranslateError",true,false);
doc.dispatchEvent(event);
}
,
__exposedProps__: {
onProgressChanged: "r",
onStateChanged: "r",
onError: "r"}};
