我正在研究引导扩展。看一下这些扩展的代码,我看到很多变量,常量和变量。函数声明。
它们都是在窗口对象中声明的吗? 命名空间污染/冲突是否存在问题?
我将一个对象/命名空间中的每一件事都包装在我已完成的叠加扩展中。 在这方面引导扩展是否有所不同?
我注意到所有bootstrapped.js
都使用相同/标准的函数名称。这是否意味着引导扩展是沙盒还是其范围包含在内?
答案 0 :(得分:3)
bootstrap.js
范围它们都是在窗口对象中声明的吗?命名空间污染/冲突是否存在问题?
...
我注意到所有bootstrapped.js都使用相同/标准的函数名称。这是否意味着引导扩展是沙盒还是其范围包含在内?
要扩展@paa评论:bootstrap.js
确实得到了它自己的范围。
AddonManager
将根据bootstrap.js创建一个新范围(如果您愿意,还可以创建“命名空间”)。现在,实现使用Components.utils.Sandbox
,但这是一个实现细节。
这意味着没有window
个对象。每个Firefox进程都会加载bootstrap.js
一次,并且没有window
个对象。这与覆盖脚本非常不同,覆盖脚本将在每个新窗口中加载一次,并与Firefox代码和其他附加组件的覆盖脚本共享一个公共范围(window
对象本身)。
这也意味着自举附加组件可以在其范围内自由选择他们喜欢的名称(他们的个人沙箱),而不必担心与其他附加组件发生冲突,只要名称是一般在Javascript中有效。
唯一的例外是
startup
,shutdown
,install
,{{1} }),uninstall
(Sandbox
)附带的预定义内容,以及Components
,Object
,String
,{{内置Javascript内置插件1}}等等。)Array
将注入的内容(例如Map
,AddonManager
,__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");
}
上的属性以避免这种情况。