Страницы: 1
При заливке расширения на Мозиллу (https://addons.mozilla.org/ru/firefox/) оно проходит автоматическое тестирование.
После тестов можно посмотреть отчет. В отчете постоянно присутствуют предупреждения о том что расширение загрязняет глобальную область видимости,
то есть создает глобальные переменные. Например протестировав такой вот код:
nsRDS.uniqueName = (function () { var uniqueA, uniqueB, uniqueC; return { methodA : function () { uniqueA = 'test A'; uniqueA += ' string'; console.log(uniqueA); }, methodB : function () { uniqueB = 'test B'; uniqueB += ' 3333'; console.log(uniqueB); }, methodC : function () { uniqueC = 'test C'; uniqueC += ' ----'; console.log(uniqueC); }, methodABC : function () { console.log(uniqueA + ' @@ ' + uniqueB + ' @@ ' + uniqueC); } }; }());
мы получим ответ что переменные: uniqueA, uniqueB, uniqueC - являются глобальными. Но это не так, переменные находятся в scope анонимной функции.
Вообщем это обычное замыкание, и никаких глобальных переменных здесь не создается.
Кто как поступает в данной ситуации?
Отредактировано Magneto (13-12-2012 14:38:08)
Отсутствует
А ты попробуй описывать функции вне описания объекта. Наверное их парсер не рассчитан на такие сложности.
Затем если не выйдет попробуй описывать стандартные именованные функции, а потом присваивать их имена.
Отсутствует
Magneto
Scope анонимной функции - да. Но этот же scope одновременно и top-level scope; если этот скрипт расположен в оконном оверлее, то этот scope - scope самого окна:
nsRDS.uniqueName = (function () { var uniqueA, uniqueB, uniqueC; Components.classes["@mozilla.org/consoleservice;1"] .getService(Components.interfaces.nsIConsoleService) .logStringMessage(this); return { methodA : function () { uniqueA = 'test A'; uniqueA += ' string'; console.log(uniqueA); }, methodB : function () { uniqueB = 'test B'; uniqueB += ' 3333'; console.log(uniqueB); }, methodC : function () { uniqueC = 'test C'; uniqueC += ' ----'; console.log(uniqueC); }, methodABC : function () { console.log(uniqueA + ' @@ ' + uniqueB + ' @@ ' + uniqueC); } }; }());
- в консоль при загрузке скрипта будет выведено [object ChromeWindow]. А на АМО нервно относятся к таким инжектам.
Самый простой выход - перенести скрипт в jsm-модуль. Я сам делаю вот так (некоторая собственная переработка заметки тов. Honza):
модуль NSMediator.jsm, расположен в resource:// расширения (код приводить не стал - его достаточно много);
оверлейная библиотечка (живет в chrome):
if (typeof(somefoo)=="undefined") { var somefoo= { lib$: function() { Components.utils.import("resource://myextension/utils/NSMediator.jsm",this); // модуль namespace-медиатора // Объявление нужных глобальных свойств, импорт модулей Object.defineProperty(this, "Cc", {get: function(){ return Components.classes; }}); Object.defineProperty(this, "Ci", {get: function(){ return Components.interfaces; }}); Object.defineProperty(this, "Cu", {get: function(){ return Components.utils; }}); Object.defineProperty(this, "moduleId", {get: function(){ return "[somefoo.lib]"; }}); Components.utils.import("resource://gre/modules/Services.jsm", this); Components.utils.import("resource://gre/modules/Dict.jsm", this); } }; somefoo.lib$.prototype= { toString: function(){ return this.moduleId}, // прочие функции глобального назначения }; } if (typeof(somefoo.lib)=="undefined") somefoo.lib=new somefoo.lib$();
и оверлейно-оконный прикладной код:
somefoo.lib.someExtensionMediator.NS(function() { with(somefoo.lib) var module= { toString: function() { return "[somefoo.overlay]"; }, // и далее прикладная логика }; Object.defineProperty(this,"module",{get: function() {return module;}}); }, "overlay"); // строковый идентификатор неймспейса
Вроде как при последней загрузке на АМО их валидатор мне ничего не пенял про namespace pollution.
Отсутствует
Страницы: 1