Расширение для браузера: выводить на странице информацию о владельце из базы
Хочется сделать расширение для браузера, которое бы выводило в левом верхнем углу, например, информацию о владельце интернет-сайта из своей базы.
Например, захожу я на сайт "Одноклассников" или "Мой мир", а в углу всплывает прямоугольник, а в нём логотипчик группы 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, время: 05:44. |