<?xml version='1.0'?>
<!DOCTYPE bindings [
<!ENTITY % omniboxDTD SYSTEM "/smartbox.dtd">
%omniboxDTD;
]>
<bindings xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xbl="http://www.mozilla.org/xbl" xmlns="http://www.mozilla.org/xbl" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

    <binding id="button">
        <resources>
            <image src="/icons/addressbar/search.png"/>
            <image src="/icons/addressbar/navigate.png"/>
        </resources>

        <implementation implements="nsIDOMEventListener">
            <field name="api" readonly="true">this.module.api</field>

            <field name="mPanelId" readonly="true">"yaOmniboxPanel"</field>
            <field name="mUrlbarPlaceholder">"&wgt.smartbox.addressbarLabel;"</field>

            <property name="_browserURLBar" onget="return gURLBar;" readonly="true"/>

            <constructor><![CDATA[this.wdgtxConstructor();]]></constructor>

            <destructor><![CDATA[this.wdgtxDestructor();]]></destructor>

            <method name="wdgtxConstructor">
                <body><![CDATA[if (this._wdgtxConstructed)
return;
this._wdgtxConstructed = true;
var urlbar = this._browserURLBar;
if (! urlbar)
{
this.api.logger.debug("Can't find urlbar.");
return;
}

urlbar.placeholder = this.mUrlbarPlaceholder;
urlbar._yaOmniboxModule = this.module;
var panel = document.getElementById(this.mPanelId);
if (! panel)
{
panel = document.createElement("panel");
panel.setAttribute("id",this.mPanelId);
panel.style.MozBinding = "url(" + this.api.Package.resolvePath("/native/bindings.xbl#popup") + ")";
panel.setAttribute("type","autocomplete");
panel.setAttribute("noautofocus","true");
panel.setAttribute("yaOS",this.api.Environment.os.name);
let mainPopupSet = document.getElementById("mainPopupSet");
if (! mainPopupSet)
{
this.api.logger.debug("Can't find mainPopupSet.");
return;
}

mainPopupSet.appendChild(panel);
}

this.module.onDelayedInit(this._initDelayed.bind(this));]]></body>
            </method>

            <method name="wdgtxDestructor">
                <body><![CDATA[if (! this._wdgtxConstructed)
return;
this._wdgtxConstructed = false;
var panel = document.getElementById(this.mPanelId);
if (panel)
panel.parentNode.removeChild(panel);
var urlbar = this._browserURLBar;
if (! urlbar)
{
this.api.logger.debug("Can't find urlbar.");
return;
}

try {
let action = urlbar._yaParseActionURL(urlbar.value || "");
if (action)
urlbar.value = action.actionurl || action.param;
}
catch (e) {

}

this._removeCustomizedUrlbarMethods();
urlbar.setAttribute("autocompletepopup",urlbar.getAttribute("yaOmniboxPreviousPopup"));
urlbar.setAttribute("autocompletesearch",urlbar.getAttribute("yaOmniboxPreviousAutocompletesearch"));
urlbar.setAttribute("sizetopopup",urlbar.getAttribute("yaOmniboxPreviousSizetopopup"));
delete urlbar.completeDefaultIndex;
this._setURLBarPopup();
urlbar.mSearchNames = null;
if ("initSearchNames" in urlbar)
urlbar.initSearchNames();
var keySet = document.getElementById(this.module.WIDGET_ID + "keyset");
if (keySet)
{
Array.slice(keySet.parentNode.getElementsByAttribute("command","Tools:Search")).forEach(function (key) key.setAttribute("disabled","false"));
keySet.parentNode.removeChild(keySet);
}
]]></body>
            </method>

            <method name="_initDelayed">
                <body><![CDATA[var urlbar = this._browserURLBar;
var panel = document.getElementById(this.mPanelId);
urlbar.setAttribute("yaOmniboxPreviousPopup",urlbar.getAttribute("autocompletepopup"));
urlbar.setAttribute("autocompletepopup",this.mPanelId);
urlbar.setAttribute("yaOmniboxPreviousAutocompletesearch",urlbar.getAttribute("autocompletesearch"));
urlbar.setAttribute("autocompletesearch",this.module.OmniBox.SEARCH_PROTOCOL_NAME);
urlbar.setAttribute("yaOmniboxPreviousSizetopopup",urlbar.getAttribute("sizetopopup"));
urlbar.removeAttribute("sizetopopup");
this._setURLBarPopup();
urlbar.mSearchNames = null;
urlbar.initSearchNames();
urlbar.completeDefaultIndex = false;
urlbar._yaInfoCollector = {
metric: "not_used"};
if (urlbar._value && urlbar._value.indexOf("moz-action:yaaction-") == 0)
urlbar.value = urlbar._value;
switch (this.api.Environment.os.name) {
case "windows":
{
let urlbarStyle = window.getComputedStyle(urlbar,null);
let panelBorderStyle = [urlbarStyle.getPropertyValue("border-bottom-width"), urlbarStyle.getPropertyValue("border-bottom-style"), urlbarStyle.getPropertyValue("border-bottom-color")].join(" ");
panel.style.setProperty("border",panelBorderStyle,"important");
break;
}

case "linux":
panel.style.setProperty("border","1px solid #999","important");
break;
}

var widgetId = this.module.WIDGET_ID;
if (! document.getElementById(widgetId + "keyset"))
{
let mainKeyset = document.getElementById("mainKeyset");
if (mainKeyset)
{
let keySet = document.createElement("keyset");
keySet.setAttribute("id",widgetId + "keyset");
["k"].forEach(function (aKey, aIndex) {
var keyNode = document.createElement("key");
keyNode.setAttribute("id",widgetId + "-key-" + aIndex);
keyNode.setAttribute("modifiers","accel");
keyNode.setAttribute("key",aKey);
keyNode.setAttribute("oncommand","gURLBar && gURLBar.focus();");
keySet.appendChild(keyNode);
}
);
Array.slice(mainKeyset.getElementsByAttribute("command","Tools:Search")).forEach(function (key) key.setAttribute("disabled","true"));
mainKeyset.parentNode.appendChild(keySet);
}

}

window.setTimeout((function () {
this._customizeUrlbarMethods();
}
).bind(this),0);]]></body>
            </method>

            <method name="_setURLBarPopup">
                <body><![CDATA[var urlbar = this._browserURLBar;
if (! urlbar)
return;
var popup = null;
var popupId = urlbar.getAttribute("autocompletepopup");
if (popupId)
popup = document.getElementById(popupId);
if (! popup)
{
popup = document.createElement("panel");
popup.setAttribute("type","autocomplete");
popup.setAttribute("noautofocus","true");
let popupset = document.getAnonymousElementByAttribute(urlbar,"anonid","popupset");
popupset.appendChild(popup);
}

popup.mInput = urlbar;
urlbar.popup = popup;]]></body>
            </method>

            <method name="saveSearchToForm">
                <parameter name="value"/>
                <body><![CDATA[var param = gURLBar._yaOmniboxModule.OmniBox.URLEngine.extractSearchParam(value);
if (! param)
return;
this.module.addToFormHistory(this.api.Autocomplete.commonHistoryCategory,param);]]></body>
            </method>

            <method name="_makePathParam">
                <body><![CDATA[var stat = this.module.OmniBox.currentStat;
if (! stat)
return "ff-smartbox";
var [type] = this.module.OmniBox.URLEngine.getInputType(stat.user_input);
var currentStyle = "";
if (gURLBar.popup.selectedIndex != - 1)
{
currentStyle = gURLBar.mController.getStyleAt(gURLBar.popup.selectedIndex);
}
else
{
if (type == "url" || gURLBar._yaInfoCollector.completed)
{
currentStyle = "nav";
}
else
{
currentStyle = "yaSearchSuggest";
}

}

var position = gURLBar.popup.selectedIndex + 1;
var metric = stat.metric == "not_shown" ? stat.metric : position == 0 ? "not_used" : gURLBar._yaInfoCollector.metric;
var current_state = stat.current_state || (type == "url" ? "nav" : "search");
var path = ["ff-smartbox", "11_0", current_state + "_" + (currentStyle.indexOf("yaSearchSuggest") != - 1 ? "to_search" : "to_nav"), metric, "p" + position];
return path.join(".");]]></body>
            </method>

            <method name="sendNavigationStatistic">
                <body><![CDATA[if (! this.module.api.Statistics.alwaysSendUsageStat)
return;
var stat = this.module.OmniBox.currentStat;
var params = {
cid: 70833,
pid: 0};
var urlbar = gURLBar;
var urlbarController = urlbar.mController;
var selectedIndex = urlbar.popup.selectedIndex;
var style = urlbarController.matchCount && urlbarController.getStyleAt(0);
var used = style && style.indexOf("yaSuperNavigationSuggest") != - 1 && selectedIndex == 0;
var top_suggest_value = "";
for (let i = 0;i < urlbarController.matchCount;i++) {
let itemStyle = urlbarController.getStyleAt(i);
if (itemStyle.indexOf("yaSearchSuggest") == - 1)
continue;
let val = urlbarController.getValueAt(i);
let action = urlbar._yaParseActionURL(val);
top_suggest_value = action ? action.param : val;
break;
}

var pos = - 1;
for (let i = 0;i < urlbarController.matchCount;i++) {
let itemStyle = urlbarController.getStyleAt(i);
if (itemStyle.indexOf("yaSuperNavigationSuggest") == - 1)
continue;
pos = i + 1;
break;
}

if (pos != - 1)
params.pos = pos;
params.path = used ? "ff-smartbox.used" : "ff-smartbox.not_used";
params.user_input = stat.user_input;
params.top_suggest = top_suggest_value;
params.r = stat.r;
params.exprt = stat.exprt;
var value = selectedIndex >= 0 && selectedIndex < urlbarController.matchCount && urlbarController.getValueAt(selectedIndex) || "";
var action = selectedIndex != - 1 ? urlbar._yaParseActionURL(value) : "";
var navUrl = action ? action.actionurl : value;
params.nav_url = navUrl || "";
params.rnd = Date.now();
params["*"] = "";
var data = [k + "=" + encodeURIComponent(params[k]) for (k in params)];
var url = "http://clck.yandex.ru/jclck/" + data.join("/");
var request = new XMLHttpRequest();
request.open("GET",url,true);
request.send(null);]]></body>
            </method>

            <method name="sendStatistic">
                <body><![CDATA[if (! this.module.api.Statistics.alwaysSendUsageStat)
return;
var stat = this.module.OmniBox.currentStat || {
exprt: 0,
r: 0,
user_input: "",
matches: []};
var urlbar = gURLBar;
var selectedIndex = urlbar.popup.selectedIndex;
var urlbarController = urlbar.mController;
var params = {
dtype: "stred",
pid: 0,
cid: 71477,
path: this._makePathParam(),
pos: urlbar.selectionStart,
user_input: stat.user_input};
var value = selectedIndex >= 0 && selectedIndex < urlbarController.matchCount && urlbarController.getValueAt(selectedIndex) || "";
var value = urlbar.mController.getValueAt(urlbar.popup.selectedIndex);
var action = selectedIndex != - 1 ? urlbar._yaParseActionURL(value) : "";
var suggestText = action ? action.param : value;
params.text = suggestText || "";
params.rnd = Date.now();
params.times = this.module.OmniBox.onlinetimes.join(".");
params.loc_times = this.module.OmniBox.localtimes.join(".");
params.matches = stat.matches.join(".");
params.ratio = [stat.user_input.length, this._getUrlBarValue().length, urlbar._yaInfoCollector.user_actions].join(".");
if (this.module.api.Environment.barPlatform.version > 4)
params.ui = this.module.api.Environment.addon.userID;
var searchURL = this.module.OmniBox.core.makeSearchURLForString("");
var engineHost = this.module.OmniBox.URLEngine.getURIParam(searchURL,"host");
params.seng = engineHost;
params.cpst = urlbar._yaInfoCollector.pasted;
params.crtd = + ! this.module.OmniBox.hasCurrentLayout(urlbar.value);
params.sstime = Date.now() - urlbar._yaInfoCollector.startTime;
params.idletime = Date.now() - urlbar._yaInfoCollector.endTime;
params["*"] = "";
var data = [k + "=" + encodeURIComponent(params[k]) for (k in params)];
var url = "http://clck.yandex.ru/jclck/" + data.join("/");
var request = new XMLHttpRequest();
request.open("GET",url,true);
request.send(null);
if (params.matches.indexOf("n") != - 1)
this.sendNavigationStatistic();
urlbar._yaInfoCollector = {
};
urlbar._yaInfoCollector.metric = "not_used";
urlbar._yaInfoCollector.user_actions = 0;
this.module.OmniBox.dropTimes();]]></body>
            </method>

            <method name="_getUrlBarValue">
                <body><![CDATA[var action = gURLBar._yaParseActionURL(gURLBar.value);
return action ? action.param : gURLBar.value;]]></body>
            </method>

            <method name="_customizeUrlbarMethods">
                <body><![CDATA[var urlbar = this._browserURLBar;
if (! urlbar)
return;
var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
urlbar._yaLastSelectedIndex = - 1;
urlbar._yaInfoCollector.user_actions = 0;
var that = this;
const COMPLETE_SEPARATOR = "\u200b\u00a0\u200b";
var currentAutoCompletedString = "";
var _getUrlbarSelection = function _getUrlbarSelection() {
var selectionController = urlbar.editor.selectionController;
return selectionController.getSelection(selectionController.SELECTION_NORMAL);
}
;
urlbar._yaParseActionURL = function _yaParseActionURL(aURL) {
if (/^moz\-action:yaaction\-/.test(aURL))
{
let parts = aURL.split("_yaacsep_");
if (parts.length)
{
let [, type, actionurl] = parts[0].match(/^moz\-action:([^,]+),(.*)$/);
let param = "";
try {
param = decodeURIComponent(parts[1]);
}
catch (e) {
param = encodeURIComponent(parts[1]);
}

actionurl = type.indexOf("opensearch") != - 1 ? that.module.OmniBox.core.makeSearchURLForString(param) : actionurl;
return {
type: type,
param: param,
actionurl: actionurl};
}

}

return this._parseActionUrl.apply(this,arguments);
}
;
var _onUrlbarSearchComplete = function _onUrlbarSearchComplete() {
if (this._yaOBXStopComplete)
return;
var selection = _getUrlbarSelection();
if (currentAutoCompletedString && selection.toString() == currentAutoCompletedString)
selection.deleteFromDocument();
this.popup.selectedIndex = 0;
var controller = this.mController;
if (controller.searchStatus != controller.STATUS_COMPLETE_MATCH)
return;
if (! controller.matchCount)
return;
var firstResultStyle = controller.getStyleAt(0);
if (! /(^|\s)yaDefaultComplete(\s|$)/.test(firstResultStyle))
return;
var searchString = controller.searchString;
var currentValue = this.value;
var typedValue = currentValue.replace(selection.toString(),"");
if (! typedValue)
return;
if (searchString.toLowerCase() != typedValue.toLowerCase())
return;
if (this.selectionStart > this.selectionEnd || this.selectionEnd < typedValue.length)
return;
var suggestedValue = controller.getLabelAt(0);
let (action = this._yaParseActionURL(suggestedValue)) {
if (action && action.param)
suggestedValue = action.param;
}

if (suggestedValue.length < typedValue.length || suggestedValue == typedValue)
return;
var mayTrimURLsSavedValue = this._mayTrimURLs;
this._mayTrimURLs = false;
var action = this._yaParseActionURL(currentValue);
var newValue = action && action.param || suggestedValue || "";
newValue = newValue.replace(/^[-\w]*:\/+/,"");
newValue = newValue.split("/")[0];
this.value = newValue;
if (newValue.indexOf(typedValue) != 0)
{
let indx = newValue.toLowerCase().indexOf(typedValue.toLowerCase());
if (indx == 0)
{
let substrIndx = typedValue.length;
let completedString = newValue.substr(substrIndx);
this.value = typedValue + completedString;
}
else
{
this.value = typedValue + COMPLETE_SEPARATOR + newValue;
}

}

selection.removeAllRanges();
var textNode = this.editor.rootElement.firstChild;
var value = textNode.textContent;
var startIndex = typedValue.length;
var rangeLength = value.length;
var range = document.createRange();
range.setStart(textNode,startIndex);
range.setEnd(textNode,rangeLength);
selection.addRange(range);
preventScroll();
currentAutoCompletedString = selection.toString();
this._mayTrimURLs = mayTrimURLsSavedValue;
}
;
var searchIcon = this.api.Package.resolvePath("icons/addressbar/search.png");
var navigateIcon = this.api.Package.resolvePath("icons/addressbar/navigate.png");
if ("SetPageProxyState" in window && ! ("_yaOriginalSetPageProxyState" in window))
{
let originalSetPageProxyState = window.SetPageProxyState;
window._yaOriginalSetPageProxyState = originalSetPageProxyState;
window.SetPageProxyState = function _SetPageProxyState() {
var res = originalSetPageProxyState.apply(window,arguments);
urlbar._yaUpdateActionIcon();
return res;
}
;
}

urlbar._yaUpdateActionIcon = function _yaUpdateActionIcon() {
var pageProxyIcon = document.getElementById("page-proxy-favicon");
if (! pageProxyIcon)
return;
var [type] = _getCurrentInputType();
var path = type == "search" ? searchIcon : navigateIcon;
if (pageProxyIcon.getAttribute("src") != path)
pageProxyIcon.setAttribute("src",path);
}
;
urlbar._yaFocusEventHandler = function _yaFocusEventHandler() {
this._yaInfoCollector.startTime = Date.now();
}
;
urlbar.addEventListener("focus",urlbar._yaFocusEventHandler,false);
var originalOnSearchComplete = urlbar.onSearchComplete;
urlbar.onSearchComplete = function _onSearchComplete() {
var origRes = originalOnSearchComplete.apply(this,arguments);
_onUrlbarSearchComplete.apply(urlbar,arguments);
urlbar._yaUpdateActionIcon();
return origRes;
}
;
var originalOnInput = urlbar.oninput;
urlbar.oninput = function _oninput() {
originalOnInput.apply(this,arguments);
if (this.value == "" && "PageProxyClearIcon" in window)
window.PageProxyClearIcon();
}
;
var originalOnBeforeValueGet = urlbar.onBeforeValueGet;
urlbar.onBeforeValueGet = function _onBeforeValueGet() {
if (this.hasAttribute("actiontype"))
{
let action = this._yaParseActionURL(this._value);
let val = (action && action.param).replace(/^https?:\/\//,"").replace(/\/$/,"");
let currentValue = this.inputField.value.replace(/^https?:\/\//,"").replace(/\/$/,"");
if (val !== currentValue)
{
this.removeAttribute("actiontype");
return null;
}

return {
value: this._value};
}

return null;
}
;
var originalOnBeforeValueSet = urlbar.onBeforeValueSet;
urlbar.onBeforeValueSet = function _onBeforeValueSet(aValue) {
this._value = aValue;
var returnValue = aValue;
var action = this._yaParseActionURL(aValue);
if (action)
{
returnValue = action.param;
this.setAttribute("actiontype",action.type);
}
else
{
this.removeAttribute("actiontype");
}

return returnValue;
}
;
var originalOnPasteEvent = urlbar.onpaste;
urlbar.onpaste = function (aEvent) {
this._yaInfoCollector.pasted = 1;
this._yaInfoCollector.endTime = Date.now();
if (originalOnPasteEvent)
return originalOnPasteEvent.apply(this,arguments);
}
;
var getValueIfKeyword = function getValueIfKeyword() {
if (urlbar.popup.selectedIndex != - 1)
return null;
var suggestedValue = urlbar.mController.getLabelAt(0);
let (action = urlbar._yaParseActionURL(suggestedValue)) {
if (action && action.param && action.type == "yaaction-keyword")
{
return urlbar.value;
}

}

return null;
}
;
var _getCurrentInputType = function _getCurrentInputType() {
var url = urlbar.value;
var action = urlbar._yaParseActionURL(url);
if (action && action.actionurl)
return [action.type == "yaaction-opensearch" ? "search" : "url", action.actionurl];
return _getInputType(url.split(COMPLETE_SEPARATOR)[1] || url);
}
;
var module = this.module;
var _getInputType = function _getInputType(aString) {
var [type, url] = module.OmniBox.URLEngine.getInputType(aString);
if (type == "maybeurl" && /\s/.test(aString.trim()))
type = "search";
if (type == "url")
return ["url", url];
if (type == "maybeurl")
{
let uri;
try {
uri = ioService.newURI(url,null,null);
}
catch (e) {

}

try {
if (! uri.host || uri.host.indexOf(" ") != - 1)
type = "search";
}
catch (e) {
if (aString.indexOf("moz-action") != 0 && aString.indexOf(" ") != - 1)
type = "search";
}

if (uri && /^https?$/.test(uri.scheme) && uri.path == "/" && aString.substr(- 1) != "/")
{
type = "search";
}

}

if (type == "search")
return ["search", module.makeSearchURLForString(aString)];
return [type, aString];
}
;
var originalHandleCommand = urlbar.handleCommand;
urlbar.handleCommand = function handleCommand() {
var url;
if (! (this._yaLastSelectedIndex >= 0) && currentAutoCompletedString.length && this.mController.matchCount)
{
let action = this._yaParseActionURL(this.mController.getValueAt(0));
if (action && action.actionurl)
{
url = action.actionurl;
}

let firstStyle = this.mController.getStyleAt(0);
if (firstStyle.indexOf("yaSuperNavigationSuggest") != - 1)
{
this._yaLastSelectedIndex = 0;
}

}

currentAutoCompletedString = "";
var value = getValueIfKeyword() || url;
if (value)
this.value = value;
if (! value && this.value)
{
let mayTrimURLsSavedValue = this._mayTrimURLs;
this._mayTrimURLs = false;
[, this.value] = _getCurrentInputType();
this._mayTrimURLs = mayTrimURLsSavedValue;
}

var yaReferrerURI = null;
if (this._yaLastSelectedIndex >= 0 && this._yaLastSelectedIndex < this.mController.matchCount)
{
let navType = this.mController.getStyleAt(this._yaLastSelectedIndex);
if (/(^|\s)ya(Super)?NavigationSuggest($|\s)/.test(navType))
{
yaReferrerURI = ioService.newURI("http://www.yandex.ru",null,null);
}

}

var originalLoadURIWithFlags = yaReferrerURI && gBrowser.loadURIWithFlags;
var originalOpenUILinkIn = yaReferrerURI && window.openUILinkIn;
if (originalLoadURIWithFlags)
{
gBrowser.loadURIWithFlags = function () {
var params = arguments;
if (yaReferrerURI && ! params[2])
params[2] = yaReferrerURI;
return originalLoadURIWithFlags.apply(this,params);
}
;
}

if (originalOpenUILinkIn)
{
window.openUILinkIn = function () {
var params = arguments;
if (yaReferrerURI && params[2] && ! params[2].referrerURI)
params[2].referrerURI = yaReferrerURI;
return originalOpenUILinkIn.apply(this,params);
}
;
}

try {
return originalHandleCommand.apply(this,arguments);
}
finally {
if (originalLoadURIWithFlags)
gBrowser.loadURIWithFlags = originalLoadURIWithFlags;
if (originalOpenUILinkIn)
window.openUILinkIn = originalOpenUILinkIn;
}

}
;
var preventScroll = function preventScroll() {
var selectionController = urlbar.editor.selectionController;
selectionController.scrollSelectionIntoView(selectionController.SELECTION_NORMAL,selectionController.SELECTION_ANCHOR_REGION,0);
}
;
var preventSelectionFlash = function preventSelectionFlash(aCurrentValue, aInputChar, aSelection) {
var selectedString = aSelection.toString();
if (selectedString.length <= 1)
return false;
if ("" != (aCurrentValue.split(selectedString)[1] || ""))
return false;
if (selectedString.toLowerCase().indexOf(aInputChar.toLowerCase()) != 0)
return false;
var completedString = aSelection.toString().substr(1);
var data = aInputChar + completedString;
var ssText = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
ssText.data = data;
var transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
transferable.addDataFlavor("text/unicode");
transferable.setTransferData("text/unicode",ssText,data.length * 2);
var editor = urlbar.editor;
editor.pasteTransferable(transferable);
aSelection.removeAllRanges();
var textNode = editor.rootElement.firstChild;
var inputValueLength = urlbar.inputField.value.length;
var completedStringLength = completedString.length;
if (completedStringLength)
{
let range = document.createRange();
range.setStart(textNode,inputValueLength - completedStringLength);
range.setEnd(textNode,inputValueLength);
aSelection.addRange(range);
preventScroll();
}

currentAutoCompletedString = aSelection.toString();
return true;
}
;
urlbar._yaProcessInput = function _yaProcessInput() {
var value;
if (this._yaInfoCollector.metric == "mouse")
{
let selectedIndex = this.popup.selectedIndex;
value = selectedIndex >= 0 && selectedIndex < this.mController.matchCount && this.mController.getValueAt(selectedIndex) || "";
if (value.indexOf("moz-action") != - 1)
{
let parsed = this._yaParseActionURL(value);
if (parsed)
value = parsed.actionurl;
}

}
else
{
[, value] = _getCurrentInputType();
}

if (currentAutoCompletedString.length)
this._yaInfoCollector.completed = true;
that.saveSearchToForm(value);
that.sendStatistic();
}
;
var yaOnProcessAction = function yaOnProcessAction(e) {
var selection = _getUrlbarSelection();
var selectionString = selection && selection.toString() || "";
if (! selectionString && urlbar.value && urlbar.value == gURLBar.mController.getLabelAt(0))
{
urlbar._yaInfoCollector.prevAction = null;
urlbar._yaInfoCollector.metric = "not_used";
}
else
if (urlbar._yaInfoCollector.prevAction == "edit")
{
urlbar._yaInfoCollector.metric = "edit";
}
else
{
let controller = gURLBar.mController;
let suggestedValue = controller.getLabelAt(0);
let (action = this._yaParseActionURL(suggestedValue)) {
if (action && action.param)
suggestedValue = action.param;
}

if (selectionString.indexOf(suggestedValue) != - 1 || currentAutoCompletedString.length)
{
urlbar._yaInfoCollector.metric = "auto";
}

}

}
;
var yaOnReturn = function yaOnReturn(e) {
var selection = _getUrlbarSelection();
var urlBarValue = urlbar.value;
let (urlBarValueAction = this._yaParseActionURL(urlBarValue)) {
if (urlBarValueAction && urlBarValueAction.param)
urlBarValue = urlBarValueAction.param;
}

var suggestedValue = this.mController.getLabelAt(this.popup.selectedIndex);
let (action = this._yaParseActionURL(suggestedValue)) {
if (action && action.param)
suggestedValue = action.param;
}

if (selection != "" && suggestedValue.indexOf(selection) != - 1 && urlBarValue == suggestedValue)
urlbar._yaInfoCollector.metric = "auto"; else
if (urlBarValue == suggestedValue)
urlbar._yaInfoCollector.metric = "keyboard";
}
;
var that = this;
urlbar._yaOnKeyDown = function _yaOnKeyDown(e) {
if (e.keyCode === KeyEvent.DOM_VK_ALT || e.keyCode === KeyEvent.DOM_VK_SHIFT)
{
this.popup.removeAttribute("noactions");
return;
}

if (e.keyCode != KeyEvent.DOM_VK_CONTROL)
return;
if (! that.module)
return;
var [type] = that.module.OmniBox.URLEngine.getInputType(this.inputField.value);
if (! this._controlHandled && type == "maybeurl" && this.inputField.value.indexOf("http://") != 0)
{
this._controlHandled = true;
this.mController.startSearch(this.inputField.value);
}

}
;
urlbar.addEventListener("keydown",urlbar._yaOnKeyDown,false);
urlbar._yaOnKeyUp = function _yaOnKeyUp(e) {
if (e.keyCode == KeyEvent.DOM_VK_CONTROL && urlbar._controlHandled == true)
{
urlbar._controlHandled = null;
this.mController.startSearch(this.inputField.value);
}

gURLBar._yaUpdateActionIcon();
}
;
urlbar.addEventListener("keyup",urlbar._yaOnKeyUp,false);
var originalOnKeyPress = urlbar.onKeyPress;
urlbar.onKeyPress = function _onKeyPress(aEvent) {
if (aEvent.target.localName != "textbox")
return;
if (aEvent.getPreventDefault())
return false;
this._yaOBXStopComplete = false;
if (! aEvent.metaKey && ! aEvent.ctrlKey)
{
let selection = _getUrlbarSelection();
if (preventSelectionFlash(this.inputField.value,String.fromCharCode(aEvent.charCode),selection))
{
this._yaInfoCollector.user_actions++;
this.mController.startSearch(this.inputField.value.substr(0,selection.anchorOffset));
return false;
}

}

switch (aEvent.keyCode) {
case KeyEvent.DOM_VK_RIGHT:
if (currentAutoCompletedString)
{
let completedText = this.value.split(COMPLETE_SEPARATOR)[1];
if (completedText)
this.value = completedText;
currentAutoCompletedString = "";
this._yaLastSelectedIndex = - 1;
}

if (this.popup.selectedIndex != - 1)
urlbar._yaInfoCollector.prevAction = "vk_right";
this.closePopup();
this._yaOBXStopComplete = true;
return;
case KeyEvent.DOM_VK_RETURN:
if (this.popup.selectedIndex == - 1)
yaOnProcessAction.call(this); else
yaOnReturn.call(this);
this._yaProcessInput();
break;
case KeyEvent.DOM_VK_LEFT:

case KeyEvent.DOM_VK_HOME:
{
if (currentAutoCompletedString)
{
let selection = _getUrlbarSelection();
if (selection.toString() === currentAutoCompletedString)
{
selection.deleteFromDocument();
currentAutoCompletedString = "";
}

}

this.closePopup();
this._yaOBXStopComplete = true;
return;
}

case KeyEvent.DOM_VK_TAB:

case KeyEvent.DOM_VK_UP:

case KeyEvent.DOM_VK_DOWN:
this._yaLastSelectedIndex = this.popup.selectedIndex;
urlbar._yaOmniboxModule.OmniBox.ProvidersManager.stopSearch();
urlbar._yaInfoCollector.prevAction = null;
currentAutoCompletedString = "";
break;
case KeyEvent.DOM_VK_BACK_SPACE:

case KeyEvent.DOM_VK_DELETE:
this._yaOBXStopComplete = true;
urlbar._yaOmniboxModule.OmniBox.ProvidersManager.stopSearch();
return;
case KeyEvent.DOM_VK_ESCAPE:
currentAutoCompletedString = "";
break;
}

this._yaInfoCollector.pasted = 0;
this._yaInfoCollector.endTime = Date.now();
if (urlbar._yaInfoCollector.prevAction && urlbar._yaInfoCollector.prevAction == "vk_right" && this.popup.selectedIndex != - 1)
{
urlbar._yaInfoCollector.prevAction = "edit";
}

var res = originalOnKeyPress.apply(this,arguments);
if (aEvent.keyCode == KeyEvent.DOM_VK_DOWN || aEvent.keyCode == KeyEvent.DOM_VK_UP)
{
this._yaLastSelectedIndex = this.popup.selectedIndex;
}
else
if (aEvent.keyCode != KeyEvent.DOM_VK_RETURN && aEvent.keyCode != KeyEvent.DOM_VK_UP && aEvent.keyCode != KeyEvent.DOM_VK_DOWN)
{
this._yaInfoCollector.user_actions++;
urlbar._yaInfoCollector.prevAction = "edit";
}

return res;
}
;
urlbar._yaBlurEventHandler = function _yaBlurEventHandler() {
this._yaInfoCollector.startTime = 0;
this._yaLastSelectedIndex = - 1;
if (! currentAutoCompletedString)
return;
var selection = _getUrlbarSelection();
if (selection.toString() !== currentAutoCompletedString)
return;
selection.deleteFromDocument();
currentAutoCompletedString = "";
this.textValue = this.value;
}
;
urlbar.addEventListener("blur",urlbar._yaBlurEventHandler,false);
var selEventHandler = function selEventHandler(aSelectUserInput) {
if (! currentAutoCompletedString)
return;
var urlbarValue = urlbar.value;
var indexOfComplete = urlbarValue.indexOf(COMPLETE_SEPARATOR);
if (indexOfComplete == - 1)
indexOfComplete = urlbarValue.lastIndexOf(currentAutoCompletedString);
if (indexOfComplete == - 1)
return;
currentAutoCompletedString = "";
urlbar.closePopup();
urlbar.value = urlbarValue.substring(0,indexOfComplete);
if (! aSelectUserInput)
return;
var textNode = urlbar.editor.rootElement.firstChild;
var range = document.createRange();
range.setStart(textNode,0);
range.setEnd(textNode,urlbar.inputField.value.length);
_getUrlbarSelection().addRange(range);
}
;
urlbar._yaSelectionEventHandler = function _yaSelectionEventHandler() selEventHandler(true);
urlbar.addEventListener("select",urlbar._yaSelectionEventHandler,false);
urlbar._yaClickEventHandler = function _yaClickEventHandler() selEventHandler(false);
urlbar.addEventListener("click",urlbar._yaClickEventHandler,false);
urlbar.yaShowUsageExample = function yaShowUsageExample(aText) {
if (this._yaShowUsageExampleTimeout)
{
window.clearTimeout(this._yaShowUsageExampleTimeout);
delete this._yaShowUsageExampleTimeout;
}

this.focus();
this.inputField.value = "";
var typeInterval = 30;
var chars = aText.split("");
var typeOneChar = (function _typeOneChar() {
this.inputField.value += chars.shift();
if (chars.length)
{
this._yaShowUsageExampleTimeout = window.setTimeout(typeOneChar,typeInterval);
return;
}

this.mController.startSearch(this.inputField.value);
}
).bind(this);
typeOneChar();
}
;]]></body>
            </method>

            <method name="_removeCustomizedUrlbarMethods">
                <body><![CDATA[var urlbar = this._browserURLBar;
if (! urlbar)
return;
if (urlbar._yaOnKeyDown)
{
urlbar.removeEventListener("keydown",urlbar._yaOnKeyDown,false);
delete urlbar._yaOnKeyDown;
}

if (urlbar._yaOnKeyUp)
{
urlbar.removeEventListener("keyup",urlbar._yaOnKeyUp,false);
delete urlbar._yaOnKeyUp;
}

if (urlbar._yaBlurEventHandler)
{
urlbar.removeEventListener("blur",urlbar._yaBlurEventHandler,false);
delete urlbar._yaBlurEventHandler;
}

if (urlbar._yaFocusEventHandler)
{
urlbar.removeEventListener("focus",urlbar._yaFocusEventHandler,false);
delete urlbar._yaFocusEventHandler;
}

if (urlbar._yaSelectionEventHandler)
{
urlbar.removeEventListener("select",urlbar._yaSelectionEventHandler,false);
delete urlbar._yaSelectionEventHandler;
}

if (urlbar._yaClickEventHandler)
{
urlbar.removeEventListener("click",urlbar._yaClickEventHandler,false);
delete urlbar._yaClickEventHandler;
}

if (this._yaShowUsageExampleTimeout)
{
window.clearTimeout(this._yaShowUsageExampleTimeout);
delete this._yaShowUsageExampleTimeout;
}

delete urlbar.onBeforeValueGet;
delete urlbar.onBeforeValueSet;
delete urlbar.onSearchComplete;
delete urlbar.handleCommand;
delete urlbar.onKeyPress;
delete urlbar.oninput;
delete urlbar.yaShowUsageExample;
delete urlbar._yaOmniboxModule;
delete urlbar._yaProcessInput;
delete urlbar._yaUpdateActionIcon;
delete urlbar._yaParseActionURL;
delete urlbar._yaLastSelectedIndex;
delete urlbar._yaInfoCollector;
if ("_yaOriginalSetPageProxyState" in window)
{
window.SetPageProxyState = window._yaOriginalSetPageProxyState;
delete window._yaOriginalSetPageProxyState;
if ("PageProxyClearIcon" in window)
PageProxyClearIcon();
if ("UpdatePageProxyState" in window)
window.UpdatePageProxyState();
}
]]></body>
            </method>
        </implementation>
    </binding>

    <binding id="panel-tutor">
        <resources>
            <stylesheet src="panel-tutor.css"/>
        </resources>

        <content class="searchTutorBox" flex="1">
            <xul:hbox class="searchTutorClose">
                <xul:hbox onclick="close(true);">
                    <xul:label value="Закрыть"/>
                    <xul:image/>
                </xul:hbox>
            </xul:hbox>
            <html:div class="searchTutorExamples">
                <html:div>
                    <html:p>Задавайте поисковые запросы прямо в адресной строке.</html:p>
                    <html:p>
                        Введите &#171;&#187; и получите ответ Яндекса.
                    </html:p>
                </html:div>
                <html:div>
                    <html:p>Не обращайте внимания на раскладку клавиатуры.</html:p>
                    <html:p>
                        Ваш браузер поймет и &#171;нфтву&#187;, и &#171;вкон&#187;.
                    </html:p>
                </html:div>
                <html:div>
                    <html:p>Перевод слова можно получить прямо в подсказках.</html:p>
                    <html:p>
                        Введите &#171;&#187; или &#171;аллилуйя по-английски&#187;.
                    </html:p>
                </html:div>
                <html:div>
                    <html:p>Цифры и факты легко узнать из поисковых подсказок.</html:p>
                    <html:p>
                        Спросите Яндекс про &#171;число пи&#187; или &#171;длина окружности&#187;.
                    </html:p>
                </html:div>
            </html:div>
            <html:div class="searchTutorVariants">
                <html:span data-exampleId="qsrch">Быстрый поиск</html:span>
                <html:span data-exampleId="kbrd">Другая раскладка</html:span>
                <html:span data-exampleId="trnsl">Быстрый перевод</html:span>
                <html:span data-exampleId="fcts">Полезные факты</html:span>
            </html:div>
        </content>

        <implementation>
            <field name="mOmniboxModule" readonly="true">gURLBar._yaOmniboxModule</field>
            <field name="api" readonly="true">this.mOmniboxModule.api</field>
            <field name="mParentFooter" readonly="true">document.getBindingParent(this)</field>

            <field name="mSearchTutorExamples" readonly="true">
                document.getAnonymousElementByAttribute(this, "class", "searchTutorExamples");
            </field>

            <field name="mSearchTutorVariants" readonly="true">
                document.getAnonymousElementByAttribute(this, "class", "searchTutorVariants");
            </field>

            <field name="mAutoShow">null</field>

            <field name="_variantsIds" readonly="true"><![CDATA[Array.map(this.mSearchTutorVariants.children,function (el) el.getAttribute("data-exampleId"));]]></field>

            <field name="_qsrchVariants" readonly="true"><![CDATA["                                                       ;                посторонним в                                           ;                головоногий моллюск                                     ;                страус фото                                             ;                купить машину                                           ;                аптеки                                                  ;                семейный кодекс                                         ;                сколько варить яйца                                     ;                рецепт глинтвейна                                       ;                гадание на кофейной гуще                                ;                универсальная электронная карта                         ;                как завязать галстук                                    ;                через тернии к звездам                                  ;                карнавала не будет                                      ;                что ты сделал                                           ;                проблема                                                ;                ".split(";").map(function (el) el.trim()).filter(function (el) ! ! el);]]></field>

            <field name="_trnslVariants" readonly="true"><![CDATA["                                                       ;                carpe diem перевод                                      ;                je t'aime перевод                                       ;                nice перевод                                            ;                cat перевод                                             ;                swag перевод                                            ;                try перевод                                             ;                occupation перевод                                      ;                hall of fame перевод                                    ;                stuff перевод                                           ;                cute перевод                                            ;                remove перевод                                          ;                still перевод                                           ;                paradise перевод                                        ;                performance перевод                                     ;                male перевод                                            ;                enterprise перевод                                      ;                value перевод                                           ;                intermediate перевод                                    ;                issue перевод                                           ;                available перевод                                       ;                draw перевод                                            ;                chest перевод                                           ;                же тем перевод                                          ;                pending перевод                                         ;                enough перевод                                          ;                charge перевод                                          ;                sweet перевод                                           ;                just перевод                                            ;                advanced перевод                                        ;                ".split(";").map(function (el) el.trim()).filter(function (el) ! ! el);]]></field>

            <constructor><![CDATA[if (this.mOmniboxModule.getStaticPref("tutor.clicked",false))
this.mAutoShow = false;
this.mParentFooter.wrapVisualModification(this,"_selectTutorVariant");]]></constructor>

            <method name="autoOpen">
                <body><![CDATA[var module = this.mOmniboxModule;
if (! module.canShowTutorial)
return;
if (! this.hidden)
{
if (! module.currentEngineIsBranded)
this.close();
return;
}

if (this.mAutoShow === null)
{
if (! module.currentEngineIsBranded)
return;
switch (module.brandedWeekSearchIsOverflowed) {
case true:
this.mAutoShow = false;
case null:
return;
}

this.mAutoShow = true;
}

if (! this.mAutoShow || ! module.currentEngineIsBranded)
return;
this._incrementAutoOpenCounter();
this.mParentFooter.switchSearchTutor();]]></body>
            </method>

            <method name="updateOnPopupShowing">
                <body><![CDATA[if (this.hidden)
return;
this.open();
if (this.mAutoShow === true)
this._incrementAutoOpenCounter();]]></body>
            </method>

            <method name="open">
                <body><![CDATA[this._selectTutorVariant();]]></body>
            </method>

            <method name="close">
                <parameter name="aManual"/>
                <body><![CDATA[this.mParentFooter.switchSearchTutor(aManual);]]></body>
            </method>

            <method name="_incrementAutoOpenCounter">
                <body><![CDATA[var module = this.mOmniboxModule;
var shownCounter = module.getStaticPref("tutor.shownCounter",0);
if (++shownCounter > 50)
{
this.close(true);
return;
}

module.setStaticPref("tutor.shownCounter",Math.min(50,shownCounter));]]></body>
            </method>

            <method name="_selectTutorVariant">
                <parameter name="aExampleIndex"/>
                <body><![CDATA[if (typeof aExampleIndex == "undefined")
{
aExampleIndex = this.mOmniboxModule.searchTutorClickedInfo.getFirstUnclikedIndex(this._variantsIds);
}

if (aExampleIndex < 0 || aExampleIndex >= this.mSearchTutorExamples.children.length)
aExampleIndex = 0;
this._makeExampleLinks(aExampleIndex);
var select = function select(element, index) {
if (index == aExampleIndex)
element.classList.add("selected"); else
element.classList.remove("selected");
}
;
Array.forEach(this.mSearchTutorExamples.children,select);
Array.forEach(this.mSearchTutorVariants.children,select);]]></body>
            </method>

            <method name="_makeExampleLinks">
                <parameter name="aExampleIndex"/>
                <body><![CDATA[var exampleElement = this.mSearchTutorExamples.children[aExampleIndex].children[1];
var text = exampleElement.textContent;
if (aExampleIndex === 0)
{
let sampleIndex = Math.floor(Math.random() * (this._qsrchVariants.length - 1));
let sample = this._qsrchVariants[sampleIndex].replace(/[«»]/g,"\"");
text = text.replace(/«[^»]*»/,"«" + sample + "»");
}
else
if (aExampleIndex === 2)
{
let sampleIndex = Math.floor(Math.random() * (this._trnslVariants.length - 1));
let sample = this._trnslVariants[sampleIndex].replace(/[«»]/g,"\"");
text = text.replace(/«[^»]*»/,"«" + sample + "»");
}

var parts = text.split(/[«»]/);
if (parts.length < 2)
return;
while (exampleElement.firstChild) exampleElement.removeChild(exampleElement.firstChild);
parts.forEach(function (part, index) {
var el = document.createTextNode(part);
if (index % 2)
{
exampleElement.appendChild(document.createTextNode("«"));
let link = document.createElementNS("http://www.w3.org/1999/xhtml","a");
link.appendChild(el);
exampleElement.appendChild(link);
exampleElement.appendChild(document.createTextNode("»"));
}
else
{
exampleElement.appendChild(el);
}

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

            <method name="_saveClickedInfo">
                <body><![CDATA[var selectedElement = Array.filter(this.mSearchTutorVariants.children,function (el) el.classList.contains("selected"))[0];
if (selectedElement)
this.mOmniboxModule.searchTutorClickedInfo.put(selectedElement.getAttribute("data-exampleId"));]]></body>
            </method>
        </implementation>

        <handlers>
            <handler button="0" event="click"><![CDATA[var target = event.originalTarget;
switch (target.localName) {
case "a":
this._saveClickedInfo();
gURLBar.yaShowUsageExample(target.textContent);
break;
case "span":
if (target.parentNode !== this.mSearchTutorVariants)
return;
if (target.classList.contains("selected"))
return false;
Array.some(this.mSearchTutorVariants.children,function (element, index) {
if (element !== target)
return false;
this._selectTutorVariant(index);
return true;
}
,this);
break;
}
]]></handler>
        </handlers>
    </binding>

    <binding id="popup-footer">
        <resources>
            <stylesheet src="panel-footer.css"/>
        </resources>

        <content flex="1">
            <xul:hbox class="searchProvidersBox" flex="1">
                <xul:vbox flex="1">
                    <html:div anonid="searchProviders"/>
                    <xul:hbox anonid="restoreDefaultEngine">
                        <xul:hbox onclick="if (event.button === 0) _restoreDefaultEngine();">
                            <xul:label anonid="restoreDefaultEngineLabel" value="&wgt.smartbox.restoreDefaultEngine;"/>
                        </xul:hbox>
                        <xul:image onclick="if (event.button === 0) _acceptDefaultEngine();"/>
                    </xul:hbox>
                </xul:vbox>
                <xul:hbox>
                    <xul:hbox active="false" anonid="searchTutorIcon" hidden="true">
                        <xul:image onclick="if (event.button === 0) switchSearchTutor(true);"/>
                    </xul:hbox>
                    <xul:hbox class="searchSettings" onclick="if (event.button === 0) _openEngineManagerDialog();">
                        <xul:image/>
                        <xul:label value="&wgt.smartbox.searchSettings;"/>
                    </xul:hbox>
                </xul:hbox>
            </xul:hbox>
            <xul:vbox class="searchTutorBox" hidden="true"/>
        </content>

        <implementation>
            <field name="mOmniboxModule" readonly="true">gURLBar._yaOmniboxModule</field>
            <field name="api" readonly="true">this.mOmniboxModule.api</field>

            <field name="mSearchProviders" readonly="true">
                document.getAnonymousElementByAttribute(this, "anonid", "searchProviders");
            </field>

            <field name="mRestoreDefaultEngine" readonly="true">
                document.getAnonymousElementByAttribute(this, "anonid", "restoreDefaultEngine");
            </field>

            <field name="mSearchSettings" readonly="true">
                document.getAnonymousElementByAttribute(this, "class", "searchSettings");
            </field>

            <field name="mSearchTutorIcon" readonly="true">
                document.getAnonymousElementByAttribute(this, "anonid", "searchTutorIcon");
            </field>

            <field name="mSearchTutorBox" readonly="true">
                document.getAnonymousElementByAttribute(this, "class", "searchTutorBox");
            </field>

            <constructor><![CDATA[this.mOmniboxModule.onDelayedInit(this.constructorEx.bind(this));]]></constructor>

            <method name="constructorEx">
                <body><![CDATA[this.setAttribute("data-os",this.api.Environment.os.name);
this.recalculateSearchTutorVisibility();
this.wrapVisualModification(this,"switchSearchTutor");
this.wrapVisualModification(this,"constructEnginesList");
this.wrapVisualModification(this,"_showOtherSearches");]]></body>
            </method>

            
            <method name="wrapVisualModification">
                <parameter name="aThisObject"/>
                <parameter name="aMethod"/>
                <body><![CDATA[var originalMethod = aThisObject[aMethod];
aThisObject[aMethod] = (function _wrapVisualModification() {
this.style.minHeight = "";
var result = originalMethod.apply(aThisObject,arguments);
this.style.minHeight = this.getBoundingClientRect().height + "px";
return result;
}
).bind(this);]]></body>
            </method>

            <method name="switchSearchTutor">
                <parameter name="aManual"/>
                <body><![CDATA[if (aManual)
{
this.mOmniboxModule.setStaticPref("tutor.clicked",true);
this.mSearchTutorBox.mAutoShow = false;
}

var hidden = ! this.mSearchTutorBox.hidden;
this.mSearchTutorIcon.setAttribute("active",! hidden);
if (! hidden)
this.mSearchTutorBox.open();
this.mSearchTutorBox.hidden = hidden;]]></body>
            </method>

            <method name="recalculateSearchTutorVisibility">
                <body><![CDATA[if (! this.mOmniboxModule.canShowTutorial)
return;
if (this.mOmniboxModule.currentEngineIsBranded)
{
this.mSearchTutorIcon.hidden = false;
if ("autoOpen" in this.mSearchTutorBox)
this.mSearchTutorBox.autoOpen();
}
else
{
this.mSearchTutorIcon.hidden = true;
}
]]></body>
            </method>

            <method name="updateOnPopupShowing">
                <body><![CDATA[if ("updateOnPopupShowing" in this.mSearchTutorBox)
{
this.mSearchTutorBox.updateOnPopupShowing();
this.mSearchTutorBox.autoOpen();
}

this.constructEnginesList();]]></body>
            </method>

            <method name="constructEnginesList">
                <body><![CDATA[this._clearEnginesList();
var boxRect = this.parentNode.getBoundingClientRect();
var settingsRect = this.mSearchSettings.getBoundingClientRect();
this.mSearchProviders.style.width = boxRect.width - settingsRect.width - 42 + "px";
var hiddenNodes = [];
var current = this.mOmniboxModule.currentEngineName;
var visibleEngines = this.mOmniboxModule.getVisibleEnginesSorted();
var defaultEngineName = visibleEngines[0].engine.name;
var restoreDefaultEngineLabel = document.getAnonymousElementByAttribute(this,"anonid","restoreDefaultEngineLabel");
restoreDefaultEngineLabel.value = restoreDefaultEngineLabel.value.replace("{providerName}",defaultEngineName);
if (current === defaultEngineName || current === this.mOmniboxModule.acceptedDefaultEngineName)
{
this.mRestoreDefaultEngine.hidden = true;
}
else
{
this.mRestoreDefaultEngine.hidden = false;
}

const MSECS_IN_DAY = 60 * 60 * 24 * 1000;
visibleEngines.forEach(function (item, index) {
var name = item.engine.name;
var url = item.engine.searchForm;
var isCurrent = current === name;
var newItem = this._createNewEngineItem(name,url,isCurrent);
if (index < 3 || isCurrent || item.usageData.mounthVisits > 2 || Math.abs(Date.now() - item.usageData.lastUsedTime) < MSECS_IN_DAY)
{
this.mSearchProviders.appendChild(newItem);
}
else
{
newItem.hidden = true;
hiddenNodes.push(newItem);
}

}
,this);
if (hiddenNodes.length > 0)
{
hiddenNodes.forEach(function (node) this.appendChild(node),this.mSearchProviders);
let otherItems = document.createElement("hbox");
otherItems.setAttribute("class","button-more");
let label = document.createElement("label");
label.setAttribute("value","...");
otherItems.appendChild(label);
let that = this;
otherItems.onclick = function (e) {
that._showOtherSearches();
this.hidden = true;
}
;
this.mSearchProviders.appendChild(otherItems);
}

this.recalculateSearchTutorVisibility();]]></body>
            </method>

            <method name="_clearEnginesList">
                <body><![CDATA[var box = this.mSearchProviders;
while (box.firstChild) box.removeChild(box.firstChild);]]></body>
            </method>

            <method name="_openEngineManagerDialog">
                <body><![CDATA[window.openDialog(this.api.Package.resolvePath("/native/engineManager/dialog.xul"),"","chrome,dialog,modal,centerscreen",this.mOmniboxModule);]]></body>
            </method>

            <method name="_showOtherSearches">
                <body><![CDATA[Array.slice(this.mSearchProviders.querySelectorAll(".engine-item")).forEach(function (n) n.hidden = false);
this.style.minHeight = this.getBoundingClientRect().height + "px";]]></body>
            </method>

            <method name="_createNewEngineItem">
                <parameter name="engineName"/>
                <parameter name="engineUrl"/>
                <parameter name="current"/>
                <body><![CDATA[var hbox = document.createElement("hbox");
hbox.setAttribute("class","engine-item" + (current ? " selected" : ""));
var label = document.createElement("label");
label.setAttribute("class","ya-se-label");
label.setAttribute("value",engineName);
hbox.setAttribute("engine-id",engineName);
hbox.setAttribute("engine-url",engineUrl);
hbox.appendChild(label);
return hbox;]]></body>
            </method>

            <method name="_restoreDefaultEngine">
                <body><![CDATA[this.mOmniboxModule.restoreDefaultEngine();
this.constructEnginesList();]]></body>
            </method>

            <method name="_acceptDefaultEngine">
                <body><![CDATA[this.mOmniboxModule.acceptCurrentEngineAsDefault();
this.constructEnginesList();]]></body>
            </method>
        </implementation>

        <handlers>
            <handler button="0" event="click"><![CDATA[var target = event.originalTarget;
while (target && target !== this && ! target.hasAttribute("engine-id")) target = target.parentNode;
if (! target)
return;
var engineId = target.getAttribute("engine-id");
if (! engineId)
return;
var engineUrl = target.getAttribute("engine-url");
var currentUrl = gBrowser.mCurrentBrowser.contentDocument.location.href.replace(/\/$/,"");
var currentURIScheme = gBrowser.selectedTab.linkedBrowser.currentURI.scheme;
var schemeRegExp = new RegExp("^" + currentURIScheme);
var addressBarUrl = gURLBar.value;
var compareUrl = schemeRegExp.test(addressBarUrl) ? addressBarUrl : currentURIScheme + "://" + addressBarUrl;
if (currentUrl === compareUrl)
{
gBrowser.mCurrentBrowser.contentDocument.location.href = engineUrl;
}
else
{
let selectionController = gURLBar.editor.selectionController;
let selection = selectionController.getSelection(selectionController.SELECTION_NORMAL);
let nullWidthSpace = new RegExp(String.fromCharCode(8203), "g");
let selectedText = selection.toString().replace(nullWidthSpace,"").trim();
if (selectedText.length)
{
gURLBar.value = gURLBar.value.replace(selectedText,"").replace(nullWidthSpace,"").trim();
}

let callSearchEngine = ! ! (! gURLBar.value.length && selectedText.length);
if (! callSearchEngine)
{
compareUrl = schemeRegExp.test(gURLBar.value) ? gURLBar.value : currentURIScheme + "://" + gURLBar.value;
callSearchEngine = compareUrl === currentUrl;
}

if (callSearchEngine)
{
try {
let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
let yaReferrerURI = ioService.newURI(this.mOmniboxModule.brandingData.searchSite,null,null);
gBrowser.selectedTab = gBrowser.addTab(engineUrl,yaReferrerURI);
}
catch (e) {
Cu.reportError(e);
}

}
else
{
let current = this.mOmniboxModule.currentEngineName;
this.mOmniboxModule.currentEngineName = engineId;
gURLBar.handleCommand();
this.mOmniboxModule.recordCurrentEngineUsage();
this.mOmniboxModule.currentEngineName = current;
}

}

this.parentNode.hidePopup();]]></handler>
        </handlers>
    </binding>

    <binding extends="chrome://browser/content/urlbarBindings.xml#urlbar-rich-result-popup" id="popup">
        <resources>
            <stylesheet src="panel.css"/>
        </resources>

        <implementation>

            <field name="api" readonly="true">gURLBar._yaOmniboxModule.api</field>

            <field name="mPopupId" readonly="true">"yaOmniboxOtherSearchesPopup"</field>

            <constructor><![CDATA[this._constructSearchEnginesList();
this.height = "";
var originalOnPopupClick = this.onPopupClick.toSource();
var strForInject1 = "                     let yaReferrerURI = null;                     if (this.selectedIndex != null && this.selectedIndex != -1) {                         let navType = controller.getStyleAt(this.selectedIndex);                         if (/(^|\\s)ya(Super)?NavigationSuggest($|\\s)/.test(navType)) {                             let iOService = Cc[\"@mozilla.org/network/io-service;1\"].getService(Ci.nsIIOService);                             yaReferrerURI = iOService.newURI(\"http://www.yandex.ru\", null, null);                         }                     }\n";
var strForInject2 = "                     let (action = this.mInput._yaParseActionURL(url)) {                         if (action && action.actionurl) {                             url = action.actionurl;                         }                     }\n";
originalOnPopupClick = Function("return " + originalOnPopupClick.replace(/(\.nsIAutoCompleteController\);)/,"$1 " + strForInject1).replace(/(controller\.handleEnter)/,"gURLBar._yaLastSelectedIndex = this.selectedIndex;\n $1").replace(/(this\.closePopup)/,strForInject2 + " $1").replace(/(openUILink\(url, aEvent)/,"$1, false, false, false, null, yaReferrerURI"))();
this.onPopupClick = function onPopupClick() {
gURLBar._yaInfoCollector.metric = "mouse";
gURLBar._yaProcessInput();
gURLBar._yaUpdateActionIcon();
return originalOnPopupClick.apply(this,arguments);
}
;
var originalInvalidate = this.invalidate;
this.invalidate = function _invalidate() {
gURLBar.onSearchComplete();
return originalInvalidate.apply(this,arguments);
}
;]]></constructor>

            <method name="_constructSearchEnginesList">
                <body><![CDATA[var footer = document.createElement("vbox");
footer.style.MozBinding = "url(" + this.api.Package.resolvePath("/native/bindings.xbl#popup-footer") + ")";
this.appendChild(footer);]]></body>
            </method>

            <method name="_yaUpdateActionIcon">
                <body><![CDATA[setTimeout(function (me) {
me.mInput && "_yaUpdateActionIcon" in me.mInput && me.mInput._yaUpdateActionIcon();
}
,0,this);]]></body>
            </method>
        </implementation>

        <handlers>
            <handler event="popupshowing"><![CDATA[if (event.target != this)
return;
var input = this.mInput;
if (! input)
return;
var startElement = document.getElementById("identity-box");
var marginLeft = Math.max(0,startElement && startElement.boxObject.x - input.boxObject.x);
this.style.marginLeft = marginLeft + "px";
var inputRect = input.getBoundingClientRect();
var popupWidth = inputRect.width;
if (popupWidth < 630)
{
let docRect = document.documentElement.getBoundingClientRect();
popupWidth = Math.min(732,docRect.right - inputRect.left) - 32;
}

popupWidth = popupWidth - marginLeft + "px";
this.style.minWidth = popupWidth;
this.style.maxWidth = popupWidth;
var footer = this.lastChild;
footer && footer.updateOnPopupShowing();]]></handler>

            <handler action="if (event.target == this) this.style.minWidth = '';" event="popuphidden"/>

            <handler action="this._yaUpdateActionIcon()" event="popuphiding"/>

            <handler action="this._yaUpdateActionIcon()" event="select"/>

            
            <handler action="event.stopPropagation();" event="mousemove" phase="capturing"/>

            
            <handler event="mousedown" phase="capturing"><![CDATA[if (event.button == 2)
return;
var target = event.originalTarget;
while (target && target.localName != "richlistitem") target = target.parentNode;
if (! target)
return;
var rc = Array.indexOf(target.parentNode.childNodes,target);
if (rc != this.selectedIndex)
this.selectedIndex = rc;]]></handler>
        </handlers>
    </binding>

    <binding extends="chrome://global/content/bindings/autocomplete.xml#autocomplete-richlistitem" id="autocomplete-richlistitem">
        <content equalsize="always" flex="1">
            <xul:hbox align="center" class="ac-url-box" flex="1">
                <xul:image anonid="type-image" class="ac-type-icon"/>
                <xul:spacer class="ac-site-icon"/>
                <xul:image class="ac-action-icon"/>
                <xul:hbox align="center" anonid="url-box" class="ac-url" flex="1">
                    <xul:description anonid="url" class="ac-normal-text ac-url-text" xbl:inherits="selected type"/>
                    <xul:description anonid="action" class="ac-normal-text ac-action-text" xbl:inherits="selected type"/>
                    <xul:description anonid="ya-gotosearch-label" class="ac-normal-text" xbl:inherits="selected,xbl:text=yaGotoSearchLabel"/>
                </xul:hbox>
                <xul:label anonid="url-overflow-ellipsis" class="ac-ellipsis-after ac-url-text" xbl:inherits="selected"/>
            </xul:hbox>
            <xul:hbox align="center" class="ac-title-box" flex="1">
                <xul:image class="ac-site-icon" hidden="true" xbl:inherits="src=image"/>
                <xul:hbox anonid="title-box" class="ac-title" flex="1">
                    <xul:description anonid="title" class="ac-normal-text" xbl:inherits="selected"/>
                    <xul:description anonid="ya-switchtab-label" class="ac-normal-text" xbl:inherits="selected">&#160;&#8212;&#160;&wgt.smartbox.action.switchToTab.label;</xul:description>
                </xul:hbox>
                <xul:label anonid="title-overflow-ellipsis" class="ac-ellipsis-after" xbl:inherits="selected"/>
                <xul:label anonid="ya-type-debug" xbl:inherits="selected,value=type"/>
                <xul:hbox align="center" anonid="extra-box" class="ac-extra" hidden="true">
                    <xul:image class="ac-result-type-tag"/>
                    <xul:label class="ac-normal-text" xbl:inherits="selected" value=":"/>
                    <xul:description anonid="extra" class="ac-normal-text" xbl:inherits="selected"/>
                </xul:hbox>
            </xul:hbox>
        </content>

        <implementation>
            <field name="_acTitleBox">document.getAnonymousElementByAttribute(this, "class", "ac-title-box")</field>

            <method name="_getSearchTokens">
                <parameter name="aSearch"/>
                <body><![CDATA[var search = aSearch.toLowerCase();
if (aSearch.length > 1)
{
let alternate = gURLBar._yaOmniboxModule.OmniBox.getSwitchedLayout(aSearch);
if (alternate)
{
alternate = alternate.toLowerCase();
if (alternate !== search)
search += " " + alternate;
}

}

return search.split(/\s+/).filter(function (s) ! ! s);]]></body>
            </method>

            <method name="_getUnescapedText">
                <parameter name="aText"/>
                <body><![CDATA[if (! /^moz\-action:yaaction\-/.test(aText) && /%[A-F0-9]{2}/.test(aText))
{
let unescapedURL = Cc["@mozilla.org/intl/texttosuburi;1"].getService(Ci.nsITextToSubURI).unEscapeURIForUI("windows-1251",aText);
if (/[А-яЁ]/i.test(unescapedURL))
return unescapedURL;
}

return aText;]]></body>
            </method>

            <constructor><![CDATA[this.setAttribute("yaOS",gURLBar._yaOmniboxModule.api.Environment.os.name);
var originalBoundaryIndices = this._getBoundaryIndices;
this._getBoundaryIndices = function _getBoundaryIndices(aText, aSearchTokens) {
var boundaryIndices = originalBoundaryIndices.apply(this,arguments);
var urlEngine = gURLBar._yaOmniboxModule && gURLBar._yaOmniboxModule.OmniBox.URLEngine;
if (urlEngine)
{
let res = [boundaryIndices[0]];
for (let i = 1, len = boundaryIndices.length;i < len;i = i + 2) {
if (! urlEngine.aroundPillarPoint(aText,boundaryIndices[i]))
continue;
res.push(boundaryIndices[i]);
res.push(boundaryIndices[i + 1]);
}

res.push(boundaryIndices[boundaryIndices.length - 1]);
boundaryIndices = res;
}

return boundaryIndices;
}
;
var originalSetUpDescription = this._setUpDescription;
this._setUpDescription = function _setUpDescription(aDescriptionElement, aText, aNoEmphasis) {
var text = aText;
switch (aDescriptionElement) {
case this._title:
{
let title = this.getAttribute("title");
if (! title || text == this.getAttribute("url"))
{
text = "";
}
else
{
text = title;
}

break;
}

case this._action:
{
let url = this.getAttribute("url");
if (/^moz\-action:yaaction\-/.test(url))
{
let parts = url.split("_yaacsep_");
if (parts.length)
text = parts[1];
}
else
if (/^moz\-action:switchtab,/.test(url))
{
let [, , param] = url.match(/^moz-action:([^,]+),(.*)$/);
text = param.replace(/^(https?|ftp):\/\//,"").replace(/\/$/,"");
text = this._getUnescapedText(text);
}

break;
}

case this._url:
{
text = this._getUnescapedText(this.getAttribute("url"));
break;
}

}

this.setAttribute("yaGotoSearchLabel","\u00a0\u2014\u00a0" + gURLBar._yaOmniboxModule.getSearchLabel(gURLBar.value));
var tmpImageReplacer = "@@@@@@" + Date.now() + "@@@@@@";
var imageHTMLText;
text = text.replace(/<img data\-type='(weather|traffic)' src='(http|xb):\/\/[^']+'\/>/,function (s) {
imageHTMLText = s;
return tmpImageReplacer;
}
);
originalSetUpDescription.apply(this,[aDescriptionElement, text, false]);
imageHTMLText && Array.forEach(aDescriptionElement.childNodes,function (el) {
var parts = el.textContent.split(tmpImageReplacer);
if (parts.length != 2)
return;
var imagePart = document.createElementNS("http://www.w3.org/1999/xhtml","span");
imagePart.innerHTML = imageHTMLText;
var span = document.createElementNS("http://www.w3.org/1999/xhtml","span");
span.appendChild(document.createTextNode(parts[0]));
span.appendChild(imagePart);
span.appendChild(document.createTextNode(parts[1]));
el.parentNode.replaceChild(span,el);
}
);
this._titleBox.tooltipText = "";
this._urlBox.tooltipText = "";
}
;
this._adjustAcItem();]]></constructor>
        </implementation>
    </binding>
</bindings>
