Bug 988122 - Expose Promise on non-window non-worker globals. r=bholley sr=bz

This commit is contained in:
Masatoshi Kimura 2014-03-29 15:55:53 +09:00
Родитель 6b002b786e
Коммит 0102f14c73
8 изменённых файлов: 41 добавлений и 9 удалений

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

@ -14,7 +14,10 @@ Cu.import("resource://gre/modules/ContactService.jsm", imports);
Cu.import("resource://gre/modules/Promise.jsm", imports);
Cu.importGlobalProperties(["indexedDB"]);
const {
// |const| will not work because
// it will make the Promise object immutable before assigning.
// Using |let| and Object.freeze() instead.
let {
STORE_NAME,
SAVED_GETALL_STORE_NAME,
REVISION_STORE,
@ -22,6 +25,7 @@ const {
ContactService,
Promise
} = imports;
Object.freeze(imports);
let DEBUG = false;
function debug(str) {

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

@ -31,6 +31,7 @@
#include "XrayWrapper.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/dom/PromiseBinding.h"
#include "mozilla/dom/TextDecoderBinding.h"
#include "mozilla/dom/TextEncoderBinding.h"
#include "mozilla/dom/URLBinding.h"
@ -974,6 +975,7 @@ xpc::GlobalProperties::Parse(JSContext *cx, JS::HandleObject obj)
uint32_t length;
bool ok = JS_GetArrayLength(cx, obj, &length);
NS_ENSURE_TRUE(ok, false);
bool promise = Promise;
for (uint32_t i = 0; i < length; i++) {
RootedValue nameValue(cx);
ok = JS_GetElement(cx, obj, i, &nameValue);
@ -984,7 +986,9 @@ xpc::GlobalProperties::Parse(JSContext *cx, JS::HandleObject obj)
}
JSAutoByteString name(cx, nameValue.toString());
NS_ENSURE_TRUE(name, false);
if (!strcmp(name.ptr(), "indexedDB")) {
if (promise && !strcmp(name.ptr(), "-Promise")) {
Promise = false;
} else if (!strcmp(name.ptr(), "indexedDB")) {
indexedDB = true;
} else if (!strcmp(name.ptr(), "XMLHttpRequest")) {
XMLHttpRequest = true;
@ -1009,6 +1013,9 @@ xpc::GlobalProperties::Parse(JSContext *cx, JS::HandleObject obj)
bool
xpc::GlobalProperties::Define(JSContext *cx, JS::HandleObject obj)
{
if (Promise && !dom::PromiseBinding::GetConstructorObject(cx, obj))
return false;
if (indexedDB && AccessCheck::isChrome(obj) &&
!IndexedDatabaseManager::DefineIndexedDB(cx, obj))
return false;

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

@ -2756,7 +2756,7 @@ nsXPCComponents_Utils::ImportGlobalProperties(HandleValue aPropertyList,
{
RootedObject global(cx, CurrentGlobalOrNull(cx));
MOZ_ASSERT(global);
GlobalProperties options;
GlobalProperties options(false);
NS_ENSURE_TRUE(aPropertyList.isObject(), NS_ERROR_INVALID_ARG);
RootedObject propertyList(cx, &aPropertyList.toObject());
NS_ENSURE_TRUE(JS_IsArrayObject(cx, propertyList), NS_ERROR_INVALID_ARG);

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

@ -30,7 +30,7 @@
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/Exceptions.h"
#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
#include "mozilla/dom/PromiseBinding.h"
#include "mozilla/dom/TextDecoderBinding.h"
#include "mozilla/dom/TextEncoderBinding.h"
#include "mozilla/dom/DOMErrorBinding.h"
@ -47,8 +47,6 @@ using namespace mozilla::dom;
using namespace xpc;
using namespace JS;
using mozilla::dom::indexedDB::IndexedDatabaseManager;
NS_IMPL_ISUPPORTS4(nsXPConnect,
nsIXPConnect,
nsISupportsWeakReference,
@ -453,7 +451,8 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
//
// XXX Please do not add any additional classes here without the approval of
// the XPConnect module owner.
if (!TextDecoderBinding::GetConstructorObject(aJSContext, global) ||
if (!PromiseBinding::GetConstructorObject(aJSContext, global) ||
!TextDecoderBinding::GetConstructorObject(aJSContext, global) ||
!TextEncoderBinding::GetConstructorObject(aJSContext, global) ||
!DOMErrorBinding::GetConstructorObject(aJSContext, global)) {
return UnexpectedFailure(NS_ERROR_FAILURE);

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

@ -3289,9 +3289,13 @@ nsresult
ThrowAndFail(nsresult errNum, JSContext *cx, bool *retval);
struct GlobalProperties {
GlobalProperties() { mozilla::PodZero(this); }
GlobalProperties(bool aPromise) {
mozilla::PodZero(this);
Promise = true;
}
bool Parse(JSContext *cx, JS::HandleObject obj);
bool Define(JSContext *cx, JS::HandleObject obj);
bool Promise : 1;
bool indexedDB : 1;
bool XMLHttpRequest : 1;
bool TextDecoder : 1;
@ -3342,6 +3346,7 @@ public:
, proto(cx)
, sameZoneAs(cx)
, invisibleToDebugger(false)
, globalProperties(true)
, metadata(cx)
{ }

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

@ -0,0 +1,12 @@
function run_test() {
var Cu = Components.utils;
sb = new Cu.Sandbox('http://www.example.com');
sb.do_check_eq = do_check_eq;
Cu.evalInSandbox('do_check_eq(typeof new Promise(function(resolve){resolve();}), "object");',
sb);
sb = new Cu.Sandbox('http://www.example.com',
{ wantGlobalProperties: ["-Promise"] });
sb.do_check_eq = do_check_eq;
Cu.evalInSandbox('do_check_eq(typeof Promise, "undefined");', sb);
do_check_eq(typeof new Promise(function(resolve){resolve();}), "object");
}

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

@ -70,6 +70,7 @@ fail-if = os == "android"
[test_nuke_sandbox.js]
[test_sandbox_metadata.js]
[test_exportFunction.js]
[test_promise.js]
[test_textDecoder.js]
[test_url.js]
[test_sandbox_atob.js]

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

@ -5,7 +5,11 @@
// Test async-utils.js
const {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
const {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
// |const| will not work because
// it will make the Promise object immutable before assigning.
// Using |let| and Object.freeze() instead.
let {Promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
Object.freeze(Promise);
const {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
const {async, asyncOnce, promiseInvoke, promiseCall} = require("devtools/async-utils");