Firefox Bootstrapped Extensions:命名空间

时间:2014-06-25 18:25:00

标签: javascript firefox firefox-addon firefox-addon-restartless

我正在研究引导扩展。看一下这些扩展的代码,我看到很多变量,常量和变量。函数声明。

它们都是在窗口对象中声明的吗? 命名空间污染/冲突是否存在问题?

我将一个对象/命名空间中的每一件事都包装在我已完成的叠加扩展中。 在这方面引导扩展是否有所不同?

我注意到所有bootstrapped.js都使用相同/标准的函数名称。这是否意味着引导扩展是沙盒还是其范围包含在内?

1 个答案:

答案 0 :(得分:3)

bootstrap.js范围

  

它们都是在窗口对象中声明的吗?命名空间污染/冲突是否存在问题?

     

...

     

我注意到所有bootstrapped.js都使用相同/标准的函数名称。这是否意味着引导扩展是沙盒还是其范围包含在内?

要扩展@paa评论:bootstrap.js确实得到了它自己的范围。

AddonManager将根据bootstrap.js创建一个新范围(如果您愿意,还可以创建“命名空间”)。现在,实现使用Components.utils.Sandbox,但这是一个实现细节。

这意味着没有window个对象。每个Firefox进程都会加载bootstrap.js一次,并且没有window个对象。这与覆盖脚本非常不同,覆盖脚本将在每个新窗口中加载一次,并与Firefox代码和其他附加组件的覆盖脚本共享一个公共范围(window对象本身)。

这也意味着自举附加组件可以在其范围内自由选择他们喜欢的名称(他们的个人沙箱),而不必担心与其他附加组件发生冲突,只要名称是一般在Javascript中有效。

唯一的例外是

  • 加载项必须实现加载项管理器将调用的入口点函数名称,因此具有特殊含义(startupshutdowninstall,{{1} }),
  • uninstallSandbox)附带的预定义内容,以及ComponentsObjectString,{{内置Javascript内置插件1}}等等。)
  • Array将注入的内容(例如MapAddonManager__SCRIPT_URI_SPEC__常量。)

Firefox 30中的预定义名称的完整列表:

ADDON_*

操纵其他范围

然而,引导加载项仍然需要考虑并避免与其他作用域交互时的冲突,例如windows,JS代码模块,其他附加引导程序范围等。操纵其他作用域也可能导致附加引导程序范围泄漏。

E.g。

APP_*

这会将Components.utils.reportError(Object.getOwnPropertyNames(this).join(", ")); // Object, Function, eval, Components, XPCNativeWrapper, dump, debug, // importFunction, IDBCursor, IDBCursorWithValue, EventTarget, IDBDatabase, // IDBFactory, FileHandle, IDBFileHandle, IDBIndex, IDBKeyRange, // IDBObjectStore, IDBRequest, IDBOpenDBRequest, IDBTransaction, Event, // IDBVersionChangeEvent, indexedDB, APP_STARTUP, APP_SHUTDOWN, ADDON_ENABLE, // ADDON_DISABLE, ADDON_INSTALL, ADDON_UNINSTALL, ADDON_UPGRADE, // ADDON_DOWNGRADE, Worker, ChromeWorker, __SCRIPT_URI_SPEC__, undefined, // Array, Boolean, JSON, Date, Math, isNaN, isFinite, parseFloat, parseInt, // NaN, Infinity, Number, String, escape, unescape, uneval, decodeURI, // encodeURI, decodeURIComponent, encodeURIComponent, RegExp, Error, // InternalError, EvalError, RangeError, ReferenceError, SyntaxError, // TypeError, URIError, Iterator, StopIteration, Int8Array, Uint8Array, // Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, // Float64Array, Uint8ClampedArray, DataView, ArrayBuffer, Proxy, WeakMap, // Map, Set, Intl 属性添加到共享Cu.import("resource://gre/modules/Services.jsm"); Services.foo = "bar"; 代码模块中的foo对象。 所有其他加载项和浏览器代码也会看到Services,因此它可能会导致冲突,而常规不会污染共享命名空间 -rules apply。

此外,当您的加载项获得Services.jsm时,您必须再次删除Services.foo,否则shutdown范围将保留对它的引用,并且因为Services.foo的值{1}}(字符串Services.jsm)存在于引导隔离专区中,由于该引用而保持引导隔离,并且有效地创建内存泄漏(在mozilla俚语中称为Zombie compartments)。 / p>

或者

foo

这相当于具有以下的重叠脚本:

"bar"

两者都会向浏览器窗口范围添加新名称// Get the most recent browser window var browserWindow = Services.wm.getMostRecentWindow("navigator:browser"); browserWindow.doSomething = function() { browserWindow.alert("hello world"); }; ,因此该名称可能与其他加载项冲突,而不会污染共享命名空间 -rules apply。 同样,这可能会以与前一个示例相同的方式泄漏,因此引导加载项必须再次删除function doSomething() { alert("hello world"); } 上的属性以避免这种情况。