Полезная информация

Mozilla Россия — свежие версии программ Mozilla, а также масса полезной информации по каждому продукту.

№111-07-2015 14:01:35

ZVanoZ
Участник
 
Группа: Members
Зарегистрирован: 11-07-2015
Сообщений: 2
UA: Firefox 39.0

Как указать scope при назначении обработчика tabs.on('open', handler)?

1. Привязываем функцию к коллекции табов.

Выделить код

Код:

require('sdk/tabs').on('open', путьКМетодуВОбъектеОбкртке.handlerOpen);

2. В функции handlerOpen привязываем события к новому tab-у.

Выделить код

Код:

handlerOpen : function(tab) {
  // Тут мы потеряли ОбъектОбертку
  tab.on('pageshow', this.tab.pageshow);
  tab.on('activate', this.tab.activate);
}

Я могу завернуть код в анонимную функцию, но это некрасивое решение

Выделить код

Код:

handlerOpen : function(tab) {
  // Тут мы потеряли ОбъектОбертку
  (function(){
    // Тут мы переустановили this
    tab.on('pageshow', this.tab.pageshow);
    tab.on('activate', this.tab.activate);
  }).call(zimMain.tabs.handlers);
}

См. строку: // this ===  require('sdk/tabs'), а ожидается "zimMain.tabs.handlers"
в методе zimMain.tabs.handlers.open
Тестовый код main.js:

Выделить код

Код:

console.log('main.js', 'BEG');

var zimMain = {
    /**
     * Контейнер для инклуда элементов SDK
     */
    sdk : {
        tabs : require('sdk/tabs'),
        contextMenu : require('context-menu'),
        buttons : require('sdk/ui/button/action'),
        simpleStorage : require('simple-storage'),
        pageMod : require('page-mod'),
        querystring : require('api-utils/querystring')
    },
    application : {
        /**
         * Код, обслуживающий главное меню.
         */
        menu  : {
            run : function() {
                console.log('main.js', 'zimMain/menu/run', this);
            }
        },
        /**
         * Код, обслуживающий панель инструментов.
         */
        panel : {
            buttons : {
                visitMozilla : {
                    item : null,
                    handler : function() {
                        console.log('main.js', 'zimMain/handlerButtonClick', this);
                        //tabs.open('https://www.mozilla.org/');
                    }
                }
            },
            createMenu : function() {
                console.log('main.js', 'zimMain/panel/createMenu', this);
                this.buttons.visitMozilla.item = zimMain.sdk.buttons.ActionButton({
                    id : 'mozilla-link',
                    label : 'Visit Mozilla',
                    icon : {
                        '16' : './icon-16.png',
                        '32' : './icon-32.png',
                        '64' : './icon-64.png'
                    },
                    onClick : this.buttons.visitMozilla.handler
                });
            },
            run : function() {
                console.log('main.js', 'zimMain/run', this);
                this.createMenu();
            }
        }, 
        tabs : {
            handlers : {
                tab : {
                    pageshow : function (tab) {
                        console.log(tab.url + ' is loaded');
                    },
                    activate : function (tab) {
                        console.log(tab.url + ' is activated');
                    },
                    deactivate : function(tab) {
                        console.log(tab.url + ' is deactivated');
                    },
                    close : function(tab) {
                        console.log(tab.url + ' is closed');
                    },
                },
                open : function(tab) {
                    // this ===  require('sdk/tabs'), а ожидается "zimMain.tabs.handlers"
                    // В этом месте потреряли "zimMain/..." т.к. "zimMain.handlers.open" вызывается внутренним объектом 'sdk/tabs'
                                        // Как это побороть?
                    var scope = this;
                    console.log(tab.url + ' is open', scope, this);
                    tab.on('pageshow', this.tab.pageshow);
                    tab.on('activate', this.tab.activate);
                    tab.on('deactivate', this.tab.deactivate);
                    tab.on('close', this.tab.close);
                }
            },
            run : function() {
                // this === zimMain.tabs
                zimMain.sdk.tabs.on('open', this.handlers.open);
            }
        }
    },
    run : function() {
                // this === zimMain
        console.log('main.js/', 'zimMain/run', this);
        this.application.panel.run();
        this.application.tabs.run();
    }
}
zimMain.run();

console.log('main.js', 'END');

Попутный вопрос: есть ли примеры правильного построения расширения?
Нужен базовый каркас, который объединит разные части расширения и не будет плодить глобальных переменных.
В идеале даже каркас должен быть изолирован:
main.js

Выделить код

Код:

(function(){
  var myAddon = new TMyAddon({
    sdk : {
       // ...
    },
    helpers : {
      base64 : {
         decode : function(){},
         encode : function(){}
      }
   }
  });
  myAddon.start()
}).call(this)

Отредактировано ZVanoZ (11-07-2015 14:04:39)

Отсутствует

 

№212-07-2015 00:29:28

Infocatcher
Not found
 
Группа: Extensions
Зарегистрирован: 24-05-2007
Сообщений: 4339
UA: Firefox 39.0

Re: Как указать scope при назначении обработчика tabs.on('open', handler)?

C Add-on SDK дела практически не имел, видимо, предполагается использовать так:

Выделить код

Код:

require('sdk/tabs').on('open', путьКМетодуВОбъектеОбкртке.handlerOpen.bind(путьКМетодуВОбъектеОбкртке));

Прошлое – это локомотив, который тянет за собой будущее. Бывает, что это прошлое вдобавок чужое. Ты едешь спиной вперед и видишь только то, что уже исчезло. А чтобы сойти с поезда, нужен билет. Ты держишь его в руках. Но кому ты его предъявишь?
Виктор Пелевин. Желтая стрела

Отсутствует

 

№312-07-2015 08:43:31

ZVanoZ
Участник
 
Группа: Members
Зарегистрирован: 11-07-2015
Сообщений: 2
UA: Firefox 39.0

Re: Как указать scope при назначении обработчика tabs.on('open', handler)?

Infocatcher пишет

видимо, предполагается использовать так:

Выделить код

Код:

require('sdk/tabs').on('open', путьКМетодуВОбъектеОбкртке.handlerOpen.bind(путьКМетодуВОбъектеОбкртке));

Не понял строку кода.  путьКМетодуВОбъектеОбкртке.handlerOpen.bind(путьКМетодуВОбъектеОбкртке)
Mozilla добавляет к любой функции JS метод bind чтобы можно было указать контекст, в котором эта функция выполняется?

Выделить код

Код:

// Что-то типа:
myAddon = {
  handlerTabsOpen : function() {
  },
  run : function() {
    require('sdk/tabs').on('open', this.handlerTabsOpen.bind(this));
  }
}
myAddon.run();

PS:
Нагуглил. Этот метод является встроенным в современном JS.
javascript.ru : https://learn.javascript.ru/bind#bind
MDN : https://developer.mozilla.org/en-US/doc … ction/bind
Infocatcher, спасибо огромное.
Самое обидное, что проходил курс javascript.ru три года назад, но многое вылетело из головы :(

Отредактировано ZVanoZ (12-07-2015 08:56:32)

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]