<?xml version='1.0'?>
<!DOCTYPE bindings [
<!ENTITY % settings SYSTEM "/native/fx/bookmarks.dtd">
%settings;
<!ENTITY % auth SYSTEM "/native/fx/login.dtd">
%auth;
]>
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <binding extends="//toolkit/native/bindings/widget.xml#widget" id="widget">
        <resources>
            <stylesheet src="bookmarks.css"/>
        </resources>

        <content>
            <toolbarbutton anonid="bookmarks-button" class="chromeclass-toolbar-additional toolbarbutton-1 label2 yauth-button" label="&bookmarks.name;" noauth-tooltip-text="&bookmarks.noauthtooltiptext;" oncommand="if (event.target == this) _onBtnCommand(event);" tooltip="bookmarks-tooltip" tooltip-text="&bookmarks.tooltiptext;" type="menu-button" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" yb-icon-overlay="true" yb-second-tooltip-text="&noauth.label;">
                <menupopup anonid="bookmarks-menupopup" contextmenu="bookmarkItemContextMenu" ondraggesture="nsDragAndDrop.startDrag(event, module);" tooltip="mainPopupSet" updated="true">
                    <menuitem label="&bookmarks.reload.label;" oncommand="refreshBookmarks();"/>
                    <menuseparator/>
                    <menuitem anonid="menuitem-add" label="&bookmarks.add.page.label;" oncommand="_onAddBookmarkCmd(event);"/>
                    <menuitem anonid="menuitem-edit" label="&bookmarks.edit.bookmark.label;" oncommand="editBookmarkOnClick(event);"/>
                    <menuseparator/>
                    <menuitem anonid="bookmarks-menuitem-goto" label="&bookmarks.open.label;" oncommand="gotoBookmarks(event);"/>
                </menupopup>
            </toolbarbutton>

            <tooltip anonid="test" noautohide="true" orient="vertical" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
                <grid flex="1">
                    <columns><column/><column flex="1"/></columns>
                    <rows>
                        <row align="center">
                            <hbox pack="end"><label value="&bookmarks.tooltip.url;: "/></hbox>
                            <label crop="right" inherits="value=value"/>
                        </row>
                        <row align="center">
                            <hbox pack="end"><label value="&bookmarks.tooltip.name;: "/></hbox>
                            <label crop="right" inherits="value=value"/>
                        </row>
                        <row align="center">
                            <hbox pack="end"><label value="&bookmarks.tooltip.descr;: "/></hbox>
                            <label crop="right" inherits="value=value"/>
                        </row>
                     </rows>
                </grid>
            </tooltip>

            <popupset id="mainPopupSet" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
                <menupopup id="bookmarkItemContextMenu" onpopupshowing="return onBookmarksPopupShow(this);">
                    <menuitem accesskey="&bookmarks.openBookmark.accesskey;" label="&bookmarks.openBookmark.label;" oncommand="openBookmark(event, 'current tab');"/>
                    <menuitem accesskey="&bookmarks.openBookmark.inNewWindow.accesskey;" label="&bookmarks.openBookmark.inNewWindow.label;" oncommand="openBookmark(event, 'new window');"/>
                    <menuitem accesskey="&bookmarks.openBookmark.inNewTab.accesskey;" label="&bookmarks.openBookmark.inNewTab.label;" oncommand="openBookmark(event, 'new tab');"/>
                    <menuitem accesskey="&bookmarks.openAllInTabs.accesskey;" label="&bookmarks.openAllInTabs.label;" oncommand="openAllInTabs();"/>
                    <menuseparator/>
                    <menuitem accesskey="&bookmarks.newBookmark.accesskey;" label="&bookmarks.newBookmark.label;" oncommand="_onAddToFolderCmd(event);"/>
                    <menuseparator/>
                    <menuitem accesskey="&bookmarks.copy.accesskey;" label="&bookmarks.copy.label;" oncommand="copyBookmarkToPersonalPanel(event);"/>
                    <menuseparator/>
                    <menuitem accesskey="&bookmarks.delete.accesskey;" label="&bookmarks.delete.label;" oncommand="deleteBookmark(event);"/>
                    <menuseparator/>
                    <menuitem accesskey="&bookmarks.edit.accesskey;" label="&bookmarks.edit.bookmark.label;" oncommand="editBookmark(event);"/>
                    <menuitem accesskey="&bookmarks.edit.accesskey;" label="&bookmarks.edit.folder.label;" oncommand="editBookmark(event);"/>
                </menupopup>
            </popupset>
        </content>

        <implementation>
            <field name="ID">this.getAttribute("id")</field>
            <field name="faviconServiceURLString"><![CDATA["http://favicon.yandex.net/favicon/";]]></field>
            <field name="yauth">(this.module.yauth)</field>
            <field name="API">(this.module.API)</field>
            <field name="utils">(this.module.utils)</field>
            <field name="title">"&bookmarks.name;"</field>

            <field name="_button" readonly="true"><![CDATA[document.getAnonymousElementByAttribute(this,"anonid","bookmarks-button");]]></field>

            <field name="_tooltip" readonly="true"><![CDATA[document.getAnonymousElementByAttribute(this,"anonid","test");]]></field>

            <field name="_menu" readonly="true"><![CDATA[document.getAnonymousElementByAttribute(this,"anonid","bookmarks-menupopup");]]></field>

            <field name="_addItem" readonly="true"><![CDATA[document.getAnonymousElementByAttribute(this,"anonid","menuitem-add");]]></field>

            <field name="_editItem" readonly="true"><![CDATA[document.getAnonymousElementByAttribute(this,"anonid","menuitem-edit");]]></field>

            <field name="_loadingData">false</field>
            <field name="_loadingTimestamp">0</field>
            <field name="_loadingTimerId"/>

            <property name="loadingData">
                <getter><![CDATA[return this._loadingData;]]></getter>
                <setter><![CDATA[this._loadingData = val;
if (this._loadingTimerId)
clearTimeout(this._loadingTimerId);
if (val)
{
this._button.setAttribute("loading",val);
this._loadingTimestamp = Date.now() + 700;
}
else
{
this._loadingTimerId = setTimeout(function (me) {
me._button && me._button.setAttribute("loading",val);
}
,Math.max(0,this._loadingTimestamp - Date.now()),this);
}
]]></setter>
            </property>

            <property name="_currentTabURI" onget="return gBrowser.selectedBrowser.currentURI" readonly="true"/>

            <constructor><![CDATA[if (this.yauth.authorized)
{
let winListener = this.API.Browser.getWindowListener(window);
winListener.addListener("WindowLocationChange",this);
this.module.loadBookmarks(this,this._onBookmarksResponse.bind(this),this._onBookmarksResponseError.bind(this),false);
}

this.yauth.addListener(this.yauth.EVENTS.AUTH_STATE_CHANGED,this);
this.API.Settings.observeChanges(this);
var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://global/content/nsDragAndDrop.js",window);
loader.loadSubScript("chrome://global/content/nsTransferable.js",window);]]></constructor>

            <property name="mode">
                <getter><![CDATA[return this._button.getAttribute("edit") == "true" ? "edit" : "add";]]></getter>
                <setter><![CDATA[var editMode = val == "edit";
this._addItem.hidden = editMode;
this._editItem.hidden = ! editMode;
this._button.setAttribute("edit","" + editMode);]]></setter>
            </property>

            <method name="bookmarksDestroy">
                <body><![CDATA[this.yauth.removeListener(this.yauth.EVENTS.AUTH_STATE_CHANGED,this);
this.API.Settings.ignoreChanges(this);
var winListener = this.API.Browser.getWindowListener(window);
winListener.removeListener("WindowLocationChange",this);]]></body>
            </method>

            <method name="refreshBookmarks">
                <body><![CDATA[this.loadingData = true;
this.module.loadBookmarks(this,this._onBookmarksResponse.bind(this),this._onBookmarksResponseError.bind(this),true);]]></body>
            </method>

            <method name="setFaviconForURL">
                <parameter name="strURL"/>
                <parameter name="menuitem"/>
                <body><![CDATA[if (! this.utils.isValidByRegExpURL(strURL))
return;
var URL = this.utils.newURI(strURL,null,null);
if (! /^https?$/.test(URL.scheme))
return;
var strFavIconURL = this.faviconServiceURLString + URL.host;
var img = document.createElementNS("http://www.w3.org/1999/xhtml","img");
img.onload = function () {
menuitem.setAttribute("image",this.src);
return false;
}
;
img.src = strFavIconURL;]]></body>
            </method>

             <method name="onSettingChange">
                <parameter name="settingName"/>
                <parameter name="newValue"/>
                <body><![CDATA[if (settingName == "showAddToFolderOnTop")
{
this._menu.setAttribute("updated",true);
}
]]></body>
            </method>

            
            <method name="observe">
                <parameter name="subject"/>
                <parameter name="topic"/>
                <parameter name="data"/>
                <body><![CDATA[switch (topic) {
case "WindowLocationChange":
this._updateBtnMode(data.uri);
break;
case this.yauth.EVENTS.AUTH_STATE_CHANGED:
let winListener = this.API.Browser.getWindowListener(window);
if (data.hasAuth)
{
winListener.addListener("WindowLocationChange",this);
this.module.loadBookmarks(this,this._onBookmarksResponse.bind(this),this._onBookmarksResponseError.bind(this),false);
}
else
{
winListener.removeListener("WindowLocationChange",this);
this.mode = "add";
}

break;
}
]]></body>
            </method>

            <method name="_onBookmarksResponse">
                <parameter name="strXmlResponse"/>
                <body><![CDATA[this._updateBtnMode();
this.loadingData = false;]]></body>
            </method>

            <method name="_onBookmarksResponseError">
                <parameter name="error"/>
                <body><![CDATA[this.loadingData = false;
if (error === "reg_required")
{
this.module.bookmarks.subscribe();
this.module.loadBookmarks(this,this._onBookmarksResponse.bind(this),this._onBookmarksResponseError.bind(this),false);
}
]]></body>
            </method>

            <method name="onBookmarksPopupShow">
                <parameter name="aPopup"/>
                <body><![CDATA[var target = document.popupNode;
if (! (target && target.classList.contains("bookmark-item")))
return false;
var menuItems = aPopup.getElementsByTagName("menuitem");
var targetIsFolder = target.localName == "menu";
for (let i = 0;i < 3;i++) menuItems[i].hidden = targetIsFolder;
menuItems[3].hidden = ! targetIsFolder;
var menuItemsLength = menuItems.length;
menuItems[menuItemsLength - 2].hidden = targetIsFolder;
menuItems[menuItemsLength - 1].hidden = ! targetIsFolder;
if (targetIsFolder)
{
let lastChild = document.popupNode.firstChild.lastChild;
menuItems[3].setAttribute("disabled",! (lastChild && lastChild.localName == "menuitem"));
}
]]></body>
            </method>

            <method name="openBookmark">
                <parameter name="event"/>
                <parameter name="target"/>
                <body><![CDATA[var popupNode = document.popupNode;
if (popupNode)
{
let url = popupNode.getAttribute("statustext");
this.module.gotoLink(url,event,target);
}
]]></body>
            </method>

            <method name="openAllInTabs">
                <parameter name="event"/>
                <body><![CDATA[var popupNode = document.popupNode;
if (popupNode)
{
this.module.openAllInTabs(popupNode,event);
}
]]></body>
            </method>

            <method name="_onAddToFolderCmd">
                <parameter name="event"/>
                <body><![CDATA[event.stopPropagation();
var popupNode = document.popupNode;
if (popupNode)
{
let folderId = popupNode.getAttribute("folderId");
this.module.addBookmark(this,folderId,event);
}
]]></body>
            </method>

            <method name="_onAddBookmarkCmd">
                <parameter name="event"/>
                <body><![CDATA[event.stopPropagation();
this.module.addBookmark(this,undefined,event);]]></body>
            </method>

            <method name="editBookmark">
                <parameter name="event"/>
                <body><![CDATA[event.stopPropagation();
var popupNode = document.popupNode;
if (popupNode)
{
let bookmarkId = popupNode.getAttribute("folderid") || popupNode.getAttribute("linkid");
this.module.editBookmarkMenu(this,bookmarkId,event);
}
]]></body>
            </method>

            <method name="editBookmarkOnClick">
                <parameter name="event"/>
                <body><![CDATA[event.stopPropagation();
this.module.editBookmarkOnClick(this._currentTabURI,this,event);]]></body>
            </method>

            <method name="gotoBookmarks">
                <parameter name="event"/>
                <body><![CDATA[event.stopPropagation();
this.module.gotoBookmarks(event);]]></body>
            </method>

            <method name="deleteBookmark">
                <parameter name="event"/>
                <body><![CDATA[event.stopPropagation();
var popupNode = document.popupNode;
if (popupNode)
{
let bookmarkId = popupNode.getAttribute("folderid") || popupNode.getAttribute("linkid");
this.module.deleteBookmark(this,bookmarkId,event);
}
]]></body>
            </method>

            <method name="copyBookmarkToPersonalPanel">
                <parameter name="event"/>
                <body><![CDATA[var popupNode = document.popupNode;
if (popupNode)
{
let bookmarkId = popupNode.getAttribute("folderid") || popupNode.getAttribute("linkid");
this.module.copyBookmarkToPersonalPanel(this,bookmarkId,event);
}
]]></body>
            </method>

            <method name="_fillTooltip">
                <parameter name="elem"/>
                <body><![CDATA[var rows = this._tooltip.getElementsByTagName("row");
var data = [elem.getAttribute("statustext"), elem.getAttribute("label"), elem.getAttribute("descr")];
var row, i = 0;
while (row = rows.item(i)) {
if (data[i])
{
row.style.display = "";
row.lastChild.setAttribute("value",data[i].replace(/[\r\n]/g," "));
}
else
{
row.style.display = "none";
}

i++;
}
]]></body>
            </method>

            <method name="_updateBtnMode">
                <parameter name="uri"/>
                <body><![CDATA[if (! uri)
uri = this._currentTabURI;
this.mode = this.utils.isValidURL(uri.spec) && this.module.getBookmark(uri) ? "edit" : "add";]]></body>
            </method>

            <method name="_onBtnCommand">
                <parameter name="event"/>
                <body><![CDATA[if (this._button.open)
return;
event.stopPropagation();
var yauth = this.module.yauth;
var mode = this.module.getPref("action","2");
if (mode == "2" || mode == "1" || ! yauth.authorized)
{
if (yauth.authorized)
{
this.module.editBookmarkOnClick(this._currentTabURI,this,event);
}
else
{
let dialogParams = {
name: "zakladki",
title: this.title};
this.module.yauth.openAuthDialog(event,dialogParams);
}

}
else
{
this._button.open = true;
}
]]></body>
            </method>

            <method name="clearShowTimeout">
                <body>if (! this._startHandler)
return false;
clearTimeout(this._startHandler);
this._startHandler = null;
return true;</body>
            </method>

        </implementation>

        <handlers>
            <handler event="popupshowing"><![CDATA[if (event.originalTarget != this._menu)
return;
if (! this.yauth.authorized)
{
this._onBtnCommand(event);
return false;
}

this.module.onRootHover(this._menu);]]></handler>

            <handler event="mouseleave">this.clearShowTimeout();
this._tooltip.hidePopup();</handler>

            <handler event="mousemove"><![CDATA[var elem = event.originalTarget;
if (elem.hasAttribute("linkid") || elem.hasAttribute("folderid"))
{
if (["open", "showing"].indexOf(this._tooltip.state) > - 1)
{
if (Math.abs(this._x - event.screenX) > 10 || Math.abs(this._y - event.screenY) > 10)
{
this._tooltip.hidePopup();
}

return;
}

this.clearShowTimeout();
this._x = event.screenX;
this._y = event.screenY;
this._startHandler = window.setTimeout((function () {
this._fillTooltip(elem);
this._tooltip.openPopupAtScreen(this._x,this._y,false);
}
).bind(this),500);
}
else
{
this._tooltip.hidePopup();
}
]]></handler>

            <handler event="DOMMenuItemActive"><![CDATA[var elem = event.originalTarget;
if (elem.hasAttribute("folderid"))
{
this.module.onFolderHover(elem.menupopup,elem.getAttribute("folderid"));
}
]]></handler>

            <handler event="DOMMenuItemInactive"><![CDATA[this._tooltip.hidePopup();]]></handler>

            <handler event="blur"><![CDATA[this._tooltip.hidePopup();]]></handler>
        </handlers>
    </binding>
</bindings>
