Context Search( Firefox24+ )
Автор: bunda1
Версия: от 19.12.2015
Описание: код заменяет стандартный пункт контекстного меню страницы для поиска в текущем поисковике на новый пункт который открывает подменю со всеми установленными поисковиками и позволяет выбрать поисковик в котором вы хотите искать выделенный текст.
Клики на пункте контекстного меню или на пункте подменю:
ЛКМ => Открыть поиск в новой активной вкладке,
ПКМ => Открыть поиск в новой фоновой вкладке.
// 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);
Отредактировано bunda1 (13-12-2013 09:22:46)
Отсутствует
Аналогичное Context Search-у дополнение есть и в виде джетпака (его установка не требует перезапуска браузера): Context Search RG.
+ в нём есть одна мелкая удобная фишка, что сам пункт меню из которого выпадает список со всеми поисковыми машинами - он кликабельный и отвечает за текущую выбранную в Панели поиска поисковую машину.
mzfx
Отсутствует
пункт меню из которого выпадает список со всеми поисковыми машинами - он кликабельный
Здесь также
Есть такая проблема, если выделенное находится с правого края, то меню выбора поисковиков закрывает осн. меню.
Было бы не плохо что-бы открывалось только при наведении курсора на стрелку или хотя бы не так быстро(~ 1.5-2 сек.), что бы успеть нажать на поиск по текущему поисковому плагину.
Отсутствует
Было бы не плохо что-бы открывалось только при наведении курсора на стрелку или хотя бы не так быстро(~ 1.5-2 сек.), что бы успеть нажать на поиск по текущему поисковому плагину.
измени в коде
на
или на
Отсутствует
bunda1
А можно сделать без подменю, а что-бы сразу показывались поисковики и без надписи выделенного, сижу на старом, кем то переделанном без подменю расширении Context Search и всякий раз обновления просятся, а там уже с подменю, да и от расширения избавиться неплохо бы.
Лучше спросить у знающих - чем лезть не зная.
Отсутствует
Как без подменю, объясни подробней.
Выделяю слово, жму правую кнопку, и у меня сразу вместе с пунктами копировать, выделить и т.д., все поисковики, не надо еще открывать подпункт с поисковиками, у меня как-то так с самого начала было, привык, меньше телодвижений.
Лучше спросить у знающих - чем лезть не зная.
Отсутствует
Если ты используешь кнопку CB Mouse Gestures то там есть жест RLRL - [Popup] Поиск текста в выбранном поисковике. Это практически аналог Context Search, попробуй.
Отсутствует
Если ты используешь кнопку CB Mouse Gestures то там есть жест RLRL - [Popup] Поиск текста в выбранном поисковике. Это практически аналог Context Search, попробуй.
Попробовал, там выходит один поисковик, а у меня их с десяток для разных целей, надо дополнительно переключаться, получается еще более неудобнее чем с подменю, если трудоемко убрать подменю то ладно, буду дальше старым расширением пользоваться, пока не сломается в новых версиях лисы, что теперь поделаешь.
Лучше спросить у знающих - чем лезть не зная.
Отсутствует
Попробовал, там выходит один поисковик, а у меня их с десяток для разных целей, надо дополнительно переключаться, получается еще более неудобнее чем с подменю,
Попробуй FireGestures :: Дополнения Firefox, там весь список поисковиков выдаёт.
Отсутствует
bunda1
'RLRL':{name:'[Popup]Search
Engines'
Всем спасибо за участие , добавил эту команду и стало то что нужно, до этого неправильно копировал из списка удаленных команд.
А еще такой вопрос,у знакомого ссылки на код кнопки кликабельны, а у меня нет, ставлю кнопки перетаскиванием в адресную строку. Скрипт текстовых ссылок Linkification стоит, если это от него зависит, или как.
Отредактировано villa7 (23-09-2012 16:19:32)
Лучше спросить у знающих - чем лезть не зная.
Отсутствует
LongLogin
Easy DragToGo+
У меня раньше стояло, сменил на кнопку Drag and go, и потом там нужно сначала выделить потом дернуть, а Linkification сразу клацнул и все, пока браузер не крашился, тьфу,тфу. Все равно спасибо.
Лучше спросить у знающих - чем лезть не зная.
Отсутствует
LongLogin
всёже обращу внимание, что при большом кол-ве поисковиков, искать по вертикальному списку может оказаться крайне утомительно
Иеется ввиду Quick Search Bar?, я пробовал ставить, но у меня по правой кнопке вообще ни какие поисковики не появляются, может какие-то настройки поменять, а может на 15 лисе не работает.
Отредактировано villa7 (24-09-2012 16:20:11)
Лучше спросить у знающих - чем лезть не зная.
Отсутствует
bunda1
А можно сделать без подменю, а что-бы сразу показывались поисковики и без надписи выделенного, сижу на старом, кем то переделанном без подменю расширении Context Search и всякий раз обновления просятся, а там уже с подменю, да и от расширения избавиться неплохо бы.
Без подменю есть расширение Context Search X
Там вручную отредактируешь параметр extensions.contextsearchx.menuItems в about:config и получишь столько пунктов меню с собственными названиями сколько тебе потребуется, стандартно есть только два или три пункта...
Отсутствует
Griever обновил contextSearcher до версии 0.0.7
// ==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();
Отсутствует
Обновлённый и русифицированный вариант
// ==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-09-2013 23:08:03)
1. Приму из добрых рук щедрый дар - инвайт на Хабр и Лепру
2. Бессмысленно осмысливать смысл неосмысленными мыслями!
3. Прежде чем подумать - подумай!
Отсутствует
SendInfo, в том-то и дело, что код из поста №19 не совсем корректно работал - не отображал текст в пункте контекстного меню
В моём предыдущем посте код с исправлением этого недоразумения.
Попутно два вопроса к знатокам:
1. Как зафиксировать этот пункт в определённом месте контекстного меню, а именно на второй позиции сверху?
2. Как заставить скрипт по умолчанию использовать поисковую систему не ту, что сейчас указана в панели поиска? Сейчас у меня в "панели поиска" задана Wikipedia, соответственно в пункте контекстного меню тоже будет она, а мне надо, чтобы там был Google (для справки он у меня первый в списке поисковых систем в панели поиска). Т.е., независимо от того, какая поисковая система указана в "панели поиска", скрипт должен подставлять в пункт меню Google.
Отредактировано PEAKTOP (20-09-2013 00:16:41)
1. Приму из добрых рук щедрый дар - инвайт на Хабр и Лепру
2. Бессмысленно осмысливать смысл неосмысленными мыслями!
3. Прежде чем подумать - подумай!
Отсутствует
2. Как заставить скрипт по умолчанию использовать поисковую систему не ту, что сейчас указана в панели поиска? Сейчас у меня в "панели поиска" задана Wikipedia, соответственно в пункте контекстного меню тоже будет она, а мне надо, чтобы там был Google (для справки он у меня первый в списке поисковых систем в панели поиска). Т.е., независимо от того, какая поисковая система указана в "панели поиска", скрипт должен подставлять в пункт меню Google.
// 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 ); })();
1. Как зафиксировать этот пункт в определённом месте контекстного меню, а именно на второй позиции сверху?
var menu = contextMenu.insertBefore( document.createElement('menu'), searchSelect );
Тут вместо searchSelect укажи пункт контекстного меню над которым пункт Искать в Google должен находится, например пункт Копировать:
Отредактировано bunda1 (21-09-2013 15:23:34)
Отсутствует
bunda1, БОЛЬШОЕ ПРЕБОЛЬШОЕ СПАСИБО!
Ещё одна просьба. Можешь добавить в текст пункта меню выделенное/искомое слово?
как здесь
Отредактировано PEAKTOP (21-09-2013 19:39:00)
1. Приму из добрых рук щедрый дар - инвайт на Хабр и Лепру
2. Бессмысленно осмысливать смысл неосмысленными мыслями!
3. Прежде чем подумать - подумай!
Отсутствует
PEAKTOP
Это если одно слово, а если ищешь фразу - или меню на весь экран расползётся или обрежется до "Программа..." в зависимости от реализации. Лично мне кажется, что это не принципиально.
bunda1
Всё работает, замечательно! Спасибо.
Context Search X дополнительно к списку моих поисков подключает поиск google последней строкой "Включает строку поиска выделенного текста на текущем сайте."
Чтобы из выделенного мной текста, например "поиск по сайту" получилась такая строка:
Эта строка в виде ссылки.
Это пример, сайт должен подставляться тот, на котором я выделил какую-то фразу.
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)
Отсутствует