Расширение для браузера: выводить на странице информацию о владельце из базы
Хочется сделать расширение для браузера, которое бы выводило в левом верхнем углу, например, информацию о владельце интернет-сайта из своей базы.
Например, захожу я на сайт "Одноклассников" или "Мой мир", а в углу всплывает прямоугольник, а в нём логотипчик группы mail.ru и чуть ниже фраза "принадлежит группе mail.ru". Начал разбираться как это всё организовать на примере простейшего расширения, вот его файл manifest.json: { "manifest_version": 2, "name": "Borderify", "version": "1.0", "description": "Adds a solid red border to all webpages matching mozilla.org.", "icons": { "48": "icons/border-48.png" }, "applications": { "gecko": { "id": "borderify@mozilla.org", "strict_min_version": "45.0" } }, "content_scripts": [ { "matches": ["*://*.mozilla.org/*"], "js": ["borderify.js"] } ] } И застрял. Если "в лоб", то получается, что в файле manifest.json нужно указывать все урлы из базы, а к ним соответствующий файл скипта, где будут прописываться стили для каждой группы урлов: "content_scripts": [ { "matches": ["*://*.mozilla.org/*", "*://*.google.com/*"], "js": ["borderify.js"] }, { "matches": ["*://*.opera.com/*", "*://*.stackoverflow.com/*"], "js": ["borderify_green.js"] } ] Здесь файлы скриптов borderify.js and borderify_green.js содержат стили: document.body.style.border = "5px solid red"; и document.body.style.border = "5px solid green"; соответственно. Т.е. на всех страницах первых двух сайтов с их поддоменами будет появляться красная рамочка, а у вторых двух - зелёная. Однако что-то подсказывает мне, что это неправильно, и всю эту логику нужно выносить в отдельный файл, а не держать её в файле manifest.json. Потому что групп урлов в базе может в итоге оказаться десятки-сотни, и для каждой группы свой стиль. Тогда получается в файле manifest.json всё красиво и аккуратно: "content_scripts": [ { "matches": ["<all_urls>"], "js": ["borderify.js"] } ] Осталось только разобраться, как задавать if-else условия в файле borderify.js. Кто-нибудь делал что-то подобное? Помогите вынести логику в отдельный файл. |
Цитата:
В манифесте подключите один файл ко всем адресам, а в самом файле уже определяйте какой сайт открыт и что с ним делать. Как-то так: if(location.host==='javascript.ru') document.body.style.border='solid 5px #0F0'; Можно еще сделать так: const controllers={ 'javascript.ru':()=>{ document.body.style.border='solid 5px #0F0'; }, 'google.ru':()=>{ document.body.style.color='#FFF'; } }; if(!!controllers[location.host]) controllers[location.host](); |
Цитата:
Однако вопрос с поддоменами остался - нужно явно указывать каждый поддомен сайта в этом списке. Уже с гуглом оказалось, что нужно указывать не просто 'google.ru':()=>{ document.body.style.border='solid 5px green';, а 'www.google.ru':()=>{ document.body.style.border='solid 5px green'; Нет ли возможности указать какое-нибудь выражение как в старт-посте, вроде *.google.ru? В лоб перепробовал и с host, и с hostname - не проходит... Получается, что нужно брать hostname и как-то вытаскивать из него (с помощью регулярных выражений, например) сам домен без поддоменов? |
trommo, можете с помощью регулярок, а можете просто разбить домен на части и смотреть уже по ним.
Например: const domainParts=location.host.split('.'); const secondLevelDomain=domainParts.slice(-2).join('.'); if(!!controllers[secondLevelDomain]) controllers[secondLevelDomain](); |
Я всё-таки пошел по регуляркам и получилось. Если кому интересно:
const controllers=[ { host: "(.*\.)?google\..*", action:()=>{ document.body.style.border='solid 5px red'; } }, { host: "(.*\.)?javascript\.ru", action:()=>{ document.body.style.border='solid 5px green'; } }, { host: "(.*\.)?stackoverflow\.com", action:()=>{ document.body.style.border='solid 5px blue'; } } ]; for (var i = 0; i < controllers.length; i++) if (!!location.hostname.match(controllers[i].host)) controllers[i].action(); |
Промежуточный итог, проблемы новые
В общем, свелось всё к тому, что в файле манифеста добавляются вот эти параметры:
"content_scripts": [ { "matches": ["<all_urls>"], "css": ["styles/main.css"], "js": ["whoiswhoose.js"] } ], "web_accessible_resources": [ "photos/*.png", "*.png" ] А в файле с логикой whoiswhoose.js пока вручную прописываем каждый контейнер: const controllers=[ { host: "(.*\.)?google\..*", action:()=>{ let newDiv = document.createElement('div'); newDiv.innerHTML += '<p>' + "Сергей Брин" + '</p>'; newDiv.innerHTML += "<center><img src='https://raw.githubusercontent.com/trommo/whoiswhose/master/brin.png'></center>"; newDiv.innerHTML += '<p>' + "Основатель Google, совладелец Youtube и прочих сервисов" + '</p>'; newDiv.classList.add('popup'); document.body.appendChild(newDiv); } }, { host: "(.*\.)?facebook\.com", action:()=>{ let newDiv = document.createElement('div'); newDiv.innerHTML += '<p>' + "Марк Цукерберг" + '</p>'; newDiv.innerHTML += "<center><img src='https://raw.githubusercontent.com/trommo/whoiswhose/master/zuckerberg.png'></center>"; newDiv.innerHTML += '<p>' + "Основатель Facebook" + '</p>'; newDiv.classList.add('popup'); document.body.appendChild(newDiv); } }, { host: "(.*\.)?instagram\.com", action:()=>{ let newDiv = document.createElement('div'); newDiv.innerHTML += '<p>' + "Марк Цукерберг" + '</p>'; newDiv.innerHTML += "<center><img src='https://raw.githubusercontent.com/trommo/whoiswhose/master/zuckerberg.png'></center>"; newDiv.innerHTML += '<p>' + "В 2004 году основал Facebook, с 2012 года совладелец Instagram" + '</p>'; newDiv.classList.add('popup'); document.body.appendChild(newDiv); } } ]; for (var i = 0; i < controllers.length; i++) if (!!location.hostname.match(controllers[i].host)) {controllers[i].action(); break;} Стиль, как видно из манифеста, задаётся в файле styles/main.css: .popup { color: red; position: fixed; top: 60px; left: 20px; z-index: 10000; width: 140px !important; height: 280px; opacity: 50%; background: black; border: 5px solid orange; } p { text-align: left; margin: 5px; } Вроде как–то работает, но оставляет множество вопросов: 1) Столкнулся с проблемой, что попап с информацией о владельце вытягивает часть стилей с каждого сайта, на котором он отображается (по логике скрипта). Не то, чтобы это совсем уродливо выглядело, но глаз замечает. Не подскажете, как исправить это, чтобы попап–контейнер с картинкой и текстом смотрелся более–менее одинаково на разных сайтах? 2) Также обнаружилось, что я не могу подгружать картинки из папки с аддоном/расширением. Причем подгружать из интернета с любого стороннего сайта получается, а из папки — нет. Не встречали такое? 3) Как видите, на примере трех доменов, напрашивается вывод, что данные можно хранить в отдельном файле, где будет находиться двухмерный массив: var content = [ ["(.*\.)?google\..*", "Сергей Брин", "./IMG/brin.png", "Описание Брина"], ["(.*\.)?facebook\.com", "Марк Цукерберг", "./IMG/zuckerberg.png", "Описание Цукерберга"], ["(.*\.)?instagram\.com", "Марк Цукерберг", "./IMG/zuckerberg.png", "Описание Цукерберга"] ] Тогда в скрипте с логикой можно будет оставить только лишь цикл, который будет пробегаться по этому массиву и в случае совпадения текущего домена в открытой вкладке браузера с паттерном из базы, будет подгружать имя владельца сайта, его фото и описание. Единственный минус в этом деле — проблема со случаем, когда владельцев два и более. Пока не представляю четко, как это можно автоматизировать кодом. Намётки есть, сводящиеся к трёхмерному массиву — но по–моему это уже нездорово и может серьёзно грузить браузер. |
Часовой пояс GMT +3, время: 23:20. |