Chrome extension — с шахматами и библиотекаршами

от автора

Добрый день, любители ездить на чужих велосипедах, у которых нет сиденья, педали надо крутить руками, а тормоза появятся через пару релизов.

Задача:
Создать расширение для браузера Chrome, которое сможет в любой из открытых табов внедрить необходимый контент и небольшой управляющий модуль для него, и если этот контент внедрен в несколько разных табов, то управляющие модули должны иметь возможность между собой общаться.

Доступные инструменты:
Content Scripts, Background Pages, Message Passing

Алгоритм решения:
Создать общий управляющий модуль который будет создавать модули потомки и управлять ими, наладить с каждым из них механизм обратной связи.

Абстрактный пример:
Общий управляющий модуль (ОУМ), создал 3 потомка (П1, П2, П3), каждый из которых работает в отдельной вкладке. Пользователь произвел действие с П1, П1 используя механизм обратной связи отправил сообщение об этом ОУМу, ОУМ совершил необходимые действия и оповестил П2, П3 о произошедших изменениях.

Конкретный пример:
Пользователь решил в 3 табах использовать расширение, которое меняет бекграунд, в одной из них он решил что его не устраивает новый зеленый фон и он хочет что бы новый фон был светло серым. Он нажимает кнопку которая внедрилась в страницу при открытии, фон страницы меняется на серый, то же самое происходит в остальных 2 табах.

Реализация:
Создаем Background Page которая создается раз и навсегда на время жизни расширения, в нем будем держать общий управляющий модуль (ОУМ).

Когда пользователь входит на страницу и хочет использовать на ней возможности расширения, он нажимает на кнопку расширения, запуская тем самым основной функционал, который внедряет в контент выбранного таба небольшой командный модуль (КМ) (фронтенд html и бекенд javascript), также расширение производит необходимые действия c этим контентом.
main.js

chrome.tabs.executeScript(null, {file: "content_script.js"}); // внедряем командный модуль // совершаем какие то действия с контентом 

Как только модуль внедрился он посылает сообщение ОУМу.
content_script.js

chrome.extension.sendMessage({cmd: "tab_add"}, function(response) {}); // отправляем сообщение ОУМу chrome.extension.onMessage.addListener(ext_msg_listener); // создаем слушатель команд от ОУМ  function ext_msg_listener () {   var cmd = arguments[0].cmd;   ... } 

ОУМ берет из сообщения идентификатор таба и кладет его в список табов для оповещения.
background.js

chrome.extension.onMessage.addListener(   function(request, sender, send_response) {     if (request.cmd == "tab_add") {       // добавляем в список для оповещения идентификатор таба = sender.tab.id     }     ...   } ) 

При совершении пользователем действий с КМ, КМ отсылает сообщение ОУМу.
content_script.js

chrome.extension.sendMessage({cmd: "some_msg_from_km"}, function(response) {}) 

ОУМ, если это необходимо оповещает КМы из списка.
background.js

chrome.extension.onMessage.addListener(   function(request, sender, send_response) {     ...     if (request.cmd == "some_msg_from_km") {       // каждому tab_id из списка отсылаем сообщение       chrome.tabs.sendMessage(tab_id, {cmd: 'some_command_from_oum', bar: 'buz'}, null)     }     ...   } ) 

КМ слушает сообщения и услышав необходимую команду от ОУМа выполняет действия.
content_script.js

function ext_msg_listener () {   ...   if (cmd=="some_command_from_oum") {     // делаем что необходимо   } } 

Когда КМ закрывается пользователем, перед закрытием он оповещает ОУМ.
content_script.js

chrome.extension.onMessage.removeListener(ext_msg_listener); chrome.extension.sendMessage({cmd: "tab_remove"}, function(response) {}); // сообщаем ОУМу о закрытии КМ 

Соответственно из списка идентификатор таба убирается.
background.js

chrome.extension.onMessage.addListener(   function(request, sender, send_response) {     ...     if (request.cmd == "tab_remove") {       // убираем из списка оповещения идентификатор таба = sender.tab.id     }   } ) 

Немного обо мне:
Пишу фронтенды на html+js или objective-c, бекэнды на php или руби (sinatra). Люблю делать интерактивные приложения для IOS, особенно игры. В одно время надо было написать приложение с использованием OpenGL ES 2.0, но все тогда сидели на 1.1, пришлось писать свой, увлекательное было занятие, если есть конкретные вопросы по OpenGL ES 2.0 — задавайте, отвечу.

PS:
Небольшое замечание для тех, кому режет глаз смешение русского текста и иностранных названий. Я придерживаюсь позиции, что если писать название в оригинале, то будет проще искать информацию в первоисточниках.

Можно также было не отправлять сообщения каждый раз, а открыть одно постоянное соединение между КМ и ОУМ.

Если что то требует более обширного объяснение — задавайте вопросы, дополню.

ссылка на оригинал статьи http://habrahabr.ru/post/159145/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *