Иметь один мозг в аддоне Firefox?

У меня есть аддон, который каждые 5 минут или около того проверяет rss-канал на наличие нового поста, и если он есть, он отображает предупреждение(). Проблема в том, что я боюсь, что если пользователь откроет несколько окон, при появлении нового сообщения появятся миллионы предупреждений, говорящих одно и то же. Возможно ли, чтобы одновременно работал только один «мозг»?

Заранее спасибо!


person mattsven    schedule 08.01.2010    source источник


Ответы (2)


Найдите что-нибудь под названием «Общие модули кода Javascript» или JSM.

Основные документы здесь:

https://developer.mozilla.org/En/Using_JavaScript_code_modules

Каждый файл .js в вашем аддоне, которому требуется общая память, будет открываться со следующей строкой:

Components.utils.import("resource://xxxxxxxx/modules/[yourFilenameHere].jsm", com.myFirefoxAddon.shared);

Приведенная выше строка открывает [yourFilenameHere].jsm и загружает его экспортированные (см. ниже) функции и переменные в объект com.myFirefoxAddon.shared. Каждый загруженный экземпляр этого объекта будет указывать на один и тот же экземпляр в памяти.

Обратите внимание, что если вы хотите надеяться, что ваш аддон пройдет модерацию, вам нужно будет написать весь свой код в объекте типа com.myFirefoxAddon.*, поскольку головорезы в AMO предотвращают одобрение аддонов, которые не Учитывать глобальное пространство имен

Самое большое предостережение для JSM заключается в том, что вам нужно вручную экспортировать каждую функцию, которую вы хотите сделать доступной для остальной части вашего кода... поскольку JS не поддерживает публичный/частный тип, это кажется мне чем-то вроде бедняка. «общедоступная» поддержка... в любом случае вам нужно будет создать массив EXPORTED_SYMBOLS где-нибудь в вашем JSM-файле и назвать каждую функцию или объект, который вы хотите экспортировать, например:

var EXPORTED_SYMBOLS = [
    /* CONSTANTS */
    "SERVER_DEBUG",
    "SERVER_RELEASE",

    "LIST_COUNTRIES",
    "LIST_TERRITORIES_NOEX",

    /* GLOBAL VARIABLES */
    /* note: primitive type variables need to be stored in the globals object */
    "urlTable",
    "globals",

    /* INTERFACES */
    "iStrSet",

    /* FUNCTIONS */
    "globalStartup",

    /* OBJECTS */
    "thinger",
    "myObject"

]
person Tom Corelis    schedule 08.01.2010
comment
Вау... звучит сложно, я думаю, это потому, что я только начинаю. Возможно, вы могли бы дать мне сценарий, чтобы помочь мне понять..? - person mattsven; 09.01.2010
comment
Подожди секунду. Если подумать, не могу ли я просто запустить скрытый диалог или что-то в этом роде и оставить в нем свой код..? - person mattsven; 09.01.2010
comment
Вместо того, чтобы экспортировать множество вещей, вы можете просто экспортировать один объект и назначить его com.myFirefoxAddon.shared. - person Nickolay; 09.01.2010
comment
Конечно, вы можете, однако я предпочитаю этот метод, поскольку он меньше печатает, когда вы делаете другой код. - person Tom Corelis; 09.01.2010
comment
@motionman95 на самом деле это довольно просто, как только вы освоитесь. Мне пришлось изучить этот материал, когда я только начинал... так что это не невозможно. Ты можешь это сделать! ... также я бы не советовал делать скрытые окна... это... грязно - person Tom Corelis; 09.01.2010
comment
@Tom, поскольку теперь я согласен с тем, что для этого можно использовать модули JS, я думаю, было бы неплохо привести реальный пример использования JSM в качестве мозга, а не просто общей памяти. К сожалению, в настоящее время в документах MDC нет таких примеров. - person Nickolay; 09.01.2010
comment
@Nickolay На самом деле это довольно просто. Внимательно изучите документы MDC... вы можете запускать любой javascript внутри JSM, если вам не нужен доступ к DOM... Функции DOM необходимо заменить их эквивалентами XPCOM. В противном случае это довольно просто... JSM действует как статический объектный класс для всего кода, в котором он создан. - person Tom Corelis; 19.01.2010
comment
Также хотелось бы отметить, что для использования таймеров внутри JSM вам необходимо использовать nsiTimers, поскольку SetInterval() и SetTimeout() являются частью DOM. Я не пробовал это, но я думаю, что вы можете использовать свой таймер JSM для запуска события, на которое могут подписаться отдельные окна. - person Tom Corelis; 19.01.2010

[отредактировано] Модули не являются правильным решением этой проблемы, поскольку код по-прежнему будет импортироваться в каждое окно, а любые установленные вами слушатели/таймеры будут работать в каждом окне. Вы должны будьте осторожны с использованием модулей для этого - все таймеры/обратные вызовы должны быть настроены в коде модуля (а не только с использованием объекта-наблюдателя, определенного в модуле), и вы не должны использовать какие-либо ссылки на окно в модуле.< /эм>

Правильный способ сделать это Я бы предпочел написать компонент XPCOM (на JS). Это несколько сложно, да, и у меня нет удобной ссылки, объясняющей, как это сделать. Одна вещь: реализовать это с помощью XPCOMUtils проще, старая документация набросает на вас много шаблонного кода.

person Nickolay    schedule 08.01.2010
comment
я не проверял; не будет ли второй импорт просто повторно использовать пространство имен без повторного запуска кода? - person Tobu; 09.01.2010
comment
Прошу не согласиться. Модули кода загружаются один раз во время всего процесса Firefox, не требуют стандартного создания экземпляра COM и не требуют дополнительных настроек, кроме того, что я упомянул. Если вы покопаетесь в исходном коде множества аддонов версии 3.0+, то увидите, как они использовали общую память. - person Tom Corelis; 09.01.2010
comment
На практике я держусь подальше от COM, когда это возможно. Наверное, хочу принять это во внимание - person Tom Corelis; 09.01.2010
comment
Я забираю комментарий о неправильном решении обратно, извините. Я до сих пор думаю, что рассуждать о модулях сложнее, чем о компонентах XPCOM, но, возможно, это просто потому, что я провел несколько лет с последними :) - person Nickolay; 09.01.2010
comment
FWIW, я также предпочитаю компонентное решение XPCOM, хотя другое тоже допустимо. - person Tobu; 10.01.2010