Context Search( Firefox24+ )
Автор: bunda1
Версия: от 19.12.2015
Описание: код заменяет стандартный пункт контекстного меню страницы для поиска в текущем поисковике на новый пункт который открывает подменю со всеми установленными поисковиками и позволяет выбрать поисковик в котором вы хотите искать выделенный текст.

Клики на пункте контекстного меню или на пункте подменю:
ЛКМ => Открыть поиск в новой активной вкладке,
ПКМ => Открыть поиск в новой фоновой вкладке.

Скриншот:
http://i66.fastpic.ru/big/2015/1219/8f/60933131e32715a354b9be338cfafc8f.jpg

Использование: положите код в любую Custom Buttons кнопку, в инициализацию. Не обязательно создавать новую CB кнопку, можно использовать уже существующую.

Выделить код

Код:

// Context Search, от 19.12.2015. ........................
((contextMenu, searchSelect, searchService)=> {
   searchSelect.collapsed = true; // удалить стандартный пункт меню для поиска
   
   
   // Создать новый пункт меню для поиска ....
   var menu = contextMenu.insertBefore(document.createElement('menu'), searchSelect);
   menu.setAttribute("class", "menu-iconic");
   addEventListener("popupshowing", (e)=> menu.hidden = searchSelect.hidden, false, contextMenu); 
      
   function setMenu() {  
      menu.engine = searchService.currentEngine;
      menu.setAttribute("label", "Искать в " + menu.engine.name + " или в ...");
      menu.setAttribute("image", menu.engine.iconURI.spec );
   };
   setMenu();

   
   // Создать подменю с поисковиками .... 
   var menuPopup = menu.appendChild(document.createElement("menupopup")); 
   menuPopup.setAttribute('style', 'overflow: scroll'); 

   function setItemsToMenuPopup(e) {
      menuPopup.textContent = "";      

      var engines = searchService.getVisibleEngines({});
      engines.forEach((engine)=> { 
         var mItem = document.createElement("menuitem");
         mItem.setAttribute("label", engine.name);
         mItem.setAttribute("class", "menuitem-iconic");
         mItem.setAttribute("src", engine.iconURI.spec);
         mItem.engine = engine;
         menuPopup.appendChild(mItem);
      })
   };  
   setItemsToMenuPopup();
   
   // установить действие для клика на меню и подменю
   menu.onmouseup =e=> {
      var background = (e.button == 0) ? false : true;
      var clip = gClipboard.read();
      goDoCommand('cmd_copy');
      setTimeout(()=> {
         contextMenu.hidePopup();
         var submission = e.target.engine.getSubmission(gClipboard.read(), null);
         gBrowser.loadOneTab(submission.uri.spec, null, null, submission.postData, background, false);
         gClipboard.write(clip);
      }, 0);
   };      
      
   
   // Наблюдатель за изменениями в поисковиках пересоздаёт меню и подменю .... 
   var getEngineModified = {
      observe:(subject, topic, data)=> {
         if ( /changed|removed|current/.test(data) ) { setMenu(), setItemsToMenuPopup() };             
      }
   };
   Services.obs.addObserver(getEngineModified, "browser-search-engine-modified", false);   
   
   
   // Удалять наблюдатели и меню, показать стандартный пункт ....
   addDestructor(()=> {
      menu.remove();            
      searchSelect.collapsed = false; 
      Services.obs.removeObserver(getEngineModified, "browser-search-engine-modified"); 
   });
      
})(document.getElementById("contentAreaContextMenu"), document.getElementById("context-searchselect"), Services.search);

Аналогичное Context Search-у дополнение есть и в виде джетпака (его установка не требует перезапуска браузера): Context Search RG.
+ в нём есть одна мелкая удобная фишка, что сам пункт меню из которого выпадает список со всеми поисковыми машинами - он кликабельный и отвечает за текущую выбранную в Панели поиска поисковую машину.

iDev.Pi пишет:

пункт меню из которого выпадает список со всеми поисковыми машинами - он кликабельный

Здесь также ;)
Есть такая проблема, если выделенное находится с правого края, то меню выбора поисковиков закрывает осн. меню.
http://img829.imageshack.us/img829/5599/image004uk.jpg
Было бы не плохо что-бы открывалось только при наведении курсора на стрелку или хотя бы не так быстро(~ 1.5-2 сек.), что бы успеть нажать на поиск по текущему поисковому плагину.

vitalii201 пишет:

Было бы не плохо что-бы открывалось только при наведении курсора на стрелку или хотя бы не так быстро(~ 1.5-2 сек.), что бы успеть нажать на поиск по текущему поисковому плагину.

измени в коде

Выделить код

Код:

this.menu._menuDelay = 300;

на

Выделить код

Код:

this.menu._menuDelay = 1000; 

или на

Выделить код

Код:

this.menu._menuDelay = 1500;

bunda1
А можно сделать без подменю, а что-бы сразу показывались поисковики и без надписи выделенного, сижу на старом, кем то переделанном без подменю расширении Context Search и всякий раз обновления просятся, а там уже с подменю, да и от расширения избавиться неплохо бы.

Как без подменю, объясни подробней.

bunda1 пишет:

Как без подменю, объясни подробней.

Выделяю слово, жму правую кнопку, и у меня сразу вместе с пунктами копировать, выделить и т.д., все поисковики, не надо еще открывать подпункт с поисковиками, у меня как-то так с самого начала было, привык, меньше телодвижений.

Если ты используешь кнопку CB Mouse Gestures то там есть жест RLRL - [Popup] Поиск текста в выбранном поисковике. Это практически аналог Context Search, попробуй.

bunda1 пишет:

Если ты используешь кнопку CB Mouse Gestures то там есть жест RLRL - [Popup] Поиск текста в выбранном поисковике. Это практически аналог Context Search, попробуй.

Попробовал, там выходит один поисковик, а у меня их с десяток для разных целей, надо дополнительно переключаться, получается еще более неудобнее чем с подменю, если трудоемко убрать подменю то ладно, буду дальше старым расширением пользоваться, пока не сломается в новых версиях лисы, что теперь поделаешь.

villa7 пишет:

Попробовал, там выходит один поисковик, а у меня их с десяток для разных целей, надо дополнительно переключаться, получается еще более неудобнее чем с подменю,

Попробуй FireGestures :: Дополнения Firefox, там весь список поисковиков выдаёт.

villa7 пишет:

Попробовал, там выходит один поисковик, а у меня их с десяток для разных целей

У меня этот жест выдаёт весь список поисковиков.

bunda1
'RLRL':{name:'[Popup]Search
Engines'

Всем спасибо за участие , добавил эту команду и стало то что нужно, до этого неправильно копировал из списка удаленных команд.


А еще такой вопрос,у знакомого ссылки на код кнопки кликабельны, а у меня нет, ставлю кнопки перетаскиванием в адресную строку. Скрипт текстовых ссылок Linkification стоит, если это от него зависит, или как.

LongLogin
Easy DragToGo+

У меня раньше стояло, сменил на кнопку Drag and go, и потом там нужно сначала выделить потом дернуть, а Linkification сразу клацнул и все, пока браузер не крашился, тьфу,тфу. Все равно спасибо.

LongLogin
Подозреваю что это

Kamui пишет:

LongLoginПодозреваю что это

Да, именно эту кнопку поставил.

LongLogin

LongLogin пишет:

всёже обращу внимание, что при большом кол-ве поисковиков, искать по вертикальному списку может оказаться крайне утомительно

Иеется ввиду Quick Search Bar?, я пробовал ставить, но у меня по правой кнопке вообще ни какие поисковики не появляются, может какие-то настройки поменять, а может на 15 лисе не работает.

bunda1
Данный код в свежей сборке Nightly не хочет работать:( . Можно ли как-нибудь вернуть ее функциональность?

villa7 пишет:

bunda1
А можно сделать без подменю, а что-бы сразу показывались поисковики и без надписи выделенного, сижу на старом, кем то переделанном без подменю расширении Context Search и всякий раз обновления просятся, а там уже с подменю, да и от расширения избавиться неплохо бы.

Без подменю есть расширение Context Search X
Там вручную отредактируешь параметр extensions.contextsearchx.menuItems в about:config и получишь столько пунктов меню с собственными названиями сколько тебе потребуется, стандартно есть только два или три пункта...

Griever обновил contextSearcher до версии 0.0.7

слегка русифицированный contextSearcher

Выделить код

Код:


// ==UserScript==
// @name contextSearcher.uc.js
// @namespace http://d.hatena.ne.jp/Griever/
// @description 右クリック→検索の強化
// @include main
// @compatibility Firefox 4
// @version 0.0.7
// @note 0.0.7 Изменен чтобы получить слово, даже на ссылку
// @note 0.0.7 Оптимизация приобретение слова
// @note 0.0.6 カタカナの正規表現のミスを修正
// @note 0.0.6 splitmenu をやめた(menu 部分をクリックして検索可能)
// @note 0.0.6 Mac でカーソル下の単語をうまく拾えてなかったらしいのを修正したかも
// @note 0.0.5 サブメニューを中クリックすると2回実行される問題を修正
// @note 0.0.5 メニューの検索エンジン名を非表示にした
// @note 0.0.5 カーソル下の単語の取得を調整
// @note 0.0.5 "・"をカタカナとして処理していたのを修正
// @note 0.0.4 アイコンの無い検索エンジンがあるとエラーになるのを修正
// ==/UserScript==
// http://f.hatena.ne.jp/Griever/20100918161044
// ホイールで既定のエンジン変更、サブメニューから他の検索エンジンの利用
// 右クリックの位置により選択文字列、カーソル下の単語を検索可能

if (window.contextSearcher) {
  window.contextSearcher.destroy();
  delete window.contextSearcher;
}

window.contextSearcher = {
  NEW_TAB: true,

  _regexp: {
    hiragana: "[\\u3040-\\u309F]+",
    katakana: "[\\u30A0-\\u30FA\\u30FC]+",
    kanji : "[\\u4E00-\\u9FA0]+",
    suuji : "[0-9_./,%-]+",
    eisu_han: "\\w[\\w\\-]*",
    eisu_zen: "[\\uFF41-\\uFF5A\\uFF21-\\uFF3A\\uFF10-\\uFF19]+",
    hankaku : "[\\uFF00-\\uFFEF]+",
    hangul : "[\\u1100-\\u11FF\\uAC00-\\uD7AF\\u3130-\\u318F]+",
  },

  get startReg() {
    let reg = {};
    for(let n in this._regexp) {
      reg[n] = new RegExp('^' + this._regexp[n]);
    }
    delete this.startReg;
    return this.startReg = reg;
  },
  get endReg() {
    let reg = {};
    for(let n in this._regexp) {
      reg[n] = new RegExp(this._regexp[n] + '$');
    }
    delete this.endReg;
    return this.endReg = reg;
  },
  getCharType: function(aChar) {
    var c = aChar.charCodeAt(0);
    //if (c >= 0x30 && c <= 0x39) return "suuji";
    if (c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A || c === 0x5F) return "eisu_han";
    if (c >= 0x30A0 && c <= 0x30FA || c === 0x30FC) return "katakana";
    if (c >= 0x3040 && c <= 0x309F) return "hiragana";
    if (c >= 0x4E00 && c <= 0x9FA0) return "kanji";
    if (c >= 0xFF41 && c <= 0x9F5A || c >= 0xFF21 && c <= 0xFF3A || c >= 0xFF10 && c <= 0xFF19) return "eisu_zen";
    if (c >= 0xFF00 && c <= 0xFFEF) return "hankaku";
    if (c >= 0x1100 && c <= 0x11FF || c >= 0xAC00 && c <= 0xD7AF || c >= 0x3130 && c <= 0x318F) return "hangul";
    return "";
  },

  searchText: '',
  searchEngines: [],
  init: function(){
    this.isMac = navigator.platform.indexOf("Mac") == 0;
    this.searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
    this.context = document.getElementById('contentAreaContextMenu');
    var searchselect = document.getElementById('context-searchselect');
    searchselect.style.display = 'none';

    this.menu = this.context.insertBefore(document.createElement('menu'), searchselect);
    this.menu.setAttribute('id', 'context-searcher');
    this.menu.setAttribute('class', 'menu-iconic');
    this.menu.setAttribute('accesskey', searchselect.accessKey);
    this.menu.setAttribute('onclick', 'if (event.target == this) { contextSearcher.command(event); closeMenus(this); }');

    this.popup = this.menu.appendChild( document.createElement('menupopup') );

    this.context.addEventListener('popupshowing', this, false);
    this.menu.addEventListener('DOMMouseScroll', this, false);
    gBrowser.mPanelContainer.addEventListener(this.isMac ? 'mousedown' : 'click', this, false);
    window.addEventListener('unload', this, false);
  },

  uninit: function() {
    this.context.removeEventListener('popupshowing', this, false);
    this.menu.removeEventListener('DOMMouseScroll', this, false);
    gBrowser.mPanelContainer.removeEventListener('click', this, false);
    gBrowser.mPanelContainer.removeEventListener('mousedown', this, false);
    window.removeEventListener('unload', this, false);
  },

  destroy: function(){
    this.uninit();
    document.getElementById('context-searchselect').style.removeProperty('display');
    var m = document.getElementById('context-searcher');
    if (m)
      m.parentNode.removeChild(m);
  },

  handleEvent: function(event) {
    if (this[event.type])
      this[event.type](event);
  },
  
  unload: function(e){
    this.uninit();
  },

  DOMMouseScroll: function(e) {
    if (this.searchEngines.length === 0)
      this.searchEngines = this.searchService.getVisibleEngines({});
    if (!this.searchEngines || this.searchEngines.length == 0)
      return;
    
    var index = this.searchEngines.indexOf(this.searchService.currentEngine);
// var newEngine = e.detail > 0?
// this.searchEngines[index+1] || this.searchEngines[0]:
// this.searchEngines[index-1] || this.searchEngines[this.searchEngines.length -1];
    var newEngine = e.detail > 0? this.searchEngines[index+1] : this.searchEngines[index-1];
    if (!newEngine)
      return;
    this.searchService.currentEngine = newEngine;
    this.setMenuitem();
  },

  command: function(e){
    var target = e.target;
    var engine = e.target.engine || this.menu.engine;

    var submission = engine.getSubmission(this.searchText, null);
    if (!submission)
      return;

    var newtab = this.NEW_TAB || e.button === 1 || e.shiftKey || e.ctrlKey;
    if (!newtab) {
      loadURI(submission.uri.spec, null, submission.postData, false);
    } else {
      gBrowser.selectedTab = gBrowser.addTab(submission.uri.spec, {
        postData: submission.postData,
        ownerTab: gBrowser.mCurrentTab,
      });
    }
  },

  click: function(event) {
    if (event.button === 2) {
      this._clickNode = event.rangeParent;
      this._clickOffset = event.rangeOffset;
      this._clientX = event.clientX;
    } else {
      this._clickNode = null;
      this._clickOffset = 0;
      this._clientX = 0;
    }
  },

  mousedown: function(event) {
    this.click(event);
  },

  setMenuitem: function() {
    var currentEngine = this.searchService.currentEngine;
    var l = this.searchText.length > 16? this.searchText.substr(0, 16) + '...' : this.searchText;
    this.menu.engine = currentEngine;
    this.menu.setAttribute('label', gNavigatorBundle.getFormattedString("contextMenuSearchText", [currentEngine.name, l]));
    //this.menu.setAttribute('label', 'Искать "' + l + '"');
    //this.menu.setAttribute('tooltiptext', currentEngine.name);
    if (currentEngine.iconURI)
      this.menu.style.listStyleImage = 'url("' + currentEngine.iconURI.spec + '")';
    else
      this.menu.style.removeProperty('list-style-image');
  },

  popupshowing: function(e){
    if (e.target != this.context) return;

    this.searchText =
      gContextMenu.isTextSelected? this.getBrowserSelection() :
      gContextMenu.onImage? gContextMenu.target.getAttribute('alt') :
      //gContextMenu.onLink? gContextMenu.linkText() :
      gContextMenu.onTextInput? this.getTextInputSelection() :
      this.getCursorPositionText();

    if (!this.searchText || !/\S/.test(this.searchText)) {
      this.menu.hidden = true;
      return;
    }
    if (this.searchText.length > 256)
      this.searchText = this.searchText.substr(0, 256);
    this.menu.hidden = false;
    
    if (!this.popup.hasChildNodes() || e.ctrlKey)
      this.createMenuitem();
    
    this.setMenuitem();
  },
  
  createMenuitem: function(){
    this.searchEngines = this.searchService.getVisibleEngines({});
    if (!this.searchEngines || this.searchEngines.length == 0)
      return;

    var f;
    while (f = this.popup.firstChild) {
      this.popup.removeChild(f);
    }

    this.menu.engine = this.searchService.currentEngine;
    if (this.menu.engine.iconURI)
      this.menu.style.listStyleImage = 'url("' + this.menu.engine.iconURI.spec + '")';
    else
      this.menu.style.removeProperty('list-style-image');
    for (var i = 0, s = this.searchEngines, l = s.length; i < l; i++) {
      var engine = s[i];
      var m = document.createElement('menuitem');
      m.setAttribute('label', engine.name);
      m.setAttribute('class', 'menuitem-iconic bookmark-item');
      if (engine.iconURI) {
        m.setAttribute('image', engine.iconURI.spec);
      }
      m.setAttribute('oncommand', 'contextSearcher.command(event);');
      m.setAttribute('onclick', 'checkForMiddleClick(this, event);');
      m.engine = engine;
      this.popup.appendChild(m);
    }
  },
  
  getBrowserSelection: function () {
    var win = document.commandDispatcher.focusedWindow;
    var sel = win.getSelection();
    var str = '';
    if (sel.isCollapsed)
      return str;

    for(var i = 0, l = sel.rangeCount; i < l; i++) {
      str += sel.getRangeAt(i) + ' ';
    }
    return str.replace(/^\s*|\s*$/g, '').replace(/\s+/g, ' ');
  },
  
  getTextInputSelection: function () {
    var elem = document.commandDispatcher.focusedElement;
    var str = elem.value.slice(elem.selectionStart, elem.selectionEnd);
    return str.replace(/^\s*|\s*$/g, '').replace(/\s+/g, ' ');
  },

  getCursorPositionText: function() {
    var node = this._clickNode;
    var offset = this._clickOffset;
    if (!node || node.nodeType !== Node.TEXT_NODE)
      return "";

    var text = node.nodeValue;

    // 文字の右半分をクリック時に次の文字を取得する対策
    var range = node.ownerDocument.createRange();
    range.setStart(node, offset);
    var rect = range.getBoundingClientRect();
    range.detach();
    if (rect.left >= this._clientX)
      offset--;

    if (!text[offset]) return "";
    var type = this.getCharType(text[offset]);
    if (!type) return "";

    var mae = text.substr(0, offset);
    var ato = text.substr(offset); // text[offset] はこっちに含まれる
    var ato_word = (this.startReg[type].exec(ato) || [""])[0];
    var str = this.endReg[type].test(mae) ? RegExp.lastMatch + ato_word : ato_word;

    if (str.length === 1) {
      if (type === "kanji") {
        if (this.startReg["hiragana"].test(ato.substr(ato_word.length)))
          str += RegExp.lastMatch;
      } else {
        return "";
      }
    }
    
    return str;
  },
  
  log: function() {
    Application.console.log("[contextSearcher] " + Array.slice(arguments));
  }
}

window.contextSearcher.init();

Обновлённый и русифицированный вариант

contextSearcher версии 0.0.8

Выделить код

Код:

// ==UserScript==
// @name           contextSearcher.uc.js
// @namespace      http://d.hatena.ne.jp/Griever/
// @description    右クリック→検索の強化
// @include        main
// @compatibility  Firefox 4
// @version        0.0.8
// @note           0.0.8 Firefox 19 で入力欄で使えなくなったのを修正
// @note           0.0.8 NEW_TAB の初期値を browser.search.openintab にした
// @note           0.0.7 リンク上でも単語を取得するように変更
// @note           0.0.7 単語の取得を効率化
// @note           0.0.6 カタカナの正規表現のミスを修正
// @note           0.0.6 splitmenu をやめた(menu 部分をクリックして検索可能)
// @note           0.0.6 Mac でカーソル下の単語をうまく拾えてなかったらしいのを修正したかも
// @note           0.0.5 サブメニューを中クリックすると2回実行される問題を修正
// @note           0.0.5 メニューの検索エンジン名を非表示にした
// @note           0.0.5 カーソル下の単語の取得を調整
// @note           0.0.5 "・"をカタカナとして処理していたのを修正
// @note           0.0.4 アイコンの無い検索エンジンがあるとエラーになるのを修正
// ==/UserScript==
// http://f.hatena.ne.jp/Griever/20100918161044
// ホイールで既定のエンジン変更、サブメニューから他の検索エンジンの利用
// 右クリックの位置により選択文字列、カーソル下の単語を検索可能

if (window.contextSearcher) {
  window.contextSearcher.destroy();
  delete window.contextSearcher;
}

window.contextSearcher = {
  NEW_TAB: Services.prefs.getBoolPref("browser.search.openintab"),

  _regexp: {
    hiragana: "[\\u3040-\\u309F]+",
    katakana: "[\\u30A0-\\u30FA\\u30FC]+",
    kanji   : "[\\u4E00-\\u9FA0]+",
    suuji   : "[0-9_./,%-]+",
    eisu_han: "\\w[\\w\\-]*",
    eisu_zen: "[\\uFF41-\\uFF5A\\uFF21-\\uFF3A\\uFF10-\\uFF19]+",
    hankaku : "[\\uFF00-\\uFFEF]+",
    hangul  : "[\\u1100-\\u11FF\\uAC00-\\uD7AF\\u3130-\\u318F]+",
  },

  get startReg() {
    let reg = {};
    for(let n in this._regexp) {
      reg[n] = new RegExp('^' + this._regexp[n]);
    }
    delete this.startReg;
    return this.startReg = reg;
  },
  get endReg() {
    let reg = {};
    for(let n in this._regexp) {
      reg[n] = new RegExp(this._regexp[n] + '$');
    }
    delete this.endReg;
    return this.endReg = reg;
  },
  getCharType: function(aChar) {
    var c = aChar.charCodeAt(0);
    //if (c >= 0x30 && c <= 0x39) return "suuji";
    if (c >= 0x30 && c <= 0x39 || c >= 0x41 && c <= 0x5A || c >= 0x61 && c <= 0x7A || c === 0x5F) return "eisu_han";
    if (c >= 0x30A0 && c <= 0x30FA || c === 0x30FC) return "katakana";
    if (c >= 0x3040 && c <= 0x309F) return "hiragana";
    if (c >= 0x4E00 && c <= 0x9FA0) return "kanji";
    if (c >= 0xFF41 && c <= 0x9F5A || c >= 0xFF21 && c <= 0xFF3A || c >= 0xFF10 && c <= 0xFF19) return "eisu_zen";
    if (c >= 0xFF00 && c <= 0xFFEF) return "hankaku";
    if (c >= 0x1100 && c <= 0x11FF || c >= 0xAC00 && c <= 0xD7AF || c >= 0x3130 && c <= 0x318F) return "hangul";
    return "";
  },

  searchText: '',
  searchEngines: [],
  init: function(){
    this.isMac = navigator.platform.indexOf("Mac") == 0;
    this.searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
    this.context = document.getElementById('contentAreaContextMenu');
    var searchselect = document.getElementById('context-searchselect');
    searchselect.style.display = 'none';

    this.menu = this.context.insertBefore(document.createElement('menu'), searchselect);
    this.menu.setAttribute('id', 'context-searcher');
    this.menu.setAttribute('class', 'menu-iconic');
    this.menu.setAttribute('accesskey', searchselect.accessKey);
    this.menu.setAttribute('onclick', 'if (event.target == this) { contextSearcher.command(event); closeMenus(this); }');

    this.popup = this.menu.appendChild( document.createElement('menupopup') );

    this.context.addEventListener('popupshowing', this, false);
    this.menu.addEventListener('DOMMouseScroll', this, false);
    gBrowser.mPanelContainer.addEventListener(this.isMac ? 'mousedown' : 'click', this, false);
    window.addEventListener('unload', this, false);
  },

  uninit: function() {
    this.context.removeEventListener('popupshowing', this, false);
    this.menu.removeEventListener('DOMMouseScroll', this, false);
    gBrowser.mPanelContainer.removeEventListener('click', this, false);
    gBrowser.mPanelContainer.removeEventListener('mousedown', this, false);
    window.removeEventListener('unload', this, false);
  },

  destroy: function(){
    this.uninit();
    document.getElementById('context-searchselect').style.removeProperty('display');
    var m = document.getElementById('context-searcher');
    if (m)
      m.parentNode.removeChild(m);
  },

  handleEvent: function(event) {
    if (this[event.type])
      this[event.type](event);
  },
  
  unload: function(e){
    this.uninit();
  },

  DOMMouseScroll: function(e) {
    if (this.searchEngines.length === 0)
      this.searchEngines = this.searchService.getVisibleEngines({});
    if (!this.searchEngines || this.searchEngines.length == 0)
      return;
    
    var index = this.searchEngines.indexOf(this.searchService.currentEngine);
//    var newEngine = e.detail > 0?
//      this.searchEngines[index+1] || this.searchEngines[0]:
//      this.searchEngines[index-1] || this.searchEngines[this.searchEngines.length -1];
    var newEngine = e.detail > 0? this.searchEngines[index+1] : this.searchEngines[index-1];
    if (!newEngine)
      return;
    this.searchService.currentEngine = newEngine;
    this.setMenuitem();
  },

  command: function(e){
    var target = e.target;
    var engine = e.target.engine || this.menu.engine;

    var submission = engine.getSubmission(this.searchText, null);
    if (!submission)
      return;

    var where = whereToOpenLink(e);
    if (this.NEW_TAB && where === 'current' || where === 'save')
      where = 'tab';

    openLinkIn(submission.uri.spec, where, {
      postData: submission.postData,
      relatedToCurrent: true
    });
  },

  click: function(event) {
    if (event.button === 2) {
      this._clickNode = event.rangeParent;
      this._clickOffset = event.rangeOffset;
      this._clientX = event.clientX;
    } else {
      this._clickNode = null;
      this._clickOffset = 0;
      this._clientX = 0;
    }
  },

  mousedown: function(event) {
    this.click(event);
  },

  setMenuitem: function() {
    var currentEngine = this.searchService.currentEngine;
    var l = this.searchText.length > 16? this.searchText.substr(0, 16) + '...' : this.searchText;
    this.menu.engine = currentEngine;
    //this.menu.setAttribute('label', gNavigatorBundle.getFormattedString("contextMenuSearchText", [currentEngine.name, l]));
    this.menu.setAttribute('label', 'Искать "' + l + '"' +' в ' + currentEngine.name);
    this.menu.setAttribute('tooltiptext', currentEngine.name);
       this.menu.setAttribute('tooltiptext', currentEngine.name);
    if (currentEngine.iconURI)
      this.menu.style.listStyleImage = 'url("' + currentEngine.iconURI.spec + '")';
    else 
      this.menu.style.removeProperty('list-style-image');
  },

  popupshowing: function(e){
    if (e.target != this.context) return;

    this.searchText = 
      gContextMenu.onTextInput? this.getTextInputSelection() :
      gContextMenu.isTextSelected? this.getBrowserSelection() :
      gContextMenu.onImage? gContextMenu.target.getAttribute('alt') :
      //gContextMenu.onLink? gContextMenu.linkText() :
      this.getCursorPositionText();

    if (!this.searchText || !/\S/.test(this.searchText)) {
      this.menu.hidden = true;
      return;
    }
    if (this.searchText.length > 256)
      this.searchText = this.searchText.substr(0, 256);
    this.menu.hidden = false;
    
    if (!this.popup.hasChildNodes() || e.ctrlKey)
      this.createMenuitem();
    
    this.setMenuitem();
  },
  
  createMenuitem: function(){
    this.searchEngines = this.searchService.getVisibleEngines({});
    if (!this.searchEngines || this.searchEngines.length == 0)
      return;

    var f;
    while (f = this.popup.firstChild) {
      this.popup.removeChild(f);
    }

    this.menu.engine = this.searchService.currentEngine;
    if (this.menu.engine.iconURI)
      this.menu.style.listStyleImage = 'url("' + this.menu.engine.iconURI.spec + '")';
    else 
      this.menu.style.removeProperty('list-style-image');
    for (var i = 0, s = this.searchEngines, l = s.length; i < l; i++) {
      var engine = s[i];
      var m = document.createElement('menuitem');
      m.setAttribute('label', engine.name);
      m.setAttribute('class', 'menuitem-iconic bookmark-item');
      if (engine.iconURI) {
        m.setAttribute('image', engine.iconURI.spec);
      }
      m.setAttribute('oncommand', 'contextSearcher.command(event);');
      m.setAttribute('onclick', 'checkForMiddleClick(this, event);');
      m.engine = engine;
      this.popup.appendChild(m);
    }
  },
  
  getBrowserSelection: function () {
    var win = document.commandDispatcher.focusedWindow;
    var sel = win.getSelection();
    var str = '';
    if (sel.isCollapsed)
      return str;

    for(var i = 0, l = sel.rangeCount; i < l; i++) {
      str += sel.getRangeAt(i) + ' ';
    }
    return str.replace(/^\s*|\s*$/g, '').replace(/\s+/g, ' ');
  },
  
  getTextInputSelection: function () {
    var elem = document.commandDispatcher.focusedElement;
    var str = elem.value.slice(elem.selectionStart, elem.selectionEnd);
    return str.replace(/^\s*|\s*$/g, '').replace(/\s+/g, ' ');
  },

  getCursorPositionText: function() {
    var node = this._clickNode;
    var offset = this._clickOffset;
    if (!node || node.nodeType !== Node.TEXT_NODE)
      return "";

    var text = node.nodeValue;

    // 文字の右半分をクリック時に次の文字を取得する対策
    var range = node.ownerDocument.createRange();
    range.setStart(node, offset);
    var rect = range.getBoundingClientRect();
    range.detach();
    if (rect.left >= this._clientX)
      offset--;

    if (!text[offset]) return "";
    var type = this.getCharType(text[offset]);
    if (!type) return "";

    var mae = text.substr(0, offset);
    var ato = text.substr(offset); // text[offset] はこっちに含まれる
    var ato_word = (this.startReg[type].exec(ato) || [""])[0];
    var str = this.endReg[type].test(mae) ? RegExp.lastMatch + ato_word : ato_word;

    if (str.length === 1) {
      if (type === "kanji") {
        if (this.startReg["hiragana"].test(ato.substr(ato_word.length)))
          str += RegExp.lastMatch;
      } else {
        return "";
      }
    }
    
    return str;
  },
  
  log: function() {
    Application.console.log("[contextSearcher] " + Array.slice(arguments));
  }
}

window.contextSearcher.init();

PEAKTOP
См. пост №19( у меня работает бесперебойно на [firefox] 23, 24, 25, 26 и [nightly] 27 )

SendInfo, в том-то и дело, что код из поста №19 не совсем корректно работал - не отображал текст в пункте контекстного меню http://images.vfl.ru/ii/1379618847/15c6a0d0/3136439.png 
В моём предыдущем посте код с исправлением этого недоразумения.


Попутно два вопроса к знатокам:
1. Как зафиксировать этот пункт в определённом месте контекстного меню, а именно на второй позиции сверху?
2. Как заставить скрипт по умолчанию использовать поисковую систему не ту, что сейчас указана в панели поиска? Сейчас у меня в "панели поиска" задана Wikipedia, соответственно в пункте контекстного меню тоже будет она, а мне надо, чтобы там был Google (для справки он у меня первый в списке поисковых систем в панели поиска).  Т.е., независимо от того, какая поисковая система указана в "панели поиска", скрипт должен подставлять  в пункт меню Google.

PEAKTOP пишет:

2. Как заставить скрипт по умолчанию использовать поисковую систему не ту, что сейчас указана в панели поиска? Сейчас у меня в "панели поиска" задана Wikipedia, соответственно в пункте контекстного меню тоже будет она, а мне надо, чтобы там был Google (для справки он у меня первый в списке поисковых систем в панели поиска).  Т.е., независимо от того, какая поисковая система указана в "панели поиска", скрипт должен подставлять  в пункт меню Google.

Если по простому :):
http://img407.imageshack.us/img407/8006/ybyc.jpg

Выделить код

Код:

// Context Search mini, от 21.09.2013. ................................
(function () {
   var searchSelect = document.getElementById('context-searchselect');  
   searchSelect.collapsed = true;

   
   var contextMenu = document.getElementById("contentAreaContextMenu");  
   var menu = contextMenu.insertBefore( document.createElement('menu'), searchSelect );
   menu.setAttribute("label", "Искать в Google или в ...");
   menu.setAttribute("class", "menu-iconic");
   menu.style.listStyleImage = 'url("https://www.google.lv/favicon.ico")';
   menu.setAttribute("onclick", "\
      if ( !!event.target.engine ) return;\
      gBrowser.loadOneTab('http://www.google.com/search?q=' + getBrowserSelection(), null, null, null, false, false);\
      setTimeout(function() { document.getElementById('contentAreaContextMenu').hidePopup() }, 0);\
   ");
   var observeStatus = new MutationObserver(function() {
          menu.hidden = searchSelect.hidden;          
   });
   observeStatus.observe( searchSelect, { attributes: true, attributeFilter: ["hidden"]  } );
   addDestructor(function() { contextMenu.removeChild( menu ); observeStatus.disconnect(); searchSelect.collapsed = false });   
   
   
   var menuPopup = menu.appendChild(document.createElement("menupopup"));
   var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService); 
   
   addEventListener('popupshowing', function(e) {
      menuPopup.textContent = "";      
      
      var engines = searchService.getVisibleEngines({});
      engines.forEach(function( engine ) {
         var mItem = document.createElement("menuitem");
         mItem.setAttribute("label", engine.name );
         mItem.setAttribute("class", "menuitem-iconic");
         mItem.setAttribute("src", engine.iconURI.spec );
         mItem.engine = engine;
         menuPopup.appendChild( mItem );
      });
      menuPopup.setAttribute("oncommand", "\
         var submission = event.target.engine.getSubmission( getBrowserSelection(), null );\
         gBrowser.loadOneTab( submission.uri.spec, null, null, submission.postData, false, false );\
      ");
   }, false, menu );  
      
})();

PEAKTOP пишет:

1. Как зафиксировать этот пункт в определённом месте контекстного меню, а именно на второй позиции сверху?

Выделить код

Код:

var menu = contextMenu.insertBefore( document.createElement('menu'), searchSelect );

Тут вместо searchSelect укажи пункт контекстного меню над которым пункт Искать в Google должен находится, например пункт Копировать:

Выделить код

Код:

document.getElementById('context-copy');

bunda1, БОЛЬШОЕ ПРЕБОЛЬШОЕ СПАСИБО!
Ещё одна просьба. Можешь добавить в текст пункта меню выделенное/искомое слово?
как здесь
http://images.vfl.ru/ii/1379777755/362931d4/3146601.png

PEAKTOP
Это если одно слово, а если ищешь фразу - или меню на весь экран расползётся или обрежется до "Программа..." в зависимости от реализации. Лично мне кажется, что это не принципиально.
bunda1
Всё работает, замечательно! Спасибо.
Context Search X дополнительно к списку моих поисков подключает поиск google последней строкой "Включает строку поиска выделенного текста на текущем сайте."
Чтобы из выделенного мной текста, например "поиск по сайту" получилась такая строка:

скрытый текст
https://www.google.com/search?q=%D0%BF%D0%BE%D0%B8%D1%81%D0%BA+%D0%BF%D0%BE+%D1%81%D0%B0%D0%B9%D1%82%D1%83&filter=0&as_q=site%3Aforum.mozilla-russia.org

Эта строка в виде ссылки.

Это пример, сайт должен подставляться тот, на котором я выделил какую-то фразу.

Можно в кнопке это реализовать?
P.S. Я перешёл на [firefox] с [opera]. Там поиск по форуму отломан и человек сделал javascript, который реализовал поиск по форуму через google именно такой функцией.
Я не знаю javascript и самостоятельно прикрутить к Вашей кнопке не смогу. Может этот код Вам пригодится?
скрытый текст

Выделить код

Код:

document.addEventListener('DOMContentLoaded', function() {
    if (typeof(searchform) != 'undefined')
    {
        var all_f = location.host + location.pathname.substring(0, location.pathname.lastIndexOf('/'));
        //opera.postError(all_f);
        var google_search = '<div>';
        google_search += '<input type="text" name="q" size="30" value="поиск в google" onblur="if (this.value == \'\') this.value = \'поиск в google\'" onfocus="if (this.value == \'поиск в google\') this.value = \'\'">';
        google_search += '<input type="submit" value=" Поиск ">';
        google_search += '<input type="hidden" name="filter" value="0">';
        if (location.pathname.indexOf('topic.dml') != '-1')
        {
            var topic_id = location.search.substring(location.search.indexOf('id='));
            if (topic_id.indexOf('&') != '-1')
                topic_id = topic_id.substring(0, topic_id.indexOf('&'));
            //opera.postError(topic_id);
            google_search += '<p>';
            google_search += '<input type="radio" name="as_q" value="site:' + all_f + ' inurl:' + topic_id + '" checked id="this-forum">';
            google_search += '<label for="this-topic">В этой теме</label>';
            google_search += '<input type="radio" name="as_q" value="site:' + all_f + '" id="all-forums">';
            google_search += '<label for="all-forums">Во всех форумах</label>';
            google_search += '</p>';
        }
        else
            google_search += '<input type="hidden" name="as_q" value="site:' + all_f + '">';
        google_search += '</div>';
        searchform.action = 'http://www.google.com/search';
        searchform.innerHTML = google_search;
    }
}, false)


P.P.S. Ещё раз спасибо.

dedmazai1870 пишет:

человек сделал javascript, который реализовал поиск по форуму через google именно такой функцией.

Для FF тоже такое есть - Search in Website+

Хотя, наверное, возможность, при зажатом Ctrl или чего-то такого, производить поиск по сайту в выбранной поисковой системе, была бы интересной, правда не знаю поддерживают ли всякие дакдаки и яндексы такую фичу...

PEAKTOP пишет:

Можешь добавить в текст пункта меню выделенное/искомое слово?

скрытый текст

Выделить код

Код:

// 2013-09-22

(function () {
    function _localize(sid) {
        let strings = {
            en : {
                siteSearch : "Site Search"
            },
            ru : {
                siteSearch : "Поиск по сайту"
            }
        };
        let locale = (Application.prefs.getValue("general.useragent.locale", false) || "en").match(/^[a-z]*/)[0];
        _localize = function (sid) {
            return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
        };
        return _localize.apply(this, arguments);
    }
    
    var searchSelect = document.getElementById('context-searchselect');
    searchSelect.collapsed = true;

    var contextMenu = document.getElementById("contentAreaContextMenu");
    var menu = contextMenu.insertBefore(document.createElement('menu'), searchSelect);

    menu.setAttribute("class", "menu-iconic");

    var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
    var engines = searchService.getVisibleEngines({});
    var isCustomEngine = false;
    
    var customName = "Google";

    if (customName != "") {
        for (let i in engines) {
            if (engines[i].name != customName)
                continue;
            menu.setAttribute("label", engines[i].name);
            menu.style.listStyleImage = 'url("' + engines[i].iconURI.spec + '")';
            menu.mEngine = engines[i];
            isCustomEngine = true;
            break;
        }
    }
    if (!isCustomEngine) {
        menu.setAttribute("label", searchService.defaultEngine.name);
        menu.style.listStyleImage = 'url("' + searchService.defaultEngine.iconURI.spec + '")';
        menu.mEngine = searchService.defaultEngine;
    }

    menu.setAttribute("onclick", "\
if (!event.target.mEngine) return;\
var submission = event.target.mEngine.getSubmission( getBrowserSelection(), null );\
gBrowser.loadOneTab( submission.uri.spec, {relatedToCurrent: true, postData: submission.postData, inBackground: false} );\
setTimeout(function() { document.getElementById('contentAreaContextMenu').hidePopup() }, 0);\
");
    var observeStatus = new MutationObserver(function () {
            menu.hidden = searchSelect.hidden;
        });
    observeStatus.observe(searchSelect, {
        attributes: true,
        attributeFilter: ["hidden"]
    });
    addDestructor(function () {
        contextMenu.removeChild(menu);
        observeStatus.disconnect();
        searchSelect.collapsed = false;
    });

    var menuPopup = menu.appendChild(document.createElement("menupopup"));
    
    addEventListener('popupshowing', function (e) {
        if (e.target != contextMenu)
            return;
        var selectedText = getBrowserSelection(16);
        if (!selectedText)
            return;
        var ellipsis = "\u2026";
        try {
            ellipsis = gPrefService.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
        } catch (e) { }
        if (selectedText.length > 15)
            selectedText = selectedText.substr(0,15) + ellipsis;
        var engineName = isCustomEngine ? customName : searchService.defaultEngine.name;
        var menuLabel = engineName;
        try {
            menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearch", [engineName, selectedText]);
        } catch (e) {
            menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearchText", [engineName, selectedText]);
        }
        menu.label = menuLabel;
        function clearMenuLabel(e) {
            if (e.target != contextMenu)
                return;
            removeEventListener(e.type, clearMenuLabel, false, contextMenu);
            menu.label = engineName;
        }
        addEventListener('popuphiding', clearMenuLabel, false, contextMenu);    
    }, false, contextMenu);

    var siteSearchGoogle;
    for (let i in engines) {
        if (engines[i].name != "Google")
            continue;
        siteSearchGoogle = engines[i];
        break;
    }
    
    addEventListener('popupshowing', function (e) {
        menuPopup.textContent = "";
        
        function mItemCreate(trg, ssg/*, dm*/) {
            var mItem = document.createElement("menuitem");
            mItem.setAttribute("class", "menuitem-iconic");
            mItem.engine = trg;
            if (ssg == "siteSearchGoogle") {
                menuPopup.appendChild(document.createElement("menuseparator"));
                mItem.setAttribute("label", _localize("siteSearch") /*+ ": " + dm*/);
                //mItem.setAttribute("src", gBrowser.selectedTab.image);
                mItem.setAttribute(ssg, "true");
            } else {
                mItem.setAttribute("label", trg.name);
                mItem.setAttribute("src", trg.iconURI.spec);
            }
            menuPopup.appendChild(mItem);
        }
        for (let i in engines) {
            if (isCustomEngine && engines[i].name == customName ||
                !isCustomEngine && engines[i].name == searchService.defaultEngine.name)
                continue;
            mItemCreate(engines[i]);
        }
        function isDomain() {
            var domain;
            try {
                domain = gBrowser.currentURI.host;
            } 
            catch (e) {}
            return domain;
        }
        if (siteSearchGoogle && isDomain()) {
            mItemCreate(siteSearchGoogle, "siteSearchGoogle"/*, isDomain()*/);
        }
        menuPopup.setAttribute("oncommand", "\
if (!event.target.engine) return;\
var ssg = '';\
if (event.target.hasAttribute('siteSearchGoogle')) {\
    ssg = ' site:' + gBrowser.currentURI.host;\
}\
var submission = event.target.engine.getSubmission(getBrowserSelection() + ssg, null);\
gBrowser.loadOneTab( submission.uri.spec, {relatedToCurrent: true, postData: submission.postData, inBackground: false} );\
");
    }, false, menu);
})();



upd: + "Поиск по сайту"
upd: исправил ошибки

dedmazai1870, в основной версии Context Search так и сделано, там стоит - в пункт меню выводится не более 16 символов из выделенного текста.

21-09-2013 23:10:33
2k1dmg, вот теперь именно то, что я хотел.
http://img-fotki.yandex.ru/get/3900/kyrtallam.e/0_18931_a1348090_M.gif

Zaycoff
А вот объединить 2 кнопки как? Чтобы с списку моих поисков добавлялся гуглопоиск последней строкой "Включает строку поиска выделенного текста на текущем сайте". Вот чего хочется. :)

Соглашусь с  dedmazai1870, пункт "Поиск по текущему сайту" с помощью этой кнопки был бы очень кстати. 
http://images.vfl.ru/ii/1379795481/02830ad0/3148423.png

dedmazai1870
PEAKTOP
№27

2k1dmg
Большое спасибо, всё здорово! http://s19.rimg.info/de025085f8915a36f1649f7aa322cecf.gif

2k1dmg
А можно привязать окно поиска к контекстному меню, чтобы оно не прыгало слева на право, а всегда было на предсказуемом месте.
Сейчас
http://s019.radikal.ru/i631/1309/57/1d6ddb20a5a4t.jpg
Хотелось бы
http://s58.radikal.ru/i160/1309/3e/596060d186bdt.jpg

Добавил "Поиск по текущему сайту" через Яндекс

Код инициализации

Выделить код

Код:

//Context Search - искать поисковыми системами через контекстное меню...............................
(function () {
    function _localize(sid) {
        let strings = {
            en : {
                siteSearch : "Search this site - Google"
            },
            ru : {
                siteSearch : "Поиск по этому сайту - Google"
            }
        };
        let locale = (Application.prefs.getValue("general.useragent.locale", false) || "en").match(/^[a-z]*/)[0];
        _localize = function (sid) {
            return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
        };
        return _localize.apply(this, arguments);
    }
  
    function _localize2(sid) {
        let strings = {
            en : {
                siteSearch2 : "Search this site - Yandex"
            },
            ru : {
                siteSearch2: "Поиск по этому сайту - Яндекс"
            }
        };
        let locale = (Application.prefs.getValue("general.useragent.locale", false) || "en").match(/^[a-z]*/)[0];
        _localize2 = function (sid) {
            return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
        };
        return _localize2.apply(this, arguments);
    }
 
    var searchSelect = document.getElementById('context-searchselect');
    searchSelect.collapsed = true;

    var contextMenu = document.getElementById("contentAreaContextMenu");
    var menu = contextMenu.insertBefore(document.createElement('menu'), searchSelect );

    menu.setAttribute("class", "menu-iconic");

    var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
    var engines = searchService.getVisibleEngines({});
    var isCustomEngine = false;
    
    var customName = "Google";

    if (customName != "") {
        for (let i in engines) {
            if (engines[i].name != customName)
                continue;
            menu.setAttribute("label", engines[i].name);
            menu.style.listStyleImage = 'url("' + engines[i].iconURI.spec + '")';
            menu.mEngine = engines[i];
            isCustomEngine = true;
            break;
        }
    }
    if (!isCustomEngine) {
        menu.setAttribute("label", searchService.defaultEngine.name);
        menu.style.listStyleImage = 'url("' + searchService.defaultEngine.iconURI.spec + '")';
        menu.mEngine = searchService.defaultEngine;
    }

    menu.setAttribute("onclick", "\
if ( !!event.target.engine || !event.target.mEngine) return;\
var submission = event.target.mEngine.getSubmission( getBrowserSelection(), null );\
gBrowser.loadOneTab( submission.uri.spec, {relatedToCurrent: true, postData: submission.postData, inBackground: false} );\
setTimeout(function() { document.getElementById('contentAreaContextMenu').hidePopup() }, 0);\
");
    var observeStatus = new MutationObserver(function () {
            menu.hidden = searchSelect.hidden;
        });
    observeStatus.observe(searchSelect, {
        attributes: true,
        attributeFilter: ["hidden"]
    });
    addDestructor(function () {
        contextMenu.removeChild(menu);
        observeStatus.disconnect();
        searchSelect.collapsed = false;
    });

    var menuPopup = menu.appendChild(document.createElement("menupopup"));

    addEventListener('popupshowing', function (e) {
        if (e.target != contextMenu)
            return;

        var selectedText = getBrowserSelection(16);
        if (!selectedText)
            return;

        var ellipsis = "\u2026";
        try {
            ellipsis = gPrefService.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
        } catch (e) { }

        if (selectedText.length > 15)
            selectedText = selectedText.substr(0,15) + ellipsis;

        var engineName = isCustomEngine ? customName : searchService.defaultEngine.name;

        var menuLabel = engineName;
        try {
            menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearch", [engineName, selectedText]);
        } catch (e) {
            menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearchText", [engineName, selectedText]);
        }

        menu.label = menuLabel;
        
        function clearMenuLabel(e) {
            if (e.target != contextMenu)
                return;
            removeEventListener(e.type, clearMenuLabel, false, contextMenu);
            menu.label = engineName;
        }
        addEventListener('popuphiding', clearMenuLabel, false, contextMenu);    
    }, false, contextMenu);

    addEventListener('popupshowing', function (e) {
        menuPopup.textContent = "";

        for (let i in engines) {
            if (isCustomEngine && engines[i].name == customName ||
                !isCustomEngine && engines[i].name == searchService.defaultEngine.name)
                continue;
            var mItem = document.createElement("menuitem");
            mItem.setAttribute("label", engines[i].name);
            mItem.setAttribute("class", "menuitem-iconic");
            mItem.setAttribute("src", engines[i].iconURI.spec);
            mItem.engine = engines[i];
            menuPopup.appendChild(mItem);
        }
        menuPopup.setAttribute("oncommand", "\
if ( !event.target.engine ) return;\
var submission = event.target.engine.getSubmission( getBrowserSelection(), null );\
gBrowser.loadOneTab( submission.uri.spec, {relatedToCurrent: true, postData: submission.postData, inBackground: false} );\
");

        menuPopup.appendChild(document.createElement("menuseparator"));
        var mItemSbS = menuPopup.appendChild(document.createElement("menuitem"));
        mItemSbS.setAttribute("class", "menuitem-iconic");
        mItemSbS.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEhIAAAEAIACABQAAFgAAACgAAAASAAAAJAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBKBMpTCYX4GMrH/9gMxn/YDQV/2cyG/9nLxr/YjMd/10xHv9cMRz/XjIa/2ExHP9gNRn/YDIV/2IwHf9ULSL/RCcU4EEoEylLKBfgcjUe/349IP98QRr/gEEd/39AKP+FUjv/h2NL/4lkUP+GYEv/hVQ+/35CJv9+Phz/gEIb/4c8H/96PCT/azgb/0koFOBpMyT/jD8i/4RFIf97RB3/hEUr/7GCdf/q29L/+e3e/97HuP/dwLD/6M2+/76VhP9+RSr/hUMg/5NAH/+NQCX/h0Ai/2Q1Iv9yOyf/lkYn/4xFJP+HSSn/m25Y//7y6v/bw7f/fkw2/3hBJv90QSX/hFI9/+nUxv+2k4H/i0kq/5VIJP+QRiL/lkYn/3Q5Kv9zQSn/mUkp/5tJKf+XSin/roJr//757f+0gG//l0oq/5NMI/+WTCH/i00u/8q0o//jx7j/mFU6/5JMJP+TTiL/l0wl/3Y/K/93Rif/oE4p/6ZNK/+jTSz/pGpS//rn2v/Np5b/kFEx/5BSK/+XTyv/nmFJ/+rTyP/lyrv/nlk+/5NRJv+WUib/l1Ik/3lFK/+BSyr/plQt/6ZULP+mUyv/nFIz/6d3Yf/hxrX/3b6n/7SUf/+7l4b/8NjL//7z6//BkoH/mlMz/55TLP+iUyv/olMp/4FJK/+FSzP/qVUz/61ZMf+sWSv/rFYs/59TM/+cWT//nmJJ/8OSgf/+8ub/+O/b/8ikkv+iVTb/qVgv/6pVMP+1WDT/qVY1/4ZMMf+MUTX/q1sx/7RZMf+2WjH/t1wv/7JbLf+oXDT/nVtD/8yajv/+8uf/ybGZ/5VYOP+zWDL/t1sx/7NYMv+5WjX/sFk2/49SM/+VVDn/s143/7hfNP+8WzX/v141/6xeMv/ZoYD/+9/I/+DBtP/Ss6P/7L+l/7l1Tf+1XjT/vlw0/7tdM/+6YC//tV42/5FYNP+cU0D/uGE9/75fNf/GZTb/wGI4/8OBYv//5tT/5byr/6RjSP+lXD//26eM//TNsf+3YkH/xGI3/8NjNf+7Yi//uGE3/5pZOv+hWEH/wGY9/8RlNP/KaDf/xWY3/9+ef///5tv/v4Vt/8NmOv+9ZUD/xI16//7o2v/FgGX/x2g5/8poNv/KaDb/xWU5/6ZYQv+mYUH/y2s7/8xwN//TbTf/0m46/+CYd///59X/vIJk/81tOv/Bbz//4a6b//7n2P/FiGL/yWw4/9FtN//KcDf/zG45/6dfQP+tZT//1W4//9pxPf/VbTz/1G5B/75wTf/31L7/z56C/8V5TP/TkGP/+NXC//XSv/+4cEr/0nA7/9VwO//Ubz7/1G88/61kP/+0bkj/4XNC/99wPv/gckL/321B/9VwR//Gf2D/6reX/+/DoP/82br//uHO//LSvv/mp33/3nhJ/9dwQv/bb0X/23BG/7RrSP+wb0r/4nhK/+V3Rf/qeEX/8HZE/+lzQf/adUf/yWg+/7lfO/+tYDz/qWFA/6xeOf/IaTn/5nND/+h1SP/pdkj/3ndN/7RtUP+NWTrg2oJX/+uGVf/ofkv/84FN/++ETv/qfk//6n5Q/+h+Uv/ngFP/5oFS/+d/UP/nfk//839O/+5+Tv/uhVj/3YFa/5JYPOCRVkEppFo64NN8UP/dgVT/3oRR/92DTP/ihVj/34FX/+ODVf/mg1T/5IRO/96ET//cglH/4YJT/+CCVv/Te1D/oVk44JBVQCkAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEE=")
        mItemSbS.setAttribute("label", _localize("siteSearch"));
        
        mItemSbS.setAttribute("oncommand", "\
var selectedText = getBrowserSelection(); if (!selectedText) return;\
try {var domain = content.document.domain;} catch (e) {return;}\
selectedText = encodeURIComponent(selectedText);\
gBrowser.loadOneTab( 'https://www.google.com/search?q=' + selectedText + '&filter=0&as_q=site:' + domain, {relatedToCurrent: true, inBackground: false} );\
");

//menuPopup.appendChild(document.createElement("menuseparator"));
        var mItemSbS = menuPopup.appendChild(document.createElement("menuitem"));
        mItemSbS.setAttribute("class", "menuitem-iconic");
        mItemSbS.setAttribute("image", "data:application/file;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABCklEQVR4nKVTuwrCUAw9vXRwEnF0kI4iTuLg5NRB/BRx6IeIk4M4iJ/SoWM/QMTByUnED5ATh+AjrdqqgXC5JDn3JOfGIyn4wpxznrnnMuZzYDgEwhAIAsD3gSi6h3MPkpS7z2bCRkN4Oul9NBJWq2JyMgCWwWIB9HpArfaxjWcQC3A+A5XKx+KsWYBWC9jvSxXeWFiAKALSFJhOgculHIXsgLhaCZ0TttvCZvPlEJ89L+N6ra0kCdDpFBKwAEmiPpkUKgHop7IAcaxnGBYWv2aQpipjEJR6PQ+w2Wj/vv8Dg+MR2O2Afv8RfSOlWSiSwsNBOBgI63XhdqsSLZfCbld9PH67C96/63wFqBHGA4wLrxUAAAAASUVORK5CYII=")
        mItemSbS.setAttribute("label", _localize2("siteSearch2"));
        
        mItemSbS.setAttribute("oncommand", "\
var selectedText = getBrowserSelection(); if (!selectedText) return;\
try {var domain = content.document.domain;} catch (e) {return;}\
selectedText = encodeURIComponent(selectedText);\
gBrowser.loadOneTab( 'http://yandex.ru/yandsearch?text=' + selectedText + '&site=' + domain, {relatedToCurrent: true, inBackground: false} );\
");
       
    }, false, menu);
})();

// Библиотека - Открывать библиотеку в вкладке и последнюю активную папку библиотеки, от 08.09.2013. ................................
(function () {
   var command;
   const pn = "CB.lastUsedLibraryFolder";
   const library = "chrome://browser/content/places/places.xul";

   
   // Перехватывать открытие библиотеки и открывать её в вкладке рядом с текущей ....
   function libraryInTab(e) {
 
      var oncommand = e.target.getAttribute("oncommand");

      if ( !/PlacesCommandHook.showPlacesOrganizer|DownloadsUI|DownloadsPanel/.test( oncommand ) ) return;
      if ( /UnfiledBookmarks/.test( oncommand ) && e.type == 'click' ) return; 
           e.stopPropagation();
           
      command = oncommand;      
      setTimeout(function() { document.getElementById("appmenu-popup").hidePopup() }, 0);
       
      // закрыть все вкладки библиотеки кроме первой ....
      var libTab = null;
      Array.slice( gBrowser.tabs ).forEach(function(tab) {
            if ( tab.linkedBrowser.currentURI.spec !== library ) return;
            !libTab ? libTab = tab : gBrowser.removeTab(tab);
      })
   
      // переместить или открыть библиотеку рядом с текущей вкладкой ....
      var selTab = gBrowser.selectedTab;
      if ( libTab !== selTab ) {
           if ( libTab && gBrowser.visibleTabs.indexOf(libTab) == -1 )
                TabView.moveTabTo( libTab, TabView._window.GroupItems._activeGroupItem.id );
           libTab = libTab || gBrowser.addTab( library );
           var pos = selTab._tPos + ( libTab._tPos > selTab._tPos );
           gBrowser.moveTabTo( libTab, pos );
           gBrowser.selectedTab = libTab;
           
           // если библиотека уже открыта
           if ( !libTab.hasAttribute('busy') ) openLastUsedFolder( false, content.document.defaultView );                          
      }
   };
   addEventListener("command", libraryInTab, true, window );
   addEventListener("click", libraryInTab, true, document.getElementById('appmenuSecondaryPane') );

   
   // Открывать и запоминать последнюю активную папку если библиотека открыта как вкладка ....
   function openLastUsedFolder( e, win ) {
   
      if ( e !== false ) {
           var win = e.target.defaultView;
           if ( win.location != library ) return;
           }

      // получить нужную папку
      try { var value = cbu.getPrefs( pn ) }
      catch(e) { var value = '' };      
      if ( /History/.test( command ) ) value = 'place:sort=4&type=3';
      if ( /UnfiledBookmarks/.test( command ) ) value = 'place:folder=UNFILED_BOOKMARKS&excludeItems=1&expandQueries=0';
      if ( /DownloadsUI|DownloadsPanel/.test( command ) ) value = 'place:transition=7&sort=4';
      if ( /DownloadsPanel/.test( command ) ) 
           setTimeout(function() { document.getElementById("downloadsPanel").hidePopup() }, 10);
     
      // открыть нужную папку используя рекурсию   
      (function f() { 
         try { 
             win.PlacesOrganizer.location = value;
             win.PlacesOrganizer._places.focus();
             }
         catch(e) { setTimeout(function() { f() }, 0) };
      })();
      
      // запоминать последнюю папку при закрытии библиотеки
      if ( e == false ) return;
      win.addEventListener("unload", function(e) {        
          this.removeEventListener( e.type, arguments.callee, false );
          
          var loc = win.PlacesOrganizer.location;          
          if ( loc == 'place:transition=7&sort=4') return; // исключить папки загрузки   
          if ( /place:beginTime|place:sort=4&type=3/.test( loc ) ) return; // исключить папки истории    
          
          cbu.setPrefs( pn, loc );        
      }, false );
   };
   addEventListener("DOMContentLoaded", openLastUsedFolder, false, gBrowser );
})();


http://images.vfl.ru/ii/1379892506/d0671faf/3154371.png

Хорошая кнопка, а когда будет готовый вариант, а то там собери, тут доложи, оттуда добавь...

Context Search 2013-09-23

Выделить код

Код:

// 2013-09-23

(function () {
    var options = {
        customName: "Google",
        // оставить пустым если не нужно закреплять
        // определенный поисковик
        // примеры customName: "Google" или customName: "Яндекс" или customName: ""
        hideDefaultEngineInList: false,
        // true - не допбовлять поисковик по умолчанию в выпадающий список поисковиков
        siteSearchIconsOn: true
        // true - добавить иконки для поисковиков по сайту
    };

    function _localize(sid) {
        let strings = {
            en: {
                siteSearchGoogle: "Search this site - Google",
                siteSearchYandex: "Search this site - Yandex",
                siteSearchYahoo: "Search this site - Yahoo",
                siteSearchBing: "Search this site - Bing",
                siteSearchDuckDuckGo: "Search this site - DuckDuckGo"
            },
            ru: {
                siteSearchGoogle: "Поиск по этому сайту - Google",
                siteSearchYandex: "Поиск по этому сайту - Яндекс",
                siteSearchYahoo: "Поиск по этому сайту - Yahoo",
                siteSearchBing: "Поиск по этому сайту - Bing",
                siteSearchDuckDuckGo: "Поиск по этому сайту - DuckDuckGo"
            }
        };
        let locale = (Application.prefs.getValue("general.useragent.locale", false) || "en").match(/^[a-z]*/)[0];
        _localize = function (sid) {
            return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
        };
        return _localize.apply(this, arguments);
    }

    var contextSearcherObj = {
        commandHandler: function (event, trg) {
            var inBg = false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = true;
            }
            var siteSearch = '';
            if (event.target.hasAttribute('siteSearch'))  {
                siteSearch = ' site:' + gBrowser.currentURI.host;
            }
            var submission = event.target.engine.getSubmission(getBrowserSelection() + siteSearch, null);
            gBrowser.loadOneTab(submission.uri.spec, {
                relatedToCurrent: true,
                postData: submission.postData,
                inBackground: inBg
            });
            if (trg == "menu") {
                setTimeout(function () {
                    document.getElementById('contentAreaContextMenu').hidePopup();
                }, 0);
            }
        }
    }

    var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
    var engines = searchService.getVisibleEngines({});

    var contextMenu = document.getElementById("contentAreaContextMenu");
    var searchSelect = document.getElementById('context-searchselect');
    searchSelect.style.display = 'none';

    var menu = contextMenu.insertBefore(document.createElement('menu'), searchSelect);
    menu.setAttribute("id", "Context_Search_mini_By_bunda1");
    menu.setAttribute("class", "menu-iconic");
    var isCustomEngine = false;
    var customName = options.customName;
    if (customName != "") {
        for (let i in engines) {
            if (engines[i].name != customName)
                continue;
            menu.setAttribute("label", engines[i].name);
            menu.style.listStyleImage = 'url("' + engines[i].iconURI.spec + '")';
            menu.engine = engines[i];
            isCustomEngine = true;
            break;
        }
    }
    if (!isCustomEngine) {
        menu.setAttribute("label", searchService.defaultEngine.name);
        menu.style.listStyleImage = 'url("' + searchService.defaultEngine.iconURI.spec + '")';
        menu.engine = searchService.defaultEngine;
    }
    menu.searchWith = contextSearcherObj.commandHandler;
    menu.setAttribute("onclick", "if (event.target == this && event.target.engine) this.searchWith(event, 'menu');");

    addEventListener('popupshowing', function (e) {
        if (e.target != contextMenu)
            return;
        var selectedText = getBrowserSelection(16);
        if (!selectedText)
            return;
        var ellipsis = "\u2026";
        try {
            ellipsis = gPrefService.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
        } catch (e) { }
        if (selectedText.length > 15)
            selectedText = selectedText.substr(0,15) + ellipsis;
        var engineName = isCustomEngine ? customName : searchService.defaultEngine.name;
        var menuLabel = engineName;
        try {
            menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearch", [engineName, selectedText]);
        } catch (e) {
            menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearchText", [engineName, selectedText]);
        }
        menu.label = menuLabel;
        function clearMenuLabel(e) {
            if (e.target != contextMenu)
                return;
            removeEventListener(e.type, clearMenuLabel, false, contextMenu);
            menu.label = engineName;
        }
        addEventListener('popuphiding', clearMenuLabel, false, contextMenu);
    }, false, contextMenu);

    var menuPopup = menu.appendChild(document.createElement("menupopup"));
    //menuPopup.textContent = "";
    var mSeparator;
    function mItemCreate(trg, ssl) {
        var mItem = document.createElement("menuitem");
        mItem.setAttribute("class", "menuitem-iconic");
        mItem.engine = trg;
        if (ssl) {
            if (!mSeparator ) {
                mSeparator = document.createElement("menuseparator");
                mSeparator.setAttribute("siteSearch", "true");
                menuPopup.appendChild(mSeparator);
            }
            mItem.setAttribute("label", _localize(ssl));
            if (options.siteSearchIconsOn) {
                mItem.setAttribute("src", trg.iconURI.spec);
            }
            mItem.setAttribute("siteSearch", "true");
        } else {
            mItem.setAttribute("label", trg.name);
            mItem.setAttribute("src", trg.iconURI.spec);
        }
        menuPopup.appendChild(mItem);
    }
    for (let i in engines) {
        if (options.hideDefaultEngineInList && isCustomEngine && engines[i].name == customName ||
            options.hideDefaultEngineInList && !isCustomEngine && engines[i].name == searchService.defaultEngine.name) {
            LOG(engines[i].name);
            continue;
        }
        mItemCreate(engines[i]);
    }
    var siteSearchArr = [];
    [
        ["Google", ["Google"]],
        ["Yandex", ["Yandex", "Яндекс"]],
        ["Yahoo", ["Yahoo"]],
        ["Bing", ["Bing"]],
        ["DuckDuckGo", ["DuckDuckGo"]]
    ].forEach(function(elem) {
        for (let i in engines) {
            if (elem[1].indexOf(engines[i].name) == -1)
                continue;
            siteSearchArr.push([elem[0], engines[i]]);
            break;
        }
    });
    if (siteSearchArr[0]) {
        siteSearchArr.forEach(function(elem) {
            mItemCreate(elem[1], "siteSearch" + elem[0]);
        });
    }
    menuPopup.searchWith = contextSearcherObj.commandHandler;
    menuPopup.setAttribute("oncommand", "if (!event.target.engine) return; this.searchWith(event);");
    menuPopup.setAttribute("onclick", "checkForMiddleClick(this, event);");

    addEventListener('popupshowing', function (e) {
        var siteSearchDomain;
        function isDomain() {
            try {
                siteSearchDomain = gBrowser.currentURI.host;
            } catch (e) {
                return false;
            }
            return true;
        }
        var mItems;
        if (!menuPopup.mItems) {
            var mItemsObg = menuPopup.getElementsByTagName("menuitem");
            menuPopup.mItems = [];
            Array.slice(mItemsObg).forEach(function(elem) {
                if (typeof elem == "object" &&
                        elem.nodeName == "menuitem" &&
                        elem.hasAttribute("siteSearch"))
                    menuPopup.mItems.push(elem);
            });
            mItems = menuPopup.mItems;
        } else {
            mItems = menuPopup.mItems;
        }
        if (isDomain()) {
            mItems.forEach(function(elem) {
                elem.removeAttribute("disabled");
                elem.setAttribute("tooltiptext", siteSearchDomain);
            });
        } else {
            mItems.forEach(function(elem) {
                elem.setAttribute("disabled", "true");
                elem.removeAttribute("tooltiptext");
            });
        }
    }, false, menu);

    var observeStatus = new MutationObserver(function () {
            menu.hidden = searchSelect.hidden;
        });
    observeStatus.observe(searchSelect, {
        attributes: true,
        attributeFilter: ["hidden"]
    });
    addDestructor(function () {
        contextMenu.removeChild(menu);
        observeStatus.disconnect();
        document.getElementById('context-searchselect').style.removeProperty('display');
    });
})();

2k1dmg пишет:

Context Search 2013-09-23

А зачем ты изменяешь меню при закрытии :/:
       

Выделить код

Код:

function clearMenuLabel(e) {
            if (e.target != contextMenu)
                return;
            removeEventListener(e.type, clearMenuLabel, false, contextMenu);
            menu.label = engineName;
        }
        addEventListener('popuphiding', clearMenuLabel, false, contextMenu);

если потом пункт меню при открытии меню опять меняется:

Выделить код

Код:

    addEventListener('popupshowing', function (e) {
....................
        menu.label = menuLabel;

2k1dmg, есть одно неудобство. Если я зафиксирую в пункте меню "Google", то он будет дублироваться и в подменю. Понятно, что ты берешь список поисковиков из "Панели поиска". Есть возможность исключить "зафиксированный" поисковик из подменю?

Screenshot
http://images.vfl.ru/ii/1380050876/22b8813a/3166840.png

PEAKTOP
Там же есть options (с описанием настроек), где можно изменить:

hideDefaultEngineInList: true

bunda1
Убрал изменение меню при закрытии и
добавил "Поиск по изображени"

скрытый текст

Выделить код

Код:

// 2013-09-25

(function () {
    var options = {
        pinnedEngineName: "",
        // оставить пустым если не нужно закреплять
        // определенный поисковик
        // примеры pinnedEngineName: "Google" или pinnedEngineName: "Яндекс" или pinnedEngineName: ""
        hideDefaultEngineInList: false,
        // true - не добавлять поисковик по умолчанию в выпадающий список (подменю) поисковиков
        siteSearch: {
            enable: true,
            // true - добавить поисковики по сайту
            iconsOn: true,
            // true - добавить иконки для поисковиков по сайту
            useDefaultNamesList: true,
            // true - использовать список поисковиков по умолчанию
            addCustomNames: false,
            // true - добавить свои поисковики по сайту
            customNamesList: [
                ["Rambler", ["Rambler", "Рамблер"]]
            ]
            // например ["Rambler", ["Rambler", "Рамблер"]]
            // первая ячека название на английском
            // вторая ячека массив с предполагаемыми именами поисковика
            // может состоять из нескольких значений
            // ["Name1", ["Name1"]],
            // ["Name2", ["Name2", "Имя2"]],
            // ["Name3", ["Name3", "Имя3", "Név3"]]
        },
        addImageSearch: true
        // true - добавить поиск изображений
    };
    function _localize(sid) {
        let strings = {
            en: {
                siteSearch: "Search this site",
                searchImage: "Search by image"
            },
            ru: {
                siteSearch: "Поиск по этому сайту",
                searchImage: "Поиск по изображению"
            }
        };
        let locale = (Application.prefs.getValue("general.useragent.locale", false) || "en").match(/^[a-z]*/)[0];
        _localize = function (sid) {
            return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
        };
        return _localize.apply(this, arguments);
    }
    var contextSearcherObj = {
        init: function() {
            var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
            var contextMenu = document.getElementById("contentAreaContextMenu");
            var searchSelect = document.getElementById("context-searchselect");
            searchSelect.style.display = "none";

            var menu = contextMenu.insertBefore(document.createElement("menu"), searchSelect);

            this.searchService = searchService;
            this.contextMenu = contextMenu;
            this.menu = menu;

            var observeStatus = new MutationObserver(function () {
                    menu.hidden = searchSelect.hidden;
                });
            observeStatus.observe(searchSelect, {
                attributes: true,
                attributeFilter: ["hidden"]
            });

            var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                        .getService(Components.interfaces.nsIPrefService);
            this.branch = prefService.getBranch("browser.search.");
            if (!("addObserver" in this.branch))
                this.branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
            this.branch.addObserver("", this, false);

            Services.ww.registerNotification(this);

            this.createMenu();

            if (options.addImageSearch)
                this.creatImageMenu();

            addDestructor(function () {
                observeStatus.disconnect();
                searchSelect.style.removeProperty("display");
                Services.ww.unregisterNotification(this);
                this.branch.removeObserver("", this);
                this.destroy();
            }, this);
        },
        destroy: function() {
            var contextMenu = this.contextMenu;
            var menu = this.menu;
            if (menu)
                contextMenu.removeChild(menu);
            var imageMenu = this.imageMenu;
            if (imageMenu)
                contextMenu.removeChild(imageMenu);
        },
        update: function() {
            this.menu.textContent = "";
            this.createMenu();
        },

        observe: function(subject, topic, data) {
            switch (topic) {
                case "domwindowclosed":
                    if (subject.document.documentElement.getAttribute("windowtype") == "Browser:SearchManager") {
                        this.update();
                    }
                    break;
                case "nsPref:changed":
                    if (data == "defaultenginename")
                        this.update();
                    break;
            }
        },
        handleEvent: function(e) {
            var contextMenu = this.contextMenu;
            var menu = this.menu;
            var imageMenu = this.imageMenu;

            switch (e.type) {
                case "popupshowing":
                    if(e.target == contextMenu) {
                        this.contextMenuPopup(e);
                        if (imageMenu)
                            this.imageMenuPopup(e);
                    }
                    else if (e.target == menu)
                        this.contextSearcherMenuPopup(e);
                    break;
            }
        },

        commandHandler: function(event, trg) {
            var inBg = false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = true;
            }
            var siteSearch = "";
            if (event.target.hasAttribute("siteSearch"))  {
                siteSearch = " site:" + gBrowser.currentURI.host;
            }
            var submission = event.target.engine.getSubmission(getBrowserSelection() + siteSearch, null);
            gBrowser.loadOneTab(submission.uri.spec, {
                relatedToCurrent: true,
                postData: submission.postData,
                inBackground: inBg
            });
            if (trg == "menu") {
                setTimeout(function () {
                    document.getElementById("contentAreaContextMenu").hidePopup();
                }, 0);
            }
        },
        contextMenuPopup: function(e) {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.menu;

            var selectedText = getBrowserSelection(16);
            if (!selectedText)
                return;
            var ellipsis = "\u2026";
            try {
                ellipsis = gPrefService.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
            } catch (e) { }
            if (selectedText.length > 15)
                selectedText = selectedText.substr(0,15) + ellipsis;
            var engineName = this.isCustomEngine ? customName : searchService.defaultEngine.name;
            var menuLabel;
            var searchFormattedString = [
                "contextMenuSearch",
                "contextMenuSearchText"
            ];
            function getMenuLabel(str) {
                try {
                    return gNavigatorBundle.getFormattedString(str, [engineName, selectedText]);
                } catch (e) {}
            }
            for(let i in searchFormattedString) {
                menuLabel = getMenuLabel(searchFormattedString[i]);
                if (menuLabel)
                    break;
                else if (!menuLabel && i == searchFormattedString.length-1)
                    menuLabel = engineName;
            }
            menu.label = menuLabel;
        },
        contextSearcherMenuPopup: function(e) {
            var siteSearchDomain;
            function isDomain() {
                try {
                    siteSearchDomain = gBrowser.currentURI.host;
                } catch (e) {
                    return false;
                }
                return true;
            }
            var mItems;
            if (!menuPopup.mItems) {
                var mItemsObg = menuPopup.getElementsByTagName("menuitem");
                menuPopup.mItems = [];
                Array.slice(mItemsObg).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menuitem" &&
                            elem.hasAttribute("siteSearch"))
                        menuPopup.mItems.push(elem);
                });
                mItems = menuPopup.mItems;
            } else {
                mItems = menuPopup.mItems;
            }
            if (isDomain()) {
                mItems.forEach(function(elem) {
                    elem.removeAttribute("disabled");
                    elem.setAttribute("tooltiptext", siteSearchDomain);
                });
            } else {
                mItems.forEach(function(elem) {
                    elem.setAttribute("disabled", "true");
                    elem.removeAttribute("tooltiptext");
                });
            }
        },
        createMenu: function() {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.menu;

            var engines = searchService.getVisibleEngines({});

            menu.setAttribute("id", "Context_Search_mini_By_bunda1");
            menu.setAttribute("class", "menu-iconic");
            this.isCustomEngine = false;
            var customName = options.pinnedEngineName;
            if (customName != "") {
                for (let i in engines) {
                    if (engines[i].name != customName)
                        continue;
                    menu.setAttribute("label", engines[i].name);
                    menu.setAttribute("image", engines[i].iconURI.spec);
                    menu.engine = engines[i];
                    this.isCustomEngine = true;
                    break;
                }
            }
            if (!this.isCustomEngine) {
                menu.setAttribute("label", searchService.defaultEngine.name);
                menu.setAttribute("image", searchService.defaultEngine.iconURI.spec);
                menu.engine = searchService.defaultEngine;
            }

            menu.gObj = this;
            menu.setAttribute("onclick", "if (event.target == this && event.target.engine) this.gObj.commandHandler(event, 'menu');");
            addEventListener("popupshowing", this, false, contextMenu);

            var menuPopup = menu.appendChild(document.createElement("menupopup"));
            var mSeparator;
            function mItemCreate(engine, siteSearch) {
                var mItem = document.createElement("menuitem");
                mItem.setAttribute("class", "menuitem-iconic");
                mItem.engine = engine;
                if (siteSearch) {
                    if (!mSeparator ) {
                        mSeparator = document.createElement("menuseparator");
                        mSeparator.setAttribute(siteSearch, "true");
                        menuPopup.appendChild(mSeparator);
                    }
                    mItem.setAttribute("label", _localize(siteSearch) + " - " + engine.name);
                    if (options.siteSearch.iconsOn) {
                        mItem.setAttribute("src", engine.iconURI.spec);
                    }
                    mItem.setAttribute(siteSearch, "true");
                } else {
                    mItem.setAttribute("label", engine.name);
                    mItem.setAttribute("src", engine.iconURI.spec);
                }
                menuPopup.appendChild(mItem);
            }
            for (let i in engines) {
                if (options.hideDefaultEngineInList && this.isCustomEngine && engines[i].name == customName ||
                    options.hideDefaultEngineInList && !this.isCustomEngine && engines[i].name == searchService.defaultEngine.name) {
                    continue;
                }
                mItemCreate(engines[i]);
            }
            function siteSearch_mItemCreate() {
                var namesList = [];
                if (options.siteSearch.useDefaultNamesList) {
                    let defaultNamesList = [
                        ["Google", ["Google"]],
                        ["Yandex", ["Yandex", "Яндекс"]],
                        ["Yahoo", ["Yahoo"]],
                        ["Bing", ["Bing"]],
                        ["DuckDuckGo", ["DuckDuckGo"]]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.siteSearch.addCustomNames &&
                        Array.isArray(options.siteSearch.customNamesList)) {
                    namesList = namesList.concat(options.siteSearch.customNamesList);
                }
                let i_skips = [];
                namesList.forEach(function(elem) {
                    for (let i in engines) {
                        if (i_skips.indexOf(i) != -1 ||
                            elem[1].indexOf(engines[i].name) == -1)
                            continue;
                        mItemCreate(engines[i], "siteSearch");
                        i_skips.push(i);
                        break;
                    }
                });
            }
            if (options.siteSearch.enable) {
                siteSearch_mItemCreate();
            }

            menuPopup.gObj = this;
            menuPopup.setAttribute("oncommand", "if (!event.target.engine) return; this.gObj.commandHandler(event);");
            menuPopup.setAttribute("onclick", "checkForMiddleClick(this, event);");
            addEventListener("popupshowing", this, false, menu);
        },

        commandHandlerSearchImage: function(event) {
            var inBg = false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = true;
            }
            var imageMenu = this.imageMenu;
            var link = event.target.link;
            var linkURI = link + encodeURIComponent(imageMenu.imageSrc);
            gBrowser.loadOneTab(linkURI, {
                relatedToCurrent: true,
                inBackground: inBg
            });
        },
        imageMenuPopup: function(e) {
            var imageMenu = this.imageMenu;

            imageMenu.hidden = !gContextMenu.onImage;
            var src = gContextMenu.mediaURL || gContextMenu.imageURL || gContextMenu.bgImageURL;
            if (!src || !(/^(ht|f)tps?:\/\//.test(src))) {
                imageMenu.hidden = true;
                return;
            }
            imageMenu.imageSrc = src;
        },
        creatImageMenu: function() {
            var menu = document.createElement("menu");

            this.imageMenu = menu;

            menu.setAttribute("id", "context-image-search");
            menu.setAttribute("class", "menu-iconic");
            menu.setAttribute("label", _localize("searchImage"));
            menu.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK6wAACusBgosNWgAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAElSURBVDiNY/z//z8DJYCRkIKsthv/kRX9Z2BgmFalARdiIcaGKZXqcH5O+01U+ay2G3MYGBiSiXUmmofnsBDSjEUTMkiBe2Eq1JnZ7TcZBHhZGNythBl0lLkZODmYGX7++sdw/sZnhl3H3zF8+voHwwsYFkR5ijNICLMzTF31hOHnr38MHGxMDJlhMgwv3vxkWL7jJYpaJmzu0lTigWtmYGBg+PHrH8P0VU8YtJV5MNRiNYCfmxmuGQZ+/PrHwMmOqRyrAX///WfgYEOV4mBjwjAUpwHHL31iyA6XgRvCwcbEkBUmw3DuxmcMtVgDkYONicHLVoTBSJOXgYONieHHz38Ml+98Ydh88DXDtx//CBtACmBiYGCYS4H+OYyU5kasgUgKAADN8WLFzlj9rgAAAABJRU5ErkJggg==");

            var mInsNode = document.getElementById("context-sep-copyimage");
            mInsNode.parentNode.insertBefore(menu, mInsNode);

            var menuPopup = menu.appendChild(document.createElement("menupopup"));

            var mItemsList = [
                [
                    "Google",
                    "https://www.google.com/searchbyimage?image_url=",
                    "data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAA9IVCSvSFQuf0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULk9IVCSvSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQuf0hUL/9IVC//SFQv/0hUL/9Y1O//rIq//+7+f//eXX//vUvf/7z7X/96Fu//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vYwv/97OH/9ZRZ//SFQv/0hUL/9IhG//zbx//3om7/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97uX/+buW//SFQv/0hUL/9IVC//SFQv/5upT/+9O6//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+b6b//zezP/0iEf/9IVC//SFQv/1klf//ezh//vPtP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/3qXr/+siq//m8lv/5wqD//vTu//3t4//1klb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0h0b//vbx//zi0//1j1H/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2nmn/+bmS/////v/4sIX/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5uJH///v5//eoef/1jU//+82y//afav/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vXw//vOs//0hUL/9IVC//ekcf/96+D/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//728v/4sIX/9IVC//SFQv/4s4n///v4//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6yKn/+byX//SFQv/0hkT//eTV//vWv//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IZE//m6lP/5u5b//OHQ///+/f/6y6//96d3//SFQv/0hUL/9IVC//SFQv/0hULm9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSfSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAA9IVCAPSFQif0hUKt9IVC8vSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvL0hUKt9IVCJ/SFQgD0hUIo9IVC7/SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULv9IVCKPSFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVC8fSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvP0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YtL//i2jv/828f//vLr///7+P///Pv//vTu//3n2v/6zbH/96Nw//SFQ//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ekcv/+8+z////////////+9fD/+9K5//m9mf/4to7/+buV//vSuf/++PT//OPT//aYYP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2l13///r3/////////fv/+b2Z//SIRv/0hUL/9IVC//SFQv/0hUL/9IVC//WNT//84M///vXv//aZYf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vPtP////////////i0i//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//WQUv///Pr//OPU//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//eTV///////+9O7/9IVD//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//3m2P//////9ppi//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/718H///////3s4f/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vDn///////4soj/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//erff////////38//WTWP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//iziv////////////iwhf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rMsP///////eXW//WSVv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/4sYb///z7/////////Pv/9ZFV//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ixhv/+8Of//vn1//rMsP/4rH//9plh//WQUv/1j1L/+s2x//////////////////m9mf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SGQ//2nmn/+buW//vNsv/82sb//e3j/////////////////////v/5wZ//9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/83Mj////////////++fb/+K+C//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9ZRZ/////////////vTt//aaYv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/1lFr////////////6xqf/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ehbf/70bj//end//3o2////v3///////3l1//0iEb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5wqD////////////96t7/96Z2//WOUP/2nWf//NvH//zcyP/1i0z/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/96l6/////////////vLr//WPUf/0hUL/9IVC//SFQv/0h0b//end//3k1f/0iUn/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/8387////////////4sYf/9IVC//SFQv/0hUL/9IVC//SFQv/6w6L///////nBn//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC///69////////vj1//SIR//0hUL/9IVC//SFQv/0hUL/9IVC//m+mv///////e3j//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL///r3///////8387/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+syw///////++fb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/95NX///////vUvP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97OH///////7y6//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//i2jv///////N/O//SFQv/0hUL/9IVC//SFQv/0hUL/96Nx////////////+s2x//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IdF//zh0P//+/j/9ZJW//SFQv/0hUL/9IVC//SKSv/96t7///////738v/1k1f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YxN//vUvf/96+D/96Z0//WNT//3om///ebY/////////Pv/+LKI//WVW//0h0X/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//agbP/7zbL//enc//749P////////////////////////////3r4P/3p3f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8/SFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVCJ/SFQu/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC7/SFQif0hUIA9IVCJfSFQq30hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8fSFQq30hUIl9IVCAIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAB"
                ],
                [
                    "Yandex",
                    "http://images.yandex.ru/yandsearch?rpt=imagedups&text=&img_url=",
                    "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=="
                ],
                [
                    "TinEye",
                    "http://www.tineye.com/search/?pluginver=firefox-1.0&url=",
                    "data:image/x-icon;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAACxeDVItHk157iAO//WtW7/482G/+XOhv/lzYL/1L98/5mTcf8UKUP/CwsM/xwcG/8AAAD/AAAA/wAAAOcAAA5ItHo25LV7Nv+1ezb/tXs2/8GPSf/EoGj/s5hw/6KPdf93bWT/ZFdK/2daTP9hVEj/XU9C/zIpH/8EAgH/AAAA5LV7Nv+1ezb/tXs2/7V7Nv+1ezb/uIA+/8eea//Wtof/48eU/+PKkv/iyJP/4MeV/9u/kf/HqHz/rI1p/3tmT/+1ezb/tXs2/7V7Nv+1ezb/zKV0/+PKlP/hxXr/zbFk/8esYf/VuW7/3sFz/+LFdf/gw3P/48Z3/+nPjv/dwJD/tXs2/7V7Nv+1ezb/y6Nx/9/Gg/+NekT/V0wv/5uSfP95cmH/JiES/zAqGv86Mh3/W08v/3lpQP+Wg03/zLFn/7V7Nv+1ezb/uoVH/8myg/+VgUr/AAAA/2xpZf/i4+X/+fn5/0JAO/8AAAD/LCkl/768uf+/vr3/Mi8q/x0ZEP+2fDf/tXs2/6WGX/+pklP/JyES/0dFQP96eHX/W1tc//////9ua2X/DAoH/6Wim/+EhIX//////6ejnP8AAAD/wo1F/8GLQ//Conf/tZ1e/wYDAP9pZmH/6+vs/9/f3/////3/Pjoz/zo2Lf/Jycb/UlJT//////+xraX/AAAA/8OORv/Djkb/1bF+/821cf83MSD/MC4s//n49P//////l5OJ/wMCAP9IRDr/////////////////ZGBW/wAAAP/Djkb/w45G/8qkcP+sllr/wKtw/zw5Mf9MSUb/VlNM/wIBAP8AAAD/FxUP/9PQyv/8+/j/rKig/wkHA/8AAAD/w45G/8OORv+1jlj/l4hm/8etZv/QuHf/m4xk/21hSP9PRjX/Mi0j/xsYFf87NzD/VFBK/xUVFf8FBwz/CQsQ/8OORv/Djkb/g2I1/8Oea//Mt4z/uJxU/56hhv92nLj/l6ut/56poP+gpJL/mJeC/5aMbP+bjmv/m49t/52Qbv/Djkb/uItP/05PUP+zjlv/yptc/9C3jP9gYFP/ABVH/wAzc/8IP4T/FUuM/xhSmP99lZ3/5sRv/9S6cf/Lsmr/w45G/1B7rv8bbdT/LWy5/8OORv/Djkf/yqRw/zswIP8AAAD/AAAA/wAAAP8AAAD/Fyk8/5CKZ/+ahU3/modW/8GNReeEj5r/L37g/0Jxqf/Cjkf/w45G/8OORv/Fllb/clYw/zoqFf8hGQ3/IhwU/x4ZFf9HRUD/vaJ5/86pdee+ikU/woxEyZ6HZ/+8jEz/w45G/8OORv/Djkb/w45G/8OORv/Djkb/v4tF/8ORTf/GlFD/xJBJ/8KMRMm+ikU/gAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAE="
                ]
            ];

            function mItemCreate(name, link, image) {
                var mItem = document.createElement("menuitem");
                mItem.setAttribute("class", "menuitem-iconic");
                mItem.setAttribute("src", image);
                mItem.setAttribute("label", name);
                mItem.link = link;
                menuPopup.appendChild(mItem);
            }
            mItemsList.forEach(function(elem) {
                mItemCreate(elem[0], elem[1], elem[2]);
            });

            var contextMenu = this.contextMenu;

            menuPopup.gObj = this;
            menuPopup.setAttribute("oncommand", "this.gObj.commandHandlerSearchImage(event);");
            menuPopup.setAttribute("onclick", "checkForMiddleClick(this, event);");
            addEventListener("popupshowing", this, false, contextMenu);
        }
    }
    contextSearcherObj.init();
})();

2k1dmg пишет:

bunda1
Убрал изменение меню при закрытии и
добавил "Поиск по изображени"

Получается отличная кнопка, но было бы не плохо если меню поисковиков открывалась и в текстовых полях, для этого можно поставить наблюдатель на пункт Копировать в контекстном меню страницы:

Выделить код

Код:

var copy = document.getElementById('context-copy');
var observeStatus = new MutationObserver(function() {
           menu.hidden = copy.hidden || copy.disabled;         
   });
observeStatus.observe( copy, { attributes: true, attributeFilter: ["hidden", "disabled"] } );
addDestructor(function() { observeStatus.disconnect() });

И мне кажется код для отслеживания изменения поисковиков в about:config можно сделать компактней:

Выделить код

Код:

var s = 'browser.search.';
gPrefService.addObserver( s, this, false );
addDestructor(function() { gPrefService.removeObserver( s, this, false ) });

И наверно можно обойтись одним обработчиком:

Выделить код

Код:

addEventListener("popupshowing", this, false, contextMenu);

2k1dmg пишет:

hideDefaultEngineInList: true

Извини, не заметил. :blush:

Создана новая кнопка и по умолчанию скрыта = скрипт не работает.
А теперь вопрос: можно ли сделать, чтобы она работала или это ограничения дополнения/браузера?


upd:
в http://forum.mozilla-russia.org/viewtop … 09#p628009 показываются только 3 поиска по сайту (Google, Yandex, Bing), должно же быть пять или нет?

Выделить код

Код:

            }
            function siteSearch_mItemCreate() {
                var namesList = [];
                if (options.siteSearch.useDefaultNamesList) {
                    let defaultNamesList = [
                        ["Google", ["Google"]],
                        ["Yandex", ["Yandex", "Яндекс"]],
                        ["Yahoo", ["Yahoo"]],
                        ["Bing", ["Bing"]],
                        ["DuckDuckGo", ["DuckDuckGo"]]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }

+
Сделайте пожалуйста, чтобы учитывало эту настройку - user_pref("browser.search.context.loadInBackground", true);

Northtech, если у тебя в панели поиска не присутствуют эти поисковики или их названия отличаются от указанных в коде , то они не будут отображаться в контекстном меню.

PEAKTOP пишет:

Northtech, если у тебя в панели поиска не присутствуют эти поисковики или их названия отличаются от указанных в коде , то они не будут отображаться в контекстном меню.

Ага, спасибо, поисковики присутствуют, но названия другие.

Но насчет настройки (browser.search.context.loadInBackground) пожелание все же остаётся. :)

Northtech
только вместо browser.search.context.loadInBackground
добавил options.loadInBackground

Выделить код

Код:

(function () {
    // Context Search mini 2013-10-09
    var options = {
        loadInBackground: false,
        // true - открывать вкладки в фоне
        pinnedEngineName: "",
        // оставить пустым если не нужно закреплять
        // определенный поисковик
        // примеры pinnedEngineName: "Google" или pinnedEngineName: "Яндекс" или pinnedEngineName: ""
        hideDefaultEngineInPopupSubMenu: false,
        // true - не добавлять поисковик по умолчанию в выпадающий список (подменю) поисковиков
        campactMenu: true,
        // true - поисковики в выпадающем списке (подменю) без назаваний
        campactMenuLengthPerLine: 5,
        // максимальное количество элементов в одной строке
        // от 3 до 10, по умолчанию 5
        searchBySite: {
            enable: true,
            // true - добавить поисковики по сайту
            iconsOn: true,
            // true - добавить иконки для поисковиков по сайту
            useDefaultNamesList: true,
            // true - использовать список поисковиков по умолчанию
            addCustomNames: false,
            // true - добавить свои поисковики по сайту
            customNamesList: [
                ["Rambler", ["Rambler", "Рамблер"]]
            ]
            // например ["Rambler", ["Rambler", "Рамблер"]]
            // первая ячека название на английском
            // вторая ячека массив с предполагаемыми именами поисковика
            // может состоять из нескольких значений
            // ["Name1", ["Name1"]],
            // ["Name2", ["Name2", "Имя2"]],
            // ["Name3", ["Name3", "Имя3", "Név3"]]
        },
        searchImageByText: {
            enable: true,
            // true - добавить поиск изображения по тексту
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        },
        searchByImage: {
            enable: true,
            // true - добавить поиск по изображению
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        },
        searchInCache: {
            enable: true,
            // true - добавить поиск в кэше
            // нужно доработать
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        }
    };
    function _localize(sid) {
        let strings = {
            en: {
                searchBySite: "Search this site",
                searchImageByText: "Search image by text",
                searchByImage: "Search by image",
                searchInCache: "Search this page in cache"

            },
            ru: {
                searchBySite: "Поиск по этому сайту",
                searchImageByText: "Поиск изображения по тексту",
                searchByImage: "Поиск по изображению",
                searchInCache: "Поиск этой страницы в кэше"
            }
        };
        //let locale = (Application.prefs.getValue("general.useragent.locale", false) || "en").match(/^[a-z]*/)[0];
        function getBrowserUILocale() { // Browser UI locale
            return Components.classes["@mozilla.org/chrome/chrome-registry;1"]
                            .getService(Components.interfaces.nsIXULChromeRegistry)
                            .getSelectedLocale("global");
        }
        let locale = ""; // ru, en
        if (!locale || locale == "")
            locale = getBrowserUILocale().match(/^[a-z]*/)[0];
        _localize = function (sid) {
            return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
        };
        return _localize.apply(this, arguments);
    }

    let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    let XHTMLNS = "http://www.w3.org/1999/xhtml"

    var contextSearcherObj = {
        initialized: false,
        init: function() {
            if(this.initialized)
                return;
            this.initialized = true;

            this.nodeIds = {
                searchMenu: "contextSearchMiniByBunda1-menu",
                searchMenuPopup: "contextSearchMiniByBunda1-popup",
                searchByImageMenu: "contextSearchMiniByBunda1-image-search-menu",
                searchByImageMenuPopup: "contextSearchMiniByBunda1-image-search-popup"
            };

            if (document.getElementById(this.nodeIds.searchMenu))
                return;

            var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
            var contextMenu = document.getElementById("contentAreaContextMenu");
            var searchSelect = document.getElementById("context-searchselect");
            searchSelect.style.display = "none";

            var searchMenu = contextMenu.insertBefore(document.createElementNS(XULNS, "menu"), searchSelect);

            this.searchService = searchService;
            this.contextMenu = contextMenu;
            this.searchSelect = searchSelect;
            this.searchMenu = searchMenu;

            this.param = {
                isPinnedEngine: false,
                pinnedEngineName: ""
            };

            try {
                this.createSearchMenu();
                if (options.searchByImage.enable)
                    this.createSearchByImageMenu();
            } catch (ex) {
                this.destroy();
                Components.utils.reportError(ex);
                return;
            }

            if (options.campactMenu)
                this.loadStyles();

            var observeStatus = new MutationObserver(function () {
                    searchMenu.hidden = searchSelect.hidden;
                });
            observeStatus.observe(searchSelect, {
                attributes: true,
                attributeFilter: ["hidden"]
            });

            /*var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                        .getService(Components.interfaces.nsIPrefService);
            this.branch = prefService.getBranch("browser.search.");
            if (!("addObserver" in this.branch))
                this.branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
            this.branch.addObserver("", this, false);*/

            /*
            var searchPref = "browser.search.";
            gPrefService.addObserver(searchPref, this, false);*/

            let os = Cc["@mozilla.org/observer-service;1"].
                        getService(Ci.nsIObserverService);
            os.addObserver(this, "browser-search-engine-modified", false);

            Services.ww.registerNotification(this);

            addEventListener("popupshowing", this, false, contextMenu);

            addDestructor(function (reason) {
                observeStatus.disconnect();
                Services.ww.unregisterNotification(this);
                //this.branch.removeObserver("", this);
                //gPrefService.removeObserver(searchPref, this, false);
                os.removeObserver(this, "browser-search-engine-modified", false);
                this.destroy();
                if (reason != "destructor")
                    this.unloadStyles();
            }, this);
        },
        destroy: function() {
            if(!this.initialized)
                return;
            this.initialized = false;
            var contextMenu = this.contextMenu;
            if (!contextMenu)
                return;
            if (this.searchMenu)
                contextMenu.removeChild(this.searchMenu);
            if (this.searchByImageMenu)
                contextMenu.removeChild(this.searchByImageMenu);
            if (this.searchSelect)
                this.searchSelect.style.removeProperty("display");
        },
        update: function() {
            this.searchMenu.textContent = "";
            this.createSearchMenu();
        },

        get isSeaMonkey() {
            delete this.isSeaMonkey;
            return this.isSeaMonkey = Services.appinfo.name == "SeaMonkey";
        },

        observe: function(subject, topic, data) {
            switch (topic) {
                case "domwindowclosed":
                    if (subject.document.documentElement.getAttribute("windowtype") == "Browser:SearchManager") {
                        this.update();
                    }
                    break;
                /*case "nsPref:changed":
                    switch (data) {
                        case "defaultenginename":
                        case "browser.search.defaultenginename":
                            this.update();
                            break;
                    }
                    break;*/
                case "browser-search-engine-modified":
                    switch (data) {
                        case "engine-current": // engine-default
                        case "engine-changed":
                        case "engine-removed":
                            this.update();
                            break;
                    }
                    break;
            }
        },
        handleEvent: function(e) {
            //var contextMenu = this.contextMenu;
            //var menu = this.menu;
            //var imageMenu = this.imageMenu;
            switch (e.type) {
                case "popupshowing":
                        this.popupshowingEvent(e);
                    break;
            }
        },
        popupshowingEvent: function(e) {
            var trgId = e.target.id;
            if (trgId) {
                if (trgId == "contentAreaContextMenu") {
                    this.contextMenuPopup(e);
                    if (this.searchByImageMenu)
                        this.searchByImageMenuPopup(e);
                } else if (trgId == this.nodeIds.searchMenuPopup)
                    this.searchMenuPopup(e);
            }
        },

        _stylesLoaded: false,
        loadStyles: function() {
            if(this._stylesLoaded)
                return;
            this._stylesLoaded = true;
            var sss = this.sss;
            var cssURI = this.cssURI = this.makeCSSURI();
            if(!sss.sheetRegistered(cssURI, sss.USER_SHEET))
                sss.loadAndRegisterSheet(cssURI, sss.USER_SHEET);
        },
        unloadStyles: function() {
            if(!this._stylesLoaded)
                return;
            this._stylesLoaded = false;
            var sss = this.sss;
            if(sss.sheetRegistered(this.cssURI, sss.USER_SHEET))
                sss.unregisterSheet(this.cssURI, sss.USER_SHEET);
        },
        get sss() {
            delete this.sss;
            return this.sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]
                .getService(Components.interfaces.nsIStyleSheetService);
        },
        makeCSSURI: function() {
            var cssStr = '\
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\n\
@-moz-document url("' + window.location.href + '") {\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n\
        /*width: 2em !important;*/\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] * {\n\
        /*padding-left: 0 !important;\n\
        padding-right: 0 !important;\n\
        margin-left: 0 !important;\n\
        margin-right: 0 !important;*/\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > spacer[campactMenu="true"] {\n\
        width: 2em !important;\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n\
        width: 3em !important;\n\
        height: 2em !important;\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox >.menuitem-iconic[campactMenu="true"] > image {\n\
        margin-left: .8em !important;\n\
    }\n\
}\n\
';            return Services.io.newURI("data:text/css," + encodeURIComponent(cssStr), null, null);
        },

        searchCommandHandler: function(event, trg) {
            var inBg = options.loadInBackground || false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = !inBg;
            }
            var searchBySite = "";
            if (event.target.hasAttribute("searchBySite"))  {
                searchBySite = " site:" + gBrowser.currentURI.host;
            } else if (event.target.hasAttribute("searchInCache")) {
                searchBySite = content.location.href;
            }
            let selectedText = this.isSeaMonkey ? content.getSelection() : getBrowserSelection();
            if (event.target.engine.imageLink) {
                gBrowser.loadOneTab(event.target.engine.imageLink + /*getBrowserSelection()*/ selectedText, {
                    relatedToCurrent: true,
                    inBackground: inBg
                });
            } else if (event.target.engine.cacheLink) {
                gBrowser.loadOneTab(event.target.engine.cacheLink + /*getBrowserSelection()*/ searchBySite, {
                    relatedToCurrent: true,
                    inBackground: inBg
                });
            } else {
                let submission = event.target.engine.getSubmission(/*getBrowserSelection()*/ selectedText + searchBySite, null);
                gBrowser.loadOneTab(submission.uri.spec, {
                    relatedToCurrent: true,
                    postData: submission.postData,
                    inBackground: inBg
                });
            }
            if (trg == "menu") {
                setTimeout(function () {
                    document.getElementById("contentAreaContextMenu").hidePopup();
                }, 0);
            }
        },
        contextMenuPopup: function(e) {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.searchMenu;

            //var selectedText = getBrowserSelection(16);
            let selectedText = this.isSeaMonkey ? content.getSelection(16) : getBrowserSelection(16);
            if (!selectedText)
                return;
            var ellipsis = "\u2026";
            try {
                ellipsis = gPrefService.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
            } catch (ex) { }
            if (selectedText.length > 15)
                selectedText = selectedText.substr(0,15) + ellipsis;
            var engineName = this.param.isPinnedEngine ? this.param.pinnedEngineName : searchService.defaultEngine.name;
            var menuLabel;
            var searchFormattedString = [
                "contextMenuSearch",
                "contextMenuSearchText",
                "searchSelected"
            ];
            var _this = this;
            function getMenuLabel(str) {
                try {
                    if (_this.isSeaMonkey) {
                        let bundle = document.getElementById("contentAreaCommandsBundle");
                        return bundle.getFormattedString(str, [engineName, selectedText]);
                    } else
                        return gNavigatorBundle.getFormattedString(str, [engineName, selectedText]);
                } catch (ex) {
                    return false;
                }
            }
            for(let i in searchFormattedString) {
                menuLabel = getMenuLabel(searchFormattedString[i]);
                if (menuLabel)
                    break;
                else if (!menuLabel && i == searchFormattedString.length-1)
                    menuLabel = engineName;
            }
            menu.label = menuLabel;
        },
        searchMenuPopup: function(e) {
            var popup = e.target;
            var items;
            if (!popup.items) {
                var itemsObj = popup.getElementsByTagName("menuitem");
                popup.items = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menuitem" &&
                            elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        popup.items.push(elem);
                });
                items = popup.items;
            } else {
                items = popup.items;
            }
            var menus;
            if (!popup.menus) {
                var itemsObj = popup.getElementsByTagName("menu");
                popup.menus = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menu" &&
                            elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        popup.menus.push(elem);
                });
                menus = popup.menus;
            } else {
                menus = popup.menus;
            }
            var siteSearchDomain;
            var gBrowser = gBrowser || getBrowser();
            function isDomain() {
                try {
                    siteSearchDomain = gBrowser.currentURI.host;
                } catch (ex) {
                    return false;
                }
                return true;
            }
            if (isDomain()) {
                items.forEach(function(elem) {
                    //if (elem.hasAttribute("searchBySite"))
                    //    elem.setAttribute("tooltiptext", siteSearchDomain);
                    elem.removeAttribute("disabled");
                });
                menus.forEach(function(elem) {
                    if (elem.hasAttribute("searchBySite"))
                        elem.setAttribute("tooltiptext", siteSearchDomain);
                    else if (elem.hasAttribute("searchInCache"))
                        elem.setAttribute("tooltiptext", content.document.title);
                    elem.removeAttribute("disabled");
                });
            } else {
                items.forEach(function(elem) {
                    //if (elem.hasAttribute("searchBySite"))
                    //    elem.removeAttribute("tooltiptext");
                    elem.setAttribute("disabled", "true");
                });
                menus.forEach(function(elem) {
                    if (elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        elem.removeAttribute("tooltiptext");
                    elem.setAttribute("disabled", "true");
                });
            }
        },
        createSearchMenu: function() {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.searchMenu;

            var engines = searchService.getVisibleEngines({});

            menu.setAttribute("id", this.nodeIds.searchMenu);

            menu.setAttribute("class", "menu-iconic");
            this.param.isPinnedEngine = false;
            this.param.pinnedEngineName = "";
            var pinnedEngineName = options.pinnedEngineName;
            if (pinnedEngineName != "") {
                for (let i in engines) {
                    if (engines[i].name != pinnedEngineName)
                        continue;
                    menu.setAttribute("label", engines[i].name);
                    menu.setAttribute("image", engines[i].iconURI.spec);
                    menu.engine = engines[i];
                    this.param.isPinnedEngine = true;
                    this.param.pinnedEngineName = pinnedEngineName;
                    break;
                }
            }
            if (!this.param.isPinnedEngine) {
                menu.setAttribute("label", searchService.defaultEngine.name);
                menu.setAttribute("image", searchService.defaultEngine.iconURI.spec);
                menu.engine = searchService.defaultEngine;
            }

            menu.gObj = this;
            menu.setAttribute("onclick", "if (event.target == this && event.target.engine) this.gObj.searchCommandHandler(event, 'menu');");

            menu.popup = menu.appendChild(document.createElementNS(XULNS, "menupopup"));
            var popup = this.searchMenu.popup;
            popup.setAttribute("id", this.nodeIds.searchMenuPopup);

            var counterMaxLength = options.campactMenuLengthPerLine;
            if (typeof counterMaxLength != "number" ||
                3 > counterMaxLength || counterMaxLength > 10)
                counterMaxLength = 5;
            var counter = 0;
            var hBox;
            function itemCreateCampact(engine, last) {
                if(counter == 0) {
                    hBox = document.createElementNS(XULNS, "hbox");
                    let item = document.createElementNS(XULNS, "spacer");
                    //item.setAttribute("style", "width: 2em");
                    item.setAttribute("campactMenu", "true");
                    hBox.appendChild(item);
                }
                counter++;
                var item = document.createElementNS(XULNS, "menuitem");
                item.engine = engine;
                item.setAttribute("class", "menuitem-iconic");
                item.setAttribute("tooltiptext", engine.name);
                //item.setAttribute("src", engine.iconURI.spec);
                var image = document.createElementNS(XULNS, "image");
                image.setAttribute("src", engine.iconURI.spec);
                item.appendChild(image);
                //item.setAttribute("style", "max-width: 2em");
                item.setAttribute("campactMenu", "true");
                hBox.appendChild(item);
                if (counter == counterMaxLength || last) {
                    popup.appendChild(hBox);
                    counter = 0;
                }
            }

            var separator = {};
            function itemCreate(engine, reason) {
                var item = document.createElementNS(XULNS, "menuitem");
                item.setAttribute("class", "menuitem-iconic");
                item.engine = engine;
                if (reason && !separator[reason]) {
                    /*let sep = separator[reason] = document.createElementNS(XULNS, "menuseparator");
                    sep.setAttribute(reason, "true");
                    popup.appendChild(sep);

                    let item = document.createElementNS(XULNS, "label");
                    //item.setAttribute("class", "menuitem-iconic");
                    item.setAttribute("value", _localize(reason) + ":");
                    item.setAttribute("style", "padding-left: 2em");
                    popup.appendChild(item);*/

                    if (!separator["menuseparator"]) {
                        let sep = separator["menuseparator"] = document.createElementNS(XULNS, "menuseparator");
                        popup.appendChild(sep);
                    }

                    let subMenu = separator[reason] = document.createElementNS(XULNS, "menu");
                    subMenu.setAttribute("class", "menu-iconic");
                    subMenu.setAttribute("label", _localize(reason));
                    subMenu.setAttribute(reason, "true");
                    subMenu.popup = subMenu.appendChild(document.createElementNS(XULNS, "menupopup"));
                    popup.appendChild(subMenu);
                }
                if (reason == "searchBySite") {
                    item.setAttribute("label", engine.name);
                    if (options.searchBySite.iconsOn) {
                        item.setAttribute("src", engine.iconURI.spec);
                    }
                    item.setAttribute(reason, "true");
                } else if (reason == "searchImageByText" ||
                            reason == "searchInCache") {
                    item.setAttribute("label", engine.name);
                    item.setAttribute("src", engine.iconURI_spec);
                    item.setAttribute(reason, "true");
                } else {
                    item.setAttribute("label", engine.name);
                    item.setAttribute("src", engine.iconURI.spec);
                }
                //popup.appendChild(item);
                if (reason) {
                    let subMenu = separator[reason];
                    subMenu.popup.appendChild(item);
                } else
                    popup.appendChild(item);
            }
            for (let i in engines) {
                if (options.hideDefaultEngineInPopupSubMenu &&
                        this.param.isPinnedEngine &&
                        engines[i].name == pinnedEngineName ||
                        options.hideDefaultEngineInPopupSubMenu &&
                        !this.param.isPinnedEngine &&
                        engines[i].name == searchService.defaultEngine.name) {
                    continue;
                }
                if (options.campactMenu)
                    itemCreateCampact(engines[i], i == engines.length-1);
                else
                    itemCreate(engines[i]);
            }
            function searchBySite_itemCreate() {
                var namesList = [];
                if (options.searchBySite.useDefaultNamesList) {
                    let defaultNamesList = [
                        ["Google", ["Google"]],
                        ["Yandex", ["Yandex", "Яндекс"]],
                        ["Yahoo", ["Yahoo"]],
                        ["Bing", ["Bing"]],
                        ["DuckDuckGo", ["DuckDuckGo"]]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchBySite.addCustomNames &&
                        Array.isArray(options.searchBySite.customNamesList)) {
                    namesList = namesList.concat(options.searchBySite.customNamesList);
                }
                //let i_skips = [];
                function isNameExist(names, engine) {
                    for (let i in names) {
                        if (names[i] != engine && i != names.length-1)
                            continue;
                        else if (names[i] == engine)
                            return true;
                        return false;
                    }
                }
                namesList.forEach(function(elem) {
                    for (let i in engines) {
                        if (/*i_skips.indexOf(i) != -1 ||*/
                            !(elem[1].some(function(listName) listName == engines[i].name))
                            /*!isNameExist(elem[1], engines[i].name)*/
                            /*elem[1].indexOf(engines[i].name) == -1*/)
                            continue;
                        itemCreate(engines[i], "searchBySite");
                        //i_skips.push(i);
                        break;
                    }
                });
            }
            if (options.searchBySite.enable) {
                searchBySite_itemCreate();
            }

            function searchImageByText_itemCreate() {
                var namesList = [];
                if (options.searchImageByText.useDefaultNamesList) {
                    let defaultNamesList = [
                        [
                            "Google",
                            "https://www.google.ru/search?tbm=isch&q=",
                            "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB41BMVEUAAAB7wUJ6wUJ6wUJ6wUL1nxn1oBn1oBn1nxl6wUJ6wUJ6wUJrvUT1mxr1nxn1nxlfu0Z8wkLznhv0mhp6wUJWuUdaukfLrSv4rhX1nxl5wUJyv0TQrCnyjhz1kyH2pRj1oBl7wkNbukfzjR3zkxv1liHuMDXuGTf2rxN7wUJeu0apuDfzjhz1nBvuNizwZi/3sxP2pBh9wkGvuTbvoRvuJy/xcC33qRhbl7F2uGOMwT94havnRTzuMjjwTTNRislRjcZ5uVpnvU0rk9Fhjr3aTkPuLTVQkM1PgsKHxD9/w0JfnKsAouPtHCTvQDRRkM1Qjstfn6p2jLHvOzDvQDVQkM1Rkc1RjstOh8Z/h6buLirtGyTvOzHvQDXwQDVPkcftPzdRkc1QkMxRkM0xlNLuNSzwQDXvQDVQkM1Rkc1QkM1Rkc3vQDTvQDXvQDXwQDV7wUL2oBr1nxn2oBl6wUJ7wkN9wkF9wkJ6wUP0lRv3qhf1oBn4rhX3qhb1nhp8wkL0nBruGjLuIzf3qRZ/w0JcukbuLCntIzl+wkFkvEbtGyVPhMRyv0QAmNfuLCruMDVRkc1ViccKltTvQDVRhcUAmdfvQDRRks5RiskcltTwQzdQkM07k9DtGyPvQzdQkMzvPzSgiRCBAAAAcHRSTlMAM9bsfmzq30TnaEIQF1b390JR9nP98873iO4nsPyvO3Vly1783sVB8T/5j+2SiIXyKITTeqTRY0ThWl/g9jAn2cBPbNfJFWXVrOjTge5EeeC0qPBsYPfUstjGvOP+dnp0+pmBR1GEikvl8paC8etfYXu9TgAAAAlwSFlzAAAASAAAAEgARslrPgAAAQJJREFUGNM1j8VWQzEARAco8NDiLsXdXQvF3d3dIQ2vOBR3CQSCFPtUUg7Mbu5i7hnY2Npp8Bd7B0cFToQQZxdXwE1xN9JVLVRiUsmah6eXNzVKQOFD1PUNXz//za0ASul2IKBRg4IREroThnAt1cmlCFMkoqJ3Y2LjEL+nSJBgTkxK3k9JPThMSz/KsMoyj0+ysoGc07PcvF97fsH5RSFQVHxZUmrt+quycvO1oeKmsur2rlqCGlaLuvqG+4dGNPFmCVpYK9D2+NQOdIhOoKubPff0vrz29Q8MvvGhYTAZC3sfGf34FFwIgTHLFxufmASmpme+OeeYnZtf+L+/uLS88gMT2kW5QAjbFwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0wNC0wNlQxMDoxMzowNSswNDowMIQ8zwwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMDQtMDZUMTA6MTM6MDUrMDQ6MDD1YXewAAAAAElFTkSuQmCC"
                        ],
                        [
                            "Yandex",
                            "http://images.yandex.ru/yandsearch?text=",
                            "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=="
                        ]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchImageByText.addCustomNames &&
                        Array.isArray(options.searchImageByText.customNamesList)) {
                    namesList = namesList.concat(options.searchImageByText.customNamesList);
                }
                namesList.forEach(function(elem) {
                    let engine = {};
                    engine.name = elem[0];
                    engine.imageLink = elem[1];
                    engine.iconURI_spec = elem[2];
                    itemCreate(engine, "searchImageByText");

                });
            }
            if (options.searchImageByText.enable) {
                searchImageByText_itemCreate();
            }

            function searchInCache() {
                var namesList = [];
                if (options.searchInCache.useDefaultNamesList) {
                    let defaultNamesList = [
                        [
                            "Google",
                            "https://www.google.com/search?q=cache:",
                            "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJgAAACAgAAAAAAAA8gIAAKMBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFESURBVDjLpZNJSwNBEIXnt4lE4kHxovgT9BDwJHqPy0HEEOJBiAuCRg+KUdC4QS4KrpC4gCBGE3NQ48JsnZ6eZ3UOM6gjaePhQU93v6+qq2q0pqgeJj2S8EdJT1hr0OxBtKCD5iEd8QxDYpvhvOBAuMDKURX9C9aPu4GA1GEVkzvMg10UBfYveWAWgYAP00V01fa+R9M2bA51wJvhIn3qR+ybt3D3JNQBE5sMjCIOLFpoHzOwdsLRO22qA6R6kiZiWwxUvy/PUQZIhYZ1vFM9cvcOOsYNdcBgysISdSJBnZjJMlR0Fw8vAp0xoz5gao/h+NZBy4i/10XGwrPA+hmvDyhVRG2Avu/LwcrkFADZa16L1h330w1RNgc3DiJzCpPYRm1bpveXX11clQR28xwblHpk1vq1iP/5mcoS0CoXDZiL0vsJ+dzfl+3T/VYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAK5SURBVFjDxVfrSxRRFJ9/Jta/oyWjF5XQm6D6EkHRgygIIgjUTcueVgqVWSRRkppEUQYWWB8ye1iGWilWlo/Ude489s7M6Zw7D9dlt53dmd29cFiWvXvO77x+51xpaaUsoSxBaUWZQ4ECy5xji2xKZDyCMlMEw6lCNiOSgwZKJK1SkcKeSealfP64t0mBjl4Ow39MkDUL0p2RSROOtqhZdeUEYM1pBl39XCg/fEeFtWcY7G9W4csvUxjlBkCsQ4Nt9QyWVfvT6RsAKXw3aoDGATZeYIt+W1kjw7cJG0RctWDTRebbKd8A6h5pwsDb70ba3w/eUr3wt/cmwgfw6Yft4TNMQaY7o1P2ncm4FT4ANQH/jQBJ2xv7kqIXEADDql8eS3+n8bku7oxNm+EDIM/dU92upb3T/NJGeaNbDx/AsbsLRUY5Xn92caWXY5d8RV6gWllxSg4fAEnTC90DQW13BLlgXR2D3dcUeDVkwOthA1bXspxILWcm3HdThcfvufB26LcJpkOEAz9NKI/lzqpSEC7feol5EWnpSeSlIxCALUkApmULdjUqxQVAQnl3D/X/yQda4QBEq2TYc12By091MQ17Bg3R88nHKlQbVmHvj89awNBLYrwT9zXY2aBAxTkGFdiSxP/Jp6FLDw+AS7GfsdJTJ2EqSO5khD43nGfBARy/ZxOQgZHe7GPM1jzUvChUtmnBAXQPcKGMJp3fdFGq6NByEhiAO4b/YptFfQJwNyQ/bZkVQGcf90Ja25ndIyrKBOa/f8wIpwi3X1G8UcxNu7ozUS7tiH0jBswwS3RIaF1w6LYKU/ML2+8sGnjygQswtKrVIy/Qd9qQP6LnO64q4fPAKpxyZIymHo1jWk6p1ag2BsdNwQMHcC+M5kHFJX+YlPxpVlbCx2mZ5DzPI04k4kUwHHdskU3pH76iftG8yWlkAAAAAElFTkSuQmCC"
                        ],
                        [
                            "Archive.org",
                            "http://web.archive.org/web/*/",
                            "data:image/x-icon;base64,AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABILAAASCwAAAAAAAAAAAAABAQH/AQEB/wEBAf8BAQH/AgIC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wAAAP8BAQH/AQEB/wAAAP8CAgL/AgIC/wEBAf8CAgL/AQEB/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BQUF/wUFBf8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wUFBf8EBAT/BAQE/wQEBP8FBQX/BQUF/wEBAf8AAAD/AQEB/wICAv8BAQH/AAAA/wAAAP8CAgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8AAAD/AgIC/wEBAf8BAQH/BgYG/wAAAP+ysrL/4uLi/9/f3//g4OD/4ODg/9/f3//g4OD/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4ODg/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/3d3d/97e3v8qKir/AQEB/wMDA/8BAQH/AgIC/wAAAP8EBAT/AAAA/7CwsP/Hx8f/w8PD/8fHx//FxcX/xcXF/8XFxf/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/FxcX/xcXF/8bGxv/FxcX/xcXF/8XFxf/Dw8P/1NTU/ywsLP8AAAD/BAQE/wEBAf8AAAD/AAAA/wEBAf8BAQH/AAAA/0pKSv9NTU3/TExM/0xMTP9LS0v/TExM/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/0xMTP9NTU3/TU1N/0xMTP9MTEz/SkpK/01NTf8SEhL/AAAA/wICAv8CAgL/BAQE/wEBAf8BAQH/AQEB/wAAAP8NDQ3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3l5ef8BAQH/BgYG/wAAAP8CAgL/AQEB/wEBAf8DAwP/AAAA/wMDA/8oKCj/LS0t/zExMf8tLS3/Kioq/ysrK/8sLCz/Ly8v/zAwMP8qKir/LCws/yoqKv8oKCj/LCws/zAwMP8rKyv/KSkp/ykpKf8qKir/MDAw/y8vL/8rKyv/ERER/wAAAP8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8CAgL/AAAA/wUFBf+rq6v/7Ozs/3V1df8AAAD/AAAA/zs7O//j4+P/4uLi/zo6Ov8AAAD/AAAA/wQEBP+rq6v/7Ozs/4WFhf8AAAD/AAAA/zw8PP/k5OT/4+Pj/zk5Of8AAAD/BQUF/wAAAP8BAQH/AQEB/wAAAP8BAQH/AAAA/wMDA/8AAAD/ISEh/+Hh4f//////uLi4/wkJCf8CAgL/bW1t////////////bW1t/wICAv8CAgL/ISEh/+Hh4f//////wMDA/woKCv8CAgL/bW1t////////////bW1t/wEBAf8HBwf/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AwMD/wAAAP8cHBz/2NjY//////+4uLj/BwcH/wAAAP9lZWX//f39//////9nZ2f/AAAA/wAAAP8ZGRn/2dnZ//////+3t7f/CAgI/wAAAP9oaGj//Pz8//7+/v9mZmb/AAAA/wYGBv8AAAD/AgIC/wEBAf8BAQH/AwMD/wICAv8BAQH/AAAA/xsbG//Y2Nj//////7i4uP8GBgb/AAAA/2pqav///////v7+/2VlZf8AAAD/AAAA/xsbG//Y2Nj//////7m5uf8HBwf/AAAA/2VlZf///////////2VlZf8AAAD/BQUF/wEBAf8DAwP/AQEB/wAAAP8AAAD/AAAA/wQEBP8AAAD/HR0d/9ra2v//////urq6/wgICP8AAAD/Z2dn////////////aGho/wAAAP8AAAD/HR0d/9vb2///////urq6/wcHB/8AAAD/aGho////////////aWlp/wAAAP8FBQX/AAAA/wEBAf8BAQH/AAAA/wAAAP8AAAD/AgIC/wAAAP8cHBz/29vb//////+4uLj/BgYG/wAAAP9mZmb///////////9nZ2f/AAAA/wAAAP8aGhr/2tra//////+4uLj/BwcH/wAAAP9lZWX///////////9mZmb/AAAA/wUFBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7i4uP8GBgb/AAAA/2ZmZv///////////2dnZ/8AAAD/AAAA/xsbG//b29v//////7m5uf8JCQn/AAAA/2hoaP///////////2dnZ/8AAAD/BQUF/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMDA/8AAAD/Ghoa/9nZ2f//////ubm5/wYGBv8AAAD/ZmZm////////////ZmZm/wAAAP8AAAD/Gxsb/9ra2v//////uLi4/wcHB/8AAAD/ZmZm//7+/v/+/v7/ZmZm/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwMD/wAAAP8aGhr/2NjY//////+6urr/BgYG/wAAAP9mZmb///////////9mZmb/AAAA/wAAAP8aGhr/2NjY//////+5ubn/BwcH/wAAAP9nZ2f//v7+//////9nZ2f/AAAA/wQEBP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7q6uv8HBwf/AAAA/2ZmZv///////////2ZmZv8AAAD/AAAA/xoaGv/Y2Nj//////7i4uP8GBgb/AAAA/2ZmZv/9/f3//v7+/2ZmZv8AAAD/BAQE/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wMDA/8AAAD/HBwc/9vb2///////urq6/wgICP8AAAD/ZmZm////////////Z2dn/wAAAP8AAAD/Gxsb/9nZ2f//////urq6/wcHB/8AAAD/Z2dn////////////Z2dn/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8CAgL/BAQE/wAAAP8dHR3/29vb//////+8vLz/BwcH/wAAAP9nZ2f///////////9mZmb/AAAA/wAAAP8bGxv/29vb//////+6urr/BgYG/wAAAP9nZ2f///////////9mZmb/AAAA/wYGBv8AAAD/AQEB/wEBAf8AAAD/AQEB/wMDA/8DAwP/AAAA/x0dHf/a2tr/+fn5/7CwsP8GBgb/AAAA/2pqav/5+fn/+fn5/2tra/8AAAD/AAAA/xwcHP/Z2dn/+fn5/7m5uf8JCQn/AAAA/2xsbP/5+fn/+fn5/2tra/8AAAD/BwcH/wEBAf8CAgL/AQEB/wEBAf8CAgL/AwMD/wMDA/8AAAD/FxcX/9zc3P//////l5eX/wcHB/8DAwP/YGBg////////////XFxc/wQEBP8FBQX/GBgY/97e3v//////s7Oz/wkJCf8EBAT/XV1d////////////W1tb/wEBAf8EBAT/AQEB/wMDA/8DAwP/AAAA/wEBAf8DAwP/AQEB/wEBAf8AAAD/LS0t/1RUVP8hISH/AAAA/wAAAP8BAQH/TExM/0tLS/8AAAD/AAAA/wAAAP8AAAD/LS0t/1NTU/8bGxv/AAAA/wAAAP8BAQH/TExM/0tLS/8BAQH/AAAA/wEBAf8AAAD/AQEB/wAAAP8CAgL/AQEB/wEBAf8AAAD/BwcH/8XFxf++vr7/tbW1/729vf/Kysr/y8vL/8fHx/+2trb/tra2/8bGxv/Ly8v/yMjI/8rKyv+7u7v/tbW1/8DAwP/Ly8v/y8vL/8XFxf+1tbX/srKy/8nJyf9PT0//AAAA/wYGBv8CAgL/AAAA/wEBAf8AAAD/AQEB/wEBAf8KCgr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3Jycv8AAAD/BwcH/wEBAf8DAwP/AQEB/wAAAP8BAQH/AAAA/wgICP95eXn/fX19/319ff9/f3//gICA/4CAgP+BgYH/gICA/39/f/+BgYH/gYGB/4CAgP+AgID/gICA/4GBgf+AgID/gICA/4GBgf9/f3//fX19/3l5ef9+fn7/MjIy/wAAAP8DAwP/AQEB/wEBAf8AAAD/AQEB/wICAv8AAAD/BgYG/4+Pj/+Tk5P/j4+P/4uLi/+Hh4f/hISE/4ODg/+CgoL/gYGB/4KCgv+CgoL/goKC/4KCgv+BgYH/f39//39/f/+EhIT/hoaG/4eHh/+MjIz/kpKS/5WVlf8uLi7/AAAA/wMDA/8AAAD/AAAA/wEBAf8AAAD/AQEB/wQEBP8EBAT/SUlJ/1RUVP+BgYH/wsLC/////////////////////////////////////////////////////////////////////////////f39/6+vr/9iYmL/S0tL/xkZGf8AAAD/AwMD/wEBAf8DAwP/AQEB/wEBAf8BAQH/AAAA/wYGBv8AAAD/AAAA/wAAAP8AAAD/AQEB/wgICP9RUVH/paWl/8rKyv/a2tr/+fn5///////5+fn/2tra/8vLy/+ampr/T09P/xQUFP8DAwP/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wEBAf8CAgL/AQEB/wICAv8BAQH/AAAA/wQEBP8EBAT/AwMD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xsbG/9nZ2f/i4uL/2dnZ/8ZGRn/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/wQEBP8CAgL/AgIC/wAAAP8DAwP/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AgIC/wICAv8BAQH/AgIC/wMDA/8DAwP/AgIC/wQEBP8HBwf/AAAA/wAAAP8AAAD/AAAA/wAAAP8HBwf/BQUF/wMDA/8BAQH/AQEB/wMDA/8CAgL/AQEB/wEBAf8CAgL/AQEB/wAAAP8CAgL/AgIC/wICAv8AAAD/AAAA/wMDA/8CAgL/AwMD/wMDA/8BAQH/AQEB/wUFBf8DAwP/AgIC/wAAAP8EBAT/BwcH/wcHB/8HBwf/BAQE/wICAv8BAQH/AgIC/wEBAf8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8AAAD/AgIC/wICAv8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                        ]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchInCache.addCustomNames &&
                        Array.isArray(options.searchInCache.customNamesList)) {
                    namesList = namesList.concat(options.searchInCache.customNamesList);
                }
                namesList.forEach(function(elem) {
                    let engine = {};
                    engine.name = elem[0];
                    engine.cacheLink = elem[1];
                    engine.iconURI_spec = elem[2];
                    itemCreate(engine, "searchInCache");

                });
            }
            if (options.searchInCache.enable) {
                searchInCache();
            }

            popup.gObj = this;
            //popup.setAttribute("oncommand", "if (!event.target.engine) return; var csObj = this.gObj || document.getElementById('contextSearchMiniByBunda1-context-popup').gObj; csObj.searchCommandHandler(event);");

            popup.setAttribute("oncommand", "if (!event.target.engine) return; this.gObj.searchCommandHandler(event);");
            popup.setAttribute("onclick", "checkForMiddleClick(this, event);");
        },

        searchByImageCommandHandler: function(event) {
            var inBg = options.loadInBackground || false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = !inBg;
            }
            var searchByImageMenu = this.searchByImageMenu;
            var link = event.target.link;
            var imageLink = searchByImageMenu.imageSrc;
            if (imageLink.indexOf("data:") == 0) {
                this.searchByImageByData(imageLink, inBg);
                return;
            } else if (imageLink.indexOf("file:") == 0) {
                this.searchByImageByFile(imageLink, inBg);
                return;
            } else {
                imageLink = encodeURIComponent(imageLink)
            }
            var gBrowser = gBrowser || getBrowser();
            gBrowser.loadOneTab(link + imageLink, {
                relatedToCurrent: true,
                inBackground: inBg
            });
        },
        // searchByImageByData() and searchByImageByFile() based on
        // Google Image Search 0.5 by Nishan Naseer
        // https://addons.mozilla.org/ru/firefox/addon/google-similar-images
        searchByImageByData: function(src, inBg) {
            var gBrowser = gBrowser || getBrowser();
            //var tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
            var tab = gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
                relatedToCurrent: true
            });
            var newTabBrowser = gBrowser.getBrowserForTab(tab);
            newTabBrowser.addEventListener("load", function byData(e) {
                newTabBrowser.removeEventListener(e.type, byData, true);
                if (src) {
                    try {
                        var image_url;
                        var sub;
                        var form = newTabBrowser.contentDocument.getElementById("qbf");
                        var inputs = form.getElementsByTagName("input");
                        for (var k = 0; k < inputs.length; k++) {
                            var i = inputs[k];
                            if (i.name && i.name == "image_url") {
                                image_url = i;
                            }
                            if (i.type && i.type == "submit") {
                                sub = i;
                            }
                        }
                        image_url.value = src;
                        sub.click();
                        src = null;
                    } catch (ex) { }
                }
            }, true);

            if (!inBg) {
                getBrowser().selectedTab = tab;
            }
        },
        searchByImageByFile: function(src, inBg) {
            //Canvas to get contents in base-64
            var canvas = gContextMenu.target.ownerDocument.createElementNS(XHTMLNS, "canvas");
            var image = new Image();
            image.src = src;

            canvas.width = image.width;
            canvas.height = image.height;

            var ctx = canvas.getContext("2d");
            ctx.drawImage(image, 0, 0);
            var dataURL = canvas.toDataURL("image/png");
            var gBrowser = gBrowser || getBrowser();
            //var tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
            var tab = gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
                relatedToCurrent: true
            });
            var newTabBrowser = gBrowser.getBrowserForTab(tab);
            newTabBrowser.addEventListener("load", function byFile(e) {
                newTabBrowser.removeEventListener(e.type, byFile, true);
                if (src) {
                    try {
                        var image_url;
                        var sub;
                        var form = newTabBrowser.contentDocument.getElementById("qbf");
                        var inputs = form.getElementsByTagName("input");
                        for (var k = 0; k < inputs.length; k++) {
                            var i = inputs[k];
                            if (i.name && i.name == "image_url") {
                                image_url = i;
                            }
                            if (i.type && i.type == "submit") {
                                sub = i;
                            }
                        }
                        image_url.value = dataURL;
                        sub.click();
                        src = null;
                    } catch (ex) { }
                }
            }, true);

            if (!inBg) {
                getBrowser().selectedTab = tab;
            }
        },
        searchByImageMenuPopup: function(e) {
            var searchByImageMenu = this.searchByImageMenu;

            searchByImageMenu.hidden = !gContextMenu.onImage;
            var src = gContextMenu.mediaURL || gContextMenu.imageURL || gContextMenu.bgImageURL;
            if (!src || !(/^((ht|f)tps?:\/\/|data:image|file:)/.test(src))) {
                searchByImageMenu.hidden = true;
                return;
            }
            //var popup = document.getElementById("contextSearchMiniByBunda1-context-image-search-popup");
            var popup = searchByImageMenu.popup;
            var items;
            if (!popup.items) {
                var itemsObj = popup.getElementsByTagName("menuitem");
                popup.items = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menuitem" &&
                            elem.getAttribute("label") != "Google")
                        popup.items.push(elem);
                });
                items = popup.items;
            } else {
                items = popup.items;
            }

            if (/^(data:image|file:)/.test(src)) {
                items.forEach(function(elem) {
                    elem.setAttribute("disabled", "true");
                });
            } else {
                items.forEach(function(elem) {
                    elem.removeAttribute("disabled");
                });
            }

            searchByImageMenu.imageSrc = src;
        },
        createSearchByImageMenu: function() {
            var menu = document.createElement("menu");
            var insertMenu = document.getElementById("context-sep-copyimage");
            insertMenu.parentNode.insertBefore(menu, insertMenu);
            this.searchByImageMenu = menu;

            menu.setAttribute("id", this.nodeIds.searchByImageMenu);
            menu.setAttribute("class", "menu-iconic");
            menu.setAttribute("label", _localize("searchByImage"));
            menu.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK6wAACusBgosNWgAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAElSURBVDiNY/z//z8DJYCRkIKsthv/kRX9Z2BgmFalARdiIcaGKZXqcH5O+01U+ay2G3MYGBiSiXUmmofnsBDSjEUTMkiBe2Eq1JnZ7TcZBHhZGNythBl0lLkZODmYGX7++sdw/sZnhl3H3zF8+voHwwsYFkR5ijNICLMzTF31hOHnr38MHGxMDJlhMgwv3vxkWL7jJYpaJmzu0lTigWtmYGBg+PHrH8P0VU8YtJV5MNRiNYCfmxmuGQZ+/PrHwMmOqRyrAX///WfgYEOV4mBjwjAUpwHHL31iyA6XgRvCwcbEkBUmw3DuxmcMtVgDkYONicHLVoTBSJOXgYONieHHz38Ml+98Ydh88DXDtx//CBtACmBiYGCYS4H+OYyU5kasgUgKAADN8WLFzlj9rgAAAABJRU5ErkJggg==");

            this.searchByImageMenu.popup = menu.appendChild(document.createElementNS(XULNS, "menupopup"));
            var popup = this.searchByImageMenu.popup;
            popup.setAttribute("id", this.nodeIds.searchByImageMenuPopup);
            popup.googleURL = "https://www.google.com/searchbyimage";

            var namesList = [];
            if (options.searchByImage.useDefaultNamesList) {
                let defaultNamesList = [
                    [
                        "Google",
                        "https://www.google.com/searchbyimage?image_url=",
                        "data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAA9IVCSvSFQuf0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULk9IVCSvSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQuf0hUL/9IVC//SFQv/0hUL/9Y1O//rIq//+7+f//eXX//vUvf/7z7X/96Fu//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vYwv/97OH/9ZRZ//SFQv/0hUL/9IhG//zbx//3om7/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97uX/+buW//SFQv/0hUL/9IVC//SFQv/5upT/+9O6//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+b6b//zezP/0iEf/9IVC//SFQv/1klf//ezh//vPtP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/3qXr/+siq//m8lv/5wqD//vTu//3t4//1klb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0h0b//vbx//zi0//1j1H/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2nmn/+bmS/////v/4sIX/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5uJH///v5//eoef/1jU//+82y//afav/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vXw//vOs//0hUL/9IVC//ekcf/96+D/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//728v/4sIX/9IVC//SFQv/4s4n///v4//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6yKn/+byX//SFQv/0hkT//eTV//vWv//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IZE//m6lP/5u5b//OHQ///+/f/6y6//96d3//SFQv/0hUL/9IVC//SFQv/0hULm9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSfSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAA9IVCAPSFQif0hUKt9IVC8vSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvL0hUKt9IVCJ/SFQgD0hUIo9IVC7/SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULv9IVCKPSFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVC8fSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvP0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YtL//i2jv/828f//vLr///7+P///Pv//vTu//3n2v/6zbH/96Nw//SFQ//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ekcv/+8+z////////////+9fD/+9K5//m9mf/4to7/+buV//vSuf/++PT//OPT//aYYP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2l13///r3/////////fv/+b2Z//SIRv/0hUL/9IVC//SFQv/0hUL/9IVC//WNT//84M///vXv//aZYf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vPtP////////////i0i//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//WQUv///Pr//OPU//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//eTV///////+9O7/9IVD//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//3m2P//////9ppi//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/718H///////3s4f/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vDn///////4soj/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//erff////////38//WTWP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//iziv////////////iwhf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rMsP///////eXW//WSVv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/4sYb///z7/////////Pv/9ZFV//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ixhv/+8Of//vn1//rMsP/4rH//9plh//WQUv/1j1L/+s2x//////////////////m9mf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SGQ//2nmn/+buW//vNsv/82sb//e3j/////////////////////v/5wZ//9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/83Mj////////////++fb/+K+C//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9ZRZ/////////////vTt//aaYv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/1lFr////////////6xqf/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ehbf/70bj//end//3o2////v3///////3l1//0iEb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5wqD////////////96t7/96Z2//WOUP/2nWf//NvH//zcyP/1i0z/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/96l6/////////////vLr//WPUf/0hUL/9IVC//SFQv/0h0b//end//3k1f/0iUn/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/8387////////////4sYf/9IVC//SFQv/0hUL/9IVC//SFQv/6w6L///////nBn//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC///69////////vj1//SIR//0hUL/9IVC//SFQv/0hUL/9IVC//m+mv///////e3j//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL///r3///////8387/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+syw///////++fb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/95NX///////vUvP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97OH///////7y6//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//i2jv///////N/O//SFQv/0hUL/9IVC//SFQv/0hUL/96Nx////////////+s2x//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IdF//zh0P//+/j/9ZJW//SFQv/0hUL/9IVC//SKSv/96t7///////738v/1k1f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YxN//vUvf/96+D/96Z0//WNT//3om///ebY/////////Pv/+LKI//WVW//0h0X/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//agbP/7zbL//enc//749P////////////////////////////3r4P/3p3f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8/SFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVCJ/SFQu/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC7/SFQif0hUIA9IVCJfSFQq30hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8fSFQq30hUIl9IVCAIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAB"
                    ],
                    [
                        "Yandex",
                        "http://images.yandex.ru/yandsearch?rpt=imagedups&text=&img_url=",
                        "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=="
                    ],
                    [
                        "TinEye",
                        "http://www.tineye.com/search/?pluginver=firefox-1.0&url=",
                        "data:image/x-icon;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAACxeDVItHk157iAO//WtW7/482G/+XOhv/lzYL/1L98/5mTcf8UKUP/CwsM/xwcG/8AAAD/AAAA/wAAAOcAAA5ItHo25LV7Nv+1ezb/tXs2/8GPSf/EoGj/s5hw/6KPdf93bWT/ZFdK/2daTP9hVEj/XU9C/zIpH/8EAgH/AAAA5LV7Nv+1ezb/tXs2/7V7Nv+1ezb/uIA+/8eea//Wtof/48eU/+PKkv/iyJP/4MeV/9u/kf/HqHz/rI1p/3tmT/+1ezb/tXs2/7V7Nv+1ezb/zKV0/+PKlP/hxXr/zbFk/8esYf/VuW7/3sFz/+LFdf/gw3P/48Z3/+nPjv/dwJD/tXs2/7V7Nv+1ezb/y6Nx/9/Gg/+NekT/V0wv/5uSfP95cmH/JiES/zAqGv86Mh3/W08v/3lpQP+Wg03/zLFn/7V7Nv+1ezb/uoVH/8myg/+VgUr/AAAA/2xpZf/i4+X/+fn5/0JAO/8AAAD/LCkl/768uf+/vr3/Mi8q/x0ZEP+2fDf/tXs2/6WGX/+pklP/JyES/0dFQP96eHX/W1tc//////9ua2X/DAoH/6Wim/+EhIX//////6ejnP8AAAD/wo1F/8GLQ//Conf/tZ1e/wYDAP9pZmH/6+vs/9/f3/////3/Pjoz/zo2Lf/Jycb/UlJT//////+xraX/AAAA/8OORv/Djkb/1bF+/821cf83MSD/MC4s//n49P//////l5OJ/wMCAP9IRDr/////////////////ZGBW/wAAAP/Djkb/w45G/8qkcP+sllr/wKtw/zw5Mf9MSUb/VlNM/wIBAP8AAAD/FxUP/9PQyv/8+/j/rKig/wkHA/8AAAD/w45G/8OORv+1jlj/l4hm/8etZv/QuHf/m4xk/21hSP9PRjX/Mi0j/xsYFf87NzD/VFBK/xUVFf8FBwz/CQsQ/8OORv/Djkb/g2I1/8Oea//Mt4z/uJxU/56hhv92nLj/l6ut/56poP+gpJL/mJeC/5aMbP+bjmv/m49t/52Qbv/Djkb/uItP/05PUP+zjlv/yptc/9C3jP9gYFP/ABVH/wAzc/8IP4T/FUuM/xhSmP99lZ3/5sRv/9S6cf/Lsmr/w45G/1B7rv8bbdT/LWy5/8OORv/Djkf/yqRw/zswIP8AAAD/AAAA/wAAAP8AAAD/Fyk8/5CKZ/+ahU3/modW/8GNReeEj5r/L37g/0Jxqf/Cjkf/w45G/8OORv/Fllb/clYw/zoqFf8hGQ3/IhwU/x4ZFf9HRUD/vaJ5/86pdee+ikU/woxEyZ6HZ/+8jEz/w45G/8OORv/Djkb/w45G/8OORv/Djkb/v4tF/8ORTf/GlFD/xJBJ/8KMRMm+ikU/gAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAE="
                    ]
                ];
                namesList = namesList.concat(defaultNamesList);
            }
            if (options.searchByImage.addCustomNames &&
                    Array.isArray(options.searchByImage.customNamesList)) {
                namesList = namesList.concat(options.searchByImage.customNamesList);
            }

            function itemCreate(name, link, image) {
                var item = document.createElementNS(XULNS, "menuitem");
                item.setAttribute("class", "menuitem-iconic");
                item.setAttribute("src", image);
                item.setAttribute("label", name);
                item.link = link;
                popup.appendChild(item);
            }
            namesList.forEach(function(elem) {
                itemCreate(elem[0], elem[1], elem[2]);
            });

            var contextMenu = this.contextMenu;

            popup.gObj = this;
            popup.setAttribute("oncommand", "this.gObj.searchByImageCommandHandler(event);");
            popup.setAttribute("onclick", "checkForMiddleClick(this, event);");
        }
    }
    contextSearcherObj.init();
})();

2k1dmg
Я в полнейшем восторге :) Спасибо!

upd: что-то "на лету" в контекстном меню не меняется поисковик по умолчанию (если изменять выбор в панели поиска), а только после перезагрузки браузера.
На всякий случай: использую hideDefaultEngineInPopupSubMenu: true, но pinnedEngineName: "" не трогаю.
p.s. если не сильно понятно расписал, могу потом показать с картинками.

2k1dmg
Крутой код получился, пора переименовать в Context Search full :)
Кстати это:

Выделить код

Код:

let os = Cc["@mozilla.org/observer-service;1"].
                        getService(Ci.nsIObserverService);
os.addObserver(this, "browser-search-engine-modified", false);

можно проще сделать:

Выделить код

Код:

Services.obs.addObserver( this, "browser-search-engine-modified", false );

09-10-2013 23:24:06
И попробуй в кнопке:

Выделить код

Код:

alert(xulns);
alert(xhtmlns);

без:

Выделить код

Код:

let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let XHTMLNS = "http://www.w3.org/1999/xhtml"

Northtech

Выделить код

Код:

(function () {
    // Context Search mini 2013-10-10
    var options = {
        loadInBackground: false,
        // true - открывать вкладки в фоне
        pinnedEngineName: "",
        // оставить пустым если не нужно закреплять
        // определенный поисковик
        // примеры pinnedEngineName: "Google" или pinnedEngineName: "Яндекс" или pinnedEngineName: ""
        hideDefaultEngineInPopupSubMenu: false,
        // true - не добавлять поисковик по умолчанию в выпадающий список (подменю) поисковиков
        campactMenu: true,
        // true - поисковики в выпадающем списке (подменю) без назаваний
        campactMenuLengthPerLine: 5,
        // максимальное количество элементов в одной строке
        // от 3 до 10, по умолчанию 5
        searchBySite: {
            enable: true,
            // true - добавить поисковики по сайту
            iconsOn: true,
            // true - добавить иконки для поисковиков по сайту
            useDefaultNamesList: true,
            // true - использовать список поисковиков по умолчанию
            addCustomNames: false,
            // true - добавить свои поисковики по сайту
            customNamesList: [
                ["Rambler", ["Rambler", "Рамблер"]]
            ]
            // например ["Rambler", ["Rambler", "Рамблер"]]
            // первая ячека название на английском
            // вторая ячека массив с предполагаемыми именами поисковика
            // может состоять из нескольких значений
            // ["Name1", ["Name1"]],
            // ["Name2", ["Name2", "Имя2"]],
            // ["Name3", ["Name3", "Имя3", "Név3"]]
        },
        searchImageByText: {
            enable: true,
            // true - добавить поиск изображения по тексту
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        },
        searchByImage: {
            enable: true,
            // true - добавить поиск по изображению
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        },
        searchInCache: {
            enable: true,
            // true - добавить поиск в кэше
            // нужно доработать
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        }
    };
    function _localize(sid) {
        let strings = {
            en: {
                searchBySite: "Search this site",
                searchImageByText: "Search image by text",
                searchByImage: "Search by image",
                searchInCache: "Search this page in cache"

            },
            ru: {
                searchBySite: "Поиск по этому сайту",
                searchImageByText: "Поиск изображения по тексту",
                searchByImage: "Поиск по изображению",
                searchInCache: "Поиск этой страницы в кэше"
            }
        };
        //let locale = (Application.prefs.getValue("general.useragent.locale", false) || "en").match(/^[a-z]*/)[0];
        function getBrowserUILocale() { // Browser UI locale
            return Components.classes["@mozilla.org/chrome/chrome-registry;1"]
                            .getService(Components.interfaces.nsIXULChromeRegistry)
                            .getSelectedLocale("global");
        }
        let locale = ""; // ru, en
        if (!locale || locale == "")
            locale = getBrowserUILocale().match(/^[a-z]*/)[0];
        _localize = function (sid) {
            return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
        };
        return _localize.apply(this, arguments);
    }

    let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    let XHTMLNS = "http://www.w3.org/1999/xhtml"

    var contextSearcherObj = {
        initialized: false,
        init: function() {
            if(this.initialized)
                return;
            this.initialized = true;

            this.nodeIds = {
                searchMenu: "contextSearchMiniByBunda1-menu",
                searchMenuPopup: "contextSearchMiniByBunda1-popup",
                searchByImageMenu: "contextSearchMiniByBunda1-image-search-menu",
                searchByImageMenuPopup: "contextSearchMiniByBunda1-image-search-popup"
            };

            if (document.getElementById(this.nodeIds.searchMenu))
                return;

            var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
            var contextMenu = document.getElementById("contentAreaContextMenu");
            var searchSelect = document.getElementById("context-searchselect");
            searchSelect.style.display = "none";

            var searchMenu = contextMenu.insertBefore(document.createElementNS(XULNS, "menu"), searchSelect);

            this.searchService = searchService;
            this.contextMenu = contextMenu;
            this.searchSelect = searchSelect;
            this.searchMenu = searchMenu;

            this.param = {
                isPinnedEngine: false,
                pinnedEngineName: ""
            };

            try {
                this.createSearchMenu();
                if (options.searchByImage.enable)
                    this.createSearchByImageMenu();
            } catch (ex) {
                this.destroy();
                Components.utils.reportError(ex);
                return;
            }

            if (options.campactMenu)
                this.loadStyles();

            var observeStatus = new MutationObserver(function () {
                    searchMenu.hidden = searchSelect.hidden;
                });
            observeStatus.observe(searchSelect, {
                attributes: true,
                attributeFilter: ["hidden"]
            });

            /*var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                        .getService(Components.interfaces.nsIPrefService);
            this.branch = prefService.getBranch("browser.search.");
            if (!("addObserver" in this.branch))
                this.branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
            this.branch.addObserver("", this, false);*/

            /*
            var searchPref = "browser.search.";
            gPrefService.addObserver(searchPref, this, false);*/


            /*let os = Cc["@mozilla.org/observer-service;1"].
                        getService(Ci.nsIObserverService);
            os.addObserver(this, "browser-search-engine-modified", false);*/
            Services.obs.addObserver(this, "browser-search-engine-modified", false);

            Services.ww.registerNotification(this);

            addEventListener("popupshowing", this, false, contextMenu);

            addDestructor(function (reason) {
                observeStatus.disconnect();
                Services.ww.unregisterNotification(this);
                //this.branch.removeObserver("", this);
                //gPrefService.removeObserver(searchPref, this, false);
                //os.removeObserver(this, "browser-search-engine-modified", false);
                Services.obs.removeObserver(this, "browser-search-engine-modified", false);
                this.destroy();
                if (reason != "destructor")
                    this.unloadStyles();
            }, this);
        },
        destroy: function() {
            if(!this.initialized)
                return;
            this.initialized = false;
            var contextMenu = this.contextMenu;
            if (!contextMenu)
                return;
            if (this.searchMenu)
                contextMenu.removeChild(this.searchMenu);
            if (this.searchByImageMenu)
                contextMenu.removeChild(this.searchByImageMenu);
            if (this.searchSelect)
                this.searchSelect.style.removeProperty("display");
        },
        update: function() {
            this.searchMenu.textContent = "";
            this.createSearchMenu();
            delete this.updateTimeoutID;
        },

        get isSeaMonkey() {
            delete this.isSeaMonkey;
            return this.isSeaMonkey = Services.appinfo.name == "SeaMonkey";
        },

        observe: function(subject, topic, data) {
            switch (topic) {
                case "domwindowclosed":
                    if (subject.document.documentElement.getAttribute("windowtype") == "Browser:SearchManager") {
                        this.update();
                    }
                    break;
                /*case "nsPref:changed":
                    switch (data) {
                        case "defaultenginename":
                        case "browser.search.defaultenginename":
                            this.update();
                            break;
                    }
                    break;*/
                case "browser-search-engine-modified":
                    /*switch (data) {
                        case "engine-default":
                        case "engine-current": // engine-default
                        case "engine-changed":
                        case "engine-removed":*/
                            if (typeof this.updateTimeoutID == "number") {
                                window.clearTimeout(this.updateTimeoutID);
                                delete this.updateTimeoutID;
                            }
                            let _this = this;
                            this.updateTimeoutID = window.setTimeout(function () {
                                _this.update();
                            }, 1000);
                            /*break;
                    }*/
                    break;
            }
        },
        handleEvent: function(e) {
            //var contextMenu = this.contextMenu;
            //var menu = this.menu;
            //var imageMenu = this.imageMenu;
            switch (e.type) {
                case "popupshowing":
                        this.popupshowingEvent(e);
                    break;
            }
        },
        popupshowingEvent: function(e) {
            var trgId = e.target.id;
            if (trgId) {
                if (trgId == "contentAreaContextMenu") {
                    this.contextMenuPopup(e);
                    if (this.searchByImageMenu)
                        this.searchByImageMenuPopup(e);
                } else if (trgId == this.nodeIds.searchMenuPopup)
                    this.searchMenuPopup(e);
            }
        },

        _stylesLoaded: false,
        loadStyles: function() {
            if(this._stylesLoaded)
                return;
            this._stylesLoaded = true;
            var sss = this.sss;
            var cssURI = this.cssURI = this.makeCSSURI();
            if(!sss.sheetRegistered(cssURI, sss.USER_SHEET))
                sss.loadAndRegisterSheet(cssURI, sss.USER_SHEET);
        },
        unloadStyles: function() {
            if(!this._stylesLoaded)
                return;
            this._stylesLoaded = false;
            var sss = this.sss;
            if(sss.sheetRegistered(this.cssURI, sss.USER_SHEET))
                sss.unregisterSheet(this.cssURI, sss.USER_SHEET);
        },
        get sss() {
            delete this.sss;
            return this.sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]
                .getService(Components.interfaces.nsIStyleSheetService);
        },
        makeCSSURI: function() {
            var cssStr = '\
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\n\
@-moz-document url("' + window.location.href + '") {\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n\
        /*width: 2em !important;*/\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] * {\n\
        /*padding-left: 0 !important;\n\
        padding-right: 0 !important;\n\
        margin-left: 0 !important;\n\
        margin-right: 0 !important;*/\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > spacer[campactMenu="true"] {\n\
        width: 2em !important;\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n\
        width: 3em !important;\n\
        height: 2em !important;\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox >.menuitem-iconic[campactMenu="true"] > image {\n\
        margin-left: .8em !important;\n\
    }\n\
}\n\
';            return Services.io.newURI("data:text/css," + encodeURIComponent(cssStr), null, null);
        },

        searchCommandHandler: function(event, trg) {
            var inBg = options.loadInBackground || false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = !inBg;
            }
            var searchBySite = "";
            if (event.target.hasAttribute("searchBySite"))  {
                searchBySite = " site:" + gBrowser.currentURI.host;
            } else if (event.target.hasAttribute("searchInCache")) {
                searchBySite = content.location.href;
            }
            let selectedText = this.isSeaMonkey ? content.getSelection().toString() : getBrowserSelection();
            if (event.target.engine.imageLink) {
                gBrowser.loadOneTab(event.target.engine.imageLink + /*getBrowserSelection()*/ selectedText, {
                    relatedToCurrent: true,
                    inBackground: inBg
                });
            } else if (event.target.engine.cacheLink) {
                gBrowser.loadOneTab(event.target.engine.cacheLink + /*getBrowserSelection()*/ searchBySite, {
                    relatedToCurrent: true,
                    inBackground: inBg
                });
            } else {
                let submission = event.target.engine.getSubmission(/*getBrowserSelection()*/ selectedText + searchBySite, null);
                gBrowser.loadOneTab(submission.uri.spec, {
                    relatedToCurrent: true,
                    postData: submission.postData,
                    inBackground: inBg
                });
            }
            if (trg == "menu") {
                setTimeout(function () {
                    document.getElementById("contentAreaContextMenu").hidePopup();
                }, 0);
            }
        },
        contextMenuPopup: function(e) {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.searchMenu;

            //var selectedText = getBrowserSelection(16);
            var selectedText = this.isSeaMonkey ? content.getSelection(16).toString() : getBrowserSelection(16);
            if (!selectedText)
                return;
            var ellipsis = "\u2026";
            try {
                ellipsis = gPrefService.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
            } catch (ex) { }
            if (selectedText.length > 15)
                selectedText = selectedText.substr(0,15) + ellipsis;
            let rEngine = this.isSeaMonkey ? "currentEngine" : "defaultEngine";
            var engineName = this.param.isPinnedEngine ? this.param.pinnedEngineName : searchService[rEngine].name;
            var menuLabel;
            var searchFormattedString = [
                "contextMenuSearch",
                "contextMenuSearchText",
                "searchSelected"
            ];
            var thisIsSM = this.isSeaMonkey;
            function getMenuLabel(str) {
                try {
                    if (thisIsSM) {
                        let bundle = document.getElementById("contentAreaCommandsBundle");
                        return bundle.getFormattedString(str, [engineName, selectedText]);
                    } else
                        return gNavigatorBundle.getFormattedString(str, [engineName, selectedText]);
                } catch (ex) {
                    return false;
                }
            }
            for(let i in searchFormattedString) {
                menuLabel = getMenuLabel(searchFormattedString[i]);
                if (menuLabel)
                    break;
                else if (!menuLabel && i == searchFormattedString.length-1)
                    menuLabel = engineName;
            }
            menu.label = menuLabel;
        },
        searchMenuPopup: function(e) {
            var popup = e.target;
            var items;
            if (!popup.items) {
                var itemsObj = popup.getElementsByTagName("menuitem");
                popup.items = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menuitem" &&
                            elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        popup.items.push(elem);
                });
                items = popup.items;
            } else {
                items = popup.items;
            }
            var menus;
            if (!popup.menus) {
                var itemsObj = popup.getElementsByTagName("menu");
                popup.menus = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menu" &&
                            elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        popup.menus.push(elem);
                });
                menus = popup.menus;
            } else {
                menus = popup.menus;
            }
            var siteSearchDomain;
            var gBrowser = gBrowser || getBrowser();
            function isDomain() {
                try {
                    siteSearchDomain = gBrowser.currentURI.host;
                } catch (ex) {
                    return false;
                }
                return true;
            }
            if (isDomain()) {
                items.forEach(function(elem) {
                    //if (elem.hasAttribute("searchBySite"))
                    //    elem.setAttribute("tooltiptext", siteSearchDomain);
                    elem.removeAttribute("disabled");
                });
                menus.forEach(function(elem) {
                    if (elem.hasAttribute("searchBySite"))
                        elem.setAttribute("tooltiptext", siteSearchDomain);
                    else if (elem.hasAttribute("searchInCache"))
                        elem.setAttribute("tooltiptext", content.document.title);
                    elem.removeAttribute("disabled");
                });
            } else {
                items.forEach(function(elem) {
                    //if (elem.hasAttribute("searchBySite"))
                    //    elem.removeAttribute("tooltiptext");
                    elem.setAttribute("disabled", "true");
                });
                menus.forEach(function(elem) {
                    if (elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        elem.removeAttribute("tooltiptext");
                    elem.setAttribute("disabled", "true");
                });
            }
        },
        createSearchMenu: function() {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.searchMenu;

            var engines = searchService.getVisibleEngines({});

            menu.setAttribute("id", this.nodeIds.searchMenu);

            menu.setAttribute("class", "menu-iconic");
            this.param.isPinnedEngine = false;
            this.param.pinnedEngineName = "";
            var pinnedEngineName = options.pinnedEngineName;
            if (pinnedEngineName != "") {
                for (let i in engines) {
                    if (engines[i].name != pinnedEngineName)
                        continue;
                    menu.setAttribute("label", engines[i].name);
                    menu.setAttribute("image", engines[i].iconURI.spec);
                    menu.engine = engines[i];
                    this.param.isPinnedEngine = true;
                    this.param.pinnedEngineName = pinnedEngineName;
                    break;
                }
            }

            let rEngine = this.isSeaMonkey ? "currentEngine" : "defaultEngine";
            if (!this.param.isPinnedEngine) {
                menu.setAttribute("label", searchService[rEngine].name);
                menu.setAttribute("image", searchService[rEngine].iconURI.spec);
                menu.engine = searchService[rEngine];
            }

            menu.gObj = this;
            menu.setAttribute("onclick", "if (event.target == this && event.target.engine) this.gObj.searchCommandHandler(event, 'menu');");

            menu.popup = menu.appendChild(document.createElementNS(XULNS, "menupopup"));
            var popup = this.searchMenu.popup;
            popup.setAttribute("id", this.nodeIds.searchMenuPopup);

            var counterMaxLength = options.campactMenuLengthPerLine;
            if (typeof counterMaxLength != "number" ||
                3 > counterMaxLength || counterMaxLength > 10)
                counterMaxLength = 5;
            var counter = 0;
            var hBox;
            function itemCreateCampact(engine, last) {
                if(counter == 0) {
                    hBox = document.createElementNS(XULNS, "hbox");
                    let item = document.createElementNS(XULNS, "spacer");
                    //item.setAttribute("style", "width: 2em");
                    item.setAttribute("campactMenu", "true");
                    hBox.appendChild(item);
                }
                counter++;
                var item = document.createElementNS(XULNS, "menuitem");
                item.engine = engine;
                item.setAttribute("class", "menuitem-iconic");
                item.setAttribute("tooltiptext", engine.name);
                //item.setAttribute("src", engine.iconURI.spec);
                var image = document.createElementNS(XULNS, "image");
                image.setAttribute("src", engine.iconURI.spec);
                item.appendChild(image);
                //item.setAttribute("style", "max-width: 2em");
                item.setAttribute("campactMenu", "true");
                hBox.appendChild(item);
                if (counter == counterMaxLength || last) {
                    popup.appendChild(hBox);
                    counter = 0;
                }
            }

            var separator = {};
            function itemCreate(engine, reason) {
                var item = document.createElementNS(XULNS, "menuitem");
                item.setAttribute("class", "menuitem-iconic");
                item.engine = engine;
                if (reason && !separator[reason]) {
                    /*let sep = separator[reason] = document.createElementNS(XULNS, "menuseparator");
                    sep.setAttribute(reason, "true");
                    popup.appendChild(sep);

                    let item = document.createElementNS(XULNS, "label");
                    //item.setAttribute("class", "menuitem-iconic");
                    item.setAttribute("value", _localize(reason) + ":");
                    item.setAttribute("style", "padding-left: 2em");
                    popup.appendChild(item);*/

                    if (!separator["menuseparator"]) {
                        let sep = separator["menuseparator"] = document.createElementNS(XULNS, "menuseparator");
                        popup.appendChild(sep);
                    }

                    let subMenu = separator[reason] = document.createElementNS(XULNS, "menu");
                    subMenu.setAttribute("class", "menu-iconic");
                    subMenu.setAttribute("label", _localize(reason));
                    subMenu.setAttribute(reason, "true");
                    subMenu.popup = subMenu.appendChild(document.createElementNS(XULNS, "menupopup"));
                    popup.appendChild(subMenu);
                }
                if (reason == "searchBySite") {
                    item.setAttribute("label", engine.name);
                    if (options.searchBySite.iconsOn) {
                        item.setAttribute("src", engine.iconURI.spec);
                    }
                    item.setAttribute(reason, "true");
                } else if (reason == "searchImageByText" ||
                            reason == "searchInCache") {
                    item.setAttribute("label", engine.name);
                    item.setAttribute("src", engine.iconURI_spec);
                    item.setAttribute(reason, "true");
                } else {
                    item.setAttribute("label", engine.name);
                    item.setAttribute("src", engine.iconURI.spec);
                }
                //popup.appendChild(item);
                if (reason) {
                    let subMenu = separator[reason];
                    subMenu.popup.appendChild(item);
                } else
                    popup.appendChild(item);
            }
            for (let i in engines) {
                if (options.hideDefaultEngineInPopupSubMenu &&
                        this.param.isPinnedEngine &&
                        engines[i].name == pinnedEngineName ||
                        options.hideDefaultEngineInPopupSubMenu &&
                        !this.param.isPinnedEngine &&
                        engines[i].name == searchService[rEngine].name) {
                    continue;
                }
                if (options.campactMenu)
                    itemCreateCampact(engines[i], i == engines.length-1);
                else
                    itemCreate(engines[i]);
            }
            function searchBySite_itemCreate() {
                var namesList = [];
                if (options.searchBySite.useDefaultNamesList) {
                    let defaultNamesList = [
                        ["Google", ["Google"]],
                        ["Yandex", ["Yandex", "Яндекс"]],
                        ["Yahoo", ["Yahoo"]],
                        ["Bing", ["Bing"]],
                        ["DuckDuckGo", ["DuckDuckGo"]]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchBySite.addCustomNames &&
                        Array.isArray(options.searchBySite.customNamesList)) {
                    namesList = namesList.concat(options.searchBySite.customNamesList);
                }
                //let i_skips = [];
                function isNameExist(names, engine) {
                    for (let i in names) {
                        if (names[i] != engine && i != names.length-1)
                            continue;
                        else if (names[i] == engine)
                            return true;
                        return false;
                    }
                }
                namesList.forEach(function(elem) {
                    for (let i in engines) {
                        if (/*i_skips.indexOf(i) != -1 ||*/
                            !(elem[1].some(function(listName) listName == engines[i].name))
                            /*!isNameExist(elem[1], engines[i].name)*/
                            /*elem[1].indexOf(engines[i].name) == -1*/)
                            continue;
                        itemCreate(engines[i], "searchBySite");
                        //i_skips.push(i);
                        break;
                    }
                });
            }
            if (options.searchBySite.enable) {
                searchBySite_itemCreate();
            }

            function searchImageByText_itemCreate() {
                var namesList = [];
                if (options.searchImageByText.useDefaultNamesList) {
                    let defaultNamesList = [
                        [
                            "Google",
                            "https://www.google.ru/search?tbm=isch&q=",
                            "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB41BMVEUAAAB7wUJ6wUJ6wUJ6wUL1nxn1oBn1oBn1nxl6wUJ6wUJ6wUJrvUT1mxr1nxn1nxlfu0Z8wkLznhv0mhp6wUJWuUdaukfLrSv4rhX1nxl5wUJyv0TQrCnyjhz1kyH2pRj1oBl7wkNbukfzjR3zkxv1liHuMDXuGTf2rxN7wUJeu0apuDfzjhz1nBvuNizwZi/3sxP2pBh9wkGvuTbvoRvuJy/xcC33qRhbl7F2uGOMwT94havnRTzuMjjwTTNRislRjcZ5uVpnvU0rk9Fhjr3aTkPuLTVQkM1PgsKHxD9/w0JfnKsAouPtHCTvQDRRkM1Qjstfn6p2jLHvOzDvQDVQkM1Rkc1RjstOh8Z/h6buLirtGyTvOzHvQDXwQDVPkcftPzdRkc1QkMxRkM0xlNLuNSzwQDXvQDVQkM1Rkc1QkM1Rkc3vQDTvQDXvQDXwQDV7wUL2oBr1nxn2oBl6wUJ7wkN9wkF9wkJ6wUP0lRv3qhf1oBn4rhX3qhb1nhp8wkL0nBruGjLuIzf3qRZ/w0JcukbuLCntIzl+wkFkvEbtGyVPhMRyv0QAmNfuLCruMDVRkc1ViccKltTvQDVRhcUAmdfvQDRRks5RiskcltTwQzdQkM07k9DtGyPvQzdQkMzvPzSgiRCBAAAAcHRSTlMAM9bsfmzq30TnaEIQF1b390JR9nP98873iO4nsPyvO3Vly1783sVB8T/5j+2SiIXyKITTeqTRY0ThWl/g9jAn2cBPbNfJFWXVrOjTge5EeeC0qPBsYPfUstjGvOP+dnp0+pmBR1GEikvl8paC8etfYXu9TgAAAAlwSFlzAAAASAAAAEgARslrPgAAAQJJREFUGNM1j8VWQzEARAco8NDiLsXdXQvF3d3dIQ2vOBR3CQSCFPtUUg7Mbu5i7hnY2Npp8Bd7B0cFToQQZxdXwE1xN9JVLVRiUsmah6eXNzVKQOFD1PUNXz//za0ASul2IKBRg4IREroThnAt1cmlCFMkoqJ3Y2LjEL+nSJBgTkxK3k9JPThMSz/KsMoyj0+ysoGc07PcvF97fsH5RSFQVHxZUmrt+quycvO1oeKmsur2rlqCGlaLuvqG+4dGNPFmCVpYK9D2+NQOdIhOoKubPff0vrz29Q8MvvGhYTAZC3sfGf34FFwIgTHLFxufmASmpme+OeeYnZtf+L+/uLS88gMT2kW5QAjbFwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0wNC0wNlQxMDoxMzowNSswNDowMIQ8zwwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMDQtMDZUMTA6MTM6MDUrMDQ6MDD1YXewAAAAAElFTkSuQmCC"
                        ],
                        [
                            "Yandex",
                            "http://images.yandex.ru/yandsearch?text=",
                            "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=="
                        ]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchImageByText.addCustomNames &&
                        Array.isArray(options.searchImageByText.customNamesList)) {
                    namesList = namesList.concat(options.searchImageByText.customNamesList);
                }
                namesList.forEach(function(elem) {
                    let engine = {};
                    engine.name = elem[0];
                    engine.imageLink = elem[1];
                    engine.iconURI_spec = elem[2];
                    itemCreate(engine, "searchImageByText");

                });
            }
            if (options.searchImageByText.enable) {
                searchImageByText_itemCreate();
            }

            function searchInCache() {
                var namesList = [];
                if (options.searchInCache.useDefaultNamesList) {
                    let defaultNamesList = [
                        [
                            "Google",
                            "https://www.google.com/search?q=cache:",
                            "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJgAAACAgAAAAAAAA8gIAAKMBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFESURBVDjLpZNJSwNBEIXnt4lE4kHxovgT9BDwJHqPy0HEEOJBiAuCRg+KUdC4QS4KrpC4gCBGE3NQ48JsnZ6eZ3UOM6gjaePhQU93v6+qq2q0pqgeJj2S8EdJT1hr0OxBtKCD5iEd8QxDYpvhvOBAuMDKURX9C9aPu4GA1GEVkzvMg10UBfYveWAWgYAP00V01fa+R9M2bA51wJvhIn3qR+ybt3D3JNQBE5sMjCIOLFpoHzOwdsLRO22qA6R6kiZiWwxUvy/PUQZIhYZ1vFM9cvcOOsYNdcBgysISdSJBnZjJMlR0Fw8vAp0xoz5gao/h+NZBy4i/10XGwrPA+hmvDyhVRG2Avu/LwcrkFADZa16L1h330w1RNgc3DiJzCpPYRm1bpveXX11clQR28xwblHpk1vq1iP/5mcoS0CoXDZiL0vsJ+dzfl+3T/VYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAK5SURBVFjDxVfrSxRRFJ9/Jta/oyWjF5XQm6D6EkHRgygIIgjUTcueVgqVWSRRkppEUQYWWB8ye1iGWilWlo/Ude489s7M6Zw7D9dlt53dmd29cFiWvXvO77x+51xpaaUsoSxBaUWZQ4ECy5xji2xKZDyCMlMEw6lCNiOSgwZKJK1SkcKeSealfP64t0mBjl4Ow39MkDUL0p2RSROOtqhZdeUEYM1pBl39XCg/fEeFtWcY7G9W4csvUxjlBkCsQ4Nt9QyWVfvT6RsAKXw3aoDGATZeYIt+W1kjw7cJG0RctWDTRebbKd8A6h5pwsDb70ba3w/eUr3wt/cmwgfw6Yft4TNMQaY7o1P2ncm4FT4ANQH/jQBJ2xv7kqIXEADDql8eS3+n8bku7oxNm+EDIM/dU92upb3T/NJGeaNbDx/AsbsLRUY5Xn92caWXY5d8RV6gWllxSg4fAEnTC90DQW13BLlgXR2D3dcUeDVkwOthA1bXspxILWcm3HdThcfvufB26LcJpkOEAz9NKI/lzqpSEC7feol5EWnpSeSlIxCALUkApmULdjUqxQVAQnl3D/X/yQda4QBEq2TYc12By091MQ17Bg3R88nHKlQbVmHvj89awNBLYrwT9zXY2aBAxTkGFdiSxP/Jp6FLDw+AS7GfsdJTJ2EqSO5khD43nGfBARy/ZxOQgZHe7GPM1jzUvChUtmnBAXQPcKGMJp3fdFGq6NByEhiAO4b/YptFfQJwNyQ/bZkVQGcf90Ja25ndIyrKBOa/f8wIpwi3X1G8UcxNu7ozUS7tiH0jBswwS3RIaF1w6LYKU/ML2+8sGnjygQswtKrVIy/Qd9qQP6LnO64q4fPAKpxyZIymHo1jWk6p1ag2BsdNwQMHcC+M5kHFJX+YlPxpVlbCx2mZ5DzPI04k4kUwHHdskU3pH76iftG8yWlkAAAAAElFTkSuQmCC"
                        ],
                        [
                            "Archive.org",
                            "http://web.archive.org/web/*/",
                            "data:image/x-icon;base64,AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABILAAASCwAAAAAAAAAAAAABAQH/AQEB/wEBAf8BAQH/AgIC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wAAAP8BAQH/AQEB/wAAAP8CAgL/AgIC/wEBAf8CAgL/AQEB/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BQUF/wUFBf8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wUFBf8EBAT/BAQE/wQEBP8FBQX/BQUF/wEBAf8AAAD/AQEB/wICAv8BAQH/AAAA/wAAAP8CAgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8AAAD/AgIC/wEBAf8BAQH/BgYG/wAAAP+ysrL/4uLi/9/f3//g4OD/4ODg/9/f3//g4OD/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4ODg/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/3d3d/97e3v8qKir/AQEB/wMDA/8BAQH/AgIC/wAAAP8EBAT/AAAA/7CwsP/Hx8f/w8PD/8fHx//FxcX/xcXF/8XFxf/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/FxcX/xcXF/8bGxv/FxcX/xcXF/8XFxf/Dw8P/1NTU/ywsLP8AAAD/BAQE/wEBAf8AAAD/AAAA/wEBAf8BAQH/AAAA/0pKSv9NTU3/TExM/0xMTP9LS0v/TExM/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/0xMTP9NTU3/TU1N/0xMTP9MTEz/SkpK/01NTf8SEhL/AAAA/wICAv8CAgL/BAQE/wEBAf8BAQH/AQEB/wAAAP8NDQ3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3l5ef8BAQH/BgYG/wAAAP8CAgL/AQEB/wEBAf8DAwP/AAAA/wMDA/8oKCj/LS0t/zExMf8tLS3/Kioq/ysrK/8sLCz/Ly8v/zAwMP8qKir/LCws/yoqKv8oKCj/LCws/zAwMP8rKyv/KSkp/ykpKf8qKir/MDAw/y8vL/8rKyv/ERER/wAAAP8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8CAgL/AAAA/wUFBf+rq6v/7Ozs/3V1df8AAAD/AAAA/zs7O//j4+P/4uLi/zo6Ov8AAAD/AAAA/wQEBP+rq6v/7Ozs/4WFhf8AAAD/AAAA/zw8PP/k5OT/4+Pj/zk5Of8AAAD/BQUF/wAAAP8BAQH/AQEB/wAAAP8BAQH/AAAA/wMDA/8AAAD/ISEh/+Hh4f//////uLi4/wkJCf8CAgL/bW1t////////////bW1t/wICAv8CAgL/ISEh/+Hh4f//////wMDA/woKCv8CAgL/bW1t////////////bW1t/wEBAf8HBwf/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AwMD/wAAAP8cHBz/2NjY//////+4uLj/BwcH/wAAAP9lZWX//f39//////9nZ2f/AAAA/wAAAP8ZGRn/2dnZ//////+3t7f/CAgI/wAAAP9oaGj//Pz8//7+/v9mZmb/AAAA/wYGBv8AAAD/AgIC/wEBAf8BAQH/AwMD/wICAv8BAQH/AAAA/xsbG//Y2Nj//////7i4uP8GBgb/AAAA/2pqav///////v7+/2VlZf8AAAD/AAAA/xsbG//Y2Nj//////7m5uf8HBwf/AAAA/2VlZf///////////2VlZf8AAAD/BQUF/wEBAf8DAwP/AQEB/wAAAP8AAAD/AAAA/wQEBP8AAAD/HR0d/9ra2v//////urq6/wgICP8AAAD/Z2dn////////////aGho/wAAAP8AAAD/HR0d/9vb2///////urq6/wcHB/8AAAD/aGho////////////aWlp/wAAAP8FBQX/AAAA/wEBAf8BAQH/AAAA/wAAAP8AAAD/AgIC/wAAAP8cHBz/29vb//////+4uLj/BgYG/wAAAP9mZmb///////////9nZ2f/AAAA/wAAAP8aGhr/2tra//////+4uLj/BwcH/wAAAP9lZWX///////////9mZmb/AAAA/wUFBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7i4uP8GBgb/AAAA/2ZmZv///////////2dnZ/8AAAD/AAAA/xsbG//b29v//////7m5uf8JCQn/AAAA/2hoaP///////////2dnZ/8AAAD/BQUF/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMDA/8AAAD/Ghoa/9nZ2f//////ubm5/wYGBv8AAAD/ZmZm////////////ZmZm/wAAAP8AAAD/Gxsb/9ra2v//////uLi4/wcHB/8AAAD/ZmZm//7+/v/+/v7/ZmZm/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwMD/wAAAP8aGhr/2NjY//////+6urr/BgYG/wAAAP9mZmb///////////9mZmb/AAAA/wAAAP8aGhr/2NjY//////+5ubn/BwcH/wAAAP9nZ2f//v7+//////9nZ2f/AAAA/wQEBP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7q6uv8HBwf/AAAA/2ZmZv///////////2ZmZv8AAAD/AAAA/xoaGv/Y2Nj//////7i4uP8GBgb/AAAA/2ZmZv/9/f3//v7+/2ZmZv8AAAD/BAQE/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wMDA/8AAAD/HBwc/9vb2///////urq6/wgICP8AAAD/ZmZm////////////Z2dn/wAAAP8AAAD/Gxsb/9nZ2f//////urq6/wcHB/8AAAD/Z2dn////////////Z2dn/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8CAgL/BAQE/wAAAP8dHR3/29vb//////+8vLz/BwcH/wAAAP9nZ2f///////////9mZmb/AAAA/wAAAP8bGxv/29vb//////+6urr/BgYG/wAAAP9nZ2f///////////9mZmb/AAAA/wYGBv8AAAD/AQEB/wEBAf8AAAD/AQEB/wMDA/8DAwP/AAAA/x0dHf/a2tr/+fn5/7CwsP8GBgb/AAAA/2pqav/5+fn/+fn5/2tra/8AAAD/AAAA/xwcHP/Z2dn/+fn5/7m5uf8JCQn/AAAA/2xsbP/5+fn/+fn5/2tra/8AAAD/BwcH/wEBAf8CAgL/AQEB/wEBAf8CAgL/AwMD/wMDA/8AAAD/FxcX/9zc3P//////l5eX/wcHB/8DAwP/YGBg////////////XFxc/wQEBP8FBQX/GBgY/97e3v//////s7Oz/wkJCf8EBAT/XV1d////////////W1tb/wEBAf8EBAT/AQEB/wMDA/8DAwP/AAAA/wEBAf8DAwP/AQEB/wEBAf8AAAD/LS0t/1RUVP8hISH/AAAA/wAAAP8BAQH/TExM/0tLS/8AAAD/AAAA/wAAAP8AAAD/LS0t/1NTU/8bGxv/AAAA/wAAAP8BAQH/TExM/0tLS/8BAQH/AAAA/wEBAf8AAAD/AQEB/wAAAP8CAgL/AQEB/wEBAf8AAAD/BwcH/8XFxf++vr7/tbW1/729vf/Kysr/y8vL/8fHx/+2trb/tra2/8bGxv/Ly8v/yMjI/8rKyv+7u7v/tbW1/8DAwP/Ly8v/y8vL/8XFxf+1tbX/srKy/8nJyf9PT0//AAAA/wYGBv8CAgL/AAAA/wEBAf8AAAD/AQEB/wEBAf8KCgr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3Jycv8AAAD/BwcH/wEBAf8DAwP/AQEB/wAAAP8BAQH/AAAA/wgICP95eXn/fX19/319ff9/f3//gICA/4CAgP+BgYH/gICA/39/f/+BgYH/gYGB/4CAgP+AgID/gICA/4GBgf+AgID/gICA/4GBgf9/f3//fX19/3l5ef9+fn7/MjIy/wAAAP8DAwP/AQEB/wEBAf8AAAD/AQEB/wICAv8AAAD/BgYG/4+Pj/+Tk5P/j4+P/4uLi/+Hh4f/hISE/4ODg/+CgoL/gYGB/4KCgv+CgoL/goKC/4KCgv+BgYH/f39//39/f/+EhIT/hoaG/4eHh/+MjIz/kpKS/5WVlf8uLi7/AAAA/wMDA/8AAAD/AAAA/wEBAf8AAAD/AQEB/wQEBP8EBAT/SUlJ/1RUVP+BgYH/wsLC/////////////////////////////////////////////////////////////////////////////f39/6+vr/9iYmL/S0tL/xkZGf8AAAD/AwMD/wEBAf8DAwP/AQEB/wEBAf8BAQH/AAAA/wYGBv8AAAD/AAAA/wAAAP8AAAD/AQEB/wgICP9RUVH/paWl/8rKyv/a2tr/+fn5///////5+fn/2tra/8vLy/+ampr/T09P/xQUFP8DAwP/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wEBAf8CAgL/AQEB/wICAv8BAQH/AAAA/wQEBP8EBAT/AwMD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xsbG/9nZ2f/i4uL/2dnZ/8ZGRn/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/wQEBP8CAgL/AgIC/wAAAP8DAwP/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AgIC/wICAv8BAQH/AgIC/wMDA/8DAwP/AgIC/wQEBP8HBwf/AAAA/wAAAP8AAAD/AAAA/wAAAP8HBwf/BQUF/wMDA/8BAQH/AQEB/wMDA/8CAgL/AQEB/wEBAf8CAgL/AQEB/wAAAP8CAgL/AgIC/wICAv8AAAD/AAAA/wMDA/8CAgL/AwMD/wMDA/8BAQH/AQEB/wUFBf8DAwP/AgIC/wAAAP8EBAT/BwcH/wcHB/8HBwf/BAQE/wICAv8BAQH/AgIC/wEBAf8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8AAAD/AgIC/wICAv8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                        ]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchInCache.addCustomNames &&
                        Array.isArray(options.searchInCache.customNamesList)) {
                    namesList = namesList.concat(options.searchInCache.customNamesList);
                }
                namesList.forEach(function(elem) {
                    let engine = {};
                    engine.name = elem[0];
                    engine.cacheLink = elem[1];
                    engine.iconURI_spec = elem[2];
                    itemCreate(engine, "searchInCache");

                });
            }
            if (options.searchInCache.enable) {
                searchInCache();
            }

            popup.gObj = this;
            //popup.setAttribute("oncommand", "if (!event.target.engine) return; var csObj = this.gObj || document.getElementById('contextSearchMiniByBunda1-context-popup').gObj; csObj.searchCommandHandler(event);");

            popup.setAttribute("oncommand", "if (!event.target.engine || event.target.nodeName == 'menu') return; this.gObj.searchCommandHandler(event);");
            popup.setAttribute("onclick", "checkForMiddleClick(this, event);");
        },

        searchByImageCommandHandler: function(event) {
            var inBg = options.loadInBackground || false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = !inBg;
            }
            var searchByImageMenu = this.searchByImageMenu;
            var link = event.target.link;
            var imageLink = searchByImageMenu.imageSrc;
            if (imageLink.indexOf("data:") == 0) {
                this.searchByImageByData(imageLink, inBg);
                return;
            } else if (imageLink.indexOf("file:") == 0) {
                this.searchByImageByFile(imageLink, inBg);
                return;
            } else {
                imageLink = encodeURIComponent(imageLink)
            }
            var gBrowser = gBrowser || getBrowser();
            gBrowser.loadOneTab(link + imageLink, {
                relatedToCurrent: true,
                inBackground: inBg
            });
        },
        // searchByImageByData() and searchByImageByFile() based on
        // Google Image Search 0.5 by Nishan Naseer
        // https://addons.mozilla.org/ru/firefox/addon/google-similar-images
        searchByImageByData: function(src, inBg) {
            var gBrowser = gBrowser || getBrowser();
            //var tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
            var tab = gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
                relatedToCurrent: true
            });
            var newTabBrowser = gBrowser.getBrowserForTab(tab);
            newTabBrowser.addEventListener("load", function byData(e) {
                newTabBrowser.removeEventListener(e.type, byData, true);
                if (src) {
                    try {
                        var image_url;
                        var sub;
                        var form = newTabBrowser.contentDocument.getElementById("qbf");
                        var inputs = form.getElementsByTagName("input");
                        for (var k = 0; k < inputs.length; k++) {
                            var i = inputs[k];
                            if (i.name && i.name == "image_url") {
                                image_url = i;
                            }
                            if (i.type && i.type == "submit") {
                                sub = i;
                            }
                        }
                        image_url.value = src;
                        sub.click();
                        src = null;
                    } catch (ex) { }
                }
            }, true);

            if (!inBg) {
                getBrowser().selectedTab = tab;
            }
        },
        searchByImageByFile: function(src, inBg) {
            //Canvas to get contents in base-64
            var canvas = gContextMenu.target.ownerDocument.createElementNS(XHTMLNS, "canvas");
            var image = new Image();
            image.src = src;

            canvas.width = image.width;
            canvas.height = image.height;

            var ctx = canvas.getContext("2d");
            ctx.drawImage(image, 0, 0);
            var dataURL = canvas.toDataURL("image/png");
            var gBrowser = gBrowser || getBrowser();
            //var tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
            var tab = gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
                relatedToCurrent: true
            });
            var newTabBrowser = gBrowser.getBrowserForTab(tab);
            newTabBrowser.addEventListener("load", function byFile(e) {
                newTabBrowser.removeEventListener(e.type, byFile, true);
                if (src) {
                    try {
                        var image_url;
                        var sub;
                        var form = newTabBrowser.contentDocument.getElementById("qbf");
                        var inputs = form.getElementsByTagName("input");
                        for (var k = 0; k < inputs.length; k++) {
                            var i = inputs[k];
                            if (i.name && i.name == "image_url") {
                                image_url = i;
                            }
                            if (i.type && i.type == "submit") {
                                sub = i;
                            }
                        }
                        image_url.value = dataURL;
                        sub.click();
                        src = null;
                    } catch (ex) { }
                }
            }, true);

            if (!inBg) {
                getBrowser().selectedTab = tab;
            }
        },
        searchByImageMenuPopup: function(e) {
            var searchByImageMenu = this.searchByImageMenu;

            searchByImageMenu.hidden = !gContextMenu.onImage;
            var src = gContextMenu.mediaURL || gContextMenu.imageURL || gContextMenu.bgImageURL;
            if (!src || !(/^((ht|f)tps?:\/\/|data:image|file:)/.test(src))) {
                searchByImageMenu.hidden = true;
                return;
            }
            //var popup = document.getElementById("contextSearchMiniByBunda1-context-image-search-popup");
            var popup = searchByImageMenu.popup;
            var items;
            if (!popup.items) {
                var itemsObj = popup.getElementsByTagName("menuitem");
                popup.items = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menuitem" &&
                            elem.getAttribute("label") != "Google")
                        popup.items.push(elem);
                });
                items = popup.items;
            } else {
                items = popup.items;
            }

            if (/^(data:image|file:)/.test(src)) {
                items.forEach(function(elem) {
                    elem.setAttribute("disabled", "true");
                });
            } else {
                items.forEach(function(elem) {
                    elem.removeAttribute("disabled");
                });
            }

            searchByImageMenu.imageSrc = src;
        },
        createSearchByImageMenu: function() {
            var menu = document.createElement("menu");
            var insertMenu = document.getElementById("context-sep-copyimage");
            insertMenu.parentNode.insertBefore(menu, insertMenu);
            this.searchByImageMenu = menu;

            menu.setAttribute("id", this.nodeIds.searchByImageMenu);
            menu.setAttribute("class", "menu-iconic");
            menu.setAttribute("label", _localize("searchByImage"));
            menu.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK6wAACusBgosNWgAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAElSURBVDiNY/z//z8DJYCRkIKsthv/kRX9Z2BgmFalARdiIcaGKZXqcH5O+01U+ay2G3MYGBiSiXUmmofnsBDSjEUTMkiBe2Eq1JnZ7TcZBHhZGNythBl0lLkZODmYGX7++sdw/sZnhl3H3zF8+voHwwsYFkR5ijNICLMzTF31hOHnr38MHGxMDJlhMgwv3vxkWL7jJYpaJmzu0lTigWtmYGBg+PHrH8P0VU8YtJV5MNRiNYCfmxmuGQZ+/PrHwMmOqRyrAX///WfgYEOV4mBjwjAUpwHHL31iyA6XgRvCwcbEkBUmw3DuxmcMtVgDkYONicHLVoTBSJOXgYONieHHz38Ml+98Ydh88DXDtx//CBtACmBiYGCYS4H+OYyU5kasgUgKAADN8WLFzlj9rgAAAABJRU5ErkJggg==");

            this.searchByImageMenu.popup = menu.appendChild(document.createElementNS(XULNS, "menupopup"));
            var popup = this.searchByImageMenu.popup;
            popup.setAttribute("id", this.nodeIds.searchByImageMenuPopup);
            popup.googleURL = "https://www.google.com/searchbyimage";

            var namesList = [];
            if (options.searchByImage.useDefaultNamesList) {
                let defaultNamesList = [
                    [
                        "Google",
                        "https://www.google.com/searchbyimage?image_url=",
                        "data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAA9IVCSvSFQuf0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULk9IVCSvSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQuf0hUL/9IVC//SFQv/0hUL/9Y1O//rIq//+7+f//eXX//vUvf/7z7X/96Fu//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vYwv/97OH/9ZRZ//SFQv/0hUL/9IhG//zbx//3om7/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97uX/+buW//SFQv/0hUL/9IVC//SFQv/5upT/+9O6//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+b6b//zezP/0iEf/9IVC//SFQv/1klf//ezh//vPtP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/3qXr/+siq//m8lv/5wqD//vTu//3t4//1klb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0h0b//vbx//zi0//1j1H/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2nmn/+bmS/////v/4sIX/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5uJH///v5//eoef/1jU//+82y//afav/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vXw//vOs//0hUL/9IVC//ekcf/96+D/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//728v/4sIX/9IVC//SFQv/4s4n///v4//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6yKn/+byX//SFQv/0hkT//eTV//vWv//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IZE//m6lP/5u5b//OHQ///+/f/6y6//96d3//SFQv/0hUL/9IVC//SFQv/0hULm9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSfSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAA9IVCAPSFQif0hUKt9IVC8vSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvL0hUKt9IVCJ/SFQgD0hUIo9IVC7/SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULv9IVCKPSFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVC8fSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvP0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YtL//i2jv/828f//vLr///7+P///Pv//vTu//3n2v/6zbH/96Nw//SFQ//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ekcv/+8+z////////////+9fD/+9K5//m9mf/4to7/+buV//vSuf/++PT//OPT//aYYP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2l13///r3/////////fv/+b2Z//SIRv/0hUL/9IVC//SFQv/0hUL/9IVC//WNT//84M///vXv//aZYf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vPtP////////////i0i//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//WQUv///Pr//OPU//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//eTV///////+9O7/9IVD//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//3m2P//////9ppi//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/718H///////3s4f/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vDn///////4soj/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//erff////////38//WTWP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//iziv////////////iwhf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rMsP///////eXW//WSVv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/4sYb///z7/////////Pv/9ZFV//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ixhv/+8Of//vn1//rMsP/4rH//9plh//WQUv/1j1L/+s2x//////////////////m9mf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SGQ//2nmn/+buW//vNsv/82sb//e3j/////////////////////v/5wZ//9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/83Mj////////////++fb/+K+C//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9ZRZ/////////////vTt//aaYv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/1lFr////////////6xqf/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ehbf/70bj//end//3o2////v3///////3l1//0iEb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5wqD////////////96t7/96Z2//WOUP/2nWf//NvH//zcyP/1i0z/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/96l6/////////////vLr//WPUf/0hUL/9IVC//SFQv/0h0b//end//3k1f/0iUn/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/8387////////////4sYf/9IVC//SFQv/0hUL/9IVC//SFQv/6w6L///////nBn//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC///69////////vj1//SIR//0hUL/9IVC//SFQv/0hUL/9IVC//m+mv///////e3j//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL///r3///////8387/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+syw///////++fb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/95NX///////vUvP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97OH///////7y6//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//i2jv///////N/O//SFQv/0hUL/9IVC//SFQv/0hUL/96Nx////////////+s2x//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IdF//zh0P//+/j/9ZJW//SFQv/0hUL/9IVC//SKSv/96t7///////738v/1k1f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YxN//vUvf/96+D/96Z0//WNT//3om///ebY/////////Pv/+LKI//WVW//0h0X/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//agbP/7zbL//enc//749P////////////////////////////3r4P/3p3f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8/SFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVCJ/SFQu/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC7/SFQif0hUIA9IVCJfSFQq30hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8fSFQq30hUIl9IVCAIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAB"
                    ],
                    [
                        "Yandex",
                        "http://images.yandex.ru/yandsearch?rpt=imagedups&text=&img_url=",
                        "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=="
                    ],
                    [
                        "TinEye",
                        "http://www.tineye.com/search/?pluginver=firefox-1.0&url=",
                        "data:image/x-icon;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAACxeDVItHk157iAO//WtW7/482G/+XOhv/lzYL/1L98/5mTcf8UKUP/CwsM/xwcG/8AAAD/AAAA/wAAAOcAAA5ItHo25LV7Nv+1ezb/tXs2/8GPSf/EoGj/s5hw/6KPdf93bWT/ZFdK/2daTP9hVEj/XU9C/zIpH/8EAgH/AAAA5LV7Nv+1ezb/tXs2/7V7Nv+1ezb/uIA+/8eea//Wtof/48eU/+PKkv/iyJP/4MeV/9u/kf/HqHz/rI1p/3tmT/+1ezb/tXs2/7V7Nv+1ezb/zKV0/+PKlP/hxXr/zbFk/8esYf/VuW7/3sFz/+LFdf/gw3P/48Z3/+nPjv/dwJD/tXs2/7V7Nv+1ezb/y6Nx/9/Gg/+NekT/V0wv/5uSfP95cmH/JiES/zAqGv86Mh3/W08v/3lpQP+Wg03/zLFn/7V7Nv+1ezb/uoVH/8myg/+VgUr/AAAA/2xpZf/i4+X/+fn5/0JAO/8AAAD/LCkl/768uf+/vr3/Mi8q/x0ZEP+2fDf/tXs2/6WGX/+pklP/JyES/0dFQP96eHX/W1tc//////9ua2X/DAoH/6Wim/+EhIX//////6ejnP8AAAD/wo1F/8GLQ//Conf/tZ1e/wYDAP9pZmH/6+vs/9/f3/////3/Pjoz/zo2Lf/Jycb/UlJT//////+xraX/AAAA/8OORv/Djkb/1bF+/821cf83MSD/MC4s//n49P//////l5OJ/wMCAP9IRDr/////////////////ZGBW/wAAAP/Djkb/w45G/8qkcP+sllr/wKtw/zw5Mf9MSUb/VlNM/wIBAP8AAAD/FxUP/9PQyv/8+/j/rKig/wkHA/8AAAD/w45G/8OORv+1jlj/l4hm/8etZv/QuHf/m4xk/21hSP9PRjX/Mi0j/xsYFf87NzD/VFBK/xUVFf8FBwz/CQsQ/8OORv/Djkb/g2I1/8Oea//Mt4z/uJxU/56hhv92nLj/l6ut/56poP+gpJL/mJeC/5aMbP+bjmv/m49t/52Qbv/Djkb/uItP/05PUP+zjlv/yptc/9C3jP9gYFP/ABVH/wAzc/8IP4T/FUuM/xhSmP99lZ3/5sRv/9S6cf/Lsmr/w45G/1B7rv8bbdT/LWy5/8OORv/Djkf/yqRw/zswIP8AAAD/AAAA/wAAAP8AAAD/Fyk8/5CKZ/+ahU3/modW/8GNReeEj5r/L37g/0Jxqf/Cjkf/w45G/8OORv/Fllb/clYw/zoqFf8hGQ3/IhwU/x4ZFf9HRUD/vaJ5/86pdee+ikU/woxEyZ6HZ/+8jEz/w45G/8OORv/Djkb/w45G/8OORv/Djkb/v4tF/8ORTf/GlFD/xJBJ/8KMRMm+ikU/gAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAE="
                    ]
                ];
                namesList = namesList.concat(defaultNamesList);
            }
            if (options.searchByImage.addCustomNames &&
                    Array.isArray(options.searchByImage.customNamesList)) {
                namesList = namesList.concat(options.searchByImage.customNamesList);
            }

            function itemCreate(name, link, image) {
                var item = document.createElementNS(XULNS, "menuitem");
                item.setAttribute("class", "menuitem-iconic");
                item.setAttribute("src", image);
                item.setAttribute("label", name);
                item.link = link;
                popup.appendChild(item);
            }
            namesList.forEach(function(elem) {
                itemCreate(elem[0], elem[1], elem[2]);
            });

            var contextMenu = this.contextMenu;

            popup.gObj = this;
            popup.setAttribute("oncommand", "this.gObj.searchByImageCommandHandler(event);");
            popup.setAttribute("onclick", "checkForMiddleClick(this, event);");
        }
    }
    contextSearcherObj.init();
})();

bunda1
а XULNS и XHTMLNS пусть будут

2k1dmg
спасибо :).

2k1dmg и bunda1 совместными усилиями вы сделали очень удобную и функциональную кнопку. БОЛЬШОЕ ВАМ СПАСИБО! http://www.kolobok.us/smiles/big_standart/clapping.gif http://www.kolobok.us/smiles/big_standart/good.gif
Вот ещё бы для пункта отображаемого при клике на картинке http://images.vfl.ru/ii/1381414585/ff80ffa7/3270720.png сделать возможность задать поисковик по умолчанию и сделать его активным - осуществлять поиск этим поисковиком при клике на пункте контекстного меню (без захода в подменю). И тогда  кнопка будет универсальная на все 100%.

2k1dmg
А можно как то поисковики впихнуть внутрь контекстного меню, чтобы не прыгали слева на право а всегда были на предсказуемом месте, или как нибудь привязать к одной стороне.
http://s019.radikal.ru/i634/1310/86/8293fdb93743t.jpg

PEAKTOP пишет:

сделать возможность задать поисковик по умолчанию и сделать его активным - осуществлять поиск этим поисковиком при клике на пункте контекстного меню (без захода в подменю).

как-нибудь потом

villa7

скрытый текст
можно попробовать добавить

Выделить код

Код:

popup.setAttribute("position", "start_before");

после

Выделить код

Код:

popup.setAttribute("id", this.nodeIds.searchMenuPopup);

https://developer.mozilla.org/en-US/doc … ositioning

2k1dmg

popup.setAttribute("position", "start_before");

Спасибо, как и хотелось, только значение другое подставить пришлось.

bunda1 пишет:

Context Search, от 13.10.2013

отвалилось на ESR 24.2.0, но если убрать/закомментировать

Выделить код

Код:

mItem.setAttribute("src", engine.iconURI.spec );

то работает, но в списке поисковиков не отображаются иконки.
Что-то поменялось в этой функции?

У меня Context Search на ESR 24.2.0 работает :/
Может у тебя конфликт с каким то кодом или расширением, попробуй на чистом профиле.

bunda1
прошу пощения, на чистом профиле и правда работает (

Evybr пишет:

bunda1 пишет:

которые и позволяет вам  выбрать

Исправьте.

Хорошо.

bunda1
В FF 26 и custombuttons-0.0.5.7pre3-20131124 эта кнопка Context Search добавляет в контекстное меню свой пункт два раза:
http://s2.ipicture.ru/uploads/20131213/BnOZ6SqF.gif
Можно ли поправить?

на моем фф вот так работает кнопка.
а на фф 24 нормально. переходить пока не собираюсть. нельзя ли что-то подправить чтобы на фф 20 работало?

rubel
Kiril__777
Временно можете попробовать эту версию

Context Search mini 2013-11-22

Выделить код

Код:

(function () {
    // Context Search mini 2013-11-22
    var options = {
        loadInBackground: false,
        // true - открывать вкладки в фоне
        pinnedEngineName: "",
        // оставить пустым если не нужно закреплять
        // определенный поисковик
        // примеры pinnedEngineName: "Google" или pinnedEngineName: "Яндекс" или pinnedEngineName: ""
        hideDefaultEngineInPopupSubMenu: false,
        // true - не добавлять поисковик по умолчанию в выпадающий список (подменю) поисковиков
        campactMenu: true,
        // true - поисковики в выпадающем списке (подменю) без назаваний
        campactMenuLengthPerLine: 5,
        // максимальное количество элементов в одной строке
        // от 3 до 10, по умолчанию 5
        searchBySite: {
            enable: true,
            // true - добавить поисковики по сайту
            iconsOn: true,
            // true - добавить иконки для поисковиков по сайту
            useDefaultNamesList: true,
            // true - использовать список поисковиков по умолчанию
            addCustomNames: false,
            // true - добавить свои поисковики по сайту
            customNamesList: [
                ["Rambler", ["Rambler", "Рамблер"]]
            ]
            // например ["Rambler", ["Rambler", "Рамблер"]]
            // первая ячека название на английском
            // вторая ячека массив с предполагаемыми именами поисковика
            // может состоять из нескольких значений
            // ["Name1", ["Name1"]],
            // ["Name2", ["Name2", "Имя2"]],
            // ["Name3", ["Name3", "Имя3", "Név3"]]
        },
        searchImageByText: {
            enable: true,
            // true - добавить поиск изображения по тексту
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        },
        searchByImage: {
            enable: true,
            // true - добавить поиск по изображению
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        },
        searchInCache: {
            enable: true,
            // true - добавить поиск в кэше
            // нужно доработать
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        }
    };
    function _localize(sid) {
        let strings = {
            en: {
                searchBySite: "Search this site",
                searchImageByText: "Search image by text",
                searchByImage: "Search by image",
                searchInCache: "Search this page in cache"

            },
            ru: {
                searchBySite: "Поиск по этому сайту",
                searchImageByText: "Поиск изображения по тексту",
                searchByImage: "Поиск по изображению",
                searchInCache: "Поиск этой страницы в кэше"
            }
        };
        //let locale = (Application.prefs.getValue("general.useragent.locale", false) || "en").match(/^[a-z]*/)[0];
        function getBrowserUILocale() {
            let gPrefService = Services.prefs; // SeaMonkey
            if (!gPrefService.getBoolPref("intl.locale.matchOS")) {
                try {
                    var locale = gPrefService.getCharPref("general.useragent.locale");
                    if (locale.substr(0, 9) == "chrome://") {
                        return gPrefService.getComplexValue("general.useragent.locale",
                            Components.interfaces.nsIPrefLocalizedString).data;
                    }
                    return locale;
                } catch (ex) {}
            }
            try {
                return Components.classes["@mozilla.org/chrome/chrome-registry;1"]
                .getService(Components.interfaces.nsIXULChromeRegistry)
                .getSelectedLocale("global");
            } catch (ex) {
                return "en-US";
            }
        }
        let locale = ""; // ru, en
        if (!locale)
            locale = getBrowserUILocale().match(/^[a-z]*/)[0];
        _localize = function (sid) {
            return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
        };
        return _localize.apply(this, arguments);
    }

    let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    let XHTMLNS = "http://www.w3.org/1999/xhtml";

    var contextSearcherObj = {
        initialized: false,
        init: function() {
            if(this.initialized)
                return;
            this.initialized = true;

            this.nodeIds = {
                searchMenu: "contextSearchMiniByBunda1-menu",
                searchMenuPopup: "contextSearchMiniByBunda1-popup",
                searchByImageMenu: "contextSearchMiniByBunda1-image-search-menu",
                searchByImageMenuPopup: "contextSearchMiniByBunda1-image-search-popup"
            };

            if (document.getElementById(this.nodeIds.searchMenu))
                return;

            var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
            var contextMenu = document.getElementById("contentAreaContextMenu");
            var searchSelect = document.getElementById("context-searchselect");
            searchSelect.style.display = "none";

            var searchMenu = contextMenu.insertBefore(document.createElementNS(XULNS, "menu"), searchSelect);

            this.searchService = searchService;
            this.contextMenu = contextMenu;
            this.searchSelect = searchSelect;
            this.searchMenu = searchMenu;

            this.param = {
                isPinnedEngine: false,
                pinnedEngineName: ""
            };

            try {
                this.createSearchMenu();
                if (options.searchByImage.enable)
                    this.createSearchByImageMenu();
            } catch (ex) {
                this.destroy();
                Components.utils.reportError(ex);
                return;
            }

            if (options.campactMenu)
                this.loadStyles();

            var observeStatus = new MutationObserver(function () {
                    searchMenu.hidden = searchSelect.hidden;
                });
            observeStatus.observe(searchSelect, {
                attributes: true,
                attributeFilter: ["hidden"]
            });

            /*var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                        .getService(Components.interfaces.nsIPrefService);
            this.branch = prefService.getBranch("browser.search.");
            if (!("addObserver" in this.branch))
                this.branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
            this.branch.addObserver("", this, false);*/

            /*
            var searchPref = "browser.search.";
            gPrefService.addObserver(searchPref, this, false);*/


            /*let os = Cc["@mozilla.org/observer-service;1"].
                        getService(Ci.nsIObserverService);
            os.addObserver(this, "browser-search-engine-modified", false);*/
            Services.obs.addObserver(this, "browser-search-engine-modified", false);

            Services.ww.registerNotification(this);

            addEventListener("popupshowing", this, false, contextMenu);

            addDestructor(function (reason) {
                observeStatus.disconnect();
                Services.ww.unregisterNotification(this);
                //this.branch.removeObserver("", this);
                //gPrefService.removeObserver(searchPref, this, false);
                //os.removeObserver(this, "browser-search-engine-modified", false);
                Services.obs.removeObserver(this, "browser-search-engine-modified", false);
                this.destroy();
                if (reason != "destructor")
                    this.unloadStyles();
            }, this);
        },
        destroy: function() {
            if(!this.initialized)
                return;
            this.initialized = false;
            var contextMenu = this.contextMenu;
            if (!contextMenu)
                return;
            if (this.searchMenu)
                contextMenu.removeChild(this.searchMenu);
            if (this.searchByImageMenu)
                contextMenu.removeChild(this.searchByImageMenu);
            if (this.searchSelect)
                this.searchSelect.style.removeProperty("display");
        },
        update: function() {
            this.searchMenu.textContent = "";
            this.createSearchMenu();
            delete this.updateTimeoutID;
        },

        get isSeaMonkey() {
            delete this.isSeaMonkey;
            return this.isSeaMonkey = Services.appinfo.name == "SeaMonkey";
        },

        observe: function(subject, topic, data) {
            switch (topic) {
                /*case "domwindowclosed":
                    if (subject.document.documentElement.getAttribute("windowtype") == "Browser:SearchManager") {
                        this.update();
                    }
                    break;*/
                /*case "nsPref:changed":
                    switch (data) {
                        case "defaultenginename":
                        case "browser.search.defaultenginename":
                            this.update();
                            break;
                    }
                    break;*/
                case "browser-search-engine-modified":
                    /*switch (data) {
                        case "engine-default":
                        case "engine-current": // engine-default
                        case "engine-changed":
                        case "engine-removed":*/
                            if (typeof this.updateTimeoutID == "number") {
                                window.clearTimeout(this.updateTimeoutID);
                                delete this.updateTimeoutID;
                            }
                            let _this = this;
                            this.updateTimeoutID = window.setTimeout(function () {
                                _this.update();
                            }, 1000);
                            /*break;
                    }*/
                    break;
            }
        },
        handleEvent: function(e) {
            //var contextMenu = this.contextMenu;
            //var menu = this.menu;
            //var imageMenu = this.imageMenu;
            switch (e.type) {
                case "popupshowing":
                        this.popupshowingEvent(e);
                    break;
            }
        },
        popupshowingEvent: function(e) {
            var trgId = e.target.id;
            if (trgId) {
                if (trgId == "contentAreaContextMenu") {
                    this.contextMenuPopup(e);
                    if (this.searchByImageMenu)
                        this.searchByImageMenuPopup(e);
                } else if (trgId == this.nodeIds.searchMenuPopup)
                    this.searchMenuPopup(e);
            }
        },

        _stylesLoaded: false,
        loadStyles: function() {
            if(this._stylesLoaded)
                return;
            this._stylesLoaded = true;
            var sss = this.sss;
            var cssURI = this.cssURI = this.makeCSSURI();
            if(!sss.sheetRegistered(cssURI, sss.USER_SHEET))
                sss.loadAndRegisterSheet(cssURI, sss.USER_SHEET);
        },
        unloadStyles: function() {
            if(!this._stylesLoaded)
                return;
            this._stylesLoaded = false;
            var sss = this.sss;
            if(sss.sheetRegistered(this.cssURI, sss.USER_SHEET))
                sss.unregisterSheet(this.cssURI, sss.USER_SHEET);
        },
        get sss() {
            delete this.sss;
            return this.sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]
                .getService(Components.interfaces.nsIStyleSheetService);
        },
        makeCSSURI: function() {
            var cssStr = '\
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\n\
@-moz-document url("' + window.location.href + '") {\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n\
        /*width: 2em !important;*/\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] * {\n\
        /*padding-left: 0 !important;\n\
        padding-right: 0 !important;\n\
        margin-left: 0 !important;\n\
        margin-right: 0 !important;*/\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > spacer[campactMenu="true"] {\n\
        width: /*2em*/26px !important;\n\
        @media (min-resolution: 2dppx) {\n\
            #' + this.nodeIds.searchMenuPopup + ' > hbox > spacer[campactMenu="true"]  {\n\
                width: 52px !important;\n\
            }\n\
        }\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n\
        /*width: 3em !important;\n\
        height: 2em !important;*/\n\
        width: 36px !important;\n\
        height: 26px !important;\n\
        -moz-box-pack: center !important;\n\
        @media (min-resolution: 2dppx) {\n\
            #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"]  {\n\
                width: 72px !important;\n\
                height: 52px !important;\n\
            }\n\
        }\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox >.menuitem-iconic[campactMenu="true"] > image {\n\
        /*margin-left: .8em !important;*/\n\
    }\n\
}\n\
';
            return Services.io.newURI("data:text/css," + encodeURIComponent(cssStr), null, null);
        },

        searchCommandHandler: function(event, trg) {
            var inBg = options.loadInBackground || false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = !inBg;
            }
            var searchBySite = "";
            if (event.target.hasAttribute("searchBySite"))  {
                searchBySite = " site:" + gBrowser.currentURI.host;
            } else if (event.target.hasAttribute("searchInCache")) {
                searchBySite = content.location.href;
            }
            let selectedText = this.isSeaMonkey ? content.getSelection().toString() : getBrowserSelection();
            if (event.target.engine.imageLink) {
                gBrowser.loadOneTab(event.target.engine.imageLink + /*getBrowserSelection()*/ selectedText, {
                    relatedToCurrent: true,
                    inBackground: inBg
                });
            } else if (event.target.engine.cacheLink) {
                gBrowser.loadOneTab(event.target.engine.cacheLink + /*getBrowserSelection()*/ searchBySite, {
                    relatedToCurrent: true,
                    inBackground: inBg
                });
            } else {
                let submission = event.target.engine.getSubmission(/*getBrowserSelection()*/ selectedText + searchBySite, null);
                gBrowser.loadOneTab(submission.uri.spec, {
                    relatedToCurrent: true,
                    postData: submission.postData,
                    inBackground: inBg
                });
            }
            if (trg == "menu") {
                setTimeout(function () {
                    document.getElementById("contentAreaContextMenu").hidePopup();
                }, 0);
            }
        },
        contextMenuPopup: function(e) {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.searchMenu;

            //var selectedText = getBrowserSelection(16);
            var selectedText = this.isSeaMonkey ? content.getSelection(16).toString() : getBrowserSelection(16);
            if (!selectedText)
                return;
            var ellipsis = "\u2026";
            try {
                ellipsis = gPrefService.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
            } catch (ex) { }
            if (selectedText.length > 15)
                selectedText = selectedText.substr(0,15) + ellipsis;
            let rEngine = this.isSeaMonkey ? "currentEngine" : "defaultEngine";
            var engineName = this.param.isPinnedEngine ? this.param.pinnedEngineName : searchService[rEngine].name;
            var menuLabel;
            var searchFormattedString = [
                "contextMenuSearch",
                "contextMenuSearchText",
                "searchSelected"
            ];
            var thisIsSM = this.isSeaMonkey;
            function getMenuLabel(str) {
                try {
                    if (thisIsSM) {
                        let bundle = document.getElementById("contentAreaCommandsBundle");
                        return bundle.getFormattedString(str, [engineName, selectedText]);
                    } else
                        return gNavigatorBundle.getFormattedString(str, [engineName, selectedText]);
                } catch (ex) {
                    return false;
                }
            }
            for(let i in searchFormattedString) {
                menuLabel = getMenuLabel(searchFormattedString[i]);
                if (menuLabel)
                    break;
                else if (!menuLabel && i == searchFormattedString.length-1)
                    menuLabel = engineName;
            }
            menu.label = menuLabel;
        },
        searchMenuPopup: function(e) {
            var popup = e.target;
            var items;
            if (!popup.items) {
                var itemsObj = popup.getElementsByTagName("menuitem");
                popup.items = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menuitem" &&
                            elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        popup.items.push(elem);
                });
                items = popup.items;
            } else {
                items = popup.items;
            }
            var menus;
            if (!popup.menus) {
                var itemsObj = popup.getElementsByTagName("menu");
                popup.menus = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menu" &&
                            elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        popup.menus.push(elem);
                });
                menus = popup.menus;
            } else {
                menus = popup.menus;
            }
            var siteSearchDomain;
            var gBrowser = gBrowser || getBrowser();
            function isDomain() {
                try {
                    siteSearchDomain = gBrowser.currentURI.host;
                } catch (ex) {
                    return false;
                }
                return true;
            }
            if (isDomain()) {
                items.forEach(function(elem) {
                    //if (elem.hasAttribute("searchBySite"))
                    //    elem.setAttribute("tooltiptext", siteSearchDomain);
                    elem.removeAttribute("disabled");
                });
                menus.forEach(function(elem) {
                    if (elem.hasAttribute("searchBySite"))
                        elem.setAttribute("tooltiptext", siteSearchDomain);
                    else if (elem.hasAttribute("searchInCache"))
                        elem.setAttribute("tooltiptext", content.document.title);
                    elem.removeAttribute("disabled");
                });
            } else {
                items.forEach(function(elem) {
                    //if (elem.hasAttribute("searchBySite"))
                    //    elem.removeAttribute("tooltiptext");
                    elem.setAttribute("disabled", "true");
                });
                menus.forEach(function(elem) {
                    if (elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        elem.removeAttribute("tooltiptext");
                    elem.setAttribute("disabled", "true");
                });
            }
        },
        createSearchMenu: function() {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.searchMenu;

            var engines = searchService.getVisibleEngines({});

            menu.setAttribute("id", this.nodeIds.searchMenu);

            menu.setAttribute("class", "menu-iconic");
            this.param.isPinnedEngine = false;
            this.param.pinnedEngineName = "";
            var pinnedEngineName = options.pinnedEngineName;
            if (pinnedEngineName != "") {
                for (let i in engines) {
                    if (engines[i].name != pinnedEngineName)
                        continue;
                    menu.setAttribute("label", engines[i].name);
                    menu.setAttribute("image", engines[i].iconURI.spec);
                    menu.engine = engines[i];
                    this.param.isPinnedEngine = true;
                    this.param.pinnedEngineName = pinnedEngineName;
                    break;
                }
            }

            let rEngine = this.isSeaMonkey ? "currentEngine" : "defaultEngine";
            if (!this.param.isPinnedEngine) {
                menu.setAttribute("label", searchService[rEngine].name);
                menu.setAttribute("image", searchService[rEngine].iconURI.spec);
                menu.engine = searchService[rEngine];
            }

            menu.gObj = this;
            menu.setAttribute("onclick", "if (event.target == this && event.target.engine) this.gObj.searchCommandHandler(event, 'menu');");

            menu.popup = menu.appendChild(document.createElementNS(XULNS, "menupopup"));
            var popup = this.searchMenu.popup;
            popup.setAttribute("id", this.nodeIds.searchMenuPopup);

            var counterMaxLength = options.campactMenuLengthPerLine;
            if (typeof counterMaxLength != "number" ||
                3 > counterMaxLength || counterMaxLength > 10)
                counterMaxLength = 5;
            var counter = 0;
            var hBox;
            function itemCreateCampact(engine, last) {
                if(counter == 0) {
                    hBox = document.createElementNS(XULNS, "hbox");
                    let item = document.createElementNS(XULNS, "spacer");
                    //item.setAttribute("style", "width: 2em");
                    item.setAttribute("campactMenu", "true");
                    hBox.appendChild(item);
                }
                counter++;
                var item = document.createElementNS(XULNS, "menuitem");
                item.engine = engine;
                item.setAttribute("class", "menuitem-iconic");
                item.setAttribute("tooltiptext", engine.name);
                //item.setAttribute("src", engine.iconURI.spec);
                var image = document.createElementNS(XULNS, "image");
                image.setAttribute("src", engine.iconURI.spec);
                item.appendChild(image);
                //item.setAttribute("style", "max-width: 2em");
                item.setAttribute("campactMenu", "true");
                hBox.appendChild(item);
                if (counter == counterMaxLength || last) {
                    popup.appendChild(hBox);
                    counter = 0;
                }
            }

            var separator = {};
            function itemCreate(engine, reason) {
                var item = document.createElementNS(XULNS, "menuitem");
                item.setAttribute("class", "menuitem-iconic");
                item.engine = engine;
                if (reason && !separator[reason]) {
                    /*let sep = separator[reason] = document.createElementNS(XULNS, "menuseparator");
                    sep.setAttribute(reason, "true");
                    popup.appendChild(sep);

                    let item = document.createElementNS(XULNS, "label");
                    //item.setAttribute("class", "menuitem-iconic");
                    item.setAttribute("value", _localize(reason) + ":");
                    item.setAttribute("style", "padding-left: 2em");
                    popup.appendChild(item);*/

                    if (!separator["menuseparator"]) {
                        let sep = separator["menuseparator"] = document.createElementNS(XULNS, "menuseparator");
                        popup.appendChild(sep);
                    }

                    let subMenu = separator[reason] = document.createElementNS(XULNS, "menu");
                    subMenu.setAttribute("class", "menu-iconic");
                    subMenu.setAttribute("label", _localize(reason));
                    subMenu.setAttribute(reason, "true");
                    subMenu.popup = subMenu.appendChild(document.createElementNS(XULNS, "menupopup"));
                    popup.appendChild(subMenu);
                }
                if (reason == "searchBySite") {
                    item.setAttribute("label", engine.name);
                    if (options.searchBySite.iconsOn) {
                        item.setAttribute("src", engine.iconURI.spec);
                    }
                    item.setAttribute(reason, "true");
                } else if (reason == "searchImageByText" ||
                            reason == "searchInCache") {
                    item.setAttribute("label", engine.name);
                    item.setAttribute("src", engine.iconURI_spec);
                    item.setAttribute(reason, "true");
                } else {
                    item.setAttribute("label", engine.name);
                    item.setAttribute("src", engine.iconURI.spec);
                }
                //popup.appendChild(item);
                if (reason) {
                    let subMenu = separator[reason];
                    subMenu.popup.appendChild(item);
                } else
                    popup.appendChild(item);
            }
            for (let i in engines) {
                if (options.hideDefaultEngineInPopupSubMenu &&
                        this.param.isPinnedEngine &&
                        engines[i].name == pinnedEngineName ||
                        options.hideDefaultEngineInPopupSubMenu &&
                        !this.param.isPinnedEngine &&
                        engines[i].name == searchService[rEngine].name) {
                    continue;
                }
                if (options.campactMenu)
                    itemCreateCampact(engines[i], i == engines.length-1);
                else
                    itemCreate(engines[i]);
            }
            function searchBySite_itemCreate() {
                var namesList = [];
                if (options.searchBySite.useDefaultNamesList) {
                    let defaultNamesList = [
                        ["Google", ["Google"]],
                        ["Yandex", ["Yandex", "Яндекс"]],
                        ["Yahoo", ["Yahoo"]],
                        ["Bing", ["Bing"]],
                        ["DuckDuckGo", ["DuckDuckGo"]]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchBySite.addCustomNames &&
                        Array.isArray(options.searchBySite.customNamesList)) {
                    namesList = namesList.concat(options.searchBySite.customNamesList);
                }
                //let i_skips = [];
                function isNameExist(names, engine) {
                    for (let i in names) {
                        if (names[i] != engine && i != names.length-1)
                            continue;
                        else if (names[i] == engine)
                            return true;
                        return false;
                    }
                }
                namesList.forEach(function(elem) {
                    for (let i in engines) {
                        if (/*i_skips.indexOf(i) != -1 ||*/
                            !(elem[1].some(function(listName) listName == engines[i].name))
                            /*!isNameExist(elem[1], engines[i].name)*/
                            /*elem[1].indexOf(engines[i].name) == -1*/)
                            continue;
                        itemCreate(engines[i], "searchBySite");
                        //i_skips.push(i);
                        break;
                    }
                });
            }
            if (options.searchBySite.enable) {
                searchBySite_itemCreate();
            }

            function searchImageByText_itemCreate() {
                var namesList = [];
                if (options.searchImageByText.useDefaultNamesList) {
                    let defaultNamesList = [
                        [
                            "Google",
                            "https://www.google.ru/search?tbm=isch&q=",
                            "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB41BMVEUAAAB7wUJ6wUJ6wUJ6wUL1nxn1oBn1oBn1nxl6wUJ6wUJ6wUJrvUT1mxr1nxn1nxlfu0Z8wkLznhv0mhp6wUJWuUdaukfLrSv4rhX1nxl5wUJyv0TQrCnyjhz1kyH2pRj1oBl7wkNbukfzjR3zkxv1liHuMDXuGTf2rxN7wUJeu0apuDfzjhz1nBvuNizwZi/3sxP2pBh9wkGvuTbvoRvuJy/xcC33qRhbl7F2uGOMwT94havnRTzuMjjwTTNRislRjcZ5uVpnvU0rk9Fhjr3aTkPuLTVQkM1PgsKHxD9/w0JfnKsAouPtHCTvQDRRkM1Qjstfn6p2jLHvOzDvQDVQkM1Rkc1RjstOh8Z/h6buLirtGyTvOzHvQDXwQDVPkcftPzdRkc1QkMxRkM0xlNLuNSzwQDXvQDVQkM1Rkc1QkM1Rkc3vQDTvQDXvQDXwQDV7wUL2oBr1nxn2oBl6wUJ7wkN9wkF9wkJ6wUP0lRv3qhf1oBn4rhX3qhb1nhp8wkL0nBruGjLuIzf3qRZ/w0JcukbuLCntIzl+wkFkvEbtGyVPhMRyv0QAmNfuLCruMDVRkc1ViccKltTvQDVRhcUAmdfvQDRRks5RiskcltTwQzdQkM07k9DtGyPvQzdQkMzvPzSgiRCBAAAAcHRSTlMAM9bsfmzq30TnaEIQF1b390JR9nP98873iO4nsPyvO3Vly1783sVB8T/5j+2SiIXyKITTeqTRY0ThWl/g9jAn2cBPbNfJFWXVrOjTge5EeeC0qPBsYPfUstjGvOP+dnp0+pmBR1GEikvl8paC8etfYXu9TgAAAAlwSFlzAAAASAAAAEgARslrPgAAAQJJREFUGNM1j8VWQzEARAco8NDiLsXdXQvF3d3dIQ2vOBR3CQSCFPtUUg7Mbu5i7hnY2Npp8Bd7B0cFToQQZxdXwE1xN9JVLVRiUsmah6eXNzVKQOFD1PUNXz//za0ASul2IKBRg4IREroThnAt1cmlCFMkoqJ3Y2LjEL+nSJBgTkxK3k9JPThMSz/KsMoyj0+ysoGc07PcvF97fsH5RSFQVHxZUmrt+quycvO1oeKmsur2rlqCGlaLuvqG+4dGNPFmCVpYK9D2+NQOdIhOoKubPff0vrz29Q8MvvGhYTAZC3sfGf34FFwIgTHLFxufmASmpme+OeeYnZtf+L+/uLS88gMT2kW5QAjbFwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0wNC0wNlQxMDoxMzowNSswNDowMIQ8zwwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMDQtMDZUMTA6MTM6MDUrMDQ6MDD1YXewAAAAAElFTkSuQmCC"
                        ],
                        [
                            "Yandex",
                            "http://images.yandex.ru/yandsearch?text=",
                            "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=="
                        ]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchImageByText.addCustomNames &&
                        Array.isArray(options.searchImageByText.customNamesList)) {
                    namesList = namesList.concat(options.searchImageByText.customNamesList);
                }
                namesList.forEach(function(elem) {
                    let engine = {};
                    engine.name = elem[0];
                    engine.imageLink = elem[1];
                    engine.iconURI_spec = elem[2];
                    itemCreate(engine, "searchImageByText");

                });
            }
            if (options.searchImageByText.enable) {
                searchImageByText_itemCreate();
            }

            function searchInCache() {
                var namesList = [];
                if (options.searchInCache.useDefaultNamesList) {
                    let defaultNamesList = [
                        [
                            "Google",
                            "https://www.google.com/search?q=cache:",
                            "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJgAAACAgAAAAAAAA8gIAAKMBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFESURBVDjLpZNJSwNBEIXnt4lE4kHxovgT9BDwJHqPy0HEEOJBiAuCRg+KUdC4QS4KrpC4gCBGE3NQ48JsnZ6eZ3UOM6gjaePhQU93v6+qq2q0pqgeJj2S8EdJT1hr0OxBtKCD5iEd8QxDYpvhvOBAuMDKURX9C9aPu4GA1GEVkzvMg10UBfYveWAWgYAP00V01fa+R9M2bA51wJvhIn3qR+ybt3D3JNQBE5sMjCIOLFpoHzOwdsLRO22qA6R6kiZiWwxUvy/PUQZIhYZ1vFM9cvcOOsYNdcBgysISdSJBnZjJMlR0Fw8vAp0xoz5gao/h+NZBy4i/10XGwrPA+hmvDyhVRG2Avu/LwcrkFADZa16L1h330w1RNgc3DiJzCpPYRm1bpveXX11clQR28xwblHpk1vq1iP/5mcoS0CoXDZiL0vsJ+dzfl+3T/VYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAK5SURBVFjDxVfrSxRRFJ9/Jta/oyWjF5XQm6D6EkHRgygIIgjUTcueVgqVWSRRkppEUQYWWB8ye1iGWilWlo/Ude489s7M6Zw7D9dlt53dmd29cFiWvXvO77x+51xpaaUsoSxBaUWZQ4ECy5xji2xKZDyCMlMEw6lCNiOSgwZKJK1SkcKeSealfP64t0mBjl4Ow39MkDUL0p2RSROOtqhZdeUEYM1pBl39XCg/fEeFtWcY7G9W4csvUxjlBkCsQ4Nt9QyWVfvT6RsAKXw3aoDGATZeYIt+W1kjw7cJG0RctWDTRebbKd8A6h5pwsDb70ba3w/eUr3wt/cmwgfw6Yft4TNMQaY7o1P2ncm4FT4ANQH/jQBJ2xv7kqIXEADDql8eS3+n8bku7oxNm+EDIM/dU92upb3T/NJGeaNbDx/AsbsLRUY5Xn92caWXY5d8RV6gWllxSg4fAEnTC90DQW13BLlgXR2D3dcUeDVkwOthA1bXspxILWcm3HdThcfvufB26LcJpkOEAz9NKI/lzqpSEC7feol5EWnpSeSlIxCALUkApmULdjUqxQVAQnl3D/X/yQda4QBEq2TYc12By091MQ17Bg3R88nHKlQbVmHvj89awNBLYrwT9zXY2aBAxTkGFdiSxP/Jp6FLDw+AS7GfsdJTJ2EqSO5khD43nGfBARy/ZxOQgZHe7GPM1jzUvChUtmnBAXQPcKGMJp3fdFGq6NByEhiAO4b/YptFfQJwNyQ/bZkVQGcf90Ja25ndIyrKBOa/f8wIpwi3X1G8UcxNu7ozUS7tiH0jBswwS3RIaF1w6LYKU/ML2+8sGnjygQswtKrVIy/Qd9qQP6LnO64q4fPAKpxyZIymHo1jWk6p1ag2BsdNwQMHcC+M5kHFJX+YlPxpVlbCx2mZ5DzPI04k4kUwHHdskU3pH76iftG8yWlkAAAAAElFTkSuQmCC"
                        ],
                        [
                            "Archive.org",
                            "http://web.archive.org/web/*/",
                            "data:image/x-icon;base64,AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABILAAASCwAAAAAAAAAAAAABAQH/AQEB/wEBAf8BAQH/AgIC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wAAAP8BAQH/AQEB/wAAAP8CAgL/AgIC/wEBAf8CAgL/AQEB/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BQUF/wUFBf8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wUFBf8EBAT/BAQE/wQEBP8FBQX/BQUF/wEBAf8AAAD/AQEB/wICAv8BAQH/AAAA/wAAAP8CAgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8AAAD/AgIC/wEBAf8BAQH/BgYG/wAAAP+ysrL/4uLi/9/f3//g4OD/4ODg/9/f3//g4OD/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4ODg/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/3d3d/97e3v8qKir/AQEB/wMDA/8BAQH/AgIC/wAAAP8EBAT/AAAA/7CwsP/Hx8f/w8PD/8fHx//FxcX/xcXF/8XFxf/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/FxcX/xcXF/8bGxv/FxcX/xcXF/8XFxf/Dw8P/1NTU/ywsLP8AAAD/BAQE/wEBAf8AAAD/AAAA/wEBAf8BAQH/AAAA/0pKSv9NTU3/TExM/0xMTP9LS0v/TExM/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/0xMTP9NTU3/TU1N/0xMTP9MTEz/SkpK/01NTf8SEhL/AAAA/wICAv8CAgL/BAQE/wEBAf8BAQH/AQEB/wAAAP8NDQ3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3l5ef8BAQH/BgYG/wAAAP8CAgL/AQEB/wEBAf8DAwP/AAAA/wMDA/8oKCj/LS0t/zExMf8tLS3/Kioq/ysrK/8sLCz/Ly8v/zAwMP8qKir/LCws/yoqKv8oKCj/LCws/zAwMP8rKyv/KSkp/ykpKf8qKir/MDAw/y8vL/8rKyv/ERER/wAAAP8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8CAgL/AAAA/wUFBf+rq6v/7Ozs/3V1df8AAAD/AAAA/zs7O//j4+P/4uLi/zo6Ov8AAAD/AAAA/wQEBP+rq6v/7Ozs/4WFhf8AAAD/AAAA/zw8PP/k5OT/4+Pj/zk5Of8AAAD/BQUF/wAAAP8BAQH/AQEB/wAAAP8BAQH/AAAA/wMDA/8AAAD/ISEh/+Hh4f//////uLi4/wkJCf8CAgL/bW1t////////////bW1t/wICAv8CAgL/ISEh/+Hh4f//////wMDA/woKCv8CAgL/bW1t////////////bW1t/wEBAf8HBwf/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AwMD/wAAAP8cHBz/2NjY//////+4uLj/BwcH/wAAAP9lZWX//f39//////9nZ2f/AAAA/wAAAP8ZGRn/2dnZ//////+3t7f/CAgI/wAAAP9oaGj//Pz8//7+/v9mZmb/AAAA/wYGBv8AAAD/AgIC/wEBAf8BAQH/AwMD/wICAv8BAQH/AAAA/xsbG//Y2Nj//////7i4uP8GBgb/AAAA/2pqav///////v7+/2VlZf8AAAD/AAAA/xsbG//Y2Nj//////7m5uf8HBwf/AAAA/2VlZf///////////2VlZf8AAAD/BQUF/wEBAf8DAwP/AQEB/wAAAP8AAAD/AAAA/wQEBP8AAAD/HR0d/9ra2v//////urq6/wgICP8AAAD/Z2dn////////////aGho/wAAAP8AAAD/HR0d/9vb2///////urq6/wcHB/8AAAD/aGho////////////aWlp/wAAAP8FBQX/AAAA/wEBAf8BAQH/AAAA/wAAAP8AAAD/AgIC/wAAAP8cHBz/29vb//////+4uLj/BgYG/wAAAP9mZmb///////////9nZ2f/AAAA/wAAAP8aGhr/2tra//////+4uLj/BwcH/wAAAP9lZWX///////////9mZmb/AAAA/wUFBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7i4uP8GBgb/AAAA/2ZmZv///////////2dnZ/8AAAD/AAAA/xsbG//b29v//////7m5uf8JCQn/AAAA/2hoaP///////////2dnZ/8AAAD/BQUF/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMDA/8AAAD/Ghoa/9nZ2f//////ubm5/wYGBv8AAAD/ZmZm////////////ZmZm/wAAAP8AAAD/Gxsb/9ra2v//////uLi4/wcHB/8AAAD/ZmZm//7+/v/+/v7/ZmZm/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwMD/wAAAP8aGhr/2NjY//////+6urr/BgYG/wAAAP9mZmb///////////9mZmb/AAAA/wAAAP8aGhr/2NjY//////+5ubn/BwcH/wAAAP9nZ2f//v7+//////9nZ2f/AAAA/wQEBP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7q6uv8HBwf/AAAA/2ZmZv///////////2ZmZv8AAAD/AAAA/xoaGv/Y2Nj//////7i4uP8GBgb/AAAA/2ZmZv/9/f3//v7+/2ZmZv8AAAD/BAQE/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wMDA/8AAAD/HBwc/9vb2///////urq6/wgICP8AAAD/ZmZm////////////Z2dn/wAAAP8AAAD/Gxsb/9nZ2f//////urq6/wcHB/8AAAD/Z2dn////////////Z2dn/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8CAgL/BAQE/wAAAP8dHR3/29vb//////+8vLz/BwcH/wAAAP9nZ2f///////////9mZmb/AAAA/wAAAP8bGxv/29vb//////+6urr/BgYG/wAAAP9nZ2f///////////9mZmb/AAAA/wYGBv8AAAD/AQEB/wEBAf8AAAD/AQEB/wMDA/8DAwP/AAAA/x0dHf/a2tr/+fn5/7CwsP8GBgb/AAAA/2pqav/5+fn/+fn5/2tra/8AAAD/AAAA/xwcHP/Z2dn/+fn5/7m5uf8JCQn/AAAA/2xsbP/5+fn/+fn5/2tra/8AAAD/BwcH/wEBAf8CAgL/AQEB/wEBAf8CAgL/AwMD/wMDA/8AAAD/FxcX/9zc3P//////l5eX/wcHB/8DAwP/YGBg////////////XFxc/wQEBP8FBQX/GBgY/97e3v//////s7Oz/wkJCf8EBAT/XV1d////////////W1tb/wEBAf8EBAT/AQEB/wMDA/8DAwP/AAAA/wEBAf8DAwP/AQEB/wEBAf8AAAD/LS0t/1RUVP8hISH/AAAA/wAAAP8BAQH/TExM/0tLS/8AAAD/AAAA/wAAAP8AAAD/LS0t/1NTU/8bGxv/AAAA/wAAAP8BAQH/TExM/0tLS/8BAQH/AAAA/wEBAf8AAAD/AQEB/wAAAP8CAgL/AQEB/wEBAf8AAAD/BwcH/8XFxf++vr7/tbW1/729vf/Kysr/y8vL/8fHx/+2trb/tra2/8bGxv/Ly8v/yMjI/8rKyv+7u7v/tbW1/8DAwP/Ly8v/y8vL/8XFxf+1tbX/srKy/8nJyf9PT0//AAAA/wYGBv8CAgL/AAAA/wEBAf8AAAD/AQEB/wEBAf8KCgr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3Jycv8AAAD/BwcH/wEBAf8DAwP/AQEB/wAAAP8BAQH/AAAA/wgICP95eXn/fX19/319ff9/f3//gICA/4CAgP+BgYH/gICA/39/f/+BgYH/gYGB/4CAgP+AgID/gICA/4GBgf+AgID/gICA/4GBgf9/f3//fX19/3l5ef9+fn7/MjIy/wAAAP8DAwP/AQEB/wEBAf8AAAD/AQEB/wICAv8AAAD/BgYG/4+Pj/+Tk5P/j4+P/4uLi/+Hh4f/hISE/4ODg/+CgoL/gYGB/4KCgv+CgoL/goKC/4KCgv+BgYH/f39//39/f/+EhIT/hoaG/4eHh/+MjIz/kpKS/5WVlf8uLi7/AAAA/wMDA/8AAAD/AAAA/wEBAf8AAAD/AQEB/wQEBP8EBAT/SUlJ/1RUVP+BgYH/wsLC/////////////////////////////////////////////////////////////////////////////f39/6+vr/9iYmL/S0tL/xkZGf8AAAD/AwMD/wEBAf8DAwP/AQEB/wEBAf8BAQH/AAAA/wYGBv8AAAD/AAAA/wAAAP8AAAD/AQEB/wgICP9RUVH/paWl/8rKyv/a2tr/+fn5///////5+fn/2tra/8vLy/+ampr/T09P/xQUFP8DAwP/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wEBAf8CAgL/AQEB/wICAv8BAQH/AAAA/wQEBP8EBAT/AwMD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xsbG/9nZ2f/i4uL/2dnZ/8ZGRn/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/wQEBP8CAgL/AgIC/wAAAP8DAwP/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AgIC/wICAv8BAQH/AgIC/wMDA/8DAwP/AgIC/wQEBP8HBwf/AAAA/wAAAP8AAAD/AAAA/wAAAP8HBwf/BQUF/wMDA/8BAQH/AQEB/wMDA/8CAgL/AQEB/wEBAf8CAgL/AQEB/wAAAP8CAgL/AgIC/wICAv8AAAD/AAAA/wMDA/8CAgL/AwMD/wMDA/8BAQH/AQEB/wUFBf8DAwP/AgIC/wAAAP8EBAT/BwcH/wcHB/8HBwf/BAQE/wICAv8BAQH/AgIC/wEBAf8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8AAAD/AgIC/wICAv8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                        ]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchInCache.addCustomNames &&
                        Array.isArray(options.searchInCache.customNamesList)) {
                    namesList = namesList.concat(options.searchInCache.customNamesList);
                }
                namesList.forEach(function(elem) {
                    let engine = {};
                    engine.name = elem[0];
                    engine.cacheLink = elem[1];
                    engine.iconURI_spec = elem[2];
                    itemCreate(engine, "searchInCache");

                });
            }
            if (options.searchInCache.enable) {
                searchInCache();
            }

            popup.gObj = this;
            //popup.setAttribute("oncommand", "if (!event.target.engine) return; var csObj = this.gObj || document.getElementById('contextSearchMiniByBunda1-context-popup').gObj; csObj.searchCommandHandler(event);");

            popup.setAttribute("oncommand", "if (!event.target.engine || event.target.nodeName == 'menu') return; this.gObj.searchCommandHandler(event);");
            popup.setAttribute("onclick", "checkForMiddleClick(this, event);");
        },

        searchByImageCommandHandler: function(event) {
            var inBg = options.loadInBackground || false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = !inBg;
            }
            var searchByImageMenu = this.searchByImageMenu;
            var link = event.target.link;
            var imageLink = searchByImageMenu.imageSrc;
            if (imageLink.indexOf("data:") == 0) {
                this.searchByImageByData(imageLink, inBg);
                return;
            } else if (imageLink.indexOf("file:") == 0) {
                this.searchByImageByFile(imageLink, inBg);
                return;
            } else {
                imageLink = encodeURIComponent(imageLink)
            }
            var gBrowser = gBrowser || getBrowser();
            gBrowser.loadOneTab(link + imageLink, {
                relatedToCurrent: true,
                inBackground: inBg
            });
        },
        // searchByImageByData() and searchByImageByFile() based on
        // Google Image Search 0.5 by Nishan Naseer
        // https://addons.mozilla.org/ru/firefox/addon/google-similar-images
        searchByImageByData: function(src, inBg) {
            var gBrowser = gBrowser || getBrowser();
            //var tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
            var tab = gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
                relatedToCurrent: true
            });
            var newTabBrowser = gBrowser.getBrowserForTab(tab);
            newTabBrowser.addEventListener("load", function byData(e) {
                newTabBrowser.removeEventListener(e.type, byData, true);
                if (src) {
                    try {
                        var image_url;
                        var sub;
                        var form = newTabBrowser.contentDocument.getElementById("qbf");
                        var inputs = form.getElementsByTagName("input");
                        for (var k = 0; k < inputs.length; k++) {
                            var i = inputs[k];
                            if (i.name && i.name == "image_url") {
                                image_url = i;
                            }
                            if (i.type && i.type == "submit") {
                                sub = i;
                            }
                        }
                        image_url.value = src;
                        sub.click();
                        src = null;
                    } catch (ex) { }
                }
            }, true);

            if (!inBg) {
                getBrowser().selectedTab = tab;
            }
        },
        searchByImageByFile: function(src, inBg) {
            //Canvas to get contents in base-64
            var canvas = gContextMenu.target.ownerDocument.createElementNS(XHTMLNS, "canvas");
            var image = new Image();
            image.src = src;

            canvas.width = image.width;
            canvas.height = image.height;

            var ctx = canvas.getContext("2d");
            ctx.drawImage(image, 0, 0);
            var dataURL = canvas.toDataURL("image/png");
            var gBrowser = gBrowser || getBrowser();
            //var tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
            var tab = gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
                relatedToCurrent: true
            });
            var newTabBrowser = gBrowser.getBrowserForTab(tab);
            newTabBrowser.addEventListener("load", function byFile(e) {
                newTabBrowser.removeEventListener(e.type, byFile, true);
                if (src) {
                    try {
                        var image_url;
                        var sub;
                        var form = newTabBrowser.contentDocument.getElementById("qbf");
                        var inputs = form.getElementsByTagName("input");
                        for (var k = 0; k < inputs.length; k++) {
                            var i = inputs[k];
                            if (i.name && i.name == "image_url") {
                                image_url = i;
                            }
                            if (i.type && i.type == "submit") {
                                sub = i;
                            }
                        }
                        image_url.value = dataURL;
                        sub.click();
                        src = null;
                    } catch (ex) { }
                }
            }, true);

            if (!inBg) {
                getBrowser().selectedTab = tab;
            }
        },
        searchByImageMenuPopup: function(e) {
            var searchByImageMenu = this.searchByImageMenu;

            searchByImageMenu.hidden = !gContextMenu.onImage;
            var src = gContextMenu.mediaURL || gContextMenu.imageURL || gContextMenu.bgImageURL;
            if (!src || !(/^((ht|f)tps?:\/\/|data:image|file:)/.test(src))) {
                searchByImageMenu.hidden = true;
                return;
            }
            //var popup = document.getElementById("contextSearchMiniByBunda1-context-image-search-popup");
            var popup = searchByImageMenu.popup;
            var items;
            if (!popup.items) {
                var itemsObj = popup.getElementsByTagName("menuitem");
                popup.items = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menuitem" &&
                            elem.getAttribute("label") != "Google")
                        popup.items.push(elem);
                });
                items = popup.items;
            } else {
                items = popup.items;
            }

            if (/^(data:image|file:)/.test(src)) {
                items.forEach(function(elem) {
                    elem.setAttribute("disabled", "true");
                });
            } else {
                items.forEach(function(elem) {
                    elem.removeAttribute("disabled");
                });
            }

            searchByImageMenu.imageSrc = src;
        },
        createSearchByImageMenu: function() {
            var menu = document.createElement("menu");
            var insertMenu = document.getElementById("context-sep-copyimage");
            insertMenu.parentNode.insertBefore(menu, insertMenu);
            this.searchByImageMenu = menu;

            menu.setAttribute("id", this.nodeIds.searchByImageMenu);
            menu.setAttribute("class", "menu-iconic");
            menu.setAttribute("label", _localize("searchByImage"));
            menu.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK6wAACusBgosNWgAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAElSURBVDiNY/z//z8DJYCRkIKsthv/kRX9Z2BgmFalARdiIcaGKZXqcH5O+01U+ay2G3MYGBiSiXUmmofnsBDSjEUTMkiBe2Eq1JnZ7TcZBHhZGNythBl0lLkZODmYGX7++sdw/sZnhl3H3zF8+voHwwsYFkR5ijNICLMzTF31hOHnr38MHGxMDJlhMgwv3vxkWL7jJYpaJmzu0lTigWtmYGBg+PHrH8P0VU8YtJV5MNRiNYCfmxmuGQZ+/PrHwMmOqRyrAX///WfgYEOV4mBjwjAUpwHHL31iyA6XgRvCwcbEkBUmw3DuxmcMtVgDkYONicHLVoTBSJOXgYONieHHz38Ml+98Ydh88DXDtx//CBtACmBiYGCYS4H+OYyU5kasgUgKAADN8WLFzlj9rgAAAABJRU5ErkJggg==");

            this.searchByImageMenu.popup = menu.appendChild(document.createElementNS(XULNS, "menupopup"));
            var popup = this.searchByImageMenu.popup;
            popup.setAttribute("id", this.nodeIds.searchByImageMenuPopup);
            popup.googleURL = "https://www.google.com/searchbyimage";

            var namesList = [];
            if (options.searchByImage.useDefaultNamesList) {
                let defaultNamesList = [
                    [
                        "Google",
                        "https://www.google.com/searchbyimage?image_url=",
                        "data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAA9IVCSvSFQuf0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULk9IVCSvSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQuf0hUL/9IVC//SFQv/0hUL/9Y1O//rIq//+7+f//eXX//vUvf/7z7X/96Fu//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vYwv/97OH/9ZRZ//SFQv/0hUL/9IhG//zbx//3om7/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97uX/+buW//SFQv/0hUL/9IVC//SFQv/5upT/+9O6//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+b6b//zezP/0iEf/9IVC//SFQv/1klf//ezh//vPtP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/3qXr/+siq//m8lv/5wqD//vTu//3t4//1klb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0h0b//vbx//zi0//1j1H/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2nmn/+bmS/////v/4sIX/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5uJH///v5//eoef/1jU//+82y//afav/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vXw//vOs//0hUL/9IVC//ekcf/96+D/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//728v/4sIX/9IVC//SFQv/4s4n///v4//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6yKn/+byX//SFQv/0hkT//eTV//vWv//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IZE//m6lP/5u5b//OHQ///+/f/6y6//96d3//SFQv/0hUL/9IVC//SFQv/0hULm9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSfSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAA9IVCAPSFQif0hUKt9IVC8vSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvL0hUKt9IVCJ/SFQgD0hUIo9IVC7/SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULv9IVCKPSFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVC8fSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvP0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YtL//i2jv/828f//vLr///7+P///Pv//vTu//3n2v/6zbH/96Nw//SFQ//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ekcv/+8+z////////////+9fD/+9K5//m9mf/4to7/+buV//vSuf/++PT//OPT//aYYP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2l13///r3/////////fv/+b2Z//SIRv/0hUL/9IVC//SFQv/0hUL/9IVC//WNT//84M///vXv//aZYf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vPtP////////////i0i//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//WQUv///Pr//OPU//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//eTV///////+9O7/9IVD//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//3m2P//////9ppi//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/718H///////3s4f/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vDn///////4soj/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//erff////////38//WTWP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//iziv////////////iwhf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rMsP///////eXW//WSVv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/4sYb///z7/////////Pv/9ZFV//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ixhv/+8Of//vn1//rMsP/4rH//9plh//WQUv/1j1L/+s2x//////////////////m9mf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SGQ//2nmn/+buW//vNsv/82sb//e3j/////////////////////v/5wZ//9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/83Mj////////////++fb/+K+C//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9ZRZ/////////////vTt//aaYv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/1lFr////////////6xqf/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ehbf/70bj//end//3o2////v3///////3l1//0iEb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5wqD////////////96t7/96Z2//WOUP/2nWf//NvH//zcyP/1i0z/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/96l6/////////////vLr//WPUf/0hUL/9IVC//SFQv/0h0b//end//3k1f/0iUn/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/8387////////////4sYf/9IVC//SFQv/0hUL/9IVC//SFQv/6w6L///////nBn//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC///69////////vj1//SIR//0hUL/9IVC//SFQv/0hUL/9IVC//m+mv///////e3j//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL///r3///////8387/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+syw///////++fb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/95NX///////vUvP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97OH///////7y6//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//i2jv///////N/O//SFQv/0hUL/9IVC//SFQv/0hUL/96Nx////////////+s2x//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IdF//zh0P//+/j/9ZJW//SFQv/0hUL/9IVC//SKSv/96t7///////738v/1k1f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YxN//vUvf/96+D/96Z0//WNT//3om///ebY/////////Pv/+LKI//WVW//0h0X/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//agbP/7zbL//enc//749P////////////////////////////3r4P/3p3f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8/SFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVCJ/SFQu/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC7/SFQif0hUIA9IVCJfSFQq30hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8fSFQq30hUIl9IVCAIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAB"
                    ],
                    [
                        "Yandex",
                        "http://images.yandex.ru/yandsearch?rpt=imagedups&text=&img_url=",
                        "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=="
                    ],
                    [
                        "TinEye",
                        "http://www.tineye.com/search/?pluginver=firefox-1.0&url=",
                        "data:image/x-icon;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAACxeDVItHk157iAO//WtW7/482G/+XOhv/lzYL/1L98/5mTcf8UKUP/CwsM/xwcG/8AAAD/AAAA/wAAAOcAAA5ItHo25LV7Nv+1ezb/tXs2/8GPSf/EoGj/s5hw/6KPdf93bWT/ZFdK/2daTP9hVEj/XU9C/zIpH/8EAgH/AAAA5LV7Nv+1ezb/tXs2/7V7Nv+1ezb/uIA+/8eea//Wtof/48eU/+PKkv/iyJP/4MeV/9u/kf/HqHz/rI1p/3tmT/+1ezb/tXs2/7V7Nv+1ezb/zKV0/+PKlP/hxXr/zbFk/8esYf/VuW7/3sFz/+LFdf/gw3P/48Z3/+nPjv/dwJD/tXs2/7V7Nv+1ezb/y6Nx/9/Gg/+NekT/V0wv/5uSfP95cmH/JiES/zAqGv86Mh3/W08v/3lpQP+Wg03/zLFn/7V7Nv+1ezb/uoVH/8myg/+VgUr/AAAA/2xpZf/i4+X/+fn5/0JAO/8AAAD/LCkl/768uf+/vr3/Mi8q/x0ZEP+2fDf/tXs2/6WGX/+pklP/JyES/0dFQP96eHX/W1tc//////9ua2X/DAoH/6Wim/+EhIX//////6ejnP8AAAD/wo1F/8GLQ//Conf/tZ1e/wYDAP9pZmH/6+vs/9/f3/////3/Pjoz/zo2Lf/Jycb/UlJT//////+xraX/AAAA/8OORv/Djkb/1bF+/821cf83MSD/MC4s//n49P//////l5OJ/wMCAP9IRDr/////////////////ZGBW/wAAAP/Djkb/w45G/8qkcP+sllr/wKtw/zw5Mf9MSUb/VlNM/wIBAP8AAAD/FxUP/9PQyv/8+/j/rKig/wkHA/8AAAD/w45G/8OORv+1jlj/l4hm/8etZv/QuHf/m4xk/21hSP9PRjX/Mi0j/xsYFf87NzD/VFBK/xUVFf8FBwz/CQsQ/8OORv/Djkb/g2I1/8Oea//Mt4z/uJxU/56hhv92nLj/l6ut/56poP+gpJL/mJeC/5aMbP+bjmv/m49t/52Qbv/Djkb/uItP/05PUP+zjlv/yptc/9C3jP9gYFP/ABVH/wAzc/8IP4T/FUuM/xhSmP99lZ3/5sRv/9S6cf/Lsmr/w45G/1B7rv8bbdT/LWy5/8OORv/Djkf/yqRw/zswIP8AAAD/AAAA/wAAAP8AAAD/Fyk8/5CKZ/+ahU3/modW/8GNReeEj5r/L37g/0Jxqf/Cjkf/w45G/8OORv/Fllb/clYw/zoqFf8hGQ3/IhwU/x4ZFf9HRUD/vaJ5/86pdee+ikU/woxEyZ6HZ/+8jEz/w45G/8OORv/Djkb/w45G/8OORv/Djkb/v4tF/8ORTf/GlFD/xJBJ/8KMRMm+ikU/gAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAE="
                    ]
                ];
                namesList = namesList.concat(defaultNamesList);
            }
            if (options.searchByImage.addCustomNames &&
                    Array.isArray(options.searchByImage.customNamesList)) {
                namesList = namesList.concat(options.searchByImage.customNamesList);
            }

            function itemCreate(name, link, image) {
                var item = document.createElementNS(XULNS, "menuitem");
                item.setAttribute("class", "menuitem-iconic");
                item.setAttribute("src", image);
                item.setAttribute("label", name);
                item.link = link;
                popup.appendChild(item);
            }
            namesList.forEach(function(elem) {
                itemCreate(elem[0], elem[1], elem[2]);
            });

            var contextMenu = this.contextMenu;

            popup.gObj = this;
            popup.setAttribute("oncommand", "this.gObj.searchByImageCommandHandler(event);");
            popup.setAttribute("onclick", "checkForMiddleClick(this, event);");
        }
    }
    contextSearcherObj.init();
})();

2k1dmg
Мне нравится ваш вариант, спасибо.

2k1dmg
Да это и не мини, а вообще расширенное меню! Спасибо. :)

2k1dmg пишет:

Временно можете попробовать эту версию

Мне ваш вариант понравился больше. Огромное спасибо.

villa7 пишет:

2k1dmg

popup.setAttribute("position", "start_before");

Спасибо, как и хотелось, только значение другое подставить пришлось.

А можно узнать, какое значение Вы поставили, и как это выглядит?

2k1dmg
Может лучше создай новую тему для Context Search mini 2013-11-22
И я думаю что это уже не mini а full.

Ader
start_before поменял на after_end

скрытый текст
http://i017.radikal.ru/1312/e3/f1fd0c3a2e71t.jpg

2k1dmg пишет:

Временно можете попробовать эту версию

2k1dmg,
мне тоже очень понравиась эта кнопка, спасибо!

Я добавил:
                var defImg = "chrome://global/skin/icons/question-16.png";
и изменил строчки:
                item.setAttribute("src", (engine.iconURI ? engine.iconURI.spec : defImg));
...
                image.setAttribute("src", (engine.iconURI ? engine.iconURI.spec : defImg));
Это - для поисковиков, не имеющих собственных иконок, чтобы не вылезала ошибка...

Пожелания:
1. Изменить сортировку иконок поисковиков. Не "слева направо, сверху вниз", а "сверху вниз, слева направо", так привычнее и удобнее.
2. Добавить возможность (например, по правому клику по иконке поисковика defImg) назначать иконки поисковикам, не имеющих собственных иконок.
3. Добавить возможность ручной сортировки поисковиков в подменю путем перетаскивания (в том числе - "перетаскивания" наиболее часто употребляемых поисковиков из подменю в основное контекстное меню). :)

bunda1
Пользуюсь версией от 13.10.2013, CB 0.0.5.7, но почему-то часто не срабатывает поиск, когда из контекстного меню я щёлкаю по другому поисковику. Приходится снова нажимать.

Что значит не срабатывает поиск, когда из контекстного меню я щёлкаю по другому поисковику, вообще ничего не происходит или что?

bunda1 пишет:

вообще ничего не происходит

Возможно именно это имеет ввиду, однако я не вижу такой проблемы, хоть убей и левой и правой и все поисковики перебрал.
Кстати отлично в [seamonkey] работает =)

22-01-2014 23:22:01
кажись какое-то расширение ему мешает...

feas
Да я тоже не вижу такой проблемы.

Да, ничего не происходит. Ладно, буду дальше копать.

1fesFFFF
на чистом профиле пробуйте - однозначно мешается что-то. Аналогичная проблема. Пока забил...

В 90% случаев не срабатывает при таком алгоритме: открывается список поисковиков, нажимаю левой кнопкой по одному из них, но кнопку не отпускаю, потом вожу курсор вверх-вниз (ищу нужный) и отпускаю кнопку напротив того, который нужен, но не над тем, над которым я зажал кнопку. В итоге не срабатывает поиск.

1fesFFFF пишет:

В 90% случаев не срабатывает при таком алгоритме: открывается список поисковиков, нажимаю левой кнопкой по одному из них, но кнопку не отпускаю, потом вожу курсор вверх-вниз (ищу нужный) и отпускаю кнопку напротив того, который нужен, но не над тем, над которым я зажал кнопку. В итоге не срабатывает поиск.

Попробуй:

Выделить код

Код:

// Context Search, от 29.01.2014. ................................
(function () {
   var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService); 

   var searchSelect = document.getElementById('context-searchselect');  
   searchSelect.collapsed = true; // удалить стандартный пункт меню для поиска

   
   // Создать новый пункт меню для поиска ....
   var contextMenu = document.getElementById("contentAreaContextMenu");
   var menu = contextMenu.insertBefore( document.createElement('menu'), searchSelect ); // над каким пунктом меню показывать
   menu.setAttribute("class", "menu-iconic");
   
   // устанавливать иконку, название и поисковик для нового пункта меню
   function setMenu() {  
      menu.engine = searchService.currentEngine;
      menu.setAttribute("label", "Искать в " + menu.engine.name + " или в ...");
      menu.setAttribute("image", menu.engine.iconURI.spec );
   };
   setMenu();   
 
   // наблюдатель за стандартным пунктом меню 'Копировать' прячет меню поиска
   var copy = document.getElementById('context-copy');  
   var setHiddenMenu = new MutationObserver(function() {
          menu.hidden = copy.hidden || copy.disabled;          
   });
   setHiddenMenu.observe( copy, { attributes: true, attributeFilter: ["hidden", "disabled"] } );
   
   
   // Создать подменю с поисковиками .... 
   var menuPopup = menu.appendChild( document.createElement("menupopup") ); 
   menuPopup.setAttribute('style', 'overflow: scroll'); 
    
   // создать пункты в подменю
   function setItemsToMenuPopup(e) {
      menuPopup.textContent = "";      

      var engines = searchService.getVisibleEngines({});
      engines.forEach(function( engine ) {
         var mItem = document.createElement("menuitem");
         mItem.setAttribute("label", engine.name );
         mItem.setAttribute("class", "menuitem-iconic");
         mItem.setAttribute("src", engine.iconURI.spec );
         mItem.engine = engine;
         menuPopup.appendChild( mItem );
      });

   };  
   setItemsToMenuPopup();
   
   
   // Установить действие для клика на меню и подменю ....
   menu.setAttribute("onmouseup", "\
      var background = ( event.button == 0 ) ? false : true;\
      var clip = gClipboard.read();\
      goDoCommand('cmd_copy');\
      setTimeout(function() {\
         document.getElementById('contentAreaContextMenu').hidePopup();\
         var submission = event.target.engine.getSubmission( gClipboard.read(), null );\
         gBrowser.loadOneTab( submission.uri.spec, null, null, submission.postData, background, false );\
         gClipboard.write( clip );\
      }, 0);\
   ");      
      
   
   // Наблюдатель за изменениями в поисковиках пересоздаёт меню и подменю .... 
   var getEngineModified = {
      observe: function(subject, topic, data) { 
         if ( /changed|removed|current/.test( data ) ) { setMenu(); setItemsToMenuPopup() };             
      }
   };
   Services.obs.addObserver( getEngineModified, "browser-search-engine-modified", false );   
   
   
   // Удалять наблюдатели и меню, показать стандартный пункт ....
   addDestructor(function() {
      contextMenu.removeChild( menu );           
      setHiddenMenu.disconnect();
      Services.obs.removeObserver( getEngineModified, "browser-search-engine-modified", false );
      
      searchSelect.collapsed = false; 
   });   
})();

bunda1
Буду пробовать. Только поставил, вроде, нормально.

эта кнопка Context Search добавляет в контекстное меню свой пункт два раза:

У меня так было, когда я кнопку поместил в строку заголовка [firefox] (на самый верх). Но когда переместил эту кнопку вниз (панель дополнений), то всё стало как надо - один пункт в меню.

Не работает. В меню присутствует, но по клику на поисковике ничего не происходит. firefox 35.0.1

mssign пишет:

Не работает. В меню присутствует, но по клику на поисковике ничего не происходит. firefox 35.0.1

Сейчас проверил и всё работает, возможно конфликт с установленными расширениями, попробуй их отключать по одному и проверять работу кода.

bunda1
Разобрался. Поисковые плагины глючили..

2k1dmg
что-то не работает поиск по картинкам в яндексе, пишет пустой поисковой запрос.

Выделить код

Код:

// Скрыть кнопку с панели.
self.style.display = 'none';



(function () {
    // Context Search mini 2013-11-22
    var options = {
        loadInBackground: true,
        // true - открывать вкладки в фоне
        pinnedEngineName: "",
        // оставить пустым если не нужно закреплять
        // определенный поисковик
        // примеры pinnedEngineName: "Google" или pinnedEngineName: "Яндекс" или pinnedEngineName: ""
        hideDefaultEngineInPopupSubMenu: true,
        // true - не добавлять поисковик по умолчанию в выпадающий список (подменю) поисковиков
        campactMenu: false,
        // true - поисковики в выпадающем списке (подменю) без назаваний
        campactMenuLengthPerLine: 5,
        // максимальное количество элементов в одной строке
        // от 3 до 10, по умолчанию 5
        searchBySite: {
            enable: true,
            // true - добавить поисковики по сайту
            iconsOn: true,
            // true - добавить иконки для поисковиков по сайту
            useDefaultNamesList: true,
            // true - использовать список поисковиков по умолчанию
            addCustomNames: false,
            // true - добавить свои поисковики по сайту
            customNamesList: [
                ["Rambler", ["Rambler", "Рамблер"]]
            ]
            // например ["Rambler", ["Rambler", "Рамблер"]]
            // первая ячека название на английском
            // вторая ячека массив с предполагаемыми именами поисковика
            // может состоять из нескольких значений
            // ["Name1", ["Name1"]],
            // ["Name2", ["Name2", "Имя2"]],
            // ["Name3", ["Name3", "Имя3", "Név3"]]
        },
        searchImageByText: {
            enable: true,
            // true - добавить поиск изображения по тексту
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        },
        searchByImage: {
            enable: true,
            // true - добавить поиск по изображению
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        },
        searchInCache: {
            enable: true,
            // true - добавить поиск в кэше
            // нужно доработать
            useDefaultNamesList: true,
            addCustomNames: false,
            customNamesList: [
                [
                    "name",
                    "link",
                    "image"
                ]
            ]
        }
    };
    function _localize(sid) {
        let strings = {
            en: {
                searchBySite: "Search this site",
                searchImageByText: "Search image by text",
                searchByImage: "Search by image",
                searchInCache: "Search this page in cache"

            },
            ru: {
                searchBySite: "Поиск по этому сайту",
                searchImageByText: "Поиск изображения по тексту",
                searchByImage: "Поиск по изображению",
                searchInCache: "Поиск этой страницы в кэше"
            }
        };
        //let locale = (Application.prefs.getValue("general.useragent.locale", false) || "en").match(/^[a-z]*/)[0];
        function getBrowserUILocale() {
            let gPrefService = Services.prefs; // SeaMonkey
            if (!gPrefService.getBoolPref("intl.locale.matchOS")) {
                try {
                    var locale = gPrefService.getCharPref("general.useragent.locale");
                    if (locale.substr(0, 9) == "chrome://") {
                        return gPrefService.getComplexValue("general.useragent.locale",
                            Components.interfaces.nsIPrefLocalizedString).data;
                    }
                    return locale;
                } catch (ex) {}
            }
            try {
                return Components.classes["@mozilla.org/chrome/chrome-registry;1"]
                .getService(Components.interfaces.nsIXULChromeRegistry)
                .getSelectedLocale("global");
            } catch (ex) {
                return "en-US";
            }
        }
        let locale = ""; // ru, en
        if (!locale)
            locale = getBrowserUILocale().match(/^[a-z]*/)[0];
        _localize = function (sid) {
            return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
        };
        return _localize.apply(this, arguments);
    }

    let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    let XHTMLNS = "http://www.w3.org/1999/xhtml";

    var contextSearcherObj = {
        initialized: false,
        init: function() {
            if(this.initialized)
                return;
            this.initialized = true;

            this.nodeIds = {
                searchMenu: "contextSearchMiniByBunda1-menu",
                searchMenuPopup: "contextSearchMiniByBunda1-popup",
                searchByImageMenu: "contextSearchMiniByBunda1-image-search-menu",
                searchByImageMenuPopup: "contextSearchMiniByBunda1-image-search-popup"
            };

            if (document.getElementById(this.nodeIds.searchMenu))
                return;

            var searchService = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
            var contextMenu = document.getElementById("contentAreaContextMenu");
            var searchSelect = document.getElementById("context-searchselect");
            searchSelect.style.display = "none";

            var searchMenu = contextMenu.insertBefore(document.createElementNS(XULNS, "menu"), searchSelect);

            this.searchService = searchService;
            this.contextMenu = contextMenu;
            this.searchSelect = searchSelect;
            this.searchMenu = searchMenu;

            this.param = {
                isPinnedEngine: false,
                pinnedEngineName: ""
            };

            try {
                this.createSearchMenu();
                if (options.searchByImage.enable)
                    this.createSearchByImageMenu();
            } catch (ex) {
                this.destroy();
                Components.utils.reportError(ex);
                return;
            }

            if (options.campactMenu)
                this.loadStyles();

            var observeStatus = new MutationObserver(function () {
                    searchMenu.hidden = searchSelect.hidden;
                });
            observeStatus.observe(searchSelect, {
                attributes: true,
                attributeFilter: ["hidden"]
            });

            /*var prefService = Components.classes["@mozilla.org/preferences-service;1"]
                        .getService(Components.interfaces.nsIPrefService);
            this.branch = prefService.getBranch("browser.search.");
            if (!("addObserver" in this.branch))
                this.branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
            this.branch.addObserver("", this, false);*/

            /*
            var searchPref = "browser.search.";
            gPrefService.addObserver(searchPref, this, false);*/


            /*let os = Cc["@mozilla.org/observer-service;1"].
                        getService(Ci.nsIObserverService);
            os.addObserver(this, "browser-search-engine-modified", false);*/
            Services.obs.addObserver(this, "browser-search-engine-modified", false);

            Services.ww.registerNotification(this);

            addEventListener("popupshowing", this, false, contextMenu);

            addDestructor(function (reason) {
                observeStatus.disconnect();
                Services.ww.unregisterNotification(this);
                //this.branch.removeObserver("", this);
                //gPrefService.removeObserver(searchPref, this, false);
                //os.removeObserver(this, "browser-search-engine-modified", false);
                Services.obs.removeObserver(this, "browser-search-engine-modified", false);
                this.destroy();
                if (reason != "destructor")
                    this.unloadStyles();
            }, this);
        },
        destroy: function() {
            if(!this.initialized)
                return;
            this.initialized = false;
            var contextMenu = this.contextMenu;
            if (!contextMenu)
                return;
            if (this.searchMenu)
                contextMenu.removeChild(this.searchMenu);
            if (this.searchByImageMenu)
                contextMenu.removeChild(this.searchByImageMenu);
            if (this.searchSelect)
                this.searchSelect.style.removeProperty("display");
        },
        update: function() {
            this.searchMenu.textContent = "";
            this.createSearchMenu();
            delete this.updateTimeoutID;
        },

        get isSeaMonkey() {
            delete this.isSeaMonkey;
            return this.isSeaMonkey = Services.appinfo.name == "SeaMonkey";
        },

        observe: function(subject, topic, data) {
            switch (topic) {
                /*case "domwindowclosed":
                    if (subject.document.documentElement.getAttribute("windowtype") == "Browser:SearchManager") {
                        this.update();
                    }
                    break;*/
                /*case "nsPref:changed":
                    switch (data) {
                        case "defaultenginename":
                        case "browser.search.defaultenginename":
                            this.update();
                            break;
                    }
                    break;*/
                case "browser-search-engine-modified":
                    /*switch (data) {
                        case "engine-default":
                        case "engine-current": // engine-default
                        case "engine-changed":
                        case "engine-removed":*/
                            if (typeof this.updateTimeoutID == "number") {
                                window.clearTimeout(this.updateTimeoutID);
                                delete this.updateTimeoutID;
                            }
                            let _this = this;
                            this.updateTimeoutID = window.setTimeout(function () {
                                _this.update();
                            }, 1000);
                            /*break;
                    }*/
                    break;
            }
        },
        handleEvent: function(e) {
            //var contextMenu = this.contextMenu;
            //var menu = this.menu;
            //var imageMenu = this.imageMenu;
            switch (e.type) {
                case "popupshowing":
                        this.popupshowingEvent(e);
                    break;
            }
        },
        popupshowingEvent: function(e) {
            var trgId = e.target.id;
            if (trgId) {
                if (trgId == "contentAreaContextMenu") {
                    this.contextMenuPopup(e);
                    if (this.searchByImageMenu)
                        this.searchByImageMenuPopup(e);
                } else if (trgId == this.nodeIds.searchMenuPopup)
                    this.searchMenuPopup(e);
            }
        },

        _stylesLoaded: false,
        loadStyles: function() {
            if(this._stylesLoaded)
                return;
            this._stylesLoaded = true;
            var sss = this.sss;
            var cssURI = this.cssURI = this.makeCSSURI();
            if(!sss.sheetRegistered(cssURI, sss.USER_SHEET))
                sss.loadAndRegisterSheet(cssURI, sss.USER_SHEET);
        },
        unloadStyles: function() {
            if(!this._stylesLoaded)
                return;
            this._stylesLoaded = false;
            var sss = this.sss;
            if(sss.sheetRegistered(this.cssURI, sss.USER_SHEET))
                sss.unregisterSheet(this.cssURI, sss.USER_SHEET);
        },
        get sss() {
            delete this.sss;
            return this.sss = Components.classes["@mozilla.org/content/style-sheet-service;1"]
                .getService(Components.interfaces.nsIStyleSheetService);
        },
        makeCSSURI: function() {
            var cssStr = '\
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\n\
@-moz-document url("' + window.location.href + '") {\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n\
        /*width: 2em !important;*/\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] * {\n\
        /*padding-left: 0 !important;\n\
        padding-right: 0 !important;\n\
        margin-left: 0 !important;\n\
        margin-right: 0 !important;*/\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > spacer[campactMenu="true"] {\n\
        width: /*2em*/26px !important;\n\
        @media (min-resolution: 2dppx) {\n\
            #' + this.nodeIds.searchMenuPopup + ' > hbox > spacer[campactMenu="true"]  {\n\
                width: 52px !important;\n\
            }\n\
        }\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n\
        /*width: 3em !important;\n\
        height: 2em !important;*/\n\
        width: 36px !important;\n\
        height: 26px !important;\n\
        -moz-box-pack: center !important;\n\
        @media (min-resolution: 2dppx) {\n\
            #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"]  {\n\
                width: 72px !important;\n\
                height: 52px !important;\n\
            }\n\
        }\n\
    }\n\
    #' + this.nodeIds.searchMenuPopup + ' > hbox >.menuitem-iconic[campactMenu="true"] > image {\n\
        /*margin-left: .8em !important;*/\n\
    }\n\
}\n\
';
            return Services.io.newURI("data:text/css," + encodeURIComponent(cssStr), null, null);
        },

        searchCommandHandler: function(event, trg) {
            var inBg = options.loadInBackground || false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = !inBg;
            }
            var searchBySite = "";
            if (event.target.hasAttribute("searchBySite"))  {
                searchBySite = " site:" + gBrowser.currentURI.host;
            } else if (event.target.hasAttribute("searchInCache")) {
                searchBySite = content.location.href;
            }
            let selectedText = this.isSeaMonkey ? content.getSelection().toString() : getBrowserSelection();
            if (event.target.engine.imageLink) {
                gBrowser.loadOneTab(event.target.engine.imageLink + /*getBrowserSelection()*/ selectedText, {
                    relatedToCurrent: true,
                    inBackground: inBg
                });
            } else if (event.target.engine.cacheLink) {
                gBrowser.loadOneTab(event.target.engine.cacheLink + /*getBrowserSelection()*/ searchBySite, {
                    relatedToCurrent: true,
                    inBackground: inBg
                });
            } else {
                let submission = event.target.engine.getSubmission(/*getBrowserSelection()*/ selectedText + searchBySite, null);
                gBrowser.loadOneTab(submission.uri.spec, {
                    relatedToCurrent: true,
                    postData: submission.postData,
                    inBackground: inBg
                });
            }
            if (trg == "menu") {
                setTimeout(function () {
                    document.getElementById("contentAreaContextMenu").hidePopup();
                }, 0);
            }
        },
        contextMenuPopup: function(e) {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.searchMenu;

            //var selectedText = getBrowserSelection(16);
            var selectedText = this.isSeaMonkey ? content.getSelection(16).toString() : getBrowserSelection(16);
            if (!selectedText)
                return;
            var ellipsis = "\u2026";
            try {
                ellipsis = gPrefService.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data;
            } catch (ex) { }
            if (selectedText.length > 15)
                selectedText = selectedText.substr(0,15) + ellipsis;
            let rEngine = this.isSeaMonkey ? "currentEngine" : "defaultEngine";
            var engineName = this.param.isPinnedEngine ? this.param.pinnedEngineName : searchService[rEngine].name;
            var menuLabel;
            var searchFormattedString = [
                "contextMenuSearch",
                "contextMenuSearchText",
                "searchSelected"
            ];
            var thisIsSM = this.isSeaMonkey;
            function getMenuLabel(str) {
                try {
                    if (thisIsSM) {
                        let bundle = document.getElementById("contentAreaCommandsBundle");
                        return bundle.getFormattedString(str, [engineName, selectedText]);
                    } else
                        return gNavigatorBundle.getFormattedString(str, [engineName, selectedText]);
                } catch (ex) {
                    return false;
                }
            }
            for(let i in searchFormattedString) {
                menuLabel = getMenuLabel(searchFormattedString[i]);
                if (menuLabel)
                    break;
                else if (!menuLabel && i == searchFormattedString.length-1)
                    menuLabel = engineName;
            }
            menu.label = menuLabel;
        },
        searchMenuPopup: function(e) {
            var popup = e.target;
            var items;
            if (!popup.items) {
                var itemsObj = popup.getElementsByTagName("menuitem");
                popup.items = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menuitem" &&
                            elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        popup.items.push(elem);
                });
                items = popup.items;
            } else {
                items = popup.items;
            }
            var menus;
            if (!popup.menus) {
                var itemsObj = popup.getElementsByTagName("menu");
                popup.menus = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menu" &&
                            elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        popup.menus.push(elem);
                });
                menus = popup.menus;
            } else {
                menus = popup.menus;
            }
            var siteSearchDomain;
            var gBrowser = gBrowser || getBrowser();
            function isDomain() {
                try {
                    siteSearchDomain = gBrowser.currentURI.host;
                } catch (ex) {
                    return false;
                }
                return true;
            }
            if (isDomain()) {
                items.forEach(function(elem) {
                    //if (elem.hasAttribute("searchBySite"))
                    //    elem.setAttribute("tooltiptext", siteSearchDomain);
                    elem.removeAttribute("disabled");
                });
                menus.forEach(function(elem) {
                    if (elem.hasAttribute("searchBySite"))
                        elem.setAttribute("tooltiptext", siteSearchDomain);
                    else if (elem.hasAttribute("searchInCache"))
                        elem.setAttribute("tooltiptext", content.document.title);
                    elem.removeAttribute("disabled");
                });
            } else {
                items.forEach(function(elem) {
                    //if (elem.hasAttribute("searchBySite"))
                    //    elem.removeAttribute("tooltiptext");
                    elem.setAttribute("disabled", "true");
                });
                menus.forEach(function(elem) {
                    if (elem.hasAttribute("searchBySite") ||
                            elem.hasAttribute("searchInCache"))
                        elem.removeAttribute("tooltiptext");
                    elem.setAttribute("disabled", "true");
                });
            }
        },
        createSearchMenu: function() {
            var searchService = this.searchService;
            var contextMenu = this.contextMenu;
            var menu = this.searchMenu;

            var engines = searchService.getVisibleEngines({});

            menu.setAttribute("id", this.nodeIds.searchMenu);

            menu.setAttribute("class", "menu-iconic");
            this.param.isPinnedEngine = false;
            this.param.pinnedEngineName = "";
            var pinnedEngineName = options.pinnedEngineName;
            if (pinnedEngineName != "") {
                for (let i in engines) {
                    if (engines[i].name != pinnedEngineName)
                        continue;
                    menu.setAttribute("label", engines[i].name);
                    menu.setAttribute("image", engines[i].iconURI.spec);
                    menu.engine = engines[i];
                    this.param.isPinnedEngine = true;
                    this.param.pinnedEngineName = pinnedEngineName;
                    break;
                }
            }

            let rEngine = this.isSeaMonkey ? "currentEngine" : "defaultEngine";
            if (!this.param.isPinnedEngine) {
                menu.setAttribute("label", searchService[rEngine].name);
                menu.setAttribute("image", searchService[rEngine].iconURI.spec);
                menu.engine = searchService[rEngine];
            }

            menu.gObj = this;
            menu.setAttribute("onclick", "if (event.target == this && event.target.engine) this.gObj.searchCommandHandler(event, 'menu');");

            menu.popup = menu.appendChild(document.createElementNS(XULNS, "menupopup"));
            var popup = this.searchMenu.popup;
            popup.setAttribute("id", this.nodeIds.searchMenuPopup);

            var counterMaxLength = options.campactMenuLengthPerLine;
            if (typeof counterMaxLength != "number" ||
                3 > counterMaxLength || counterMaxLength > 10)
                counterMaxLength = 5;
            var counter = 0;
            var hBox;
            function itemCreateCampact(engine, last) {
                if(counter == 0) {
                    hBox = document.createElementNS(XULNS, "hbox");
                    let item = document.createElementNS(XULNS, "spacer");
                    //item.setAttribute("style", "width: 2em");
                    item.setAttribute("campactMenu", "true");
                    hBox.appendChild(item);
                }
                counter++;
                var item = document.createElementNS(XULNS, "menuitem");
                item.engine = engine;
                item.setAttribute("class", "menuitem-iconic");
                item.setAttribute("tooltiptext", engine.name);
                //item.setAttribute("src", engine.iconURI.spec);
                var image = document.createElementNS(XULNS, "image");
                image.setAttribute("src", engine.iconURI.spec);
                item.appendChild(image);
                //item.setAttribute("style", "max-width: 2em");
                item.setAttribute("campactMenu", "true");
                hBox.appendChild(item);
                if (counter == counterMaxLength || last) {
                    popup.appendChild(hBox);
                    counter = 0;
                }
            }

            var separator = {};
            function itemCreate(engine, reason) {
                var item = document.createElementNS(XULNS, "menuitem");
                item.setAttribute("class", "menuitem-iconic");
                item.engine = engine;
                if (reason && !separator[reason]) {
                    /*let sep = separator[reason] = document.createElementNS(XULNS, "menuseparator");
                    sep.setAttribute(reason, "true");
                    popup.appendChild(sep);

                    let item = document.createElementNS(XULNS, "label");
                    //item.setAttribute("class", "menuitem-iconic");
                    item.setAttribute("value", _localize(reason) + ":");
                    item.setAttribute("style", "padding-left: 2em");
                    popup.appendChild(item);*/

                    if (!separator["menuseparator"]) {
                        let sep = separator["menuseparator"] = document.createElementNS(XULNS, "menuseparator");
                        popup.appendChild(sep);
                    }

                    let subMenu = separator[reason] = document.createElementNS(XULNS, "menu");
                    subMenu.setAttribute("class", "menu-iconic");
                    subMenu.setAttribute("label", _localize(reason));
                    subMenu.setAttribute(reason, "true");
                    subMenu.popup = subMenu.appendChild(document.createElementNS(XULNS, "menupopup"));
                    popup.appendChild(subMenu);
                }
                if (reason == "searchBySite") {
                    item.setAttribute("label", engine.name);
                    if (options.searchBySite.iconsOn) {
                        item.setAttribute("src", engine.iconURI.spec);
                    }
                    item.setAttribute(reason, "true");
                } else if (reason == "searchImageByText" ||
                            reason == "searchInCache") {
                    item.setAttribute("label", engine.name);
                    item.setAttribute("src", engine.iconURI_spec);
                    item.setAttribute(reason, "true");
                } else {
                    item.setAttribute("label", engine.name);
                    item.setAttribute("src", engine.iconURI.spec);
                }
                //popup.appendChild(item);
                if (reason) {
                    let subMenu = separator[reason];
                    subMenu.popup.appendChild(item);
                } else
                    popup.appendChild(item);
            }
            for (let i in engines) {
                if (options.hideDefaultEngineInPopupSubMenu &&
                        this.param.isPinnedEngine &&
                        engines[i].name == pinnedEngineName ||
                        options.hideDefaultEngineInPopupSubMenu &&
                        !this.param.isPinnedEngine &&
                        engines[i].name == searchService[rEngine].name) {
                    continue;
                }
                if (options.campactMenu)
                    itemCreateCampact(engines[i], i == engines.length-1);
                else
                    itemCreate(engines[i]);
            }
            function searchBySite_itemCreate() {
                var namesList = [];
                if (options.searchBySite.useDefaultNamesList) {
                    let defaultNamesList = [
                        ["Google", ["Google"]],
                        ["Yandex", ["Yandex", "Яндекс"]],
                        ["Yahoo", ["Yahoo"]],
                        ["Bing", ["Bing"]],
                        ["DuckDuckGo", ["DuckDuckGo"]]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchBySite.addCustomNames &&
                        Array.isArray(options.searchBySite.customNamesList)) {
                    namesList = namesList.concat(options.searchBySite.customNamesList);
                }
                //let i_skips = [];
                function isNameExist(names, engine) {
                    for (let i in names) {
                        if (names[i] != engine && i != names.length-1)
                            continue;
                        else if (names[i] == engine)
                            return true;
                        return false;
                    }
                }
                namesList.forEach(function(elem) {
                    for (let i in engines) {
                        if (/*i_skips.indexOf(i) != -1 ||*/
                            !(elem[1].some(function(listName) listName == engines[i].name))
                            /*!isNameExist(elem[1], engines[i].name)*/
                            /*elem[1].indexOf(engines[i].name) == -1*/)
                            continue;
                        itemCreate(engines[i], "searchBySite");
                        //i_skips.push(i);
                        break;
                    }
                });
            }
            if (options.searchBySite.enable) {
                searchBySite_itemCreate();
            }

            function searchImageByText_itemCreate() {
                var namesList = [];
                if (options.searchImageByText.useDefaultNamesList) {
                    let defaultNamesList = [
                        [
                            "Google",
                            "https://www.google.ru/search?tbm=isch&q=",
                            "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB41BMVEUAAAB7wUJ6wUJ6wUJ6wUL1nxn1oBn1oBn1nxl6wUJ6wUJ6wUJrvUT1mxr1nxn1nxlfu0Z8wkLznhv0mhp6wUJWuUdaukfLrSv4rhX1nxl5wUJyv0TQrCnyjhz1kyH2pRj1oBl7wkNbukfzjR3zkxv1liHuMDXuGTf2rxN7wUJeu0apuDfzjhz1nBvuNizwZi/3sxP2pBh9wkGvuTbvoRvuJy/xcC33qRhbl7F2uGOMwT94havnRTzuMjjwTTNRislRjcZ5uVpnvU0rk9Fhjr3aTkPuLTVQkM1PgsKHxD9/w0JfnKsAouPtHCTvQDRRkM1Qjstfn6p2jLHvOzDvQDVQkM1Rkc1RjstOh8Z/h6buLirtGyTvOzHvQDXwQDVPkcftPzdRkc1QkMxRkM0xlNLuNSzwQDXvQDVQkM1Rkc1QkM1Rkc3vQDTvQDXvQDXwQDV7wUL2oBr1nxn2oBl6wUJ7wkN9wkF9wkJ6wUP0lRv3qhf1oBn4rhX3qhb1nhp8wkL0nBruGjLuIzf3qRZ/w0JcukbuLCntIzl+wkFkvEbtGyVPhMRyv0QAmNfuLCruMDVRkc1ViccKltTvQDVRhcUAmdfvQDRRks5RiskcltTwQzdQkM07k9DtGyPvQzdQkMzvPzSgiRCBAAAAcHRSTlMAM9bsfmzq30TnaEIQF1b390JR9nP98873iO4nsPyvO3Vly1783sVB8T/5j+2SiIXyKITTeqTRY0ThWl/g9jAn2cBPbNfJFWXVrOjTge5EeeC0qPBsYPfUstjGvOP+dnp0+pmBR1GEikvl8paC8etfYXu9TgAAAAlwSFlzAAAASAAAAEgARslrPgAAAQJJREFUGNM1j8VWQzEARAco8NDiLsXdXQvF3d3dIQ2vOBR3CQSCFPtUUg7Mbu5i7hnY2Npp8Bd7B0cFToQQZxdXwE1xN9JVLVRiUsmah6eXNzVKQOFD1PUNXz//za0ASul2IKBRg4IREroThnAt1cmlCFMkoqJ3Y2LjEL+nSJBgTkxK3k9JPThMSz/KsMoyj0+ysoGc07PcvF97fsH5RSFQVHxZUmrt+quycvO1oeKmsur2rlqCGlaLuvqG+4dGNPFmCVpYK9D2+NQOdIhOoKubPff0vrz29Q8MvvGhYTAZC3sfGf34FFwIgTHLFxufmASmpme+OeeYnZtf+L+/uLS88gMT2kW5QAjbFwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0wNC0wNlQxMDoxMzowNSswNDowMIQ8zwwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMDQtMDZUMTA6MTM6MDUrMDQ6MDD1YXewAAAAAElFTkSuQmCC"
                        ],
                        [
                            "Yandex",
                            "http://images.yandex.ru/yandsearch?text=",
                            "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=="
                        ]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchImageByText.addCustomNames &&
                        Array.isArray(options.searchImageByText.customNamesList)) {
                    namesList = namesList.concat(options.searchImageByText.customNamesList);
                }
                namesList.forEach(function(elem) {
                    let engine = {};
                    engine.name = elem[0];
                    engine.imageLink = elem[1];
                    engine.iconURI_spec = elem[2];
                    itemCreate(engine, "searchImageByText");

                });
            }
            if (options.searchImageByText.enable) {
                searchImageByText_itemCreate();
            }

            function searchInCache() {
                var namesList = [];
                if (options.searchInCache.useDefaultNamesList) {
                    let defaultNamesList = [
                        [
                            "Google",
                            "https://www.google.com/search?q=cache:",
                            "data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJgAAACAgAAAAAAAA8gIAAKMBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFESURBVDjLpZNJSwNBEIXnt4lE4kHxovgT9BDwJHqPy0HEEOJBiAuCRg+KUdC4QS4KrpC4gCBGE3NQ48JsnZ6eZ3UOM6gjaePhQU93v6+qq2q0pqgeJj2S8EdJT1hr0OxBtKCD5iEd8QxDYpvhvOBAuMDKURX9C9aPu4GA1GEVkzvMg10UBfYveWAWgYAP00V01fa+R9M2bA51wJvhIn3qR+ybt3D3JNQBE5sMjCIOLFpoHzOwdsLRO22qA6R6kiZiWwxUvy/PUQZIhYZ1vFM9cvcOOsYNdcBgysISdSJBnZjJMlR0Fw8vAp0xoz5gao/h+NZBy4i/10XGwrPA+hmvDyhVRG2Avu/LwcrkFADZa16L1h330w1RNgc3DiJzCpPYRm1bpveXX11clQR28xwblHpk1vq1iP/5mcoS0CoXDZiL0vsJ+dzfl+3T/VYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAK5SURBVFjDxVfrSxRRFJ9/Jta/oyWjF5XQm6D6EkHRgygIIgjUTcueVgqVWSRRkppEUQYWWB8ye1iGWilWlo/Ude489s7M6Zw7D9dlt53dmd29cFiWvXvO77x+51xpaaUsoSxBaUWZQ4ECy5xji2xKZDyCMlMEw6lCNiOSgwZKJK1SkcKeSealfP64t0mBjl4Ow39MkDUL0p2RSROOtqhZdeUEYM1pBl39XCg/fEeFtWcY7G9W4csvUxjlBkCsQ4Nt9QyWVfvT6RsAKXw3aoDGATZeYIt+W1kjw7cJG0RctWDTRebbKd8A6h5pwsDb70ba3w/eUr3wt/cmwgfw6Yft4TNMQaY7o1P2ncm4FT4ANQH/jQBJ2xv7kqIXEADDql8eS3+n8bku7oxNm+EDIM/dU92upb3T/NJGeaNbDx/AsbsLRUY5Xn92caWXY5d8RV6gWllxSg4fAEnTC90DQW13BLlgXR2D3dcUeDVkwOthA1bXspxILWcm3HdThcfvufB26LcJpkOEAz9NKI/lzqpSEC7feol5EWnpSeSlIxCALUkApmULdjUqxQVAQnl3D/X/yQda4QBEq2TYc12By091MQ17Bg3R88nHKlQbVmHvj89awNBLYrwT9zXY2aBAxTkGFdiSxP/Jp6FLDw+AS7GfsdJTJ2EqSO5khD43nGfBARy/ZxOQgZHe7GPM1jzUvChUtmnBAXQPcKGMJp3fdFGq6NByEhiAO4b/YptFfQJwNyQ/bZkVQGcf90Ja25ndIyrKBOa/f8wIpwi3X1G8UcxNu7ozUS7tiH0jBswwS3RIaF1w6LYKU/ML2+8sGnjygQswtKrVIy/Qd9qQP6LnO64q4fPAKpxyZIymHo1jWk6p1ag2BsdNwQMHcC+M5kHFJX+YlPxpVlbCx2mZ5DzPI04k4kUwHHdskU3pH76iftG8yWlkAAAAAElFTkSuQmCC"
                        ],
                        [
                            "Archive.org",
                            "http://web.archive.org/web/*/",
                            "data:image/x-icon;base64,AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABILAAASCwAAAAAAAAAAAAABAQH/AQEB/wEBAf8BAQH/AgIC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wAAAP8BAQH/AQEB/wAAAP8CAgL/AgIC/wEBAf8CAgL/AQEB/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BQUF/wUFBf8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wUFBf8EBAT/BAQE/wQEBP8FBQX/BQUF/wEBAf8AAAD/AQEB/wICAv8BAQH/AAAA/wAAAP8CAgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8AAAD/AgIC/wEBAf8BAQH/BgYG/wAAAP+ysrL/4uLi/9/f3//g4OD/4ODg/9/f3//g4OD/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4ODg/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/3d3d/97e3v8qKir/AQEB/wMDA/8BAQH/AgIC/wAAAP8EBAT/AAAA/7CwsP/Hx8f/w8PD/8fHx//FxcX/xcXF/8XFxf/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/FxcX/xcXF/8bGxv/FxcX/xcXF/8XFxf/Dw8P/1NTU/ywsLP8AAAD/BAQE/wEBAf8AAAD/AAAA/wEBAf8BAQH/AAAA/0pKSv9NTU3/TExM/0xMTP9LS0v/TExM/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/0xMTP9NTU3/TU1N/0xMTP9MTEz/SkpK/01NTf8SEhL/AAAA/wICAv8CAgL/BAQE/wEBAf8BAQH/AQEB/wAAAP8NDQ3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3l5ef8BAQH/BgYG/wAAAP8CAgL/AQEB/wEBAf8DAwP/AAAA/wMDA/8oKCj/LS0t/zExMf8tLS3/Kioq/ysrK/8sLCz/Ly8v/zAwMP8qKir/LCws/yoqKv8oKCj/LCws/zAwMP8rKyv/KSkp/ykpKf8qKir/MDAw/y8vL/8rKyv/ERER/wAAAP8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8CAgL/AAAA/wUFBf+rq6v/7Ozs/3V1df8AAAD/AAAA/zs7O//j4+P/4uLi/zo6Ov8AAAD/AAAA/wQEBP+rq6v/7Ozs/4WFhf8AAAD/AAAA/zw8PP/k5OT/4+Pj/zk5Of8AAAD/BQUF/wAAAP8BAQH/AQEB/wAAAP8BAQH/AAAA/wMDA/8AAAD/ISEh/+Hh4f//////uLi4/wkJCf8CAgL/bW1t////////////bW1t/wICAv8CAgL/ISEh/+Hh4f//////wMDA/woKCv8CAgL/bW1t////////////bW1t/wEBAf8HBwf/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AwMD/wAAAP8cHBz/2NjY//////+4uLj/BwcH/wAAAP9lZWX//f39//////9nZ2f/AAAA/wAAAP8ZGRn/2dnZ//////+3t7f/CAgI/wAAAP9oaGj//Pz8//7+/v9mZmb/AAAA/wYGBv8AAAD/AgIC/wEBAf8BAQH/AwMD/wICAv8BAQH/AAAA/xsbG//Y2Nj//////7i4uP8GBgb/AAAA/2pqav///////v7+/2VlZf8AAAD/AAAA/xsbG//Y2Nj//////7m5uf8HBwf/AAAA/2VlZf///////////2VlZf8AAAD/BQUF/wEBAf8DAwP/AQEB/wAAAP8AAAD/AAAA/wQEBP8AAAD/HR0d/9ra2v//////urq6/wgICP8AAAD/Z2dn////////////aGho/wAAAP8AAAD/HR0d/9vb2///////urq6/wcHB/8AAAD/aGho////////////aWlp/wAAAP8FBQX/AAAA/wEBAf8BAQH/AAAA/wAAAP8AAAD/AgIC/wAAAP8cHBz/29vb//////+4uLj/BgYG/wAAAP9mZmb///////////9nZ2f/AAAA/wAAAP8aGhr/2tra//////+4uLj/BwcH/wAAAP9lZWX///////////9mZmb/AAAA/wUFBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7i4uP8GBgb/AAAA/2ZmZv///////////2dnZ/8AAAD/AAAA/xsbG//b29v//////7m5uf8JCQn/AAAA/2hoaP///////////2dnZ/8AAAD/BQUF/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMDA/8AAAD/Ghoa/9nZ2f//////ubm5/wYGBv8AAAD/ZmZm////////////ZmZm/wAAAP8AAAD/Gxsb/9ra2v//////uLi4/wcHB/8AAAD/ZmZm//7+/v/+/v7/ZmZm/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwMD/wAAAP8aGhr/2NjY//////+6urr/BgYG/wAAAP9mZmb///////////9mZmb/AAAA/wAAAP8aGhr/2NjY//////+5ubn/BwcH/wAAAP9nZ2f//v7+//////9nZ2f/AAAA/wQEBP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7q6uv8HBwf/AAAA/2ZmZv///////////2ZmZv8AAAD/AAAA/xoaGv/Y2Nj//////7i4uP8GBgb/AAAA/2ZmZv/9/f3//v7+/2ZmZv8AAAD/BAQE/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wMDA/8AAAD/HBwc/9vb2///////urq6/wgICP8AAAD/ZmZm////////////Z2dn/wAAAP8AAAD/Gxsb/9nZ2f//////urq6/wcHB/8AAAD/Z2dn////////////Z2dn/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8CAgL/BAQE/wAAAP8dHR3/29vb//////+8vLz/BwcH/wAAAP9nZ2f///////////9mZmb/AAAA/wAAAP8bGxv/29vb//////+6urr/BgYG/wAAAP9nZ2f///////////9mZmb/AAAA/wYGBv8AAAD/AQEB/wEBAf8AAAD/AQEB/wMDA/8DAwP/AAAA/x0dHf/a2tr/+fn5/7CwsP8GBgb/AAAA/2pqav/5+fn/+fn5/2tra/8AAAD/AAAA/xwcHP/Z2dn/+fn5/7m5uf8JCQn/AAAA/2xsbP/5+fn/+fn5/2tra/8AAAD/BwcH/wEBAf8CAgL/AQEB/wEBAf8CAgL/AwMD/wMDA/8AAAD/FxcX/9zc3P//////l5eX/wcHB/8DAwP/YGBg////////////XFxc/wQEBP8FBQX/GBgY/97e3v//////s7Oz/wkJCf8EBAT/XV1d////////////W1tb/wEBAf8EBAT/AQEB/wMDA/8DAwP/AAAA/wEBAf8DAwP/AQEB/wEBAf8AAAD/LS0t/1RUVP8hISH/AAAA/wAAAP8BAQH/TExM/0tLS/8AAAD/AAAA/wAAAP8AAAD/LS0t/1NTU/8bGxv/AAAA/wAAAP8BAQH/TExM/0tLS/8BAQH/AAAA/wEBAf8AAAD/AQEB/wAAAP8CAgL/AQEB/wEBAf8AAAD/BwcH/8XFxf++vr7/tbW1/729vf/Kysr/y8vL/8fHx/+2trb/tra2/8bGxv/Ly8v/yMjI/8rKyv+7u7v/tbW1/8DAwP/Ly8v/y8vL/8XFxf+1tbX/srKy/8nJyf9PT0//AAAA/wYGBv8CAgL/AAAA/wEBAf8AAAD/AQEB/wEBAf8KCgr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3Jycv8AAAD/BwcH/wEBAf8DAwP/AQEB/wAAAP8BAQH/AAAA/wgICP95eXn/fX19/319ff9/f3//gICA/4CAgP+BgYH/gICA/39/f/+BgYH/gYGB/4CAgP+AgID/gICA/4GBgf+AgID/gICA/4GBgf9/f3//fX19/3l5ef9+fn7/MjIy/wAAAP8DAwP/AQEB/wEBAf8AAAD/AQEB/wICAv8AAAD/BgYG/4+Pj/+Tk5P/j4+P/4uLi/+Hh4f/hISE/4ODg/+CgoL/gYGB/4KCgv+CgoL/goKC/4KCgv+BgYH/f39//39/f/+EhIT/hoaG/4eHh/+MjIz/kpKS/5WVlf8uLi7/AAAA/wMDA/8AAAD/AAAA/wEBAf8AAAD/AQEB/wQEBP8EBAT/SUlJ/1RUVP+BgYH/wsLC/////////////////////////////////////////////////////////////////////////////f39/6+vr/9iYmL/S0tL/xkZGf8AAAD/AwMD/wEBAf8DAwP/AQEB/wEBAf8BAQH/AAAA/wYGBv8AAAD/AAAA/wAAAP8AAAD/AQEB/wgICP9RUVH/paWl/8rKyv/a2tr/+fn5///////5+fn/2tra/8vLy/+ampr/T09P/xQUFP8DAwP/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wEBAf8CAgL/AQEB/wICAv8BAQH/AAAA/wQEBP8EBAT/AwMD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xsbG/9nZ2f/i4uL/2dnZ/8ZGRn/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/wQEBP8CAgL/AgIC/wAAAP8DAwP/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AgIC/wICAv8BAQH/AgIC/wMDA/8DAwP/AgIC/wQEBP8HBwf/AAAA/wAAAP8AAAD/AAAA/wAAAP8HBwf/BQUF/wMDA/8BAQH/AQEB/wMDA/8CAgL/AQEB/wEBAf8CAgL/AQEB/wAAAP8CAgL/AgIC/wICAv8AAAD/AAAA/wMDA/8CAgL/AwMD/wMDA/8BAQH/AQEB/wUFBf8DAwP/AgIC/wAAAP8EBAT/BwcH/wcHB/8HBwf/BAQE/wICAv8BAQH/AgIC/wEBAf8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8AAAD/AgIC/wICAv8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                        ]
                    ];
                    namesList = namesList.concat(defaultNamesList);
                }
                if (options.searchInCache.addCustomNames &&
                        Array.isArray(options.searchInCache.customNamesList)) {
                    namesList = namesList.concat(options.searchInCache.customNamesList);
                }
                namesList.forEach(function(elem) {
                    let engine = {};
                    engine.name = elem[0];
                    engine.cacheLink = elem[1];
                    engine.iconURI_spec = elem[2];
                    itemCreate(engine, "searchInCache");

                });
            }
            if (options.searchInCache.enable) {
                searchInCache();
            }

            popup.gObj = this;
            //popup.setAttribute("oncommand", "if (!event.target.engine) return; var csObj = this.gObj || document.getElementById('contextSearchMiniByBunda1-context-popup').gObj; csObj.searchCommandHandler(event);");

            popup.setAttribute("oncommand", "if (!event.target.engine || event.target.nodeName == 'menu') return; this.gObj.searchCommandHandler(event);");
            popup.setAttribute("onclick", "checkForMiddleClick(this, event);");
        },

        searchByImageCommandHandler: function(event) {
            var inBg = options.loadInBackground || false;
            if (event.type == "click" && event.button && event.button == 1) {
                inBg = !inBg;
            }
            var searchByImageMenu = this.searchByImageMenu;
            var link = event.target.link;
            var imageLink = searchByImageMenu.imageSrc;
            if (imageLink.indexOf("data:") == 0) {
                this.searchByImageByData(imageLink, inBg);
                return;
            } else if (imageLink.indexOf("file:") == 0) {
                this.searchByImageByFile(imageLink, inBg);
                return;
            } else {
                imageLink = encodeURIComponent(imageLink)
            }
            var gBrowser = gBrowser || getBrowser();
            gBrowser.loadOneTab(link + imageLink, {
                relatedToCurrent: true,
                inBackground: inBg
            });
        },
        // searchByImageByData() and searchByImageByFile() based on
        // Google Image Search 0.5 by Nishan Naseer
        // https://addons.mozilla.org/ru/firefox/addon/google-similar-images
        searchByImageByData: function(src, inBg) {
            var gBrowser = gBrowser || getBrowser();
            //var tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
            var tab = gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
                relatedToCurrent: true
            });
            var newTabBrowser = gBrowser.getBrowserForTab(tab);
            newTabBrowser.addEventListener("load", function byData(e) {
                newTabBrowser.removeEventListener(e.type, byData, true);
                if (src) {
                    try {
                        var image_url;
                        var sub;
                        var form = newTabBrowser.contentDocument.getElementById("qbf");
                        var inputs = form.getElementsByTagName("input");
                        for (var k = 0; k < inputs.length; k++) {
                            var i = inputs[k];
                            if (i.name && i.name == "image_url") {
                                image_url = i;
                            }
                            if (i.type && i.type == "submit") {
                                sub = i;
                            }
                        }
                        image_url.value = src;
                        sub.click();
                        src = null;
                    } catch (ex) { }
                }
            }, true);

            if (!inBg) {
                getBrowser().selectedTab = tab;
            }
        },
        searchByImageByFile: function(src, inBg) {
            //Canvas to get contents in base-64
            var canvas = gContextMenu.target.ownerDocument.createElementNS(XHTMLNS, "canvas");
            var image = new Image();
            image.src = src;

            canvas.width = image.width;
            canvas.height = image.height;

            var ctx = canvas.getContext("2d");
            ctx.drawImage(image, 0, 0);
            var dataURL = canvas.toDataURL("image/png");
            var gBrowser = gBrowser || getBrowser();
            //var tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
            var tab = gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
                relatedToCurrent: true
            });
            var newTabBrowser = gBrowser.getBrowserForTab(tab);
            newTabBrowser.addEventListener("load", function byFile(e) {
                newTabBrowser.removeEventListener(e.type, byFile, true);
                if (src) {
                    try {
                        var image_url;
                        var sub;
                        var form = newTabBrowser.contentDocument.getElementById("qbf");
                        var inputs = form.getElementsByTagName("input");
                        for (var k = 0; k < inputs.length; k++) {
                            var i = inputs[k];
                            if (i.name && i.name == "image_url") {
                                image_url = i;
                            }
                            if (i.type && i.type == "submit") {
                                sub = i;
                            }
                        }
                        image_url.value = dataURL;
                        sub.click();
                        src = null;
                    } catch (ex) { }
                }
            }, true);

            if (!inBg) {
                getBrowser().selectedTab = tab;
            }
        },
        searchByImageMenuPopup: function(e) {
            var searchByImageMenu = this.searchByImageMenu;

            searchByImageMenu.hidden = !gContextMenu.onImage;
            var src = gContextMenu.mediaURL || gContextMenu.imageURL || gContextMenu.bgImageURL;
            if (!src || !(/^((ht|f)tps?:\/\/|data:image|file:)/.test(src))) {
                searchByImageMenu.hidden = true;
                return;
            }
            //var popup = document.getElementById("contextSearchMiniByBunda1-context-image-search-popup");
            var popup = searchByImageMenu.popup;
            var items;
            if (!popup.items) {
                var itemsObj = popup.getElementsByTagName("menuitem");
                popup.items = [];
                Array.slice(itemsObj).forEach(function(elem) {
                    if (typeof elem == "object" &&
                            elem.nodeName == "menuitem" &&
                            elem.getAttribute("label") != "Google")
                        popup.items.push(elem);
                });
                items = popup.items;
            } else {
                items = popup.items;
            }

            if (/^(data:image|file:)/.test(src)) {
                items.forEach(function(elem) {
                    elem.setAttribute("disabled", "true");
                });
            } else {
                items.forEach(function(elem) {
                    elem.removeAttribute("disabled");
                });
            }

            searchByImageMenu.imageSrc = src;
        },
        createSearchByImageMenu: function() {
            var menu = document.createElement("menu");
            var insertMenu = document.getElementById("context-sep-copyimage");
            insertMenu.parentNode.insertBefore(menu, insertMenu);
            this.searchByImageMenu = menu;

            menu.setAttribute("id", this.nodeIds.searchByImageMenu);
            menu.setAttribute("class", "menu-iconic");
            menu.setAttribute("label", _localize("searchByImage"));
            menu.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK6wAACusBgosNWgAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAElSURBVDiNY/z//z8DJYCRkIKsthv/kRX9Z2BgmFalARdiIcaGKZXqcH5O+01U+ay2G3MYGBiSiXUmmofnsBDSjEUTMkiBe2Eq1JnZ7TcZBHhZGNythBl0lLkZODmYGX7++sdw/sZnhl3H3zF8+voHwwsYFkR5ijNICLMzTF31hOHnr38MHGxMDJlhMgwv3vxkWL7jJYpaJmzu0lTigWtmYGBg+PHrH8P0VU8YtJV5MNRiNYCfmxmuGQZ+/PrHwMmOqRyrAX///WfgYEOV4mBjwjAUpwHHL31iyA6XgRvCwcbEkBUmw3DuxmcMtVgDkYONicHLVoTBSJOXgYONieHHz38Ml+98Ydh88DXDtx//CBtACmBiYGCYS4H+OYyU5kasgUgKAADN8WLFzlj9rgAAAABJRU5ErkJggg==");

            this.searchByImageMenu.popup = menu.appendChild(document.createElementNS(XULNS, "menupopup"));
            var popup = this.searchByImageMenu.popup;
            popup.setAttribute("id", this.nodeIds.searchByImageMenuPopup);
            popup.googleURL = "https://www.google.com/searchbyimage";

            var namesList = [];
            if (options.searchByImage.useDefaultNamesList) {
                let defaultNamesList = [
                    [
                        "Google",
                        "https://www.google.com/searchbyimage?image_url=",
                        "data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAA9IVCSvSFQuf0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULk9IVCSvSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQuf0hUL/9IVC//SFQv/0hUL/9Y1O//rIq//+7+f//eXX//vUvf/7z7X/96Fu//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vYwv/97OH/9ZRZ//SFQv/0hUL/9IhG//zbx//3om7/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97uX/+buW//SFQv/0hUL/9IVC//SFQv/5upT/+9O6//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+b6b//zezP/0iEf/9IVC//SFQv/1klf//ezh//vPtP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/3qXr/+siq//m8lv/5wqD//vTu//3t4//1klb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0h0b//vbx//zi0//1j1H/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2nmn/+bmS/////v/4sIX/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5uJH///v5//eoef/1jU//+82y//afav/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vXw//vOs//0hUL/9IVC//ekcf/96+D/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//728v/4sIX/9IVC//SFQv/4s4n///v4//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6yKn/+byX//SFQv/0hkT//eTV//vWv//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IZE//m6lP/5u5b//OHQ///+/f/6y6//96d3//SFQv/0hUL/9IVC//SFQv/0hULm9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSfSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAA9IVCAPSFQif0hUKt9IVC8vSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvL0hUKt9IVCJ/SFQgD0hUIo9IVC7/SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULv9IVCKPSFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVC8fSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvP0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YtL//i2jv/828f//vLr///7+P///Pv//vTu//3n2v/6zbH/96Nw//SFQ//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ekcv/+8+z////////////+9fD/+9K5//m9mf/4to7/+buV//vSuf/++PT//OPT//aYYP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2l13///r3/////////fv/+b2Z//SIRv/0hUL/9IVC//SFQv/0hUL/9IVC//WNT//84M///vXv//aZYf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vPtP////////////i0i//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//WQUv///Pr//OPU//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//eTV///////+9O7/9IVD//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//3m2P//////9ppi//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/718H///////3s4f/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vDn///////4soj/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//erff////////38//WTWP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//iziv////////////iwhf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rMsP///////eXW//WSVv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/4sYb///z7/////////Pv/9ZFV//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ixhv/+8Of//vn1//rMsP/4rH//9plh//WQUv/1j1L/+s2x//////////////////m9mf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SGQ//2nmn/+buW//vNsv/82sb//e3j/////////////////////v/5wZ//9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/83Mj////////////++fb/+K+C//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9ZRZ/////////////vTt//aaYv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/1lFr////////////6xqf/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ehbf/70bj//end//3o2////v3///////3l1//0iEb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5wqD////////////96t7/96Z2//WOUP/2nWf//NvH//zcyP/1i0z/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/96l6/////////////vLr//WPUf/0hUL/9IVC//SFQv/0h0b//end//3k1f/0iUn/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/8387////////////4sYf/9IVC//SFQv/0hUL/9IVC//SFQv/6w6L///////nBn//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC///69////////vj1//SIR//0hUL/9IVC//SFQv/0hUL/9IVC//m+mv///////e3j//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL///r3///////8387/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+syw///////++fb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/95NX///////vUvP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97OH///////7y6//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//i2jv///////N/O//SFQv/0hUL/9IVC//SFQv/0hUL/96Nx////////////+s2x//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IdF//zh0P//+/j/9ZJW//SFQv/0hUL/9IVC//SKSv/96t7///////738v/1k1f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YxN//vUvf/96+D/96Z0//WNT//3om///ebY/////////Pv/+LKI//WVW//0h0X/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//agbP/7zbL//enc//749P////////////////////////////3r4P/3p3f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8/SFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVCJ/SFQu/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC7/SFQif0hUIA9IVCJfSFQq30hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8fSFQq30hUIl9IVCAIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAB"
                    ],
                    [
                        "Yandex",
                        "http://images.yandex.ru/yandsearch?rpt=imagedups&text=&img_url=",
                        "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=="
                    ],
                    [
                        "TinEye",
                        "http://www.tineye.com/search/?pluginver=firefox-1.0&url=",
                        "data:image/x-icon;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAACxeDVItHk157iAO//WtW7/482G/+XOhv/lzYL/1L98/5mTcf8UKUP/CwsM/xwcG/8AAAD/AAAA/wAAAOcAAA5ItHo25LV7Nv+1ezb/tXs2/8GPSf/EoGj/s5hw/6KPdf93bWT/ZFdK/2daTP9hVEj/XU9C/zIpH/8EAgH/AAAA5LV7Nv+1ezb/tXs2/7V7Nv+1ezb/uIA+/8eea//Wtof/48eU/+PKkv/iyJP/4MeV/9u/kf/HqHz/rI1p/3tmT/+1ezb/tXs2/7V7Nv+1ezb/zKV0/+PKlP/hxXr/zbFk/8esYf/VuW7/3sFz/+LFdf/gw3P/48Z3/+nPjv/dwJD/tXs2/7V7Nv+1ezb/y6Nx/9/Gg/+NekT/V0wv/5uSfP95cmH/JiES/zAqGv86Mh3/W08v/3lpQP+Wg03/zLFn/7V7Nv+1ezb/uoVH/8myg/+VgUr/AAAA/2xpZf/i4+X/+fn5/0JAO/8AAAD/LCkl/768uf+/vr3/Mi8q/x0ZEP+2fDf/tXs2/6WGX/+pklP/JyES/0dFQP96eHX/W1tc//////9ua2X/DAoH/6Wim/+EhIX//////6ejnP8AAAD/wo1F/8GLQ//Conf/tZ1e/wYDAP9pZmH/6+vs/9/f3/////3/Pjoz/zo2Lf/Jycb/UlJT//////+xraX/AAAA/8OORv/Djkb/1bF+/821cf83MSD/MC4s//n49P//////l5OJ/wMCAP9IRDr/////////////////ZGBW/wAAAP/Djkb/w45G/8qkcP+sllr/wKtw/zw5Mf9MSUb/VlNM/wIBAP8AAAD/FxUP/9PQyv/8+/j/rKig/wkHA/8AAAD/w45G/8OORv+1jlj/l4hm/8etZv/QuHf/m4xk/21hSP9PRjX/Mi0j/xsYFf87NzD/VFBK/xUVFf8FBwz/CQsQ/8OORv/Djkb/g2I1/8Oea//Mt4z/uJxU/56hhv92nLj/l6ut/56poP+gpJL/mJeC/5aMbP+bjmv/m49t/52Qbv/Djkb/uItP/05PUP+zjlv/yptc/9C3jP9gYFP/ABVH/wAzc/8IP4T/FUuM/xhSmP99lZ3/5sRv/9S6cf/Lsmr/w45G/1B7rv8bbdT/LWy5/8OORv/Djkf/yqRw/zswIP8AAAD/AAAA/wAAAP8AAAD/Fyk8/5CKZ/+ahU3/modW/8GNReeEj5r/L37g/0Jxqf/Cjkf/w45G/8OORv/Fllb/clYw/zoqFf8hGQ3/IhwU/x4ZFf9HRUD/vaJ5/86pdee+ikU/woxEyZ6HZ/+8jEz/w45G/8OORv/Djkb/w45G/8OORv/Djkb/v4tF/8ORTf/GlFD/xJBJ/8KMRMm+ikU/gAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAE="
                    ]
                ];
                namesList = namesList.concat(defaultNamesList);
            }
            if (options.searchByImage.addCustomNames &&
                    Array.isArray(options.searchByImage.customNamesList)) {
                namesList = namesList.concat(options.searchByImage.customNamesList);
            }

            function itemCreate(name, link, image) {
                var item = document.createElementNS(XULNS, "menuitem");
                item.setAttribute("class", "menuitem-iconic");
                item.setAttribute("src", image);
                item.setAttribute("label", name);
                item.link = link;
                popup.appendChild(item);
            }
            namesList.forEach(function(elem) {
                itemCreate(elem[0], elem[1], elem[2]);
            });

            var contextMenu = this.contextMenu;

            popup.gObj = this;
            popup.setAttribute("oncommand", "this.gObj.searchByImageCommandHandler(event);");
            popup.setAttribute("onclick", "checkForMiddleClick(this, event);");
        }
    }
    contextSearcherObj.init();
})();

Northtech
Замени в коде:

Выделить код

Код:

http://images.yandex.ru/yandsearch?rpt=imagedups&text=&img_url=

на:

Выделить код

Код:

https://yandex.ru/images/search?uinfo=sw-1024-sh-768-ww-1024-wh-612-pd-1-wp-4x3_1024x768&viewport=wide&_=1433085221683&rpt=imageview&img_url=

bunda1
А у меня в Яндексе ищет, зато в Гугле нет.

bunda1
спасибо.

voqabuhe пишет:

bunda1
А у меня в Яндексе ищет, зато в Гугле нет.

А мне на FF38 без проблем, попробуй искать изображения в Гугле на FF41 не используя код Context Search mini и если поиск работает скопируй правильный адрес из адресной строки браузера в код Context Search mini. И все дела.

Перечитал ветку несколько раз, так и не пойму, рабочий готовый код или установочная ссылка тут есть?

emlen пишет:

рабочий готовый код или установочная ссылка тут есть?

А кто его знает, на Seamonkey их никто не проверял.

я бы проверил))) было бы что проверить...

Проверил Context Search на SeaMonkey, работает.

bunda1 пишет:

Проверил Context Search на SeaMonkey, работает.

Очень благодарен, тоже заработало! :music:

bunda1
Спасибо - отличная кнопка! Хочу слезть с аддона Select Search и посему вопрос - реально ли сделать в Вашей кнопке компактный вид в 5 - 6 рядов, как Context Search mini, а то у меня высота чуть менее, чем полностью :) на весь экран

bunda1, вы как всегда радуете, уже не один аддон вашими кнопками заменил. Ну и конечно просьба,

Клики на пункте контекстного меню или на пункте подменю:
ЛКМ => Открыть поиск в новой активной вкладке,
ПКМ => Открыть поиск в новой фоновой вкладке.

Как кнопки поменять? Не могу привыкнуть, мне бы ЛКМ в фоне, а ПКМ - активная.

Уважаемый bunda1, нельзя ли добавить в кнопку следующие возможности:
1. Поиск по вводимому тексту (а не только выделенному):
Например, если открыт find-bar, то в главном контекстном меню чтоб тоже присутствовал этот менюитем (ещё лучше, чтобы по правому клику на find-barе вызывалось бы сразу контекстное меню поиска) - тогда можно было бы и набирать нужный текст в find-barе - и искать по нему
2. Делать несколько меню-списков поисковых машин, чтобы избегать скроллинг
3. Длинный ЛКМ или ПКМ на менюитем (поисковую машину) делает то же, что обычный ЛКМ или ПКМ, но меню не исчезает - чтобы делать поиск по нескольким машинам
Спасибо

Mishania пишет:

просьба,
Как кнопки поменять? Не могу привыкнуть, мне бы ЛКМ в фоне, а ПКМ - активная.

В:

Выделить код

Код:

   // установить действие для клика на меню и подменю
   menu.onmouseup =e=> {
      var background = (e.button == 0) ? false : true;

поменяй false и true местами.

bunda1
Спасибо.

bezuma пишет:

bunda1
Спасибо - отличная кнопка! Хочу слезть с аддона Select Search и посему вопрос - реально ли сделать в Вашей кнопке компактный вид в 5 - 6 рядов, как Context Search mini, а то у меня высота чуть менее, чем полностью :) на весь экран

Сделаем.

Context Search 2 (mini)

скрытый текст

Выделить код

Код:

(function() {

// Context Search 2 2015-12-28v2

'use strict';

let options = {
    loadInBackground: false,
    // true - открывать вкладки в фоне
    pinnedEngineName: '',
    // оставить пустым если не нужно закреплять
    // определенный поисковик
    // примеры pinnedEngineName: 'Google' или pinnedEngineName: 'Яндекс' или pinnedEngineName: ''
    hideDefaultEngineInPopupSubMenu: false,
    // true - не добавлять поисковик по умолчанию в выпадающий список (подменю) поисковиков
    campactMenu: true,
    // true - поисковики в выпадающем списке (подменю) без назаваний
    campactMenuLengthPerLine: 5,
    // максимальное количество элементов в одной строке
    // от 3 до 10, по умолчанию 5
    searchBySite: {
        enable: true,
        // true - добавить поисковики по сайту
        iconsOn: true,
        // true - добавить иконки для поисковиков по сайту
        useDefaultNamesList: true,
        // true - использовать список поисковиков по умолчанию
        addCustomNames: false,
        // true - добавить свои поисковики по сайту
        customNamesList: [
            ['Rambler', ['Rambler', 'Рамблер']]
        ]
        // например ['Rambler', ['Rambler', 'Рамблер']]
        // первая ячека название на английском
        // вторая ячека массив с предполагаемыми именами поисковика
        // может состоять из нескольких значений
        // ['Name1', ['Name1']],
        // ['Name2', ['Name2', 'Имя2']],
        // ['Name3', ['Name3', 'Имя3', 'Nev3']]
    },
    searchImageByText: {
        enable: true,
        // true - добавить поиск изображения по тексту
        useDefaultNamesList: true,
        addCustomNames: false,
        customNamesList: [
            [
                'name',
                'link',
                'image'
            ]
        ]
    },
    searchByImage: {
        enable: true,
        // true - добавить поиск по изображению
        useDefaultNamesList: true,
        addCustomNames: false,
        customNamesList: [
            [
                'name',
                'link',
                'image'
            ]
        ]
    },
    searchInCache: {
        enable: true,
        // true - добавить поиск в кэше
        // нужно доработать
        useDefaultNamesList: true,
        addCustomNames: false,
        customNamesList: [
            [
                'name',
                'link',
                'image'
            ]
        ]
    },
    defaultIcon: 'chrome://mozapps/skin/places/defaultFavicon.png'
};
if (Services.appinfo.OS == 'Darwin' &&
        devicePixelRatio >= 2) {
    options.defaultIcon = 'chrome://mozapps/skin/places/defaultFavicon@2x.png';
}

function _localize(sid) {
    let strings = {
        en: {
            searchBySite: 'Search this site',
            searchImageByText: 'Search image by text',
            searchByImage: 'Search by image',
            searchInCache: 'Search this page in cache'

        },
        ru: {
            searchBySite: 'Поиск по этому сайту',
            searchImageByText: 'Поиск изображения по тексту',
            searchByImage: 'Поиск по изображению',
            searchInCache: 'Поиск этой страницы в кэше'
        }
    };
    let getBrowserUILocale = function() {
        let gPrefService = Services.prefs; // SeaMonkey
        if (!gPrefService.getBoolPref('intl.locale.matchOS')) {
            try {
                let locale = gPrefService.getCharPref('general.useragent.locale');
                if (locale.substr(0, 9) == 'chrome://') {
                    return gPrefService.getComplexValue('general.useragent.locale',
                        Components.interfaces.nsIPrefLocalizedString).data;
                }
                return locale;
            }
            catch (ex) {}
        }
        try {
            return Components.classes['@mozilla.org/chrome/chrome-registry;1']
                .getService(Components.interfaces.nsIXULChromeRegistry)
                .getSelectedLocale('global');
        }
        catch (ex) {
            return 'en-US';
        }
    };
    let locale = ''; // ru, en
    if (!locale)
        locale = getBrowserUILocale().match(/^[a-z]*/)[0];
    _localize = function(sid) {
        return strings[locale] && strings[locale][sid] || strings.en[sid] || sid;
    };
    return _localize(sid);
}

let XULNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
let XHTMLNS = 'http://www.w3.org/1999/xhtml';

let contextSearcherObj = {
    initialized: false,
    init: function() {
        if (this.initialized)
            return;
        this.initialized = true;

        this.nodeIds = {
            searchMenu: 'context-search-2-by-2k1dmg-menu',
            searchMenuPopup: 'context-search-2-by-2k1dmg-popup',
            searchByImageMenu: 'context-search-2-by-2k1dmg-image-search-menu',
            searchByImageMenuPopup: 'context-search-2-by-2k1dmg-image-search-popup'
        };

        if (document.getElementById(this.nodeIds.searchMenu))
            return;

        let searchService = Cc['@mozilla.org/browser/search-service;1']
            .getService(Ci.nsIBrowserSearchService);
        let contextMenu = document.getElementById('contentAreaContextMenu');
        let searchSelect = document.getElementById('context-searchselect');
        searchSelect.style.display = 'none';

        let searchMenu = contextMenu
            .insertBefore(document.createElementNS(XULNS, 'menu'), searchSelect);

        this.searchService = searchService;
        this.contextMenu = contextMenu;
        this.searchSelect = searchSelect;
        this.searchMenu = searchMenu;

        this.param = {
            isPinnedEngine: false,
            pinnedEngineName: ''
        };

        try {
            this.createSearchMenu();
            if (options.searchByImage.enable)
                this.createSearchByImageMenu();
        }
        catch (ex) {
            this.destroy();
            Components.utils.reportError(ex);
            return;
        }

        if (options.campactMenu)
            this.loadSheet(window, this.makeCSS());

        let observeStatus = this.observeStatus = new MutationObserver(function() {
            searchMenu.hidden = searchSelect.hidden;
        });
        observeStatus.observe(searchSelect, {
            attributes: true,
            attributeFilter: ['hidden']
        });

        Services.obs.addObserver(this, 'browser-search-engine-modified', false);
        contextMenu.addEventListener('popupshowing', this, false);

        if (typeof addDestructor == 'function' &&  // userChromeJS/uc
                addDestructor != ('addDestructor' in window && window.addDestructor)) {
            addDestructor(function(reason) {
                this.destroy(reason);
            }, this);
        }
    },
    destroy: function(reason) {
        if (!this.initialized)
            return;
        this.initialized = false;

        if (this.observeStatus)
            this.observeStatus.disconnect();
        Services.obs.removeObserver(this, 'browser-search-engine-modified', false);

        let contextMenu = this.contextMenu;
        if (!contextMenu)
            return;
        contextMenu.removeEventListener('popupshowing', this, false);
        if (this.searchMenu)
            contextMenu.removeChild(this.searchMenu);
        if (this.searchByImageMenu)
            contextMenu.removeChild(this.searchByImageMenu);
        if (this.searchSelect)
            this.searchSelect.style.removeProperty('display');
        this.removeSheet(window, this.makeCSS());
    },
    update: function() {
        this.searchMenu.textContent = '';
        this.createSearchMenu();
        this.updateTimeoutID = null;
    },

    get isSeaMonkey() {
        delete this.isSeaMonkey;
        return this.isSeaMonkey = Services.appinfo.name == 'SeaMonkey';
    },

    observe: function(subject, topic, data) {
        switch (topic) {
            case 'browser-search-engine-modified':
                if (typeof this.updateTimeoutID == 'number') {
                    window.clearTimeout(this.updateTimeoutID);
                    this.updateTimeoutID = null;
                }
                this.updateTimeoutID = window.setTimeout(function() {
                    this.update();
                }.bind(this), 1000);
                break;
        }
    },
    handleEvent: function(e) {
        switch (e.type) {
            case 'popupshowing':
                this.popupshowingEvent(e);
                break;
        }
    },
    popupshowingEvent: function(e) {
        let trgId = e.target.id;
        if (trgId) {
            if (trgId == 'contentAreaContextMenu') {
                this.contextMenuPopup(e);
                if (this.searchByImageMenu)
                    this.searchByImageMenuPopup(e);
            }
            else if (trgId == this.nodeIds.searchMenuPopup)
                this.searchMenuPopup(e);
        }
    },

    makeCSS: function() {
        return '@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\n' +
            '#' + this.nodeIds.searchMenuPopup + ' > hbox > spacer[campactMenu="true"] {\n' +
            '    width: 26px !important;\n' +
            '}\n' +
            '@media (min-resolution: 2dppx) {\n' +
            '    #' + this.nodeIds.searchMenuPopup + ' > hbox > spacer[campactMenu="true"] {\n' +
            '        width: 52px !important;\n' +
            '    }\n' +
            '}\n' +
            '#' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n' +
            '    width: 36px !important;\n' +
            '    height: 26px !important;\n' +
            '    -moz-box-pack: center !important;\n' +
            '}\n' +
            '@media (min-resolution: 2dppx) {\n' +
            '    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic[campactMenu="true"] {\n' +
            '        width: 72px !important;\n' +
            '        height: 52px !important;\n' +
            '    }\n' +
            '}\n' +
            '#' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic > image {\n' +
            '    width: 16px !important;\n' +
            '    height: 16px !important;\n' +
            '}\n' +
            '@media (min-resolution: 2dppx) {\n' +
            '    #' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic > image {\n' +
            '        width: 32px !important;\n' +
            '        height: 32px !important;\n' +
            '    }\n' +
            '}\n' +
            '#' + this.nodeIds.searchMenuPopup + ' > hbox > .menuitem-iconic > *:not(image) {\n' +
            '    display: none !important;\n' +
            '}';
    },

    SHEET_TYPE: {
      'agent': 'AGENT_SHEET',
      'user': 'USER_SHEET',
      'author': 'AUTHOR_SHEET'
    },
    isTypeValid: function(type) {
        return type in SHEET_TYPE;
    },
    makeCSSURI: function(url) {
        if (!/css$/.test(url))
            url = 'data:text/css,' + encodeURIComponent(url);
        return this.ios.newURI(url, null, null);
    },
    get ios() {
        delete this.ios;
        return this.ios = Cc['@mozilla.org/network/io-service;1'].
            getService(Ci.nsIIOService);
    },
    getDOMWindowUtils: function(window) {
        return window.QueryInterface(Ci.nsIInterfaceRequestor).
                    getInterface(Ci.nsIDOMWindowUtils);
    },
    loadSheet: function(window, url, type) {
        if (!(type && type in SHEET_TYPE))
            type = 'author';
        type = this.SHEET_TYPE[type];
        if (!(url instanceof Ci.nsIURI))
            url = this.makeCSSURI(url);
        let winUtils = this.getDOMWindowUtils(window);
        try {
            winUtils.loadSheet(url, winUtils[type]);
        }
        catch (e) {};
    },
    removeSheet: function(window, url, type) {
        if (!(type && type in SHEET_TYPE))
            type = 'author';
        type = this.SHEET_TYPE[type];
        if (!(url instanceof Ci.nsIURI))
            url = this.makeCSSURI(url);
        let winUtils = this.getDOMWindowUtils(window);
        try {
            winUtils.removeSheet(url, winUtils[type]);
        }
        catch (e) {};
    },

    searchCommandHandler: function(event, trg) {
        let inBg = options.loadInBackground || false;
        if (event.type == 'click' && event.button && event.button == 1) {
            inBg = !inBg;
        }
        let searchBySite = '';
        let _gBrowser = gBrowser || getBrowser();
        if (event.target.hasAttribute('searchBySite')) {
            searchBySite = ' site:' + _gBrowser.currentURI.host;
        }
        else if (event.target.hasAttribute('searchInCache')) {
            searchBySite = content.location.href;
        }
        let selectedText = this.isSeaMonkey ? content.getSelection().toString() : getBrowserSelection();
        if (event.target.engine.imageLink) {
            _gBrowser.loadOneTab(event.target.engine.imageLink + selectedText, {
                relatedToCurrent: true,
                inBackground: inBg
            });
        }
        else if (event.target.engine.cacheLink) {
            _gBrowser.loadOneTab(event.target.engine.cacheLink + searchBySite, {
                relatedToCurrent: true,
                inBackground: inBg
            });
        }
        else {
            let submission = event.target.engine.getSubmission(selectedText + searchBySite, null);
            _gBrowser.loadOneTab(submission.uri.spec, {
                relatedToCurrent: true,
                postData: submission.postData,
                inBackground: inBg
            });
        }
        if (trg == 'menu') {
            setTimeout(function() {
                document.getElementById('contentAreaContextMenu').hidePopup();
            }, 0);
        }
    },
    contextMenuPopup: function(e) {
        let searchService = this.searchService;
        let contextMenu = this.contextMenu;
        let menu = this.searchMenu;

        let selectedText = this.isSeaMonkey ? content.getSelection(16).toString() : getBrowserSelection(16);
        if (!selectedText)
            return;
        let ellipsis = '\u2026';
        try {
            ellipsis = gPrefService.getComplexValue('intl.ellipsis', Ci.nsIPrefLocalizedString).data;
        }
        catch (ex) {}
        if (selectedText.length > 15)
            selectedText = selectedText.substr(0, 15) + ellipsis;
        let currentBrowserEngine = this.isSeaMonkey ? 'currentEngine' : 'defaultEngine';
        let engineName = this.param.isPinnedEngine ? this.param.pinnedEngineName : searchService[currentBrowserEngine].name;
        let menuLabel;
        let searchFormattedString = [
            'contextMenuSearch',
            'contextMenuSearchText',
            'searchSelected' // SeaMonkey
        ];
        let thisIsSM = this.isSeaMonkey;
        let getMenuLabel = function(str) {
            try {
                if (thisIsSM) {
                    let bundle = document.getElementById('contentAreaCommandsBundle');
                    return bundle.getFormattedString(str, [engineName, selectedText]);
                }
                else
                    return gNavigatorBundle.getFormattedString(str, [engineName, selectedText]);
            }
            catch (ex) {
                return false;
            }
        };
        for (let i = 0, len = searchFormattedString.length; i < len; i++) {
            menuLabel = getMenuLabel(searchFormattedString[i]);
            if (menuLabel)
                break;
            else if (!menuLabel && i == searchFormattedString.length - 1)
                menuLabel = engineName;
        }
        menu.label = menuLabel;
    },
    searchMenuPopup: function(e) {
        let popup = e.target;
        let items;
        if (!popup.items) {
            let itemsObj = popup.getElementsByTagName('menuitem');
            popup.items = [];
            Array.slice(itemsObj).forEach(function(elem) {
                if (typeof elem == 'object' &&
                    elem.nodeName == 'menuitem' &&
                    elem.hasAttribute('searchBySite') ||
                    elem.hasAttribute('searchInCache'))
                    popup.items.push(elem);
            });
            items = popup.items;
        }
        else {
            items = popup.items;
        }
        let menus;
        if (!popup.menus) {
            let itemsObj = popup.getElementsByTagName('menu');
            popup.menus = [];
            Array.slice(itemsObj).forEach(function(elem) {
                if (typeof elem == 'object' &&
                    elem.nodeName == 'menu' &&
                    elem.hasAttribute('searchBySite') ||
                    elem.hasAttribute('searchInCache'))
                    popup.menus.push(elem);
            });
            menus = popup.menus;
        }
        else {
            menus = popup.menus;
        }
        let siteSearchDomain;
        let _gBrowser = gBrowser || getBrowser();
        let isDomain = function() {
            try {
                siteSearchDomain = _gBrowser.currentURI.host;
            }
            catch (ex) {
                return false;
            }
            return true;
        };
        if (isDomain()) {
            items.forEach(function(elem) {
                elem.removeAttribute('disabled');
            });
            menus.forEach(function(elem) {
                if (elem.hasAttribute('searchBySite'))
                    elem.setAttribute('tooltiptext', siteSearchDomain);
                else if (elem.hasAttribute('searchInCache'))
                    elem.setAttribute('tooltiptext', content.document.title);
                elem.removeAttribute('disabled');
            });
        }
        else {
            items.forEach(function(elem) {
                elem.setAttribute('disabled', 'true');
            });
            menus.forEach(function(elem) {
                if (elem.hasAttribute('searchBySite') ||
                    elem.hasAttribute('searchInCache'))
                    elem.removeAttribute('tooltiptext');
                elem.setAttribute('disabled', 'true');
            });
        }
    },
    createSearchMenu: function() {
        let searchService = this.searchService;
        let contextMenu = this.contextMenu;
        let menu = this.searchMenu;
        let engines = searchService.getVisibleEngines({});

        menu.setAttribute('id', this.nodeIds.searchMenu);
        menu.setAttribute('class', 'menu-iconic');

        this.param.isPinnedEngine = false;
        this.param.pinnedEngineName = '';
        let pinnedEngineName = options.pinnedEngineName;
        if (pinnedEngineName != '') {
            for (let i in engines) {
                if (engines[i].name != pinnedEngineName)
                    continue;
                menu.setAttribute('label', engines[i].name);
                menu.setAttribute('image', engines[i].iconURI.spec);
                menu.engine = engines[i];
                this.param.isPinnedEngine = true;
                this.param.pinnedEngineName = pinnedEngineName;
                break;
            }
        }

        let currentBrowserEngine = this.isSeaMonkey ? 'currentEngine' : 'defaultEngine';
        if (!this.param.isPinnedEngine) {
            menu.setAttribute('label', searchService[currentBrowserEngine].name);
            menu.setAttribute('image', (searchService[currentBrowserEngine].iconURI ? searchService[currentBrowserEngine].iconURI.spec : options.defaultIcon));
            menu.engine = searchService[currentBrowserEngine];
        }

        menu.gObj = this;
        menu.setAttribute('onclick', 'if (event.target == this && event.target.engine) this.gObj.searchCommandHandler(event, "menu");');

        menu.popup = menu.appendChild(document.createElementNS(XULNS, 'menupopup'));
        let popup = this.searchMenu.popup;
        popup.setAttribute('id', this.nodeIds.searchMenuPopup);

        let counterMaxLength = options.campactMenuLengthPerLine;
        if (typeof counterMaxLength != 'number' ||
            3 > counterMaxLength || counterMaxLength > 10)
            counterMaxLength = 5;
        let counter = 0;
        let hBox;
        let itemCreateCampact = function(engine, last) {
            if (counter == 0) {
                hBox = document.createElementNS(XULNS, 'hbox');
                let item = document.createElementNS(XULNS, 'spacer');
                item.setAttribute('campactMenu', 'true');
                hBox.appendChild(item);
            }
            counter++;
            let item = document.createElementNS(XULNS, 'menuitem');
            item.engine = engine;
            item.setAttribute('class', 'menuitem-iconic');
            item.setAttribute('tooltiptext', engine.name);
            let image = document.createElementNS(XULNS, 'image');
            image.setAttribute('src', (engine.iconURI ? engine.iconURI.spec : options.defaultIcon));
            item.appendChild(image);
            item.setAttribute('campactMenu', 'true');
            hBox.appendChild(item);
            if (counter == counterMaxLength || last) {
                popup.appendChild(hBox);
                counter = 0;
            }
        };

        let separator = {};
        let itemCreate = function(engine, reason) {
            let item = document.createElementNS(XULNS, 'menuitem');
            item.setAttribute('class', 'menuitem-iconic');
            item.engine = engine;
            if (reason && !separator[reason]) {
                if (!separator['menuseparator']) {
                    let sep = separator['menuseparator'] = document.createElementNS(XULNS, 'menuseparator');
                    popup.appendChild(sep);
                }
                let subMenu = separator[reason] = document.createElementNS(XULNS, 'menu');
                subMenu.setAttribute('class', 'menu-iconic');
                subMenu.setAttribute('label', _localize(reason));
                subMenu.setAttribute(reason, 'true');
                subMenu.popup = subMenu.appendChild(document.createElementNS(XULNS, 'menupopup'));
                popup.appendChild(subMenu);
            }
            if (reason == 'searchBySite') {
                item.setAttribute('label', engine.name);
                if (options.searchBySite.iconsOn) {
                    item.setAttribute('src', (engine.iconURI ? engine.iconURI.spec : options.defaultIcon));
                }
                item.setAttribute(reason, 'true');
            }
            else if (reason == 'searchImageByText' ||
                reason == 'searchInCache') {
                item.setAttribute('label', engine.name);
                item.setAttribute('src', (engine.iconURI_spec != '' ? engine.iconURI_spec : options.defaultIcon));
                item.setAttribute(reason, 'true');
            }
            else {
                item.setAttribute('label', engine.name);
                item.setAttribute('src', (engine.iconURI ? engine.iconURI.spec : options.defaultIcon));
            }
            if (reason) {
                let subMenu = separator[reason];
                subMenu.popup.appendChild(item);
            }
            else
                popup.appendChild(item);
        };

        for (let i in engines) {
            if (options.hideDefaultEngineInPopupSubMenu &&
                this.param.isPinnedEngine &&
                engines[i].name == pinnedEngineName ||
                options.hideDefaultEngineInPopupSubMenu && !this.param.isPinnedEngine &&
                engines[i].name == searchService[currentBrowserEngine].name) {
                continue;
            }
            if (options.campactMenu)
                itemCreateCampact(engines[i], i == engines.length - 1);
            else
                itemCreate(engines[i]);
        }
        let itemCreateSearchBySite = function() {
            let namesList = [];
            if (options.searchBySite.useDefaultNamesList) {
                let defaultNamesList = [
                    ['Google', ['Google']],
                    ['Yandex', ['Yandex', 'Яндекс']],
                    ['Yahoo', ['Yahoo']],
                    ['Bing', ['Bing']],
                    ['DuckDuckGo', ['DuckDuckGo']]
                ];
                namesList = namesList.concat(defaultNamesList);
            }
            if (options.searchBySite.addCustomNames &&
                Array.isArray(options.searchBySite.customNamesList)) {
                namesList = namesList.concat(options.searchBySite.customNamesList);
            }
            namesList.forEach(function(elem) {
                for (let i in engines) {
                    if (!(elem[1].some(function(listName) {
                                    return listName == engines[i].name
                                })
                            )
                        )
                        continue;
                    itemCreate(engines[i], 'searchBySite');
                    break;
                }
            });
        };
        if (options.searchBySite.enable) {
            itemCreateSearchBySite();
        }

        let itemCreateSearchImageByText = function() {
            let namesList = [];
            if (options.searchImageByText.useDefaultNamesList) {
                let defaultNamesList = [
                    [
                        'Google',
                        'https://www.google.ru/search?tbm=isch&q=',
                        'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAB41BMVEUAAAB7wUJ6wUJ6wUJ6wUL1nxn1oBn1oBn1nxl6wUJ6wUJ6wUJrvUT1mxr1nxn1nxlfu0Z8wkLznhv0mhp6wUJWuUdaukfLrSv4rhX1nxl5wUJyv0TQrCnyjhz1kyH2pRj1oBl7wkNbukfzjR3zkxv1liHuMDXuGTf2rxN7wUJeu0apuDfzjhz1nBvuNizwZi/3sxP2pBh9wkGvuTbvoRvuJy/xcC33qRhbl7F2uGOMwT94havnRTzuMjjwTTNRislRjcZ5uVpnvU0rk9Fhjr3aTkPuLTVQkM1PgsKHxD9/w0JfnKsAouPtHCTvQDRRkM1Qjstfn6p2jLHvOzDvQDVQkM1Rkc1RjstOh8Z/h6buLirtGyTvOzHvQDXwQDVPkcftPzdRkc1QkMxRkM0xlNLuNSzwQDXvQDVQkM1Rkc1QkM1Rkc3vQDTvQDXvQDXwQDV7wUL2oBr1nxn2oBl6wUJ7wkN9wkF9wkJ6wUP0lRv3qhf1oBn4rhX3qhb1nhp8wkL0nBruGjLuIzf3qRZ/w0JcukbuLCntIzl+wkFkvEbtGyVPhMRyv0QAmNfuLCruMDVRkc1ViccKltTvQDVRhcUAmdfvQDRRks5RiskcltTwQzdQkM07k9DtGyPvQzdQkMzvPzSgiRCBAAAAcHRSTlMAM9bsfmzq30TnaEIQF1b390JR9nP98873iO4nsPyvO3Vly1783sVB8T/5j+2SiIXyKITTeqTRY0ThWl/g9jAn2cBPbNfJFWXVrOjTge5EeeC0qPBsYPfUstjGvOP+dnp0+pmBR1GEikvl8paC8etfYXu9TgAAAAlwSFlzAAAASAAAAEgARslrPgAAAQJJREFUGNM1j8VWQzEARAco8NDiLsXdXQvF3d3dIQ2vOBR3CQSCFPtUUg7Mbu5i7hnY2Npp8Bd7B0cFToQQZxdXwE1xN9JVLVRiUsmah6eXNzVKQOFD1PUNXz//za0ASul2IKBRg4IREroThnAt1cmlCFMkoqJ3Y2LjEL+nSJBgTkxK3k9JPThMSz/KsMoyj0+ysoGc07PcvF97fsH5RSFQVHxZUmrt+quycvO1oeKmsur2rlqCGlaLuvqG+4dGNPFmCVpYK9D2+NQOdIhOoKubPff0vrz29Q8MvvGhYTAZC3sfGf34FFwIgTHLFxufmASmpme+OeeYnZtf+L+/uLS88gMT2kW5QAjbFwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxMi0wNC0wNlQxMDoxMzowNSswNDowMIQ8zwwAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTItMDQtMDZUMTA6MTM6MDUrMDQ6MDD1YXewAAAAAElFTkSuQmCC'
                    ],
                    [
                        'Yandex',
                        'http://images.yandex.ru/yandsearch?text=',
                        'data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=='
                    ]
                ];
                namesList = namesList.concat(defaultNamesList);
            }
            if (options.searchImageByText.addCustomNames &&
                Array.isArray(options.searchImageByText.customNamesList)) {
                namesList = namesList.concat(options.searchImageByText.customNamesList);
            }
            namesList.forEach(function(elem) {
                let engine = {};
                engine.name = elem[0];
                engine.imageLink = elem[1];
                engine.iconURI_spec = elem[2]; //
                itemCreate(engine, 'searchImageByText');

            });
        };
        if (options.searchImageByText.enable) {
            itemCreateSearchImageByText();
        }

        let itemCreateSearchInCache = function() {
            let namesList = [];
            if (options.searchInCache.useDefaultNamesList) {
                let defaultNamesList = [
                    [
                        'Google',
                        'https://www.google.com/search?q=cache:',
                        'data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJgAAACAgAAAAAAAA8gIAAKMBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFESURBVDjLpZNJSwNBEIXnt4lE4kHxovgT9BDwJHqPy0HEEOJBiAuCRg+KUdC4QS4KrpC4gCBGE3NQ48JsnZ6eZ3UOM6gjaePhQU93v6+qq2q0pqgeJj2S8EdJT1hr0OxBtKCD5iEd8QxDYpvhvOBAuMDKURX9C9aPu4GA1GEVkzvMg10UBfYveWAWgYAP00V01fa+R9M2bA51wJvhIn3qR+ybt3D3JNQBE5sMjCIOLFpoHzOwdsLRO22qA6R6kiZiWwxUvy/PUQZIhYZ1vFM9cvcOOsYNdcBgysISdSJBnZjJMlR0Fw8vAp0xoz5gao/h+NZBy4i/10XGwrPA+hmvDyhVRG2Avu/LwcrkFADZa16L1h330w1RNgc3DiJzCpPYRm1bpveXX11clQR28xwblHpk1vq1iP/5mcoS0CoXDZiL0vsJ+dzfl+3T/VYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAK5SURBVFjDxVfrSxRRFJ9/Jta/oyWjF5XQm6D6EkHRgygIIgjUTcueVgqVWSRRkppEUQYWWB8ye1iGWilWlo/Ude489s7M6Zw7D9dlt53dmd29cFiWvXvO77x+51xpaaUsoSxBaUWZQ4ECy5xji2xKZDyCMlMEw6lCNiOSgwZKJK1SkcKeSealfP64t0mBjl4Ow39MkDUL0p2RSROOtqhZdeUEYM1pBl39XCg/fEeFtWcY7G9W4csvUxjlBkCsQ4Nt9QyWVfvT6RsAKXw3aoDGATZeYIt+W1kjw7cJG0RctWDTRebbKd8A6h5pwsDb70ba3w/eUr3wt/cmwgfw6Yft4TNMQaY7o1P2ncm4FT4ANQH/jQBJ2xv7kqIXEADDql8eS3+n8bku7oxNm+EDIM/dU92upb3T/NJGeaNbDx/AsbsLRUY5Xn92caWXY5d8RV6gWllxSg4fAEnTC90DQW13BLlgXR2D3dcUeDVkwOthA1bXspxILWcm3HdThcfvufB26LcJpkOEAz9NKI/lzqpSEC7feol5EWnpSeSlIxCALUkApmULdjUqxQVAQnl3D/X/yQda4QBEq2TYc12By091MQ17Bg3R88nHKlQbVmHvj89awNBLYrwT9zXY2aBAxTkGFdiSxP/Jp6FLDw+AS7GfsdJTJ2EqSO5khD43nGfBARy/ZxOQgZHe7GPM1jzUvChUtmnBAXQPcKGMJp3fdFGq6NByEhiAO4b/YptFfQJwNyQ/bZkVQGcf90Ja25ndIyrKBOa/f8wIpwi3X1G8UcxNu7ozUS7tiH0jBswwS3RIaF1w6LYKU/ML2+8sGnjygQswtKrVIy/Qd9qQP6LnO64q4fPAKpxyZIymHo1jWk6p1ag2BsdNwQMHcC+M5kHFJX+YlPxpVlbCx2mZ5DzPI04k4kUwHHdskU3pH76iftG8yWlkAAAAAElFTkSuQmCC'
                    ],
                    [
                        'Archive.org',
                        'http://web.archive.org/web/*/',
                        'data:image/x-icon;base64,AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAABILAAASCwAAAAAAAAAAAAABAQH/AQEB/wEBAf8BAQH/AgIC/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wAAAP8BAQH/AQEB/wAAAP8CAgL/AgIC/wEBAf8CAgL/AQEB/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BQUF/wUFBf8EBAT/BAQE/wQEBP8EBAT/BAQE/wQEBP8EBAT/BAQE/wUFBf8EBAT/BAQE/wQEBP8FBQX/BQUF/wEBAf8AAAD/AQEB/wICAv8BAQH/AAAA/wAAAP8CAgL/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8AAAD/AgIC/wEBAf8BAQH/BgYG/wAAAP+ysrL/4uLi/9/f3//g4OD/4ODg/9/f3//g4OD/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/4ODg/+Hh4f/h4eH/4eHh/+Hh4f/h4eH/3d3d/97e3v8qKir/AQEB/wMDA/8BAQH/AgIC/wAAAP8EBAT/AAAA/7CwsP/Hx8f/w8PD/8fHx//FxcX/xcXF/8XFxf/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/Gxsb/xsbG/8bGxv/FxcX/xcXF/8bGxv/FxcX/xcXF/8XFxf/Dw8P/1NTU/ywsLP8AAAD/BAQE/wEBAf8AAAD/AAAA/wEBAf8BAQH/AAAA/0pKSv9NTU3/TExM/0xMTP9LS0v/TExM/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/01NTf9NTU3/TU1N/0xMTP9NTU3/TU1N/0xMTP9MTEz/SkpK/01NTf8SEhL/AAAA/wICAv8CAgL/BAQE/wEBAf8BAQH/AQEB/wAAAP8NDQ3//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3l5ef8BAQH/BgYG/wAAAP8CAgL/AQEB/wEBAf8DAwP/AAAA/wMDA/8oKCj/LS0t/zExMf8tLS3/Kioq/ysrK/8sLCz/Ly8v/zAwMP8qKir/LCws/yoqKv8oKCj/LCws/zAwMP8rKyv/KSkp/ykpKf8qKir/MDAw/y8vL/8rKyv/ERER/wAAAP8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8CAgL/AAAA/wUFBf+rq6v/7Ozs/3V1df8AAAD/AAAA/zs7O//j4+P/4uLi/zo6Ov8AAAD/AAAA/wQEBP+rq6v/7Ozs/4WFhf8AAAD/AAAA/zw8PP/k5OT/4+Pj/zk5Of8AAAD/BQUF/wAAAP8BAQH/AQEB/wAAAP8BAQH/AAAA/wMDA/8AAAD/ISEh/+Hh4f//////uLi4/wkJCf8CAgL/bW1t////////////bW1t/wICAv8CAgL/ISEh/+Hh4f//////wMDA/woKCv8CAgL/bW1t////////////bW1t/wEBAf8HBwf/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AwMD/wAAAP8cHBz/2NjY//////+4uLj/BwcH/wAAAP9lZWX//f39//////9nZ2f/AAAA/wAAAP8ZGRn/2dnZ//////+3t7f/CAgI/wAAAP9oaGj//Pz8//7+/v9mZmb/AAAA/wYGBv8AAAD/AgIC/wEBAf8BAQH/AwMD/wICAv8BAQH/AAAA/xsbG//Y2Nj//////7i4uP8GBgb/AAAA/2pqav///////v7+/2VlZf8AAAD/AAAA/xsbG//Y2Nj//////7m5uf8HBwf/AAAA/2VlZf///////////2VlZf8AAAD/BQUF/wEBAf8DAwP/AQEB/wAAAP8AAAD/AAAA/wQEBP8AAAD/HR0d/9ra2v//////urq6/wgICP8AAAD/Z2dn////////////aGho/wAAAP8AAAD/HR0d/9vb2///////urq6/wcHB/8AAAD/aGho////////////aWlp/wAAAP8FBQX/AAAA/wEBAf8BAQH/AAAA/wAAAP8AAAD/AgIC/wAAAP8cHBz/29vb//////+4uLj/BgYG/wAAAP9mZmb///////////9nZ2f/AAAA/wAAAP8aGhr/2tra//////+4uLj/BwcH/wAAAP9lZWX///////////9mZmb/AAAA/wUFBf8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7i4uP8GBgb/AAAA/2ZmZv///////////2dnZ/8AAAD/AAAA/xsbG//b29v//////7m5uf8JCQn/AAAA/2hoaP///////////2dnZ/8AAAD/BQUF/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wMDA/8AAAD/Ghoa/9nZ2f//////ubm5/wYGBv8AAAD/ZmZm////////////ZmZm/wAAAP8AAAD/Gxsb/9ra2v//////uLi4/wcHB/8AAAD/ZmZm//7+/v/+/v7/ZmZm/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AwMD/wAAAP8aGhr/2NjY//////+6urr/BgYG/wAAAP9mZmb///////////9mZmb/AAAA/wAAAP8aGhr/2NjY//////+5ubn/BwcH/wAAAP9nZ2f//v7+//////9nZ2f/AAAA/wQEBP8AAAD/AAAA/wAAAP8AAAD/AAAA/wEBAf8DAwP/AAAA/xwcHP/a2tr//////7q6uv8HBwf/AAAA/2ZmZv///////////2ZmZv8AAAD/AAAA/xoaGv/Y2Nj//////7i4uP8GBgb/AAAA/2ZmZv/9/f3//v7+/2ZmZv8AAAD/BAQE/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wMDA/8AAAD/HBwc/9vb2///////urq6/wgICP8AAAD/ZmZm////////////Z2dn/wAAAP8AAAD/Gxsb/9nZ2f//////urq6/wcHB/8AAAD/Z2dn////////////Z2dn/wAAAP8EBAT/AAAA/wAAAP8AAAD/AAAA/wAAAP8CAgL/BAQE/wAAAP8dHR3/29vb//////+8vLz/BwcH/wAAAP9nZ2f///////////9mZmb/AAAA/wAAAP8bGxv/29vb//////+6urr/BgYG/wAAAP9nZ2f///////////9mZmb/AAAA/wYGBv8AAAD/AQEB/wEBAf8AAAD/AQEB/wMDA/8DAwP/AAAA/x0dHf/a2tr/+fn5/7CwsP8GBgb/AAAA/2pqav/5+fn/+fn5/2tra/8AAAD/AAAA/xwcHP/Z2dn/+fn5/7m5uf8JCQn/AAAA/2xsbP/5+fn/+fn5/2tra/8AAAD/BwcH/wEBAf8CAgL/AQEB/wEBAf8CAgL/AwMD/wMDA/8AAAD/FxcX/9zc3P//////l5eX/wcHB/8DAwP/YGBg////////////XFxc/wQEBP8FBQX/GBgY/97e3v//////s7Oz/wkJCf8EBAT/XV1d////////////W1tb/wEBAf8EBAT/AQEB/wMDA/8DAwP/AAAA/wEBAf8DAwP/AQEB/wEBAf8AAAD/LS0t/1RUVP8hISH/AAAA/wAAAP8BAQH/TExM/0tLS/8AAAD/AAAA/wAAAP8AAAD/LS0t/1NTU/8bGxv/AAAA/wAAAP8BAQH/TExM/0tLS/8BAQH/AAAA/wEBAf8AAAD/AQEB/wAAAP8CAgL/AQEB/wEBAf8AAAD/BwcH/8XFxf++vr7/tbW1/729vf/Kysr/y8vL/8fHx/+2trb/tra2/8bGxv/Ly8v/yMjI/8rKyv+7u7v/tbW1/8DAwP/Ly8v/y8vL/8XFxf+1tbX/srKy/8nJyf9PT0//AAAA/wYGBv8CAgL/AAAA/wEBAf8AAAD/AQEB/wEBAf8KCgr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3Jycv8AAAD/BwcH/wEBAf8DAwP/AQEB/wAAAP8BAQH/AAAA/wgICP95eXn/fX19/319ff9/f3//gICA/4CAgP+BgYH/gICA/39/f/+BgYH/gYGB/4CAgP+AgID/gICA/4GBgf+AgID/gICA/4GBgf9/f3//fX19/3l5ef9+fn7/MjIy/wAAAP8DAwP/AQEB/wEBAf8AAAD/AQEB/wICAv8AAAD/BgYG/4+Pj/+Tk5P/j4+P/4uLi/+Hh4f/hISE/4ODg/+CgoL/gYGB/4KCgv+CgoL/goKC/4KCgv+BgYH/f39//39/f/+EhIT/hoaG/4eHh/+MjIz/kpKS/5WVlf8uLi7/AAAA/wMDA/8AAAD/AAAA/wEBAf8AAAD/AQEB/wQEBP8EBAT/SUlJ/1RUVP+BgYH/wsLC/////////////////////////////////////////////////////////////////////////////f39/6+vr/9iYmL/S0tL/xkZGf8AAAD/AwMD/wEBAf8DAwP/AQEB/wEBAf8BAQH/AAAA/wYGBv8AAAD/AAAA/wAAAP8AAAD/AQEB/wgICP9RUVH/paWl/8rKyv/a2tr/+fn5///////5+fn/2tra/8vLy/+ampr/T09P/xQUFP8DAwP/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AQEB/wEBAf8CAgL/AQEB/wICAv8BAQH/AAAA/wQEBP8EBAT/AwMD/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/xsbG/9nZ2f/i4uL/2dnZ/8ZGRn/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AgIC/wQEBP8CAgL/AgIC/wAAAP8DAwP/AgIC/wEBAf8AAAD/AQEB/wEBAf8AAAD/AgIC/wICAv8BAQH/AgIC/wMDA/8DAwP/AgIC/wQEBP8HBwf/AAAA/wAAAP8AAAD/AAAA/wAAAP8HBwf/BQUF/wMDA/8BAQH/AQEB/wMDA/8CAgL/AQEB/wEBAf8CAgL/AQEB/wAAAP8CAgL/AgIC/wICAv8AAAD/AAAA/wMDA/8CAgL/AwMD/wMDA/8BAQH/AQEB/wUFBf8DAwP/AgIC/wAAAP8EBAT/BwcH/wcHB/8HBwf/BAQE/wICAv8BAQH/AgIC/wEBAf8BAQH/AgIC/wICAv8BAQH/AAAA/wEBAf8AAAD/AgIC/wICAv8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='
                    ]
                ];
                namesList = namesList.concat(defaultNamesList);
            }
            if (options.searchInCache.addCustomNames &&
                Array.isArray(options.searchInCache.customNamesList)) {
                namesList = namesList.concat(options.searchInCache.customNamesList);
            }
            namesList.forEach(function(elem) {
                let engine = {};
                engine.name = elem[0];
                engine.cacheLink = elem[1];
                engine.iconURI_spec = elem[2]; // !!! это не engine.iconURI.spec
                itemCreate(engine, 'searchInCache');

            });
        };
        if (options.searchInCache.enable) {
            itemCreateSearchInCache();
        }

        popup.gObj = this;
        popup.setAttribute('oncommand', 'if (!event.target.engine || event.target.nodeName == "menu") return; this.gObj.searchCommandHandler(event);');
        popup.setAttribute('onclick', 'checkForMiddleClick(this, event);');
    },

    searchByImageCommandHandler: function(event) {
        let inBg = options.loadInBackground || false;
        if (event.type == 'click' && event.button && event.button == 1) {
            inBg = !inBg;
        }
        let searchByImageMenu = this.searchByImageMenu;
        let link = event.target.link;
        let imageLink = searchByImageMenu.imageSrc;
        if (imageLink.indexOf('data:') == 0) {
            this.searchByImageByData(imageLink, inBg);
            return;
        }
        else if (imageLink.indexOf('file:') == 0) {
            this.searchByImageByFile(imageLink, inBg);
            return;
        }
        else {
            imageLink = encodeURIComponent(imageLink)
        }
        let _gBrowser = gBrowser || getBrowser();
        _gBrowser.loadOneTab(link + imageLink, {
            relatedToCurrent: true,
            inBackground: inBg
        });
    },
    // searchByImageByData() and searchByImageByFile() based on
    // Google Image Search 0.5 by Nishan Naseer
    // https://addons.mozilla.org/ru/firefox/addon/google-similar-images
    searchByImageByData: function(src, inBg) {
        let _gBrowser = gBrowser || getBrowser();
        //let tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
        let tab = _gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
            relatedToCurrent: true
        });
        let newTabBrowser = _gBrowser.getBrowserForTab(tab);
        newTabBrowser.addEventListener('load', function byData(e) {
            newTabBrowser.removeEventListener(e.type, byData, true);
            if (src) {
                try {
                    let image_url;
                    let sub;
                    let form = newTabBrowser.contentDocument.getElementById('qbf');
                    let inputs = form.getElementsByTagName('input');
                    for (let k = 0; k < inputs.length; k++) {
                        let i = inputs[k];
                        if (i.name && i.name == 'image_url') {
                            image_url = i;
                        }
                        if (i.type && i.type == 'submit') {
                            sub = i;
                        }
                    }
                    image_url.value = src;
                    sub.click();
                    src = null;
                }
                catch (ex) {}
            }
        }, true);

        if (!inBg) {
            getBrowser().selectedTab = tab;
        }
    },
    searchByImageByFile: function(src, inBg) {
        //Canvas to get contents in base-64
        let canvas = gContextMenu.target.ownerDocument.createElementNS(XHTMLNS, 'canvas');
        let image = new Image();
        image.src = src;

        canvas.width = image.width;
        canvas.height = image.height;

        let ctx = canvas.getContext('2d');
        ctx.drawImage(image, 0, 0);
        let dataURL = canvas.toDataURL('image/png');
        let _gBrowser = gBrowser || getBrowser();
        //let tab = gBrowser.addTab(this.searchByImageMenu.popup.googleURL);
        let tab = _gBrowser.loadOneTab(this.searchByImageMenu.popup.googleURL, {
            relatedToCurrent: true
        });
        let newTabBrowser = _gBrowser.getBrowserForTab(tab);
        newTabBrowser.addEventListener('load', function byFile(e) {
            newTabBrowser.removeEventListener(e.type, byFile, true);
            if (src) {
                try {
                    let image_url;
                    let sub;
                    let form = newTabBrowser.contentDocument.getElementById('qbf');
                    let inputs = form.getElementsByTagName('input');
                    for (let k = 0; k < inputs.length; k++) {
                        let i = inputs[k];
                        if (i.name && i.name == 'image_url') {
                            image_url = i;
                        }
                        if (i.type && i.type == 'submit') {
                            sub = i;
                        }
                    }
                    image_url.value = dataURL;
                    sub.click();
                    src = null;
                }
                catch (ex) {}
            }
        }, true);

        if (!inBg) {
            getBrowser().selectedTab = tab;
        }
    },
    searchByImageMenuPopup: function(e) {
        let searchByImageMenu = this.searchByImageMenu;

        searchByImageMenu.hidden = !gContextMenu.onImage;
        let src = gContextMenu.mediaURL || gContextMenu.imageURL || gContextMenu.bgImageURL;
        if (!src || !(/^((ht|f)tps?:\/\/|data:image|file:)/.test(src))) {
            searchByImageMenu.hidden = true;
            return;
        }
        let popup = searchByImageMenu.popup;
        let items;
        if (!popup.items) {
            let itemsObj = popup.getElementsByTagName('menuitem');
            popup.items = [];
            Array.slice(itemsObj).forEach(function(elem) {
                if (typeof elem == 'object' &&
                    elem.nodeName == 'menuitem' &&
                    elem.getAttribute('label') != 'Google')
                    popup.items.push(elem);
            });
            items = popup.items;
        }
        else {
            items = popup.items;
        }

        if (/^(data:image|file:)/.test(src)) {
            items.forEach(function(elem) {
                elem.setAttribute('disabled', 'true');
            });
        }
        else {
            items.forEach(function(elem) {
                elem.removeAttribute('disabled');
            });
        }

        searchByImageMenu.imageSrc = src;
    },
    createSearchByImageMenu: function() {
        let menu = document.createElement('menu');
        let insertMenu = document.getElementById('context-sep-copyimage');
        insertMenu.parentNode.insertBefore(menu, insertMenu);
        this.searchByImageMenu = menu;

        menu.setAttribute('id', this.nodeIds.searchByImageMenu);
        menu.setAttribute('class', 'menu-iconic');
        menu.setAttribute('label', _localize('searchByImage'));
        menu.setAttribute('image', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAK6wAACusBgosNWgAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAElSURBVDiNY/z//z8DJYCRkIKsthv/kRX9Z2BgmFalARdiIcaGKZXqcH5O+01U+ay2G3MYGBiSiXUmmofnsBDSjEUTMkiBe2Eq1JnZ7TcZBHhZGNythBl0lLkZODmYGX7++sdw/sZnhl3H3zF8+voHwwsYFkR5ijNICLMzTF31hOHnr38MHGxMDJlhMgwv3vxkWL7jJYpaJmzu0lTigWtmYGBg+PHrH8P0VU8YtJV5MNRiNYCfmxmuGQZ+/PrHwMmOqRyrAX///WfgYEOV4mBjwjAUpwHHL31iyA6XgRvCwcbEkBUmw3DuxmcMtVgDkYONicHLVoTBSJOXgYONieHHz38Ml+98Ydh88DXDtx//CBtACmBiYGCYS4H+OYyU5kasgUgKAADN8WLFzlj9rgAAAABJRU5ErkJggg==');

        this.searchByImageMenu.popup = menu.appendChild(document.createElementNS(XULNS, 'menupopup'));
        let popup = this.searchByImageMenu.popup;
        popup.setAttribute('id', this.nodeIds.searchByImageMenuPopup);
        popup.googleURL = 'https://www.google.com/searchbyimage';

        let namesList = [];
        if (options.searchByImage.useDefaultNamesList) {
            let defaultNamesList = [
                [
                    'Google',
                    'https://www.google.com/searchbyimage?image_url=',
                    'data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAASCwAAEgsAAAAAAAAAAAAA9IVCSvSFQuf0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULk9IVCSvSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQuf0hUL/9IVC//SFQv/0hUL/9Y1O//rIq//+7+f//eXX//vUvf/7z7X/96Fu//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vYwv/97OH/9ZRZ//SFQv/0hUL/9IhG//zbx//3om7/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97uX/+buW//SFQv/0hUL/9IVC//SFQv/5upT/+9O6//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+b6b//zezP/0iEf/9IVC//SFQv/1klf//ezh//vPtP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/3qXr/+siq//m8lv/5wqD//vTu//3t4//1klb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0h0b//vbx//zi0//1j1H/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2nmn/+bmS/////v/4sIX/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5uJH///v5//eoef/1jU//+82y//afav/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vXw//vOs//0hUL/9IVC//ekcf/96+D/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//728v/4sIX/9IVC//SFQv/4s4n///v4//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/6yKn/+byX//SFQv/0hkT//eTV//vWv//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IZE//m6lP/5u5b//OHQ///+/f/6y6//96d3//SFQv/0hUL/9IVC//SFQv/0hULm9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSfSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULm9IVCSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsAAAAAAAAAAAAA9IVCAPSFQif0hUKt9IVC8vSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvL0hUKt9IVCJ/SFQgD0hUIo9IVC7/SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULv9IVCKPSFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVC8fSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQvP0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YtL//i2jv/828f//vLr///7+P///Pv//vTu//3n2v/6zbH/96Nw//SFQ//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ekcv/+8+z////////////+9fD/+9K5//m9mf/4to7/+buV//vSuf/++PT//OPT//aYYP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2l13///r3/////////fv/+b2Z//SIRv/0hUL/9IVC//SFQv/0hUL/9IVC//WNT//84M///vXv//aZYf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vPtP////////////i0i//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//WQUv///Pr//OPU//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//eTV///////+9O7/9IVD//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//3m2P//////9ppi//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/718H///////3s4f/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vDn///////4soj/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//erff////////38//WTWP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//iziv////////////iwhf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rMsP///////eXW//WSVv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/4sYb///z7/////////Pv/9ZFV//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ixhv/+8Of//vn1//rMsP/4rH//9plh//WQUv/1j1L/+s2x//////////////////m9mf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SGQ//2nmn/+buW//vNsv/82sb//e3j/////////////////////v/5wZ//9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/83Mj////////////++fb/+K+C//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9ZRZ/////////////vTt//aaYv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/1lFr////////////6xqf/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ehbf/70bj//end//3o2////v3///////3l1//0iEb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5wqD////////////96t7/96Z2//WOUP/2nWf//NvH//zcyP/1i0z/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/96l6/////////////vLr//WPUf/0hUL/9IVC//SFQv/0h0b//end//3k1f/0iUn/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/8387////////////4sYf/9IVC//SFQv/0hUL/9IVC//SFQv/6w6L///////nBn//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC///69////////vj1//SIR//0hUL/9IVC//SFQv/0hUL/9IVC//m+mv///////e3j//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL///r3///////8387/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+syw///////++fb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/95NX///////vUvP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/97OH///////7y6//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//i2jv///////N/O//SFQv/0hUL/9IVC//SFQv/0hUL/96Nx////////////+s2x//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IdF//zh0P//+/j/9ZJW//SFQv/0hUL/9IVC//SKSv/96t7///////738v/1k1f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YxN//vUvf/96+D/96Z0//WNT//3om///ebY/////////Pv/+LKI//WVW//0h0X/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//agbP/7zbL//enc//749P////////////////////////////3r4P/3p3f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8/SFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVCJ/SFQu/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC7/SFQif0hUIA9IVCJfSFQq30hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8fSFQq30hUIl9IVCAIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAB'
                ],
                [
                    'Yandex',
                    'http://images.yandex.ru/yandsearch?rpt=imageview&&img_url=',
                    'data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAkdx+AJHc5wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3P8Akdz/AJHc/wCR3JYArvIAAK7yAACu8gAArvIAA5Pd5wCr8P8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8ArvL/AK7y/wCu8v8CnOT/A5PdewCu8gAArvIAAK7yAAeV3/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/ALDz/wCw8/8AsPP/Aa3x/weW4P8Hld8PALDzAACw8wAMmOH///////////////////////////////////////////////////////////8GpOr/DJjhigCy9AAAsvQAEZzk//////8VpOn/Fbr1/xW69f+c4fv/ddb5/xW69f8VuvX/Fbr1/x2o6v//////AbT0/w+f5v8RnOQ8ALX1ABeg5v//////F6bp/xe48/8XuPP/hdf3/4XX9/80wPT/F7jz/xe48/8dqOr//////wC49v8IsPD/F6DmpQC49gAepOn//////wOe6P8DrvD/A67w/1/G8/9fxvP/TsLy/wSu8P8DrvD/CaHo//////8Au/j/ALv4/xep7f8epOlmJKjs//////9GvfD/ft78/37e/P///////////+f5/v+A3/z/ft78/03A8P//////AL75/wC++f8Huvf/JKjszyut7///////OLvw/2Pa/P9j2vz///////////+R5f3/Y9r8/2Pa/P8/vvD//////wDC+v8Awvr/CL74/yut788xsfL//////ya48P9F1fz/RdX8///////N8/7/RdX8/0XV/P9F1fz/Lrnw//////8Axfv/AMX7/yW29P8xsfJmOLX1//////8XtfD/KNH8/yjR/P/8/v//UNr9/yjR/P8o0fz/KNH8/x+48P//////AMn8/xTC+v84tfWlAMn8AD659///////ALHw/wCx8P8AsfD/Gbjw/wCx8P8AsfD/ALHw/wCx8P8JtPD//////wPM/v83u/j/Prn3PADN/gBDvfr///////////////////////////////////////////////////////////8lxvz/Q736igTR/gAE0f4ASMD8/xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8S1f//EtX//xLV//8Y0///R8D8/0jA/A8S1f8AEtX/AEzD/uRa2f//XNz//1zc//9c3P//XNz//1zc//9c3P//XNz//1zc//9c3P//Ucv+/0zD/nhc3P8AXNz/AFzc/wBPxf97T8X/5E/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F//9Pxf//T8X//0/F/5Zc3P8AXNz/AFzc/wBc3P8AAA8AAAAHAAAAAwAAAAMAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAMAAAADAAAABwAAAA8AAA=='
                ],
                [
                    'TinEye',
                    'http://www.tineye.com/search/?pluginver=firefox-1.0&url=',
                    'data:image/x-icon;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAACxeDVItHk157iAO//WtW7/482G/+XOhv/lzYL/1L98/5mTcf8UKUP/CwsM/xwcG/8AAAD/AAAA/wAAAOcAAA5ItHo25LV7Nv+1ezb/tXs2/8GPSf/EoGj/s5hw/6KPdf93bWT/ZFdK/2daTP9hVEj/XU9C/zIpH/8EAgH/AAAA5LV7Nv+1ezb/tXs2/7V7Nv+1ezb/uIA+/8eea//Wtof/48eU/+PKkv/iyJP/4MeV/9u/kf/HqHz/rI1p/3tmT/+1ezb/tXs2/7V7Nv+1ezb/zKV0/+PKlP/hxXr/zbFk/8esYf/VuW7/3sFz/+LFdf/gw3P/48Z3/+nPjv/dwJD/tXs2/7V7Nv+1ezb/y6Nx/9/Gg/+NekT/V0wv/5uSfP95cmH/JiES/zAqGv86Mh3/W08v/3lpQP+Wg03/zLFn/7V7Nv+1ezb/uoVH/8myg/+VgUr/AAAA/2xpZf/i4+X/+fn5/0JAO/8AAAD/LCkl/768uf+/vr3/Mi8q/x0ZEP+2fDf/tXs2/6WGX/+pklP/JyES/0dFQP96eHX/W1tc//////9ua2X/DAoH/6Wim/+EhIX//////6ejnP8AAAD/wo1F/8GLQ//Conf/tZ1e/wYDAP9pZmH/6+vs/9/f3/////3/Pjoz/zo2Lf/Jycb/UlJT//////+xraX/AAAA/8OORv/Djkb/1bF+/821cf83MSD/MC4s//n49P//////l5OJ/wMCAP9IRDr/////////////////ZGBW/wAAAP/Djkb/w45G/8qkcP+sllr/wKtw/zw5Mf9MSUb/VlNM/wIBAP8AAAD/FxUP/9PQyv/8+/j/rKig/wkHA/8AAAD/w45G/8OORv+1jlj/l4hm/8etZv/QuHf/m4xk/21hSP9PRjX/Mi0j/xsYFf87NzD/VFBK/xUVFf8FBwz/CQsQ/8OORv/Djkb/g2I1/8Oea//Mt4z/uJxU/56hhv92nLj/l6ut/56poP+gpJL/mJeC/5aMbP+bjmv/m49t/52Qbv/Djkb/uItP/05PUP+zjlv/yptc/9C3jP9gYFP/ABVH/wAzc/8IP4T/FUuM/xhSmP99lZ3/5sRv/9S6cf/Lsmr/w45G/1B7rv8bbdT/LWy5/8OORv/Djkf/yqRw/zswIP8AAAD/AAAA/wAAAP8AAAD/Fyk8/5CKZ/+ahU3/modW/8GNReeEj5r/L37g/0Jxqf/Cjkf/w45G/8OORv/Fllb/clYw/zoqFf8hGQ3/IhwU/x4ZFf9HRUD/vaJ5/86pdee+ikU/woxEyZ6HZ/+8jEz/w45G/8OORv/Djkb/w45G/8OORv/Djkb/v4tF/8ORTf/GlFD/xJBJ/8KMRMm+ikU/gAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAE='
                ]
            ];
            namesList = namesList.concat(defaultNamesList);
        }
        if (options.searchByImage.addCustomNames &&
            Array.isArray(options.searchByImage.customNamesList)) {
            namesList = namesList.concat(options.searchByImage.customNamesList);
        }

        let itemCreate = function(name, link, image) {
            let item = document.createElementNS(XULNS, 'menuitem');
            item.setAttribute('class', 'menuitem-iconic');
            item.setAttribute('src', image);
            item.setAttribute('label', name);
            item.link = link;
            popup.appendChild(item);
        };
        namesList.forEach(function(elem) {
            itemCreate(elem[0], elem[1], elem[2]);
        });

        let contextMenu = this.contextMenu;

        popup.gObj = this;
        popup.setAttribute('oncommand', 'this.gObj.searchByImageCommandHandler(event);');
        popup.setAttribute('onclick', 'checkForMiddleClick(this, event);');
    }
};
contextSearcherObj.init();

}());

2k1dmg

Выделить код

Код:

alert( Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService) == Services.io ); //== true

Кстати, красивый код у тебя получился.

2k1dmg
Спасибо, не знаю насколько код красивый, но очень полезный.

Как в этой кнопке сделать чтобы убрать надпись "Поиск <бла-бла> в Google, оставив только Google.
https://forum.mozilla-russia.org/viewto … 50#p703450
http://savepic.ru/8254894m.png

villa7 пишет:

убрать

Ломать не строить :).

скрытый текст

Выделить код

Код:

                // this.contextMenuPopup(e);

Dumby
Спасибо.

Context Search 2 2016-01-10
https://gist.github.com/2k1dmg/985bba49138d3d2a1889

2k1dmg пишет:

Context Search 2 2016-01-10
https://gist.github.com/2k1dmg/985bba49138d3d2a1889

Уважаемый 2k1dmg,
У меня есть несколько предложений по Вашей кнопке, а также вопросов.
1. Кнопка осуществляет поиск в кэше (Гугл, ВэбАрхив). Но для этого не нужно выделение слова - его приходится выделять только, чтобы вызвать через КонтекстМеню поиск. Нельзя ли сделать так, чтобы менюитем этого поиска присутствовал бы в КонтекстМеню всегда - тогда бы не надо было искусственного выделения для поиска в кэше.
2. Есть много сайтов - анализаторов СЕО и другой информации о сайтах по их URL (аналогично поиску в кэше) - такие сайты тоже можно было бы ввести как поисковые, если бы менюитем поиска по Вашей кнопке присутствовал бы в КонтекстМеню всегда и если бы в случае когда ничего не выделено - при вызове того или  иного поисковика, подавал бы на его вход URL текущего сайта. Кстати, в этом случае ВэбАрхив может тоже быть добавлен пользователем как обычный поисковик. С Гугл кэш у меня так не получилось. Но его (единственного) можно добавить без подменю - как обычную иконку.
3. Таким образом останется лишь одно подменю - поиск по текущему сайту через гугл или яндекс (я бы их тоже добавил бы двумя иконками и избавился бы от подменю вообще)
4. Очень желательно добавить поиск картинок по картинкам. В приципе, такие поисковики - это обычные поисковики, на вход которых подаётся src картинки (обычно - URL).
То есть, если добавить правило: если ничего не выбрано, а  правый клик на картинке - на выбранный поисковик подаётся src картинки - тогда пользователь мог бы добавить в список  поисковиков поисковики картинок по картинкам (Гугл, Яндекс, TinEye, KarmaDecay и др.)
5. К правилу п.4 можно было бы добавить: если ничего не выбрано, а правый клик - на линке (но не на картинке) - поиск по URL линка
6. Было бы совсем роскошно добавить ещё и поле ввода, чтобы можно было бы делать  поиск не только по выделенному тексту, но и набранному. Тогда бы не нужно было бы дополнения Ctrl Ctrl. Если делать поле ввода сложно, то можно было бы использовать findbar...
7. Можно ли добавить вызов Вашего мини-меню кликом на кнопку? Чтоб не только через вызов контекстного меню?
8. У меня также вопрос касательно мини-меню: оно у Вас организовано в 5 колонок с интервалами между ними а также с отступами слева и справа.
Можно ли узнать, где в Вашем коде задаётся число колонок, отступы слева и справа и интервалы как по горизонтали, так и по вертикали?
Я это спрашиваю не для того, чтобы менять, а чтобы научиться как сооружать такое меню.
Спасибо

difabor
1. Да, это не привычно, но так меньше кода.
4. Он и так есть.
8. CSS и эта часть:

скрытый текст

Выделить код

Код:

        let counterMaxLength = options.campactMenuLengthPerLine;
        if (typeof counterMaxLength != 'number' ||
            3 > counterMaxLength || counterMaxLength > 10)
            counterMaxLength = 5;
        let counter = 0;
        let hBox;
        let itemCreateCampact = function(engine, last) {


А по всему остальному: ничего нового добавлять не планирую, сохранить бы в рабочем состоянии что есть.

difabor пишет:

Я это спрашиваю не для того, чтобы менять, а чтобы научиться как сооружать такое меню.

Другой пример:

Выделить код

Код:

custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3EDoubleM%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bdata%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAAQElEQVR42mNkIBEwAvG/f/+IVM3ExATVAGQRVA1RhtCwf/9+ZGlHR8d//2YgmZ0xqmGYaCAtaRBUDbMHrIEkAABT+ooR2wR10QAAAABJRU5ErkJggg%3D%3D%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B//%20%u041D%u0430%u0441%u0442%u0440%u043E%u0439%u043A%u0430%20%u0444%u0443%u043D%u043A%u0446%u0438%u0439%20%u043A%u043B%u0438%u043A%u043E%u0432%20%u043C%u044B%u0448%u0438%20....................%20%0Athis._handleClick%20%3D%28%29%3D%3E%20popup.openPopup%28this%29%3B%0A%0A%0A//%20%u0421%u043E%u0437%u0434%u0430%u0442%u044C%20%u0434%u0432%u0443%u0445%u0441%u0435%u043A%u0446%u0438%u043E%u043D%u043D%u043E%u0435%20%u043C%u0435%u043D%u044E%20......................%20%0Avar%20popup%20%3D%20addElement%28%22menupopup%22%2C%20%7B%0A%20%20%20position%3A%20%22after_start%22%2C%0A%20%20%20oncontextmenu%3A%20%22return%20false%22%2C%0A%20%20%20style%3A%20%22-moz-appearance%3A%20none%3B%20border%3A%201px%20solid%22%0A%7D%2C%20self%29%3B%0A%0Avar%20mainBox%20%3D%20addElement%28%22hbox%22%2C%20%7B%7D%2C%20popup%29%3B%0Avar%20leftBox%20%3D%20addElement%28%22vbox%22%2C%20%7B%7D%2C%20%20mainBox%29%3B%20%20%20%20%20//%20%u041B%u0435%u0432%u043E%u0435%20%u043C%u0435%u043D%u044E%0Avar%20rightBox%20%3D%20addElement%28%22vbox%22%2C%20%7B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20//%20%u041F%u0440%u0430%u0432%u043E%u0435%20%u043C%u0435%u043D%u044E%0A%20%20%20style%3A%20%22background-color%3A%20rgb%28241%2C%20245%2C%20251%29%3B%20box-shadow%3A%201px%200px%202px%20rgb%28204%2C%20214%2C%20234%29%20inset%3B%22%20//%20%u0441%u0442%u0438%u043B%u044C%20%u043F%u0440%u0430%u0432%u043E%u0433%u043E%20%u043C%u0435%u043D%u044E%0A%7D%2C%20mainBox%29%3B%0A%0A%0A%0A//%20%u041B%u0435%u0432%u044B%u0435%20%u043F%u0443%u043D%u043A%u0442%u044B%20%u043C%u0435%u043D%u044E%20......................%20%0Avar%20leftItem0%20%3D%20addElement%28%22menuitem%22%2C%20%7B%0A%20%20%20label%3A%20%22%u041D%u043E%u0432%u043E%u0435%20%u043F%u0440%u0438%u0432%u0430%u0442%u043D%u043E%u0435%20%u043E%u043A%u043D%u043E%22%2C%0A%20%20%20oncommand%3A%20%22OpenBrowserWindow%28%7Bprivate%3A%20true%7D%29%22%2C%0A%20%20%20image%3A%20%22chrome%3A//browser/skin/Privacy-16.png%22%0A%7D%2C%20leftBox%29%3B%0A%0Avar%20leftItem1%20%3D%20addElement%28%22menuseparator%22%2C%20%7B%7D%2C%20%20leftBox%29%3B%0A%0Avar%20leftItem2%20%3D%20addElement%28%22menuitem%22%2C%20%7B%0A%20%20%20label%3A%20%22%u041E%u0442%u043A%u0440%u044B%u0442%u044C%20%u0444%u0430%u0439%u043B%22%2C%0A%20%20%20oncommand%3A%20%22BrowserOpenFileWindow%28%29%22%0A%7D%2C%20leftBox%29%3B%0A%0Avar%20leftItem3%20%3D%20addElement%28%22menuitem%22%2C%20%7B%0A%20%20%20label%3A%20%22%u0421%u043E%u0445%u0440%u0430%u043D%u0438%u0442%u044C%20%u043A%u0430%u043A%u2026%22%2C%0A%20%20%20oncommand%3A%20%22saveDocument%28window.content.document%29%22%0A%7D%2C%20leftBox%29%3B%0A%0Avar%20leftItem4%20%3D%20addElement%28%22menuitem%22%2C%20%7B%0A%20%20%20label%3A%20%22%u041F%u0435%u0447%u0430%u0442%u044C%u2026%22%2C%0A%20%20%20oncommand%3A%20%22PrintUtils.print%28%29%22%0A%7D%2C%20leftBox%29%3B%0A%0Avar%20leftItem5%20%3D%20addElement%28%22menuseparator%22%2C%20%7B%7D%2C%20%20leftBox%29%3B%0A%0Avar%20leftItem6%20%3D%20addElement%28%22menu%22%2C%20%7B%0A%20%20%20label%3A%20%22%u0412%u0435%u0431-%u0440%u0430%u0437%u0440%u0430%u0431%u043E%u0442%u043A%u0430%u2026%22%2C%0A%20%20%20onclick%3A%20%22gDevToolsBrowser.toggleToolboxCommand%28gBrowser%29%22%0A%7D%2C%20leftBox%29%0A.appendChild%28document.getElementById%28%27menuWebDeveloperPopup%27%29.cloneNode%28true%29%29%3B%0A%0Avar%20leftItem7%20%3D%20addElement%28%22menuseparator%22%2C%20%7B%7D%2C%20%20leftBox%29%3B%0A%0Avar%20leftItem8%20%3D%20addElement%28%22menuitem%22%2C%20%7B%0A%20%20%20label%3A%20%22%u041F%u043E%u043B%u043D%u044B%u0439%20%u044D%u043A%u0440%u0430%u043D%22%2C%0A%20%20%20oncommand%3A%20%22BrowserFullScreen%28%29%22%0A%7D%2C%20leftBox%29%3B%0A%0Avar%20leftItem9%20%3D%20addElement%28%22menuitem%22%2C%20%7B%0A%20%20%20label%3A%20%22%u041D%u0430%u0441%u0442%u0440%u043E%u0438%u0442%u044C%20Sync%u2026%22%2C%0A%20%20%20oncommand%3A%20%22gSyncUI.openSetup%28%29%22%0A%7D%2C%20leftBox%29%3B%0A%0Avar%20leftItem10%20%3D%20addElement%28%22menuitem%22%2C%20%7B%0A%20%20%20label%3A%20%22%u0417%u0430%u043A%u0440%u044B%u0442%u044C%20%u0431%u0440%u0430%u0443%u0437%u0435%u0440%22%2C%0A%20%20%20oncommand%3A%20%22Application.quit%28%29%22%0A%7D%2C%20leftBox%29%3B%0A%0A%0A%0A//%20%u041F%u0440%u0430%u0432%u044B%u0435%20%u043F%u0443%u043D%u043A%u0442%u044B%20%u043C%u0435%u043D%u044E%20......................%20%0Avar%20rightItem0%20%3D%20addElement%28%22menu%22%2C%20%7B%0A%20%20%20label%3A%20%22%u0417%u0430%u043A%u043B%u0430%u0434%u043A%u0438%22%2C%0A%20%20%20image%3A%20%22chrome%3A//custombuttons/skin/button.png%22%2C%0A%7D%2C%20rightBox%29%0A.appendChild%28document.getElementById%28%27bookmarksMenuPopup%27%29.cloneNode%28true%29%29%3B%0A%0Avar%20rightItem1%20%3D%20addElement%28%22menuitem%22%2C%20%7B%0A%20%20%20label%3A%20%22menuitem%20R1%22%2C%0A%20%20%20image%3A%20%22chrome%3A//global/skin/icons/information-16.png%22%2C%0A%20%20%20oncommand%3A%20%22alert%28this.label%29%3B%22%0A%7D%2C%20rightBox%29%3B%0A%0Avar%20rightItem2%20%3D%20addElement%28%22menuseparator%22%2C%20%7B%7D%2C%20%20rightBox%29%3B%0A%0A%0A%0A//%20%u0421%u043E%u0437%u0434%u0430%u0432%u0430%u0442%u044C%20%u044D%u043B%u0435%u043C%u0435%u043D%u0442%u044B%20%u0441%20%u0443%u043A%u0430%u0437%u0430%u043D%u043D%u044B%u043C%u0438%20%u0430%u0442%u0440%u0438%u0431%u0443%u0442%u0430%u043C%u0438%20......................%20%0Afunction%20addElement%28elementName%2C%20attributes%2C%20parent%29%20%7B%0A%20%20%20var%20element%20%3D%20document.createElement%28elementName%29%3B%0A%20%20%20%0A%20%20%20element.id%20%3D%20_id%20+%20%22-%22%20+%20elementName%20+%20%22-%22%20+%20Date.now%28%29%3B%20%20%20%0A%20%20%20for%20%28%20var%20attribute%20in%20attributes%20%29%20element.setAttribute%28attribute%2C%20attributes%5Battribute%5D%29%3B%0A%20%20%20if%20%28%20%5B%22menu%22%2C%20%22menuitem%22%5D.indexOf%28elementName%29%20%21%3D%20-1%20%29%20element.classList.add%28elementName%20+%20%22-iconic%22%29%3B%0A%20%20%20%0A%20%20%20return%20parent.appendChild%28element%29%3B%0A%7D%3B%0AaddDestructor%28%28%29%3D%3E%20popup.remove%28%29%20%29%3B%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5B/*CODE*/%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E

2k1dmg, а какие кардинальные отличия от версии 2013-10-10? Я визуальных не нашёл.

PEAKTOP
Вот скрин, который высылал 2k1dmg. Так стало в 43-й версии [firefox]. Исправление этого и есть изменение.

скрытый текст
http://i.imgur.com/yYs2kRo.png

Добрый вечер, перестал работать поиск в NewsFox. http://take.ms/r0qjI
И ещё в полях ввода, но тут не уверен что работало раньше. FF42, Custom Buttons 0.0.5.8.2 (на 0.0.5.8.1 тоже не работает).
PS. Проверил одноимённое расширение - работает.

Моя вина, делал новый профиль и перепутал кнопки Context Search 2 2016-01-19 - работает.

del

bunda1
Добрый день. На firefox 51 x64, перестал работать Context Search - его просто нет в контекстном меню.

1fesFFFF
В 51-й, вообще кнопки перестали работать с текущей версией на АМО
Custom Buttons | Форум Mozilla Россия

bunda1

И дабы не плодить темы, ещё у меня сломалась функция, которая работала из папки chrome - ScrollSearchEngines.uc  - позволяла менять поисковые движки колёсиком мыши.

Вот сам файл ссылка ,  а вот его содержимое:
Чтобы это всё работало, установлено дополнение  UC

скрытый текст

Выделить код

Код:

// ==UserScript==
// @name           Scroll Search Engines
// @namespace      http://amb.vis.ne.jp/mozilla/
// @description    Change the selected search engine by scroll wheel on 'Search xxx for yyy' menu and do search by middle-clicking the menu.
// @include        main
// @compatibility  Firefox 2.0 3.0 3.1 3.2a1
// @author         Gomita
// @permalink      http://amb.vis.ne.jp/mozilla/?p=71
// @contributor    Alice0775, .
// @Note           http://space.geocities.yahoo.co.jp/gl/alice0775
// @version        2009/02/20 18:00 works without searchbar by alice0775
// @version        2009/02/18 21:00 works with full screen mode by alice0775
// ==/UserScript==
// @version        2007/10/21 03:50 compatibility with Fx3 and conqueryModoki2.uc.xul and performance improved by alice0775
// @version        2007.01.18
(function()
{
    const nsIBSS = Components.interfaces.nsIBrowserSearchService;
    const searchService =Components.classes["@mozilla.org/browser/search-service;1"]
                         .getService(nsIBSS);
    var timer,index;
    try{
      var searchBar = BrowserSearch.getSearchBar();
    }catch(e){
      var searchBar = BrowserSearch.searchBar;  //fx3
    }

    var mouseScrollHandler = function(event)
    {
        var engineName,flg;
        var engines = searchService.getVisibleEngines({ });
        // make sure that search bar is visible
        //if (!searchBar)
        //    return;
        event.stopPropagation();
        // Find the new index
        if(!index) index = engines.indexOf(searchService.currentEngine);
        // change search engine
        var i = index;
        if(event.detail > 0){
          do{
            i = i + 1;
            if(i >= engines.length) {
              i= index;
              break;
            }
            engineName = engines[i].name;
            flg = engineName.match(/-{2,}|\u2015{2,}/)
                  || (engineName.match(/^{/) && !engineName.match(/}/))
                  || (engineName.match(/}/)  && !engineName.match(/{/))
          }while(flg)
        }else{
          do{
            i = i - 1;
            if(i < 0 ) {
              i= index;
              break;
            }
            engineName = engines[i].name;
            flg = engineName.match(/-{2,}|\u2015{2,}/)
                  || (engineName.match(/^{/) && !engineName.match(/}/))
                  || (engineName.match(/}/)  && !engineName.match(/{/))
          }while(flg)
        }
        index = i;
        if(!gContextMenu){
          searchService.currentEngine = engines[i];  //指示されたエンジンにする
          return;
        }
        // update context menu label
        if(timer) clearTimeout(timer);
        engineName = engines[i].name;
        var label = gNavigatorBundle.getFormattedString("contextMenuSearchText", [engineName, getBrowserSelection(16)]);
        var menuitem = event.originalTarget;
        menuitem.engine = engines[i];
        menuitem.setAttribute("label", label);
        // update context menu icon
        timer = setTimeout(function(){
          searchService.currentEngine = engines[i];
          var iconURI = engines[i].iconURI;
          if (iconURI)
              menuitem.setAttribute("src", iconURI.spec);
          else
              menuitem.removeAttribute("src");
        },100);
    };

    if (searchBar) {
      // enable to change search engine by mouse-wheel on engine button
      document.getAnonymousElementByAttribute(searchBar, "anonid", "searchbar-engine-button")
          .addEventListener("DOMMouseScroll", mouseScrollHandler, false);
    }
    document.getElementById("cmd_CustomizeToolbars").addEventListener("DOMAttrModified", function(e) {
      if (e.attrName == "disabled" && !e.newValue){
        try{
          var searchBar = BrowserSearch.getSearchBar();
        }catch(e){
          var searchBar = BrowserSearch.searchBar;  //fx3
        }
        if(searchBar) document.getAnonymousElementByAttribute(searchBar, "anonid", "searchbar-engine-button").addEventListener("DOMMouseScroll", mouseScrollHandler, false);
      }
    }, false);
    var searchMenu = document.getElementById("context-searchselect");
    if(!searchMenu) return;
    // enables to change search engine by mouse-wheel on context menu
    searchMenu.addEventListener("DOMMouseScroll", mouseScrollHandler, false);
    // update context menu icon on showing popup
    document.getElementById("contentAreaContextMenu").addEventListener("popupshowing",function(aEvent)
    {
        var ss = Cc["@mozilla.org/browser/search-service;1"].
                 getService(Ci.nsIBrowserSearchService);
        if(aEvent.originalTarget != document.getElementById('contentAreaContextMenu')) return;
        if (!gContextMenu || !gContextMenu.isTextSelected)
            return;
        // update context menu icon
        var menuitem = document.getElementById("context-searchselect");
        var iconURI = ss.currentEngine.iconURI;
        if (iconURI)
            menuitem.setAttribute("src", iconURI.spec);
        else
            menuitem.removeAttribute("src");
    }, false);
    // enable to search by middle-click
    searchMenu.addEventListener("click", function(event)
    {
        if (event.button == 1)
        {
            searchMenu.loadSearch(getBrowserSelection(), true, searchMenu.engine);
            event.originalTarget.parentNode.hidePopup();
        }
    }, false);

    searchMenu.loadSearch = function(searchText, useNewTab, engine) {
      var ss = Cc["@mozilla.org/browser/search-service;1"].
               getService(Ci.nsIBrowserSearchService);
      if (typeof engine == "undefined"){
        // If the search bar is visible, use the current engine, otherwise, fall
        // back to the default engine.
        //if (isElementVisible(this.searchBar))
          engine = ss.currentEngine;
        //else
        //  engine = ss.defaultEngine;
      }
      var submission = engine.getSubmission(searchText, null); // HTML response

      // getSubmission can return null if the engine doesn't have a URL
      // with a text/html response type.  This is unlikely (since
      // SearchService._addEngineToStore() should fail for such an engine),
      // but let's be on the safe side.
      if (!submission)
        return;

      if (useNewTab) {
        gBrowser.loadOneTab(submission.uri.spec, null, null,
                            submission.postData, window.fullScreen?false:null, false);
      } else
        loadURI(submission.uri.spec, null, submission.postData, false);
    }
    searchMenu.setAttribute("oncommand", "this.loadSearch(getBrowserSelection(), true, this.engine);");
    // ready to show icon in search menu
    document.getElementById("context-searchselect").className = "menuitem-iconic";
}());


В 51-й, вообще кнопки перестали работать

какая-нибудь рабочая бета-версия CB есть?

1fesFFFF

какая-нибудь рабочая бета-версия CB есть?

Так ссылка в сообщении
рабочая бета-версия CB

oleg.sgh
404-я

Здесь умельцы выкладывали исправленную
https://cloud.mail.ru/public/FYVt/Wgi1kgRi8
Нужно сделать это
Как отключить проверку цифровых подписей в дополнениях Firefox | Форум Mozilla Россия
Ссылка исправлена

Скажите пожалуйста, можно ли сделать данную кнопка как на скриншоте?
без выпадающего меню и подписей

скрытый текст
http://i90.fastpic.ru/big/2017/0126/54/8ef915e600c171c15e103f10cd986354.png

oleg.sgh пишет:

Здесь умельцы выкладывали исправленнуюhttps://cloud.mail.ru/public/FYVt/Wgi1kgRi8Нужно сделать этоКак отключить проверку цифровых подписей в дополнениях Firefox | Форум Mozilla РоссияСсылка исправлена
                    Отредактировано oleg.sgh (24-01-2017 15:59:52)

куда следует кинуть вот этот файл? custombuttons@xsms.org.xpi ?

Артик

куда следует кинуть вот этот файл? custombuttons@xsms.org.xpi ?

Скачать дополнение. На вкладке дополнения - шестеренка - установить дополнение из файла.
Проверка дополнений должна быть отключена.

oleg.sgh пишет:

Артик

куда следует кинуть вот этот файл? custombuttons@xsms.org.xpi ?

Скачать дополнение. На вкладке дополнения - шестеренка - установить дополнение из файла.
Проверка дополнений должна быть отключена.

большое спасибо, помогло

Можно ли сделать, чтобы контекстное меню не закрывалось после жмакания по поисковику, т.е. когда поиск открывается в фоне, можно было ещё жмакнуть на 2 и 3 поисковик?

Исходный код из первого сообщения (https://forum.mozilla-russia.org/viewto … 72#p533572) не захотел работать в 59.0.1
Однако заработал, если закомментировать строчку №36 исходного кода

Выделить код

Код:

setItemsToMenuPopup();

и вставить её, допустим, 59-й строчкой.

Чуточку портит радость показ всех поисковых систем, вместо только включенных.
Может быть есть для этого решение?

Coroner
:/

скрытый текст

Выделить код

Код:

(async (contextMenu, searchSelect, searchService) => {

   var fullText = true;

   Services.search.isInitialized || await new Promise(
      resolve => Services.search.init(resolve)
   );
   searchSelect.collapsed = true; // удалить стандартный пункт меню для поиска

   // Создать новый пункт меню для поиска ....
   var menu = contextMenu.insertBefore(document.createElement('menu'), searchSelect);
   menu.setAttribute("class", "menu-iconic");
   addEventListener("popupshowing", (e)=> menu.hidden = searchSelect.hidden, false, contextMenu); 
      
   function setMenu() {  
      menu.engine = searchService.currentEngine;
      menu.setAttribute("label", "Искать в " + menu.engine.name + " или в ...");
      menu.setAttribute("image", menu.engine.iconURI.spec );
   };
   setMenu();

   
   // Создать подменю с поисковиками .... 
   var menuPopup = menu.appendChild(document.createElement("menupopup")); 
   menuPopup.setAttribute('style', 'overflow: scroll'); 

   function setItemsToMenuPopup(e) {
      menuPopup.textContent = "";      

      var engines = searchService.getVisibleEngines({})
         .filter(engine => engine != searchService.currentEngine);
      var hiddenList = Services.prefs.getStringPref("browser.search.hiddenOneOffs").split(",");
      engines.forEach((engine)=> { 
         if (hiddenList.includes(engine.name)) return;
         var mItem = document.createElement("menuitem");
         mItem.setAttribute("label", engine.name);
         mItem.setAttribute("class", "menuitem-iconic");
         mItem.setAttribute("src", engine.iconURI.spec);
         mItem.engine = engine;
         menuPopup.appendChild(mItem);
      })
   };  
   setItemsToMenuPopup();
   
   // установить действие для клика на меню и подменю
   menu.onmouseup = e => {
      var background = e.button != 0;
      var text = gContextMenuContentData.selectionInfo[fullText ? "fullText" : "text"];
      contextMenu.hidePopup();
      var submission = e.target.engine.getSubmission(text, null);
      gBrowser.loadOneTab(submission.uri.spec, null, null, submission.postData, background, false);
   }
      
   
   // Наблюдатель за изменениями в поисковиках пересоздаёт меню и подменю .... 
   var getEngineModified = {
      observe:(subject, topic, data)=> {
         if ( /changed|removed|current/.test(data) ) { setMenu(), setItemsToMenuPopup() };             
      }
   };
   Services.obs.addObserver(getEngineModified, "browser-search-engine-modified", false);   
   Services.prefs.addObserver("browser.search.hiddenOneOffs", setItemsToMenuPopup);
   
   
   // Удалять наблюдатели и меню, показать стандартный пункт ....
   addDestructor(()=> {
      menu.remove();            
      searchSelect.collapsed = false; 
      Services.obs.removeObserver(getEngineModified, "browser-search-engine-modified"); 
      Services.prefs.removeObserver("browser.search.hiddenOneOffs", setItemsToMenuPopup);
   });
      
})(document.getElementById("contentAreaContextMenu"), document.getElementById("context-searchselect"), Services.search);

Dumby, спасибо добрый человек. Работает как надо.
Так привык к возможности быстро найти что надо и там где надо, что недоумеваю почему из коробки такие унылые возможности для поиска.

И этот чудный код отвалился. Кому помешал?
Возможно та же причина что и в https://forum.mozilla-russia.org/viewto … 37#p762537
Разве что там вместо addTab стоит loadOneTab

Если так, то не ли способа вроде https://forum.mozilla-russia.org/viewto … 86#p761786 , только для loadOneTab?
Сама менюшка работает, но по клику поиск во вкладке не открывается.

Coroner
В данном случае так, наверно

скрытый текст

Выделить код

Код:

      /*
      contextMenu.hidePopup();
      var submission = e.target.engine.getSubmission(text, null);
      gBrowser.loadOneTab(submission.uri.spec, null, null, submission.postData, background, false);
      */
      var {principal} = gContextMenu;
      contextMenu.hidePopup();
      var submission = e.target.engine.getSubmission(text, null);
      gBrowser.loadOneTab(submission.uri.spec, {
         postData: submission.postData,
         inBackground: background,
         triggeringPrincipal: principal
      });

Dumby, нет, поведение не изменилось. :(
Менюшка есть — клик по ней реакции не вызывает.

Может кто-нибудь проверит?

Coroner

скрытый текст
https://addons.mozilla.org/ru/firefox/a … xt-search/
То же, что делает этот скрипт + можно настроить особое контекстное меню для ссылки (например, поиск в Archive.org), для изображения (поиск в Google image search), для текущей страницы (например, перевести страницу в Google Translate), поиск в Google по текущему сайту и др.

Yeesha, он у меня установлен (про запас). Просто привык минимумом дополнений обходиться.
Но раз уж посоветовали — включу его. :)