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

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

Скриншот:
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 пишет

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

Здесь также ;)
Есть такая проблема, если выделенное находится с правого края, то меню выбора поисковиков закрывает осн. меню.
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 не совсем корректно работал - не отображал текст в пункте контекстного меню 3136439.png 
В моём предыдущем посте код с исправлением этого недоразумения.


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

PEAKTOP пишет

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

Если по простому :):
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, БОЛЬШОЕ ПРЕБОЛЬШОЕ СПАСИБО!
Ещё одна просьба. Можешь добавить в текст пункта меню выделенное/искомое слово?
как здесь
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, вот теперь именно то, что я хотел.
0_18931_a1348090_M.gif

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

Соглашусь с  dedmazai1870, пункт "Поиск по текущему сайту" с помощью этой кнопки был бы очень кстати. 
3148423.png

dedmazai1870
PEAKTOP
№27

2k1dmg
Большое спасибо, всё здорово! de025085f8915a36f1649f7aa322cecf.gif

2k1dmg
А можно привязать окно поиска к контекстному меню, чтобы оно не прыгало слева на право, а всегда было на предсказуемом месте.
Сейчас
1d6ddb20a5a4t.jpg
Хотелось бы
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 );
})();


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
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 совместными усилиями вы сделали очень удобную и функциональную кнопку. БОЛЬШОЕ ВАМ СПАСИБО! clapping.gif good.gif
Вот ещё бы для пункта отображаемого при клике на картинке 3270720.png сделать возможность задать поисковик по умолчанию и сделать его активным - осуществлять поиск этим поисковиком при клике на пункте контекстного меню (без захода в подменю). И тогда  кнопка будет универсальная на все 100%.

2k1dmg
А можно как то поисковики впихнуть внутрь контекстного меню, чтобы не прыгали слева на право а всегда были на предсказуемом месте, или как нибудь привязать к одной стороне.
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 добавляет в контекстное меню свой пункт два раза:
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

скрытый текст
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
8254894m.png

villa7 пишет

убрать

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

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

Выделить код

Код:

// this.contextMenuPopup(e);

Dumby
Спасибо.

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

2k1dmg пишет

Уважаемый 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]. Исправление этого и есть изменение.

скрытый текст
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 Россия
Ссылка исправлена

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

скрытый текст
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, он у меня установлен (про запас). Просто привык минимумом дополнений обходиться.
Но раз уж посоветовали — включу его. :)

Странное поведение кода на FF 56, а именно ищется выделенный текст, который искался до него. Как это можно исправить?

Проблему решил кнопкой Context Search 2.

_backup пишет

Проблему решил кнопкой Context Search 2.

Поделись

Maxut пишет
_backup пишет

Проблему решил кнопкой Context Search 2.

Поделись

https://forum.mozilla-russia.org/viewto … 67#p704467