Пишем сами расширение для Chrome: смена цвета социальной сети
Ожидает приглашения
Добрый день, дорогие посетители хабра. Однажды мне приелся стандартный цвет Вконтакте и я решил изменить эту ситуацию. Начал двигаться в сторону написания расширения. Почему именно Вконтакте? А потому что весь сайт выдержан в одном цвете.
А началось все примерно год назад, когда я начал экспериментировать с расширениями для Chrome. Сперва я просто хотел сделать несколько предустановленных цветов — красный, серый и т.п. Идей реализаций было много.
Сперва хотел получать все css файлы и менять коды HEX-коды цветов в них и подключать 1 css файл с полностью измененными цветами, но столкнулся с проблемами. Во-первых, надо было каждый раз мониторить новые css, т.к. все завязано на них, исключить определенные цвета, которые перекрывались другими стилями, что очень затратно по времени, учитывая размеры их CSS. Во-вторых, покраска изображений, если предустановленные стили, то можно и заранее перекрасить все иконки, но опять же нужно мониторить сайт на наличие новых. В итоге я забросил эту идею на некоторое время.
Через пол года я опять вернулся к этому расширению, но уже с другой позиции. Мне захотелось не только несколько цветов. Мне захотелось сделать выбор любого цвета. И я начал искать пути решения. Через несколько дней поиска решения я наткнулся на статью про фильтры изображений. И решил попробовать использовать их.
Сразу же заметил фильтр
Применил на тег и получил хорошую картину :)

Вроде бы все круто, здорово, но вот только фильтр накладывается на всю страницу и красит даже изображения. А что будет, если я добавлю тот же фильтр на тег , но только со знаком минус? Получилось как раз то, что нужно.

Осталось дело за малым — написать само расширение. Тут мне помогла документация гугла.
Сперва я создал popup окно расширения, в котором можно было бы выбирать нужный цвет и сохранять его.
popup.js:
Сохранение и получение происходит посредством chrome.storage.local.
popup.html
Результат:

Теперь надо было запустить расширение непосредственно на страницах ВК.
Для моментального изменения цвета без перезагрузки использовал chrome.tabs.query и chrome.tabs.executeScript
Как можно было увидеть в коде выше, добавил черно-белое оформление(к сожалению, изображения так же стали ч/б) и контрастную, в ней пришлось правда сделать текст жирным, т.к. иначе было трудно читать.
Мой код очень далек от совершенства, т.к. мне многому еще надо научиться, а так же я очень торопился и делал исключительно для себя, но друзья попросили выложить в chrome.store.
Исходники расширения — http://joxi.ru/25-AUtg5CbD2GC7gFmU
Страница с расширением в chrome.store — https://chrome.google.com/webstore/detail/vk-color-changer....../jmdenoijfejikcljfggmiijccnmdifjj
А началось все примерно год назад, когда я начал экспериментировать с расширениями для Chrome. Сперва я просто хотел сделать несколько предустановленных цветов — красный, серый и т.п. Идей реализаций было много.
Сперва хотел получать все css файлы и менять коды HEX-коды цветов в них и подключать 1 css файл с полностью измененными цветами, но столкнулся с проблемами. Во-первых, надо было каждый раз мониторить новые css, т.к. все завязано на них, исключить определенные цвета, которые перекрывались другими стилями, что очень затратно по времени, учитывая размеры их CSS. Во-вторых, покраска изображений, если предустановленные стили, то можно и заранее перекрасить все иконки, но опять же нужно мониторить сайт на наличие новых. В итоге я забросил эту идею на некоторое время.
Через пол года я опять вернулся к этому расширению, но уже с другой позиции. Мне захотелось не только несколько цветов. Мне захотелось сделать выбор любого цвета. И я начал искать пути решения. Через несколько дней поиска решения я наткнулся на статью про фильтры изображений. И решил попробовать использовать их.
Сразу же заметил фильтр
-webkit-filter: hue-rotate(Xdeg);
Применил на тег и получил хорошую картину :)

Вроде бы все круто, здорово, но вот только фильтр накладывается на всю страницу и красит даже изображения. А что будет, если я добавлю тот же фильтр на тег , но только со знаком минус? Получилось как раз то, что нужно.

Осталось дело за малым — написать само расширение. Тут мне помогла документация гугла.
Сперва я создал popup окно расширения, в котором можно было бы выбирать нужный цвет и сохранять его.
popup.js:
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('#grey').addEventListener('click', save_options);
document.querySelector('#invert').addEventListener('click', save_options);
});
chrome.storage.local.get('vkColorChanger', function(result){
var values = result['vkColorChanger'];
values = JSON.parse(values);
if(values.grey =='on'){
document.getElementById('grey').click();
}
if(values.invert =='on'){
document.getElementById('invert').click();
invert(1);
}
document.querySelector('#hue-deg').value = values['hue-deg'];
});
function invert(val) {
data = "#block_picker,canvas{-webkit-filter: invert("+val+");}";
var css = document.getElementById("VKcolorChanger");
if(css){
css.innerHTML = data;
}else{
var css = document.createElement("style");
css.setAttribute("type", "text/css");
css.setAttribute("rel", "stylesheet");
css.setAttribute("id", "VKcolorChanger");
css.innerHTML = data;
document.getElementsByTagName("head")[0].appendChild(css);
}
}
function save_options(e) {
var deg = e;
var values = new Object();
values['hue-deg'] = document.querySelector('#hue-deg').value;
if(document.querySelector('#grey').checked){
values['grey'] = document.querySelector('#grey').value;
}else{
values['grey'] = "";
}
if(document.querySelector('#invert').checked){
values['invert'] = document.querySelector('#invert').value;
invert(1);
}else{
values['invert'] = "";
invert(0);
}
values = JSON.stringify(values);
chrome.storage.local.set({'vkColorChanger': values});
/**Изменение всех открытых вкладок */
chrome.tabs.query({'url': 'http://vk.com/*'}, function(tabs) {
for(var i = 0;i<tabs.length;i++){
chrome.tabs.executeScript(tabs[i].id, {file : "bg.js"});
}
});
}
Сохранение и получение происходит посредством chrome.storage.local.
popup.html
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script type="text/javascript" src="js/lib.js"></script>
<script src="popup.js"></script>
</head>
<body>
<div class="picker" id="primary_block" >
<div id="line">
<div id="arrows">
<div class="left_arrow"></div>
<div class="right_arrow"></div>
</div>
</div>
<div id="block_picker"></div>
<input type="hidden" id="hue-deg" />
</div>
<div class="options">
<h4>Дополнительные настройки</h4>
<label>Черно-белый <input type="checkbox" id="grey" name="grey" onclick="save_options()"/> </label><br>
<label>Инвертирование <input type="checkbox" id="invert" name="invert" onclick="save_options()"/> </label>
</div>
<p id="message"></p>
<script type="text/javascript" src="js/picker.js"></script>
</body>
</html>
Результат:

Теперь надо было запустить расширение непосредственно на страницах ВК.
// Получаем цвета
chrome.storage.local.get('vkColorChanger', function(result){
var values = result['vkColorChanger'];
values = JSON.parse(values);
var filter = "-webkit-filter:";
var filterReverse = "-webkit-filter:";
additionalParam = "";
var deg = parseInt(values['hue-deg'])+145;
if (values.grey == "on") {
deg = 0;
filter += " grayscale(100%) contrast(120%)";
filterReverse += " grayscale(100%) contrast(120%)";
}
if(values.invert == "on"){
filter += " invert(1)";
additionalParam += "font-weight:bold !important";
filterReverse += " invert(1)";
}
filter += " hue-rotate("+deg+"deg)";
filterReverse += " hue-rotate("+(-deg)+"deg)";
// Формируем CSS
data = "html{"+filter+";}"+
"body{"+additionalParam+";}"+
"img{"+filterReverse+";}"+
".video_image_div{"+filterReverse+";}"+
".video_external_inline{"+filterReverse+";}"+
".page_doc_photo{"+filterReverse+";}"+
"#mv_content{"+filterReverse+";}"+
".page_video_inline_wrap{"+filterReverse+";}"+
".wall_module td.page_media_link_thumb{"+filterReverse+";}";
//Вставляем в страницу или заменяем существующий
var css = document.getElementById("VKcolorChanger");
if(css){
css.innerHTML = data;
}else{
var css = document.createElement("style");
css.setAttribute("type", "text/css");
css.setAttribute("rel", "stylesheet");
css.setAttribute("id", "VKcolorChanger");
css.innerHTML = data;
document.getElementsByTagName("head")[0].appendChild(css);
}
});
Для моментального изменения цвета без перезагрузки использовал chrome.tabs.query и chrome.tabs.executeScript
/**Изменение всех открытых вкладок */
chrome.tabs.query({'url': 'http://vk.com/*'}, function(tabs) {
for(var i = 0;i<tabs.length;i++){
chrome.tabs.executeScript(tabs[i].id, {file : "bg.js"});
}
});
Как можно было увидеть в коде выше, добавил черно-белое оформление(к сожалению, изображения так же стали ч/б) и контрастную, в ней пришлось правда сделать текст жирным, т.к. иначе было трудно читать.
Мой код очень далек от совершенства, т.к. мне многому еще надо научиться, а так же я очень торопился и делал исключительно для себя, но друзья попросили выложить в chrome.store.
Исходники расширения — http://joxi.ru/25-AUtg5CbD2GC7gFmU
Страница с расширением в chrome.store — https://chrome.google.com/webstore/detail/vk-color-changer....../jmdenoijfejikcljfggmiijccnmdifjj