"use strict";
const EXPORTED_SYMBOLS = ["core", "resources"];
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
const resources = {
browser: {
styles: ["/native/fx/bindings.css"]}};
const WIDGET_NAME = "http://bar.yandex.ru/packages/yandexbar#opinions";
const core = {
init: function OpinionsWidget_init(api) {
this._api = api;
this._logger = api.logger;
this._loadModules();
var barNavig = this._api.Statistics.BarNavig;
this.barNavigDataProvider = barNavigDataProvider;
barNavig.addDataProvider(barNavigDataProvider);
barNavigDataProvider._dataContainer = api.SysUtils.createDataContainer({
expirationTime: 2 * 60 * 60 * 1000,
convertKeyFunctions: {
convert: function convert(aKey) {
return ":" + (aKey && aKey.split(/\?|#/)[0] || "");
}
,
unconvert: function unconvert(aKey) {
return aKey.substr(1);
}
}});
}
,
finalize: function OpinionsWidget_finalize() {
this._setOpinionsListRequestTimer(null);
this._api.Statistics.BarNavig.removeDataProvider(barNavigDataProvider);
barNavigDataProvider._dataContainer.finalize();
barNavigDataProvider._dataContainer = null;
delete this.barNavigDataProvider;
delete this.utils;
delete this._api;
delete this._logger;
}
,
buildWidget: function OpinionsWidget_buildWidget(WIID, item) {
item.setAttribute("yb-native-widget-name",WIDGET_NAME);
item.setAttribute("yb-native-widget-wiid",WIID);
item.module = this;
}
,
destroyWidget: function OpinionsWidget_destroyWidget(WIID, item, context) {
try {
if (typeof item.opinionsDestroy == "function")
item.opinionsDestroy();
}
 finally {
item.removeAttribute("yb-native-widget-name");
item.removeAttribute("yb-native-widget-wiid");
}

}
,
get API() {
return this._api;
}
,
gotoComments: function OpinionsWidget_gotoComments(event, widget) {
var wListener = this._api.Browser.getWindowListener(event.view);
var strURL = this._getURL(wListener.currentURI);
strURL = String.concat(this._OPINIONS_URL,"text=","!link='",encodeURIComponent(strURL),"'");
this._navToPage(strURL,this._STAT_CODES.GOTO_COMMENTS,event);
}
,
gotoAddComment: function OpinionsWidget_gotoAddComment(event, widget) {
if (! this.yauth.authorized)
{
let dialogParams = {
name: "opinions",
title: widget.title};
this.yauth.openAuthDialog(event,dialogParams,false,(function () {
this._addCommentToPage(event);
}
).bind(this));
}
 else
{
this._addCommentToPage(event);
}

}
,
_getDialogID: function OpinionsWidget__getDialogID(window) {
var util = window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
return "OpinionsDialog-" + util.outerWindowID;
}
,
_getWindowByWindowId: function OpinionsWidget__getWindowByWindowId(aId) {
var someWindow = this.utils.getCurrentWindow();
if (someWindow)
{
let windowUtils = someWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
return windowUtils.getOuterWindowWithId(aId.replace(/^OpinionsDialog\-/,""));
}

return null;
}
,
_getCurWinTabs: function OpinionsWidget__getCurWinTabs(window) {
return [].concat(window.gBrowser.browsers);
}
,
_getURL: function OpinionsWidget__getURL(URI) {
if (this.utils.isValidURL(URI.spec))
{
return URI.spec.split(/\?|#/)[0];
}

return "";
}
,
getPackagePref: function OpinionsWidget_getPackagePref(strPrefName, defaultValue) {
var prefFullName = this._api.Settings.getPackageBranchPath() + strPrefName;
var prefsModule = this._api.Settings.PrefsModule;
return prefsModule.get(prefFullName,defaultValue);
}
,
getPref: function OpinionsWidget_getPref(strPrefName, defaultValue) {
var prefFullName = this._api.Settings.getComponentBranchPath() + strPrefName;
var prefsModule = this._api.Settings.PrefsModule;
return prefsModule.get(prefFullName,defaultValue);
}
,
setPref: function OpinionsWidget_setPref(strPrefName, strPrefValue) {
var prefFullName = this._api.Settings.getComponentBranchPath() + strPrefName;
var prefsModule = this._api.Settings.PrefsModule;
return prefsModule.set(prefFullName,strPrefValue);
}
,
_STAT_CODES: {
GOTO_COMMENTS: 3300,
GOTO_ADD_COMMENT: 3310},
_MODULES: {
utils: "utils.jsm",
yauth: "yauth.jsm",
dlgman: "dlgman.jsm"},
get _OPINIONS_URL() {
var blogsHost = this._api.Localization.createStringBundle("/urls/common.properties").get("opinionsBlogsHost");
delete this._OPINIONS_URL;
return this._OPINIONS_URL = "http://" + blogsHost + "/search.xml?";
}
,
_addCommentToPage: function OpinionsWidget__addCommentToPage(event) {
const srcChromeWnd = event.target.ownerDocument.defaultView;
const sharedDoc = srcChromeWnd.content.document;
var username = this.yauth.user.name;
var dataToSend = {
body: this.utils.getDocumentDescription(sharedDoc),
title: sharedDoc.title,
URL: srcChromeWnd.content.location.href,
YARU_retpath: "http://" + username + ".ya.ru/posts_add_link.xml"};
var postParams = [];
postParams.push("URL=" + encodeURIComponent(dataToSend.URL.substr(0,1000000)));
postParams.push("title=" + encodeURIComponent(dataToSend.title.substr(0,1000000)));
postParams.push("body=" + encodeURIComponent(dataToSend.body.substr(0,1000000)));
postParams.push("YARU_retpath=" + encodeURIComponent(dataToSend.YARU_retpath.substr(0,1000000)));
postParams = postParams.join("&");
var postStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
postStream.setData(postParams,postParams.length);
var postData = Cc["@mozilla.org/network/mime-input-stream;1"].createInstance(Ci.nsIMIMEInputStream);
postData.addHeader("Content-Type","application/x-www-form-urlencoded");
postData.addContentLength = true;
postData.setData(postStream);
this._navToPage("http://my.ya.ru/request_to_session.xml",this._STAT_CODES.GOTO_ADD_COMMENT,event,postData);
barNavigDataProvider.removeDataForURL(dataToSend.URL);
}
,
_loadModules: function OpinionsWidget__loadModules() {
var shAPI = this._api.shareableAPI;
for each(let [moduleName, moduleFileName] in Iterator(this._MODULES)) {
Cu.import(this._api.Package.resolvePath("/native/fx/modules/" + moduleFileName),this);
let module = this[moduleName];
if (typeof module.init == "function")
module.init(shAPI);
}

}
,
_navToPage: function OpinionsWidget__navToPage(strURL, statAction, origEvent, postData) {
if (statAction)
this.API.Statistics.logShortAction(statAction);
this.API.Controls.navigateBrowser({
url: strURL,
target: "new tab",
postData: postData,
eventInfo: origEvent});
}
,
_getTabDataObject: function OpinionsWidget__getTabDataObject(aWindow, aTab) {
var winListener = this._api.Browser.getWindowListener(aWindow);
return winListener.getTabData(aTab,WIDGET_NAME);
}
,
_getTabData: function OpinionsWidget__getTabData(aWindow, aTab, aKey) {
return this._getTabDataObject(aWindow,aTab)[aKey] || undefined;
}
,
_setTabData: function OpinionsWidget__setTabData(aWindow, aTab, aKey, aValue) {
var tabData = this._getTabDataObject(aWindow,aTab);
if (tabData)
tabData[aKey] = aValue;
}
,
_removeTabData: function OpinionsWidget__removeTabData(aWindow, aTab, aKey) {
var tabData = this._getTabDataObject(aWindow,aTab);
if (tabData)
delete tabData[aKey];
}
,
sendBarNavigRequest: function OpinionsWidget_sendBarNavigRequest(aBrowser, aManual) {
var url = aBrowser.currentURI.spec;
if (aManual)
barNavigDataProvider._removeData(url);
var data = barNavigDataProvider._getData(url);
if (aManual && data.buttonState !== barNavigDataProvider.DATA_STATE_REQUEST || data.buttonState === barNavigDataProvider.DATA_STATE_UNKNOWN && aBrowser.contentDocument.readyState === "complete")
{
data.buttonState = barNavigDataProvider.DATA_STATE_REQUEST;
this.API.Statistics.BarNavig.sendRequest({
url: url,
urlinfo: 2},barNavigDataProvider);
}

return data;
}
,
OPINIONS_LIST_URL: "http://blogs.yandex.ru/bar.xml",
_opinionsListRequestTimer: null,
_setOpinionsListRequestTimer: function OpinionsWidget__setOpinionsListRequestTimer(aCallbackFunc) {
if (this._opinionsListRequestTimer)
{
this._opinionsListRequestTimer.cancel();
this._opinionsListRequestTimer = null;
}

if (aCallbackFunc)
{
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback({
notify: function () aCallbackFunc()},3 * 1000,timer.TYPE_ONE_SHOT);
this._opinionsListRequestTimer = timer;
}

}
,
requestOpinionsListTimed: function OpinionsWidget_requestOpinionsListTimed(aBrowser) {
this._setOpinionsListRequestTimer(null);
var url = aBrowser.currentURI.spec;
var data = barNavigDataProvider._getData(url);
if (! (data.count > 0) && data.buttonState !== barNavigDataProvider.DATA_STATE_REQUEST)
{
data.windowState = data.buttonState == barNavigDataProvider.DATA_STATE_ERROR ? barNavigDataProvider.DATA_STATE_ERROR : barNavigDataProvider.DATA_STATE_RESPONSE;
this._requestOpinionsListCallback(url,null);
return;
}

this._setOpinionsListRequestTimer(this.requestOpinionsList.bind(this,aBrowser));
}
,
requestOpinionsList: function OpinionsWidget_requestOpinionsList(aBrowser) {
var url = aBrowser.currentURI.spec;
var data = barNavigDataProvider._getData(url);
if (! (data.count > 0) || data.windowState !== barNavigDataProvider.DATA_STATE_UNKNOWN && data.windowState !== barNavigDataProvider.DATA_STATE_TIMED_REQUEST)
{
this._requestOpinionsListCallback(url,null);
return;
}

data._content = null;
data.windowState = barNavigDataProvider.DATA_STATE_REQUEST;
var strURL = this.OPINIONS_LIST_URL + "?count=" + data.count + "&text=" + encodeURIComponent("!link=\"" + url + "\"");
this.utils.sendRequest(strURL,{
bypassCache: true,
callbackFunc: this._requestOpinionsListCallback.bind(this,url)});
}
,
_requestOpinionsListCallback: function OpinionsWidget_requestOpinionsListCallback(aURL, aRequest) {
var data = barNavigDataProvider._getData(aURL);
if (aRequest !== null)
data.windowState = barNavigDataProvider.DATA_STATE_ERROR;
this._parseRequestOpinionsList(aRequest,data,aURL);
var wndEnum = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator).getEnumerator("navigator:browser");
while (wndEnum.hasMoreElements()) this.updateToolbaritemData(wndEnum.getNext().gBrowser.mCurrentBrowser,aURL,data);
}
,
_parseRequestOpinionsList: function OpinionsWidget__parseRequestOpinionsList(aRequest, aData, aURL) {
if (this.utils.isReqError(aRequest))
return;
try {
let responseXML = aRequest.target.responseXML;
if (! (responseXML instanceof Ci.nsIDOMDocument))
return;
let resultTransformationFrag = this._api.XMLUtils.transformXMLToFragment(responseXML,this._xslOpinionsListDoc,this._api.XMLUtils.getDOMParser(null,null,true).parseFromString("<emptyDoc/>","text/xml"),{
searchURL: this._OPINIONS_URL + "text=" + encodeURIComponent("!link=\"" + aURL + "\"")});
if (! resultTransformationFrag || resultTransformationFrag.firstChild.localName === "parsererror")
return;
aData._content = resultTransformationFrag;
aData.windowState = barNavigDataProvider.DATA_STATE_RESPONSE;
}
catch (e) {
this._logger.debug("Request Opinions list callback error: " + e);
}

}
,
get _xslOpinionsListDoc() {
var xslDoc = null;
try {
let filePath = "/native/fx/opinions/opinions-data.xsl";
let channel = this.API.Package.getFileInputChannel(filePath);
xslDoc = this.API.XMLUtils.xmlDocFromStream(channel.contentStream,this.utils.newURI(this.API.Package.resolvePath(filePath),null,null),null,true);
}
catch (ex) {
this._logger.error(ex);
}

delete this._xslOpinionsListDoc;
this.__defineGetter__("_xslOpinionsListDoc",function _xslOpinionsListDoc() xslDoc);
return this._xslOpinionsListDoc;
}
,
updateToolbaritemData: function OpinionsWidget_updateToolbaritemData(aBrowser, aURL, aData) {
var tabBrowsers = [];
if (aBrowser)
{
tabBrowsers.push(aBrowser);
}
 else
{
let wndEnum = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator).getEnumerator("navigator:browser");
while (wndEnum.hasMoreElements()) tabBrowsers.push(wndEnum.getNext().gBrowser.mCurrentBrowser);
}

tabBrowsers.forEach(function (tabBrowser) {
this._updateToolbaritemDataInBrowser(tabBrowser,aURL,aData);
}
,this);
}
,
_updateToolbaritemDataInBrowser: function OpinionsWidget__updateToolbaritemDataInBrowser(aBrowser, aURL, aData) {
var tabBrowser = "getTabBrowser" in aBrowser && aBrowser.getTabBrowser();
if (! (tabBrowser && tabBrowser.mCurrentBrowser === aBrowser))
return;
var currentURL = aBrowser.currentURI.spec;
if (currentURL === "about:blank")
currentURL = "";
if (currentURL.split("#")[0] !== aURL.split("#")[0])
return;
var toolbaritem = aBrowser.ownerDocument.querySelector("[yb-native-widget-name='" + WIDGET_NAME + "']");
if (! toolbaritem)
return;
if (! ("setOpinionsCount" in toolbaritem))
return;
toolbaritem.setOpinionsCount(aData);
}
,
getDataForURL: function OpinionsWidget_getDataForURL(aURL) {
return barNavigDataProvider._getData(aURL);
}
};
const barNavigDataProvider = {
onWindowLocationChange: function OpinionsWidget_BNDP_onWindowLocationChange(aParams) {
if (! aParams.windowListenerData.isCurrentTab)
return false;
var data = this._getData(aParams.url);
if (data.buttonState === this.DATA_STATE_UNKNOWN && aParams.windowListenerData.readyState === "complete")
{
data.buttonState = this.DATA_STATE_REQUEST;
aParams.barNavigParams.urlinfo |= 2;
core.updateToolbaritemData(aParams.browser,aParams.url,data);
return this;
}

core.updateToolbaritemData(aParams.browser,aParams.url,data);
return false;
}
,
onPageLoad: function OpinionsWidget_BNDP_onPageLoad(aParams) {
if (! aParams.windowListenerData.isCurrentTab)
return false;
var data = this._getData(aParams.url);
if (data.isGoodURL)
{
data.buttonState = this.DATA_STATE_REQUEST;
aParams.barNavigParams.urlinfo |= 2;
core.updateToolbaritemData(aParams.browser,aParams.url,data);
return this;
}

core.updateToolbaritemData(aParams.browser,aParams.url,data);
return false;
}
,
onBarNavigResponse: function OpinionsWidget_BNDP_onBarNavigResponse(aParams) {
var url = aParams.url || aParams.barNavigParams.url;
var data = this._getData(url);
if (aParams.responseXML)
{
let page = aParams.responseXML.querySelector("urlinfo > page");
data.count = page && parseInt(page.getAttribute("count"),10) || 0;
data.buttonState = this.DATA_STATE_RESPONSE;
data.windowState = this.DATA_STATE_UNKNOWN;
}
 else
{
data.buttonState = this.DATA_STATE_ERROR;
data.windowState = this.DATA_STATE_ERROR;
}

core.updateToolbaritemData(aParams.browser,url,data);
}
,
removeDataForURL: function OpinionsWidget_BNDP_removeDataForURL(aURL) {
this._removeData(aURL);
}
,
DATA_STATE_UNKNOWN: 1 << 0,
DATA_STATE_TIMED_REQUEST: 1 << 1,
DATA_STATE_REQUEST: 1 << 2,
DATA_STATE_ERROR: 1 << 3,
DATA_STATE_RESPONSE: 1 << 4,
_dataContainer: null,
_makeURL: function OpinionsWidget_BNDP__makeURL(aURL) {
var isGoodURL = aURL && /^https?:\/\//.test(aURL);
var url = isGoodURL ? aURL.split(/\?|#/)[0] : "";
return url;
}
,
_removeData: function OpinionsWidget_BNDP__removeData(aURL) {
this._dataContainer.remove(this._makeURL(aURL));
}
,
_getData: function OpinionsWidget_BNDP__getData(aURL) {
var url = this._makeURL(aURL);
var isGoodURL = ! ! url;
var data = this._dataContainer.get(url);
if (data)
return data;
var state = isGoodURL ? this.DATA_STATE_UNKNOWN : this.DATA_STATE_RESPONSE;
return this._dataContainer.set(aURL,{
STATES: {
UNKNOWN: this.DATA_STATE_UNKNOWN,
TIMED_REQUEST: this.DATA_STATE_TIMED_REQUEST,
REQUEST: this.DATA_STATE_REQUEST,
ERROR: this.DATA_STATE_ERROR,
RESPONSE: this.DATA_STATE_RESPONSE},
isGoodURL: isGoodURL,
url: url,
windowState: state,
buttonState: state,
count: 0,
get content() {
return this._content ? this._content.cloneNode(true) : null;
}
,
_content: null}).value;
}
};
