Как лучше для расширения Firefox, чтобы избежать загрязнения глобального пространства имен? - PullRequest
6 голосов
/ 13 июля 2011

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

Вкратце, у меня было предложенное решение, позволяющее избежать добавления любых дополнительных переменных.в глобальное пространство имен;обернуть все в функцию.Проблема здесь в том, что в ваших XUL-оверлеях нет ничего, на что можно сослаться.Вы должны объявить элементы в ваших оверлеях, а затем в JS добавить тонну addEventListener s, чтобы заменить то, что было бы похоже на oncommand="..." в XUL.Я не хочу этого делать;Я определенно хочу, чтобы мой XUL включал события в сам XUL, потому что я думаю, что он выглядит чище, так что это не решение для меня.Поэтому мне нужна как минимум 1 глобальная переменная для атрибутов XUL oncommand="...", на которую можно ссылаться.

Таким образом, консенсус, по-видимому, состоит в том, чтобы иметь одну (и только одну) переменную для вашего расширения и поместить весь ваш код в нее.,Вот проблема: обычно люди рекомендуют называть эту переменную красивым длинным уникальным именем, чтобы иметь почти нулевую вероятность столкновения с другими переменными.Поэтому, если идентификатор моего расширения myextension@mycompany.com, я мог бы назвать свою переменную myextensionAtMycompanyDotCom или com.mycompany.myextension.Это хорошо для предотвращения коллизий в глобальном пространстве имен, но есть одна проблема;имя этой переменной длинное и громоздкое.Мой XUL будет усеян ссылками на обработчики событий в соответствии с oncommand="myextensionAtMycompanyDotCom.doSomeEvent".Нет никакого способа избежать ссылки на глобальное пространство имен в моих наложениях XUL, потому что наложение просто добавляется в DOM окна браузера;у него нет собственного пространства имен, поэтому мы не можем каким-то образом ограничить область переменных нашего расширения только нашими собственными оверлеями.Итак, на мой взгляд, есть четыре решения:

1.Просто используйте длинное имя переменной в XUL

В результате получается довольно громоздкий, подробный код XUL, такой как:

<statusbarpanel id="myStatusBar" onmousedown="myextensionAtMycompanyDotCom.onMyStatusBarClick();">

2.Добавьте элемент случайности к короткому имени переменной

Мы придумали гораздо более короткое имя переменной для нашего расширения, скажем, myExt, и добавили несколько случайных символов, чтобы сделать его почти наверняка уникальным, напримеркак myExtAX8T9.Затем в XUL мы имеем:

<statusbarpanel id="myStatusBar" onmousedown="myExtAX8T9.onMyStatusBarClick();">

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

3.Ни в коем случае не объявляйте глобальные переменные

Вы можете просто обернуть все в функции.Это, конечно, означает, что в вашем XUL нет ничего, на что можно ссылаться, и поэтому каждое событие должно быть присоединено к элементам XUL, используя addEventListener в вашем коде JavaScript.Мне не нравится это решение, потому что, как упомянуто выше, я думаю, что было бы лучше иметь ссылки на события в коде XUL, а не искать тонну кода JS, чтобы найти, какие события присоединены к каким элементам XUL.

4.Просто используйте короткое имя переменной в XUL

Я мог бы просто вызвать переменную моего расширения myExt, и затем я получил хороший код XUL, такой как:

<statusbarpanel id="myStatusBar" onmousedown="myExt.onMyStatusBarClick();">

Конечно, это короткое имягораздо более вероятно столкновение с чем-то другим в глобальном пространстве имен и поэтому не идеально.

Итак, я что-то пропустил?Есть ли альтернатива 4 решениям, которые я предложил выше?Если нет, что будет лучшим из 4 (учитывая, что № 3 в принципе неприемлем для меня) и почему?

Ответы [ 2 ]

5 голосов
/ 13 июля 2011

Мы используем шаблон модуля JavaScript, описанный в этом сообщении в блоге: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth. Вы можете экспортировать символы, которые вы хотите использовать в обработчиках XUL, как описано.

Кроме того, мы используем обратное имя хоста в качестве префикса имени модуля, чтобы гарантировать, что мы контролируем пространство имен:

/* Set up the global namespace. */
if (typeof(com) == "undefined") var com = {};
if (!com.salsitasoft) com.salsitasoft = {};

/* Main namespace. */
com.salsitasoft.myExtensionGlobalStuffGoesHere = (function (my) {
  return my;
})(com.salsitasoft.myExtensionGlobalStuffGoesHere || {});

Обновление: я изменил это, чтобы передать com.salsitasoft.myExtensionGlobalStuffGoesHere в замыкание, если оно уже существует, чтобы пространство имен можно было распределить по нескольким файлам.

1 голос
/ 13 июля 2011

Ваши функции должны где-то «жить», так что вы не можете не претендовать на какое-то пространство имен. Я также согласен с вашей точкой зрения, что лучше определить событие в XUL, чем присоединить их. Итак, я предлагаю гибрид между 3 + 4:

  • Найдите пространство имен, которое является уникальным для вашего плагина, но как можно более запоминающимся, например "catchyseo".
  • Поместите весь код вашего плагина и все переменные в это пространство имен. Используйте шаблон обертки анонимной функции, как (взгляните на некоторые плагины jQuery в качестве примеров кода):

    window.catchyseo = (function(){var private = x; [...] })();
    
  • В вашем пространстве имен предоставьте некоторые обработчики событий, на которые вы можете ссылаться в вашем XUL.

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

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