Bug 877478 - Add a SpecialPowers API for wrapping callbacks and callback objects. r=mrbkap

This commit is contained in:
Bobby Holley 2013-06-04 19:56:41 -07:00
Родитель 2cb13b8c8a
Коммит 81e97b35a3
1 изменённых файлов: 53 добавлений и 1 удалений

Просмотреть файл

@ -58,6 +58,10 @@ function unwrapIfWrapped(x) {
return isWrapper(x) ? unwrapPrivileged(x) : x;
};
function wrapIfUnwrapped(x) {
return isWrapper(x) ? x : wrapPrivileged(x);
}
function isXrayWrapper(x) {
return Cu.isXrayWrapper(x);
}
@ -395,6 +399,24 @@ SPConsoleListener.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleListener])
};
function wrapCallback(cb) {
return function SpecialPowersCallbackWrapper() {
args = Array.prototype.map.call(arguments, wrapIfUnwrapped);
return cb.apply(this, args);
}
}
function wrapCallbackObject(obj) {
wrapper = { __exposedProps__: ExposedPropsWaiver };
for (var i in obj) {
if (typeof obj[i] == 'function')
wrapper[i] = wrapCallback(obj[i]);
else
wrapper[i] = obj[i];
}
return wrapper;
}
SpecialPowersAPI.prototype = {
/*
@ -425,10 +447,40 @@ SpecialPowersAPI.prototype = {
* properties. This is explained in a comment in the wrapper code above,
* and shouldn't be a problem.
*/
wrap: function(obj) { return isWrapper(obj) ? obj : wrapPrivileged(obj); },
wrap: wrapIfUnwrapped,
unwrap: unwrapIfWrapped,
isWrapper: isWrapper,
/*
* When content needs to pass a callback or a callback object to an API
* accessed over SpecialPowers, that API may sometimes receive arguments for
* whom it is forbidden to create a wrapper in content scopes. As such, we
* need a layer to wrap the values in SpecialPowers wrappers before they ever
* reach content.
*/
wrapCallback: wrapCallback,
wrapCallbackObject: wrapCallbackObject,
/*
* Create blank privileged objects to use as out-params for privileged functions.
*/
createBlankObject: function () {
var obj = new Object;
obj.__exposedProps__ = ExposedPropsWaiver;
return obj;
},
/*
* Because SpecialPowers wrappers don't preserve identity, comparing with ==
* can be hazardous. Sometimes we can just unwrap to compare, but sometimes
* wrapping the underlying object into a content scope is forbidden. This
* function strips any wrappers if they exist and compare the underlying
* values.
*/
compare: function(a, b) {
return unwrapIfWrapped(a) === unwrapIfWrapped(b);
},
get MockFilePicker() {
return MockFilePicker
},