"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#zakladki";
const core = {
init: function BookmarksWidget_init(api) {
this._api = api;
this._logger = api.logger;
this._loadModules();
}
,
finalize: function BookmarksWidget_finalize() {
delete this.__stringBundle;
delete this.utils;
delete this._api;
delete this._logger;
}
,
buildWidget: function BookmarksWidget_buildWidget(WIID, item) {
item.setAttribute("yb-native-widget-name",WIDGET_NAME);
item.setAttribute("yb-native-widget-wiid",WIID);
item.module = this;
}
,
destroyWidget: function BookmarksWidget_destroyWidget(WIID, item, context) {
try {
if (typeof item.bookmarksDestroy == "function")
item.bookmarksDestroy();
this.dlgman.closeBookmarksDialog();
}
 finally {
item.removeAttribute("yb-native-widget-name");
item.removeAttribute("yb-native-widget-wiid");
}

}
,
get API() {
return this._api;
}
,
__stringBundle: null,
get _stringBundle() {
return this.__stringBundle || (this.__stringBundle = this._api.Localization.createStringBundle("/native/fx/bookmarks.properties"));
}
,
getPref: function BookmarksWidget_getPref(strPrefName, defaultValue) {
var prefFullName = this._api.Settings.getComponentBranchPath() + strPrefName;
var prefsModule = this._api.Settings.PrefsModule;
return prefsModule.get(prefFullName,defaultValue);
}
,
setPref: function BookmarksWidget_setPref(strPrefName, strPrefValue) {
var prefFullName = this._api.Settings.getComponentBranchPath() + strPrefName;
var prefsModule = this._api.Settings.PrefsModule;
return prefsModule.set(prefFullName,strPrefValue);
}
,
gotoBookmarks: function BookmarksWidget_gotoBookmarks(event) {
this._navToBookmarksURL(this._getBookmarksURL(),this._STAT_CODES.GOTO_BOOKMARKS,event);
}
,
gotoLink: function BookmarksWidget_gotoLink(strURL, event, target) {
this._navToBookmarksURL(strURL,this._STAT_CODES.GOTO_BOOKMARKS,event,target);
}
,
openAllInTabs: function BookmarksWidget_openAllInTabs(menuFolder, event) {
var links = this._getLinksInFolder(menuFolder);
Array.forEach(links,(function (link) {
var URL = this.utils.tryCreateFixupURI(link);
if (URL)
{
let strURL = URL.spec;
this.API.Statistics.logShortAction(this._STAT_CODES.OPEN_BOOKMARK);
this.API.Controls.navigateBrowser({
url: strURL,
target: "new tab",
eventInfo: event});
}

}
).bind(this));
}
,
addBookmark: function BookmarksWidget_addBookmark(widget, folderId, event) {
var bookmark = this._createNewBookmark(folderId);
var arrTags = this._getAllTags();
var showYaRuWindow = this.getPref("yaruLiveWindowEnabled",true);
this.dlgman.openBookmarksDialog(this.yauth,bookmark,arrTags,showYaRuWindow,(function (event) {
if (event.type == "accept")
{
widget.mode = "edit";
this._setUpdated(widget,event.data.bookmarkData.parentId);
this.setPref("yaruLiveWindowEnabled",event.data.showYaRuWindow);
}

}
).bind(this));
}
,
editBookmarkOnClick: function BookmarksWidget_editBookmarkOnClick(uri, widget, event) {
var bookmark = this.getBookmark(uri);
var mode = this.getPref("action","2");
if (! bookmark)
{
if (mode == "2")
{
bookmark = this._createNewBookmark("0");
widget.loadingData = true;
let success = function (xmlResponse) {
widget.loadingData = false;
widget.mode = "edit";
this._setUpdated(widget,0);
}
;
let error = function (msg) {
widget.loadingData = false;
this._showError(msg);
}
;
this.bookmarks.addBookmark(bookmark,success.bind(this),error.bind(this,"Exception:service"));
}
 else
{
this.addBookmark(widget,0);
}

}
 else
{
this._editBookmark(widget,bookmark);
}

}
,
editBookmarkMenu: function BookmarksWidget_editBookmarkMenu(widget, id, event) {
var bookmark = this.yauth.user.selectBookmark(id);
if (bookmark)
{
this._editBookmark(widget,bookmark);
}

}
,
_editBookmark: function BookmarksWidget_editBookmark(widget, bookmark) {
var arrTags = this._getAllTags();
var oldParentId = bookmark.parentId;
this.dlgman.openBookmarksDialog(this.yauth.user.name,bookmark,arrTags,false,(function (event) {
if (event.type == "accept")
{
this._setUpdated(widget,oldParentId);
if (bookmark.parentId != oldParentId)
{
this._setUpdated(widget,event.data.bookmarkData.parentId);
}

}

}
).bind(this));
}
,
deleteBookmark: function BookmarksWidget_deleteBookmark(widget, id, event) {
var bookmark = this.yauth.user.selectBookmark(id);
if (bookmark)
{
let result = this.utils.showPromptExWithYesNo(null,this._stringBundle.get("ConfirmDelete" + bookmark.type + "Title"),this._stringBundle.get("ConfirmDelete" + bookmark.type + "Msg",[bookmark.name]));
if (result == 0)
{
widget.loadingData = true;
this.bookmarks.deleteBookmark(bookmark,(function () {
this._setUpdated(widget,bookmark.parentId);
widget.loadingData = false;
}
).bind(this));
}

}

}
,
getBookmark: function BookmarksWidget_getBookmark(URI) {
var bookmark = null;
var strURL = this._convertToBookmarkURL(URI);
if (strURL)
{
let user = this.yauth.user;
bookmark = user.selectBookmarkByURL(strURL);
return bookmark;
}

return bookmark;
}
,
loadBookmarks: function BookmarksWidget__loadBookmarks(widget, onSuccess, onError, forceUpdate) {
this.bookmarks.loadBookmarks(forceUpdate,(function () {
this._setUpdated(widget,0);
if (onSuccess)
onSuccess();
}
).bind(this),onError);
}
,
copyBookmarkToPersonalPanel: function BookmarksWidget_copyBookmarkToPersonalPanel(widget, id, event) {
var bookmark = this.yauth.user.selectBookmark(id);
if (bookmark)
{
if (bookmark.type != "folder")
{
this._createLink(this._bmsvc.toolbarFolder,bookmark);
}
 else
{
this._createFolder(this._bmsvc.toolbarFolder,bookmark);
}

}

}
,
_createFolder: function BookmarksWidget__createFolder(folderId, bookmark) {
var newFolderId = this._bmsvc.createFolder(folderId,bookmark.name,this._bmsvc.DEFAULT_INDEX);
var children = this.bookmarks.getBookmarksTree(bookmark.id);
children.forEach((function (child) {
if (child.type != "folder")
{
this._createLink(newFolderId,child);
}
 else
{
this._createFolder(newFolderId,child);
}

}
).bind(this));
return newFolderId;
}
,
_createLink: function BookmarksWidget__createLink(folderId, bookmark) {
var uri = this.utils.newURI(bookmark.url);
if (! uri)
return null;
return this._bmsvc.insertBookmark(folderId,uri,this._bmsvc.DEFAULT_INDEX,bookmark.name);
}
,
get _bmsvc() {
delete this._bmsvc;
return this._bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
}
,
onDragStart: function BookmarksWidget_onDragStart(event, xferData, dragAction) {
var target = event.target;
if (! /bookmark\-item/.test(target.getAttribute("class")))
return false;
switch (target.localName) {
case "menuitem":
let mozUrlData = target.getAttribute("statustext") + "\n" + target.getAttribute("label");
event.dataTransfer.setData("text/x-moz-url",mozUrlData);
event.dataTransfer.effectAllowed = "copyLink";
break;
default:
return false;
}

return true;
}
,
onRootHover: function BookmarksWidget_onRootHover(menu) {
var user = this.yauth.user;
if (menu.getAttribute("updated"))
{
let arrBookmarks = this.bookmarks.getBookmarksTree(0);
arrBookmarks.sort(this._compareBookmarks.bind(this));
let elemBookmarks = menu.childNodes;
let toDelete = [], len = elemBookmarks.length;
for (let i = len - 1;i > 5;--i) {
toDelete.push(elemBookmarks[i]);
}

toDelete.forEach(function (child) {
menu.removeChild(child);
}
);
if (arrBookmarks.length)
{
let separator = this._createSeparator();
menu.appendChild(separator);
this._buildMenu(menu,arrBookmarks);
}

menu.removeAttribute("updated");
}

}
,
onFolderHover: function BookmarksWidget_onFolderHover(menu, folderId) {
var user = this.yauth.user;
if (menu.getAttribute("updated"))
{
let arrBookmarks = this.bookmarks.getBookmarksTree(folderId);
arrBookmarks.sort(this._compareBookmarks.bind(this));
while (menu.firstChild) menu.removeChild(menu.firstChild);
let addToFolderOnTop = this.getPref("showAddToFolderOnTop","1");
if (addToFolderOnTop == "1")
{
let addItem = this._createAddMenuItem(folderId);
menu.appendChild(addItem);
if (arrBookmarks.length)
{
let separator = this._createSeparator();
menu.appendChild(separator);
}

}

if (arrBookmarks.length)
{
this._buildMenu(menu,arrBookmarks);
let links = arrBookmarks.filter(function (item) {
return item.type != "folder";
}
);
if (links.length)
{
let openAllItem = this._createOpenAllMenuItem(folderId);
let separator = this._createSeparator();
menu.appendChild(separator);
menu.appendChild(openAllItem);
}

}

if (addToFolderOnTop == "0")
{
let addItem = this._createAddMenuItem(folderId);
if (arrBookmarks.length)
{
let separator = this._createSeparator();
menu.appendChild(separator);
}

menu.appendChild(addItem);
}

menu.removeAttribute("updated");
}

}
,
_compareBookmarks: function BookmarksWidget__compareBookmarks(a, b) {
if (a.type == "folder" && b.type != "folder")
return - 1;
if (b.type == "folder" && a.type != "folder")
return 1;
return a.name.localeCompare(b.name);
}
,
_buildMenu: function BookmarksWidget__buildMenu(menu, arrBookmarks) {
arrBookmarks.forEach((function (child) {
if (child.type == "folder")
{
let subMenu = this._createMenu(child);
menu.appendChild(subMenu);
}
 else
{
let menuItem = this._createMenuItem(child);
menu.appendChild(menuItem);
}

}
).bind(this));
}
,
_createMenu: function BookmarksWidget__createMenu(data) {
var document = this.utils.getCurrentWindow().document;
var menu = document.createElement("menu");
menu.setAttribute("label",data.name);
menu.setAttribute("descr",data.desc ? data.desc : "");
menu.setAttribute("container",true);
menu.setAttribute("class","menu-iconic bookmark-item");
menu.setAttribute("folderid",data.id);
var menupopup = document.createElement("menupopup");
menupopup.setAttribute("updated",true);
menupopup.setAttribute("contextmenu","bookmarkItemContextMenu");
menu.appendChild(menupopup);
return menu;
}
,
_createMenuItem: function BookmarksWidget__createMenuItem(data) {
var document = this.utils.getCurrentWindow().document;
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label",data.name);
menuitem.setAttribute("class","menuitem-iconic menuitem-with-favicon bookmark-item");
menuitem.setAttribute("statustext",data.url);
menuitem.setAttribute("linkid",data.id);
menuitem.setAttribute("descr",data.desc ? data.desc : "");
menuitem.setAttribute("oncommand","getBindingParent(this).module.gotoLink('" + data.url + "', event);");
menuitem.setAttribute("onclick","if (event.button === 1) getBindingParent(this).module.gotoLink('" + data.url + "', event);");
menuitem.setAttribute("onload","getBindingParent(this).setFaviconForURL('" + data.url + "', this)");
return menuitem;
}
,
_createSeparator: function BookmarksWidget__createSeparator() {
var document = this.utils.getCurrentWindow().document;
var separator = document.createElement("menuseparator");
return separator;
}
,
_createAddMenuItem: function BookmarksWidget__createAddMenuItem(folderId) {
var document = this.utils.getCurrentWindow().document;
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label",this._stringBundle.get("addBookmarkToFolder"));
menuitem.setAttribute("accesskey",this._stringBundle.get("addBookmarkToFolderKey"));
menuitem.setAttribute("class","menuitem-iconic menuitem-with-favicon bookmark-item add-page-to-folder");
menuitem.setAttribute("oncommand","getBindingParent(this).module.addBookmark(getBindingParent(this), '" + folderId + "', event)");
return menuitem;
}
,
_createOpenAllMenuItem: function BookmarksWidget__createOpenAllMenuItem(folderId) {
var document = this.utils.getCurrentWindow().document;
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label",this._stringBundle.get("openAll"));
menuitem.setAttribute("accesskey",this._stringBundle.get("openAllKey"));
menuitem.setAttribute("oncommand","getBindingParent(this).module.openAllInTabs(event.originalTarget.parentNode)");
return menuitem;
}
,
_setUpdated: function BookmarksWidget__setUpdated(widget, folderid) {
if (folderid == "0")
{
widget._menu.setAttribute("updated",true);
}

var menuFolder = widget._menu.querySelector("[folderid='" + folderid + "']");
if (menuFolder)
{
menuFolder.menupopup.setAttribute("updated",true);
}

}
,
_showError: function BookmarksWidget__showError(strError, isEdit) {
if (! strError.indexOf("Exception:"))
{
strError = strError.split(":")[1].trim();
let errorType = "Error_" + strError + "_";
let errorTypeTitle = "Error_" + strError + "_Title";
try {
this._stringBundle.get(errorTypeTitle);
}
catch (ex) {
errorType = "Error_0_";
}

let t1 = [this._stringBundle.get("Action_" + (isEdit ? "edit" : "add") + "_InTitle")];
let t2 = [this._stringBundle.get("Action_" + (isEdit ? "edit" : "add") + "_InMessage")];
if (strError === "input")
{
t2.unshift(t1);
}

this.utils.showAlert(null,this._stringBundle.get(errorType + "Title",t1),this._stringBundle.get(errorType + "Message",t2));
return;
}

this.utils.showAlert(null,"Error",strError);
}
,
_createNewBookmark: function BookmarksWidget__createNewBookmark(aFolderId) {
var window = this.utils.getCurrentWindow();
var contentDoc = window.content.document;
var strURL = contentDoc.location.href;
var strTitle = (contentDoc.title || strURL).trim();
var bookmark = {
id: "",
url: strURL,
type: "link",
name: strTitle,
desc: this.utils.getDocumentDescription(contentDoc),
tags: "",
parentId: aFolderId};
return bookmark;
}
,
_getHostPort: function BookmarksWidget__getHostPort(URI) {
var strHostPort = "";
if ("scheme" in URI && /^(ftp|https?)$/.test(URI.scheme))
{
strHostPort = [URI.scheme, "://", URI.scheme == "file" ? "/" : "", URI.hostPort].join("");
}

return strHostPort;
}
,
_convertToBookmarkURL: function BookmarksWidget__convertToBookmarkURL(URI) {
var strURL = "";
if ("scheme" in URI && /ftp|https?/.test(URI.scheme))
{
strURL = [this._getHostPort(URI), URI.path].join("").replace(/(\/|#.+)+$/,"");
}

return strURL;
}
,
_getAllTags: function BookmarksWidget__getAllTags() {
var tagsHash = Object.create(null);
var strTags = this.yauth.user.selectBookmarksTags() || "";
strTags.split(",").map(function (strTag) {
return strTag.replace(/[^\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]/g,"").trim().replace(/\s+/g," ");
}
).forEach(function (tag) {
if (! (tag in tagsHash))
tagsHash[tag] = {
value: tag,
count: 0};
tagsHash[tag].count++;
}
);
var arrTags = [];
for each(let tag in tagsHash) arrTags.push(tag);
function sort(strA, strB) {
for (var i = 0, length = strA.length;i < length;i++) {
if (! strB[i])
{
return 1;
}

let letter1 = strA[i].toLowerCase();
let letter2 = strB[i].toLowerCase();
if (letter1 != letter2)
{
return letter1 > letter2 ? 1 : - 1;
}
 else
if (strA[i] != strB[i])
{
return strA.charCodeAt(i) - strB.charCodeAt(i);
}

}

return 0;
}

arrTags.sort(function (a, b) {
return a.count > b.count ? - 1 : a.count < b.count ? 1 : sort(a.value,b.value);
}
);
return arrTags.map(function (tag) tag.value);
}
,
_STAT_CODES: {
GOTO_BOOKMARKS: 1900,
OPEN_BOOKMARK: 1910},
_MODULES: {
utils: "utils.jsm",
yauth: "yauth.jsm",
dlgman: "dlgman.jsm",
bookmarks: "bookmarks.jsm",
User: "user.jsm"},
_loadModules: function BookmarksWidget__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);
}

}
,
_getBookmarksURL: function BookmarksWidget__getBookmarksURL() {
return "zakladki.yandex.ru";
}
,
_navToBookmarksURL: function BookmarksWidget__navToBookmarksURL(strBookmarksURL, statAction, origEvent, target) {
if (statAction)
this.API.Statistics.logShortAction(statAction);
this.API.Controls.navigateBrowser({
url: strBookmarksURL,
target: target,
eventInfo: origEvent});
}
,
_getLinksInFolder: function BookmarksWidget__getLinksInFolder(menuFolder) {
var itemsLinks = menuFolder.querySelectorAll("[linkid]");
var urlArray = [];
for (let i = 0, len = itemsLinks.length;i < len;++i) {
let URL = itemsLinks[i].getAttribute("statustext");
urlArray.push(URL);
}

return urlArray;
}
};
