28.08.2011 Chrome extensions и закрытия окна (диалога) расширения


С недавних пор мне выпал случай создать расширения для Google Chrome. И тут появился ряд нетривиальных задач, которые пришлось решить в процессе. Хочу поделиться небольшим опытом, который я приобрел в процессе:

1. При закрытии popup окошка, вызванного нажатием на значок расширения в панели Chrome мне потребовалось выполнять кое-какие действия. Логично повесить handler на событие onbeforeunload или unload объекта текущего window. Так то оно так, но не совсем. Обычные действия, внутри callback этого события отказываются выполнятся наотрез. Но! Работает взаимодействие с localStorage. Путем нехитрых умозаключений и поиска похожей проблемы на просторах интернетов появилось такое вот решение:
  1. var background = chrome.extension.getBackgroundPage();
  2. window.addEventListener('unload', function() {
  3.   background.indicator.show();
  4. }, true);
Суть метода заключается в описании действия в background странице и последующем вызове этого действия при наступлении события через объект backgroundPage. Связано это с тем, что backgroundPage расширения живет еще какое-то время после закрытия всплывающего окна расширения (около 500мс), что дает небольшое окно времени для моих целей. Код подключаемый к background.html выглядит так:
  1. function Indicator() { }
  2. Indicator.prototype.show = function() {
  3.     if (localStorage.unsubmitedCount) {
  4.         chrome.browserAction.setBadgeText({text: localStorage.unsubmitedCount});
  5.         chrome.browserAction.setTitle({title: "You have some actions to save"});
  6.     }
  7. }
  8. Indicator.prototype.update = function() {
  9.     if(!localStorage.unsubmitedCount) {
  10.         localStorage.unsubmitedCount = 1;
  11.     } else {
  12.         ++localStorage.unsubmitedCount;
  13.     }
  14. }
  15. Indicator.prototype.reset = function() {
  16.     chrome.browserAction.setBadgeText({text: ""});
  17.     chrome.browserAction.setTitle({title: "Default extension text"});
  18.     localStorage.removeItem('unsubmitedCount');
  19. }
  20. var indicator = new Indicator();