Непонятно зачем нерабочий yandex.com добавлять и не добавлять рабочий google.com, ну да ладно.
Не понял, что значит "не добавлять рабочий google.com". Точнее, зачем его добавлять отдельно от google.ru?
#react-duckbar у меня не работает.
Есть такое. Я вчера добавлял вручную на открытой странице, и всё получалось. А оказывается, в тот момент, когда скрипт отрабатывает, нужная часть странички ещё не существует (и элемент с .react-results--main тоже ещё не существует).
Но в скрипте для duckduckgo вообще отдельная ветка кода имеется, пришлось в неё изменения внести.
Что интересно, еще вчера на google.ru был .noHIxc, а сегодня уже нет, но скрипт все равно работает, так как есть .gLFyf.
И еще вчера поисковая выдача различалась, а сегодня идентична.
И у меня тоже. Именно поэтому я и не стал разносить .ru и .com.
Теперь по поводу "нерабочий yandex.com". Я сознательно это сделал, чтобы потом об этом поговорить.
Дело в том, что нынешний код скрипта работает так: берёт имя домена той странички, где скрипт запущен, выделяет из него вторую с конца часть и начинает перебирать имена поисковиков из массива ENGINES. Если имя из массива не совпадает с тем выделенным кусочком имени домена, будет создана ссылка и добавлена на страничку. Если имя совпадёт, ссылка создана не будет (чтобы на страничках поисковика не было ссылок на него же).
Сравнение с доменом происходит без учёта регистра, поэтому для визуального различия ссылок в массиве можно написать, скажем, "Yandex" и "YANDEX". Но в результате на всех других поисковиках будут две вполне рабочие ссылки на разные Яндексы, однако на каждом из Яндексов ссылки на другой Яндекс не будет.
Нужны ли эти два Яндекса одновременно, я не знаю. Посетителей из России yandex.com всё равно перебрасывает на yandex.ru (который вообще ничем не отличается от ya.ru). А верно ли обратное, сказать не могу - когда пытаюсь зайти на yandex.ru из-за границы, мне выдаёт капчу, через которую не могу пройти.
И наконец, остаётся принципиальная невозможность добавлять в скрипт поисковики, у которых существенная часть имени домена не вторая с конца, а третья.
Чтобы такое позволить, нужно менять алгоритм сравнения и саму структура массива ENGINES.
А пока рабочий скрипт вот такой:
// ==UserScript== // @name Alternative search engines 2 // @description Adds search on other sites for google, bing, yandex, duckduckgo // @namespace 2k1dmg@userscript // @license MIT // @version 0.3.2 // @grant none // @noframes // @match *://yandex.com/* // @match *://yandex.ru/* // @match *://ya.ru/* // @match *://www.google.com/* // @match *://www.google.ru/* // @match *://www.bing.com/* // @match *://duckduckgo.com/* // ==/UserScript== // 2024-08-11 (function() { 'use strict'; var SEARCH_ON = '• '; var SEARCH_END = ' •'; var LINK_BOX_ID = 'oeid-box'; var ENGINES_SEPARATOR = ' - '; var POSITION = 'left'; var ENGINES = [ ['Ya', 'https://ya.ru/search?text='], ['Yandex', 'https://yandex.ru/search?text='], ['YANDEX', 'https://yandex.com/search?text='], ['Google', 'https://www.google.ru/search?q='], ['Bing', 'https://www.bing.com/search?q='], ['DuckDuckGo', 'https://duckduckgo.com/?q='] ]; var PLACEHOLDER_SELECTORS = [ '.main__center', // ya .content__left не встречал нигде, даже в стилях '.main__center', // yandex.ru '#categories', // yandex.com '#center_col', // google '.sb_count', // bing '.header__search-wrap' // duckduckgo ].join(','); var INPUT_FIELD_SELECTORS = [ 'input.HeaderForm-Input', // ya 'input.HeaderForm-Input', // yandex.ru '#q', // yandex.com '#APjFqb', // google '#sb_form_q', // bing '#search_form_input' // duckduckgo ].join(','); function addCSSStyle() { var cssStyle = document.createElement('style'); cssStyle.type = 'text/css'; cssStyle.textContent = [ '#' + LINK_BOX_ID + ' {', ' display: inline-block;', ' padding-right: 10px;', ' padding-bottom: 10px;', ' color: rgb(115, 115, 115);' , ' font-family: Verdana,sans-serif;', ' font-size: 9pt;', ' text-align: ' + POSITION + ';', ' z-index: 10000;', '}', '#' + LINK_BOX_ID + ' > a {', ' text-decoration: none;', '}' ].join('\n'); document.head.appendChild(cssStyle); } function createLinkBox() { var domain = document.domain.split('.').splice(-2, 2)[0]; var fragment = document.createDocumentFragment(); var divNode = document.createElement('div'); divNode.id = LINK_BOX_ID; fragment.appendChild(divNode); divNode.appendChild(document.createTextNode(SEARCH_ON)); ENGINES.forEach(function(engine) { if(engine[0].toLowerCase() == domain) { return; } var node = document.createElement('a'); node.target = '_blank'; node.href = engine[1]; node.textContent = engine[0]; divNode.appendChild(node); divNode.appendChild(document.createTextNode(ENGINES_SEPARATOR)); }); divNode.lastChild.textContent = SEARCH_END; return fragment; } function linkBoxMouseOver(event) { var aHref = event.target; if(aHref.nodeName.toLowerCase() != 'a') { return; } var engineSource; ENGINES.forEach(function(engine) { if(engine[0] == aHref.textContent) { engineSource = engine[1]; return; } }); var engineURL; var engineParam = ''; if(Array.isArray(engineSource)) { engineParam = engineSource[1]; engineURL = engineSource[0]; } else if(typeof engineSource == 'string') { engineURL = engineSource; } else { return; } var searchText = document.querySelector(INPUT_FIELD_SELECTORS); if(engineURL && searchText && searchText.value.length > 0) { aHref.href = engineURL + encodeURIComponent(searchText.value) + engineParam; } } function linkBoxMouseOut(event) { var aHref = event.target; if(aHref.nodeName.toLowerCase() != 'a') { return; } ENGINES.forEach(function(engine) { if(engine[0] == aHref.textContent) { aHref.href = engine[1]; return; } }); } if(document.getElementById(LINK_BOX_ID)) { return; } var results = document.querySelector(PLACEHOLDER_SELECTORS); if(!results) { return; } addCSSStyle(); var fragment = createLinkBox(); var domain = document.domain.split('.').splice(-2, 2)[0]; if(domain == 'duckduckgo') { results.appendChild(fragment); } else { results.insertBefore(fragment, results.firstChild); } var linkBox = document.querySelector('#'+LINK_BOX_ID); if(domain == 'duckduckgo') { linkBox.setAttribute('style', 'padding-top: 10px;'); } linkBox.addEventListener('mouseover', linkBoxMouseOver); linkBox.addEventListener('mouseout', linkBoxMouseOut); })();
Думаю скрипт постоянно исправлять придется, главное, что теперь понятно как.
Я, например, вообще не понимаю интереса к данному скрипту. Всё то же самое можно получить без каких-либо заморочек, просто пользуясь поисковой строкой браузера.
Отредактировано yup (17-05-2025 13:19:07)
Отсутствует
пришлось в неё изменения внести
И что оно делает? Не вижу разницы.
У меня ddg на ddg светится. Интересует именно это.
Отбой, я просто имена поменял, не думал, что это влияет.
Я, например, вообще не понимаю интереса к данному скрипту. Всё то же самое можно получить без каких-либо заморочек, просто пользуясь поисковой строкой браузера.
Что получить? Из строки адреса зашел на поисковик, а там не устроила выдача, вы предлагаете заново вбивать запрос в адресную строку? или копипастить?
.content__left не встречал нигде, даже в стилях
Плохо искали.
Отредактировано _zt (17-05-2025 14:45:10)
Отсутствует
И что оно делает? Не вижу разницы.
Исходно выглядело так:
Но оказалось, что у того элемента, который был задан в массиве PLACEHOLDER_SELECTORS для DDG, в момент выполнения скрипта ещё нет дочерних элементов, и поэтому в его firstChild сидит undefined. А такого элемента, чтобы и firstChild у него уже был, и результат на экране красиво смотрелся, не нашлось. Пришлось переписать как
и подобрать подходящий для этого варианта встраивания элемент.
.content__left не встречал нигде, даже в стилях
Плохо искали.
Показать аналогичную картинку у меня в Инспекторе?
Но в то же время истинность показанной картинки под сомнение не ставлю - я уже писал выше, что у меня в разных браузерах структура странички Яндекса совершенно разной оказывается. И то, что я включил в скрипт, взято со странички, которую у меня "не очень свежий Firefox" получает.
Всё то же самое можно получить без каких-либо заморочек, просто пользуясь поисковой строкой браузера.
Что получить?
Получить возможность поискать одним поисковиком, после чего щёлкнуть куда-то мышкой и получить результат поиска другим поисковиком.
Из строки адреса зашел на поисковик, а там не устроила выдача, вы предлагаете заново вбивать запрос в адресную строку? или копипастить?
А не надо из строки адреса. Я же писал про использование строки поиска - её содержимое никуда не девается и никак не меняется.
Отсутствует
Я вообще на главные страницы поисковиков не захожу, поэтому вполне бы устроило
// @match http*://ya.ru/*search*
Зачем нужны PLACEHOLDER_SELECTORS и INPUT_FIELD_SELECTORS если ихние значения можно объединить с ENGINES, который переделать под массив объектов. В каждом объекте можно кучу свойств задать, в том числе и доменное имя
Не приветствую стили, подключаемые через body, т.к. все больше сайтов, которые такой способ блочат
По барабану также прослушки mouseover и mouseout, ибо не вижу смысла изменять в поиске название и искать его в другом поисковике, так что скрипт так себе, на троечку
Отредактировано dinn (18-05-2025 01:20:08)
Отсутствует
Я вообще на главные страницы поисковиков не захожу, поэтому вполне бы устроило
// @match http*://ya.ru/*search*
Скажем так: на главной странице этот скрипт вообще какого-либо смысла не имеет, и с большой вероятностью он там вообще работать не будет за отсутствием необходимых элементов на странице.
Зачем нужны PLACEHOLDER_SELECTORS и INPUT_FIELD_SELECTORS если ихние значения можно объединить с ENGINES, который переделать под массив объектов. В каждом объекте можно кучу свойств задать, в том числе и доменное имя
Именно это я имел в виду, когда писал, что структуру ENGINES имеет смысл переделать. В том числе и то, что имена, показываемые пользователю, нужно отвязать от доменов. И не доменные имена прописывать в массиве, а регулярные выражения - такие же, как в заголовке скрипта.
Не приветствую стили, подключаемые через body, т.к. все больше сайтов, которые такой способ блочат
Не очень понял, о чём речь. Скрипт засовывает стиль не в body, а как положено - в head.
Или это о том, что стиль одним куском текста задан, а не собирается поштучно из отдельных элементов?
Но ведь в любом случае это внутрибраузерные дела, и сайты никак не могут повлиять на работоспособность метода.
Или возможности сайтов что-то запрещать уже и на это распространили?
По барабану также прослушки mouseover и mouseout, ибо не вижу смысла изменять в поиске название и искать его в другом поисковике, так что скрипт так себе, на троечку
На самом деле некоторый смысл есть. Если человек решил, что в другом поисковике хочет поискать изменённую строку, то сейчас он может написать нужное и сразу поискать его там. А без этой прослушки ему сначала придётся на другом поисковике потратить время на поиск того, что искал текущий поисковик, и только после этого он сможет запустить поиск нужного.
Отредактировано yup (18-05-2025 03:06:50)
Отсутствует
Зачем нужны...
Затем, что другого нет. Сделайте лучше.
Бензин кончился?
Получить возможность поискать одним поисковиком, после чего щёлкнуть куда-то мышкой и получить результат поиска другим поисковиком.
Опять двадцать пять, якобы да кабы. Ну так сделайте.
Отредактировано _zt (18-05-2025 02:10:43)
Отсутствует
Бензин кончился?
Практически да. Кончилась связь с провайдером.
Опять двадцать пять, якобы да кабы. Ну так сделайте.
"Но как, Холмс?" Я же писал о том, что уже есть (и всегда было) в браузере. Это стандартный элемент интерфейса и его стандартная функциональность.
Отредактировано yup (18-05-2025 02:26:29)
Отсутствует
Скрипт засовывает стиль не в body, а как положено - в head
опечатался
Но ведь в любом случае это внутрибраузерные дела, и сайты никак не могут повлиять на работоспособность метода.
Или возможности сайтов что-то запрещать уже и на это распространили?
Давно уже, поэтому все свои monkey скрипты переделал. Если сайты еще больше станут наглеть, то буду модифицировать их CSP или вообще удалять
Как пример. CSP утки
1) ddg: default-src 'none' ;...style-src список сайтов 'unsafe-inline';
2) ddg(no script version): default-src 'none' ;...style-src список сайтов;
Во втором случае стили, добавленные в head, работать не будут
В том числе и то, что имена, показываемые пользователю, нужно отвязать от доменов
Не знаю, зачем в скрипте привязка такая и куча лишнего. Под мои потребности достаточно было бы 20-ти строчек кода, если не учитывать стили и описания массивов
И не доменные имена прописывать в массиве, а регулярные выражения - такие же, как в заголовке скрипта
Это только все усложнит. И все ради ya.ru и yandex.ru, у которых одинаковые селекторы?
А без этой прослушки ему сначала придётся на другом поисковике потратить время на поиск того, что искал текущий поисковик, и только после этого он сможет запустить поиск нужного
Да нет уж, если я изменил строку поиска, то Enter нажму (страница обновится и скрипт перезагрузится), чтобы в текущем поисковике посмотреть, а уж потом можно и на другом
Отсутствует
Не знаю, зачем в скрипте привязка такая
Там единственная цель этого: чтобы среди ссылок, добавляемых на страницу поисковика, не было ссылок на этот самый поисковик.
Но один и тот же поисковик может существовать под огромным количеством доменных имён (у Гугла для каждой страны отдельное доменное имя, а то и не одно), и в заголовке в @match-ах это легко может быть учтено (как в том самом первом варианте скрипта, с которого всё здесь началось), поэтому в скрипте была сделана попытка выделять существенную часть доменного имени. Но попытка эта слабенькая, я приводил примеры сайтов, где она обламывается.
А чтобы сделать надёжно, нужно либо держать в скрипте список всех "двузначных" TLD (а он огромный), либо использовать регулярки.
Это только все усложнит. И все ради ya.ru и yandex.ru, у которых одинаковые селекторы?
Нет, ради доменов вида google.com.ua.
Да нет уж, если я изменил строку поиска, то Enter нажму (страница обновится и скрипт перезагрузится), чтобы в текущем поисковике посмотреть, а уж потом можно и на другом
Это если поисковая строка является просто набором слов. А вот если задействовать в ней "расширенный синтаксис" поисковых выражений, то ситуация усложняется, потому что у разных сайтов этот синтаксис несколько отличается.
Например, слово, которое на странице обязательно должно быть, для DDG нужно брать в кавычки, а для Яндекса перед таким словом нужно ставить плюс.
Отсутствует
А не надо из строки адреса. Я же писал про использование строки поиска - её содержимое никуда не девается и никак не меняется.
Я уже забыл об этом рудименте. Только если в расширенном меню его расположить, на панели он мне не нужен. Все равно скрипт удобнее.
Отсутствует
Только если в расширенном меню его расположить
А я в панель меню засунул, и это очень удобно - поле ввода в пол-экрана длиной получается (да и то потому, что я туда же кучу кнопок от CustomButtons пристроил, а то бы строка ещё длиннее была).
Все равно скрипт удобнее.
To whom how.
Чтобы от низа страницы до тех ссылок добраться, нужно её вверх мотать, а поисковая строка доступна сразу.
Но главное - она не поломается при любом изменении дизайна страничек поисковиков.
Отредактировано yup (18-05-2025 14:29:21)
Отсутствует
Если сайты еще больше станут наглеть, то буду модифицировать их CSP или вообще удалять
Как пример. CSP утки
1) ddg: default-src 'none' ;...style-src список сайтов 'unsafe-inline';
2) ddg(no script version): default-src 'none' ;...style-src список сайтов;Во втором случае стили, добавленные в head, работать не будут
А вот интересно:
У каждой веб-странички есть document.styleSheets - псевдомассив, каждый элемент которого соответствует одному файлу .CSS или одному блоку <style> в основном .HTML. И каждый элемент этого псевдомассива, вроде бы, "read only", но при этом имеет методы addRule(), insertRule(), deleteRule(), removeRule(), и эти методы реально работают. А в результате их работы я получаю стиль, который числится загруженным из "правильного" источника, и при этом содержит нужные мне добавления и прочие изменения.
Как там распоследние к этому относятся? Позволяют такие махинации?
Отсутствует
Чтобы от низа страницы до тех ссылок добраться, нужно её вверх мотать, а поисковая строка доступна сразу
А зачем в скрипте вобще нужен PLACEHOLDER_SELECTORS? Можно меню в body добавлять, зафиксить отображение и располагать над строкой ввода. В результате при скролле страницы меню уезжать не будет.
в скрипте была сделана попытка выделять существенную часть доменного имени
Проще явно прописать самому + фильтровать массив для исключения отображения текущего сайта и поддоменов
Как там распоследние
к этому относятся? Позволяют такие махинации?
А почему нет? Из консоли пашет, значит и из скрипта можно в большинстве случаев. Xray Vision
Отсутствует
А зачем в скрипте вобще нужен PLACEHOLDER_SELECTORS?
Автору так захотелось.
Я, например, не понимаю, почему он цепляет свой блок к какому-нибудь элементу ниже строки, а не к самой строке - всё равно ведь ради неё INPUT_FIELD_SELECTORS держать приходится.
Можно меню в body добавлять, зафиксить отображение и располагать над строкой ввода.
Можно. Но, например, у Яндекса блок со строкой поиска тоже вверху страницы зафиксирован, и нужно позаботиться, чтобы эти два блока между собой согласовались. А потом ещё с каким-нибудь поисковиком дело иметь придётся, авторы которого похожий трюк применят - и нужно будет свой блок согласовывать уже с этими двумя...
Проще явно прописать самому
Зависит от того, как автор рассматривает свой скрипт.
Если как болванку, которую каждый "конечный пользователь" перепиливает под себя, то да, "достаточно было бы 20-ти строчек кода". Всё равно ведь тот, кто ищет на google.ru, не полезет на google.nl.
А если как нечто универсальное, во что этот самый "конечный пользователь" вмешивается по-минимуму, то тоже можно заниматься не этим дурацким сравнением домена со строками показываемых имён, а использовать те @include и @match, которые прописаны в заголовке скрипта.
Но ведь: "скрипт так себе, на троечку".
yup пишетКак там распоследние
к этому относятся? Позволяют такие махинации?
А почему нет?
В раже борьбы за чистоту крови CSP могли и отобрать такую возможность.
А то ведь у меня так и скрипты, загруженные с сайта, подменяются: загоняю любому элементу массива document.scripts в .text что-то своё, и пожалуйста - скрипт мой, а источником сайт числится.
Отредактировано yup (Вчера 17:13:14)
Отсутствует
Но, например, у Яндекса блок со строкой поиска тоже вверху страницы зафиксирован, и нужно позаботиться, чтобы эти два блока между собой согласовались
положение меню можно стилями регулировать и добиться оптимала
Вот, можно от
// ==UserScript== // @name ASE // @description Adds search on other sites for google, bing, yandex, duckduckgo // @version 0.3.3 // @author IgnorAmus // @match http*://yandex.ru/yandsearch* // @match http*://ya.ru/*search* // @match http*://www.google.com/search* // @match http*://www.google.ru/search* // @match http*://www.bing.com/search* // @match http*://duckduckgo.com/* // @match http*://html.duckduckgo.com/* // @grant none // @noframes // ==/UserScript== // 2025-05-16 FF138+ ((id, cssOut, cssIn, filterArray, siteObj) => { 'use strict'; var ENGINES = [ { name: "Yandex", key: "yandex", host: "yandex.ru", lnk: "https://yandex.ru/yandsearch?text=", inputSel: ".HeaderForm-Input", }, { name: "Google", key: "google", host: "www.google.com", lnk: "https://www.google.com/search?q=", inputSel: "textarea[name='q']", }, { name: "DuckDuckGo", key: "duckduckgo", host: "duckduckgo.com", lnk: "https://duckduckgo.com/?q=", inputSel: "#search_form_input", }, { name: "Bing", key: "bing", host: "www.bing.com", lnk: "https://www.bing.com/search?q=", inputSel: "#sb_form_q", }, { name: "HtmlDuckDuckGo", key: "duckduckgo", host: "html.duckduckgo.com", lnk: "https://html.duckduckgo.com/html?q=", inputSel: "#search_form_input_homepage", }, { name: "Ya", key: "yandex", host: "ya.ru", lnk: "https://ya.ru/yandsearch?text=", inputSel: ".HeaderForm-Input", }, ]; if(document.getElementById(id)) { alert("повтор"); return; } var searchText = (() => { siteObj = ENGINES.find(x => x.host === location.hostname); var text = document.querySelector(siteObj.inputSel).value; return encodeURIComponent(text); })(); filterArray = ENGINES.filter( obj => filterArray.includes(obj.key) ? false : filterArray.push(obj.key) ).filter(obj => obj.key !== siteObj.key); var div = document.createElement("div"); div.id = id; div.style.cssText = cssOut; filterArray.forEach(obj => { var a = document.createElement('a'); a.target = '_blank'; a.href = obj.lnk + searchText; a.textContent = obj.name; a.style.cssText = cssIn; div.appendChild(a); }); document.body.appendChild(div); })( "oeid-box", ` position: fixed; inset: 0 0 0 60%; z-index: 123456; `, ` margin-inline-end: 1em; text-decoration: none; `, [] );
Отсутствует
положение меню можно стилями регулировать и добиться оптимала
Можно. Но согласовать между собой скрипт и два разных сайта может оказаться намного труднее, чем скрипт и только один сайт.
Фильтрация по key
Я и говорю: всю зависит от того, насколько автор хочет сделать свой скрипт универсальным.
Например, как быть с этим вариантом скрипта тому, кто задумается: "Меня же может по ссылкам с разных форумов, stackoverflow и других злачных мест на хрен знает какой Гугл занести. Как сделать, чтобы на любом из них ссылки добавлялись?"
В общем, браузерная строка поиска - rulezz.
Отсутствует
кто ищет на google.ru, не полезет на google.nl
Теперь все полезут на google.com - гугл отменил национальные домены . Какое то время они оставлены зеркалами универсального поиска , а потом будут ликвидирваны .
Это касается не только поиска .
Отредактировано AlAvis (Вчера 19:14:59)
Отсутствует