Merge m-c to b2g-inbound

This commit is contained in:
Wes Kocher 2014-06-11 18:50:50 -07:00
commit 6840fd7537
211 changed files with 3141 additions and 1388 deletions

View File

@ -213,7 +213,8 @@ this.ContentControl.prototype = {
let focusedAcc = Utils.AccRetrieval.getAccessibleFor(
this.document.activeElement);
if (focusedAcc && focusedAcc.role === Roles.ENTRY) {
if (focusedAcc && this.vc.position === focusedAcc
&& focusedAcc.role === Roles.ENTRY) {
let accText = focusedAcc.QueryInterface(Ci.nsIAccessibleText);
let oldOffset = accText.caretOffset;
let newOffset = aMessage.json.offset;

View File

@ -50,7 +50,7 @@ let inputTests = [
{
input: "testDOMException()",
output: 'DOMException [SyntaxError: "An invalid or illegal string was specified"',
printOutput: '[object XrayWrapper [object DOMException]]"',
printOutput: '"SyntaxError: An invalid or illegal string was specified"',
inspectable: true,
variablesViewLabel: "SyntaxError",
},

View File

@ -2087,9 +2087,10 @@ public:
const nsAString& aTypeExtension,
uint32_t aNamespaceID,
mozilla::ErrorResult& rv) = 0;
virtual JSObject*
virtual void
RegisterElement(JSContext* aCx, const nsAString& aName,
const mozilla::dom::ElementRegistrationOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv) = 0;
/**

View File

@ -1617,12 +1617,14 @@ public:
// HasAttributes is defined inline in Element.h.
bool HasAttributes() const;
nsDOMAttributeMap* GetAttributes();
JS::Value SetUserData(JSContext* aCx, const nsAString& aKey,
JS::Handle<JS::Value> aData,
nsIDOMUserDataHandler* aHandler,
mozilla::ErrorResult& aError);
JS::Value GetUserData(JSContext* aCx, const nsAString& aKey,
mozilla::ErrorResult& aError);
void SetUserData(JSContext* aCx, const nsAString& aKey,
JS::Handle<JS::Value> aData,
nsIDOMUserDataHandler* aHandler,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
void GetUserData(JSContext* aCx, const nsAString& aKey,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
// Helper method to remove this node from its parent. This is not exposed
// through WebIDL.

View File

@ -25,8 +25,7 @@ NS_IMPL_RELEASE_INHERITED(FileIOObject, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileIOObject)
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_CLASS(FileIOObject)
@ -35,16 +34,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileIOObject,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mProgressNotifier)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
// Can't traverse mChannel because it's a multithreaded object.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileIOObject,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mProgressNotifier)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_EVENT_HANDLER(FileIOObject, abort)
NS_IMPL_EVENT_HANDLER(FileIOObject, error)
NS_IMPL_EVENT_HANDLER(FileIOObject, progress)
@ -141,29 +138,31 @@ FileIOObject::Notify(nsITimer* aTimer)
return NS_OK;
}
// nsIStreamListener
// InputStreamCallback
NS_IMETHODIMP
FileIOObject::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
FileIOObject::OnInputStreamReady(nsIAsyncInputStream* aStream)
{
return DoOnStartRequest(aRequest, aContext);
}
if (mReadyState != 1 || aStream != mAsyncStream) {
return NS_OK;
}
NS_IMETHODIMP
FileIOObject::DoOnStartRequest(nsIRequest *request, nsISupports *ctxt)
{
return NS_OK;
}
uint64_t aCount;
nsresult rv = aStream->Available(&aCount);
NS_IMETHODIMP
FileIOObject::OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount)
{
nsresult rv;
rv = DoOnDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_SUCCEEDED(rv) && aCount) {
rv = DoReadData(aStream, aCount);
}
if (NS_SUCCEEDED(rv)) {
rv = DoAsyncWait(aStream);
}
if (!aCount || NS_FAILED(rv)) {
if (rv == NS_BASE_STREAM_CLOSED) {
rv = NS_OK;
}
return OnLoadEnd(rv);
}
mTransferred += aCount;
@ -180,15 +179,9 @@ FileIOObject::OnDataAvailable(nsIRequest *aRequest,
return NS_OK;
}
NS_IMETHODIMP
FileIOObject::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
nsresult aStatus)
nsresult
FileIOObject::OnLoadEnd(nsresult aStatus)
{
// If we're here as a result of a call from Abort(),
// simply ignore the request.
if (aRequest != mChannel)
return NS_OK;
// Cancel the progress event timer
ClearProgressEventTimer();
@ -196,8 +189,7 @@ FileIOObject::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
mReadyState = 2;
nsString successEvent, termEvent;
nsresult rv = DoOnStopRequest(aRequest, aContext, aStatus,
successEvent, termEvent);
nsresult rv = DoOnLoadEnd(aStatus, successEvent, termEvent);
NS_ENSURE_SUCCESS(rv, rv);
// Set the status field as appropriate
@ -213,6 +205,15 @@ FileIOObject::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
return NS_OK;
}
nsresult
FileIOObject::DoAsyncWait(nsIAsyncInputStream* aStream)
{
return aStream->AsyncWait(this,
/* aFlags*/ 0,
/* aRequestedCount */ 0,
NS_GetCurrentThread());
}
void
FileIOObject::Abort(ErrorResult& aRv)
{

View File

@ -7,12 +7,11 @@
#define FileIOObject_h__
#include "mozilla/DOMEventTargetHelper.h"
#include "nsIChannel.h"
#include "nsIFile.h"
#include "nsIDOMFile.h"
#include "nsIStreamListener.h"
#include "nsITimer.h"
#include "nsCOMPtr.h"
#include "nsIAsyncInputStream.h"
#include "mozilla/dom/DOMError.h"
@ -29,7 +28,7 @@ extern const uint64_t kUnknownSize;
// A common base class for FileReader and FileSaver
class FileIOObject : public DOMEventTargetHelper,
public nsIStreamListener,
public nsIInputStreamCallback,
public nsITimerCallback
{
public:
@ -61,26 +60,21 @@ public:
NS_DECL_NSITIMERCALLBACK
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIINPUTSTREAMCALLBACK
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FileIOObject, DOMEventTargetHelper)
protected:
// Implemented by the derived class to do whatever it needs to do for abort
virtual void DoAbort(nsAString& aEvent) = 0;
// for onStartRequest (this has a default impl since FileReader doesn't need
// special handling
NS_IMETHOD DoOnStartRequest(nsIRequest *aRequest, nsISupports *aContext);
// for onStopRequest
NS_IMETHOD DoOnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
nsresult aStatus, nsAString& aSuccessEvent,
nsAString& aTerminationEvent) = 0;
// and for onDataAvailable
NS_IMETHOD DoOnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
nsIInputStream *aInputStream, uint64_t aOffset,
uint32_t aCount) = 0;
virtual nsresult DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount) = 0;
virtual nsresult DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent,
nsAString& aTerminationEvent) = 0;
nsresult OnLoadEnd(nsresult aStatus);
nsresult DoAsyncWait(nsIAsyncInputStream* aStream);
void StartProgressEventTimer();
void ClearProgressEventTimer();
@ -91,8 +85,9 @@ protected:
bool mProgressEventWasDelayed;
bool mTimerIsActive;
nsCOMPtr<nsIAsyncInputStream> mAsyncStream;
nsRefPtr<DOMError> mError;
nsCOMPtr<nsIChannel> mChannel;
uint16_t mReadyState;

View File

@ -10,41 +10,25 @@
#include "nsDOMClassInfoID.h"
#include "nsDOMFile.h"
#include "nsError.h"
#include "nsIConverterInputStream.h"
#include "nsIDocument.h"
#include "nsIFile.h"
#include "nsIFileStreams.h"
#include "nsIInputStream.h"
#include "nsIMIMEService.h"
#include "nsIUnicodeDecoder.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsLayoutCID.h"
#include "nsXPIDLString.h"
#include "nsReadableUtils.h"
#include "nsIURI.h"
#include "nsStreamUtils.h"
#include "nsXPCOM.h"
#include "nsIDOMEventListener.h"
#include "nsJSEnvironment.h"
#include "nsIScriptGlobalObject.h"
#include "nsCExternalHandlerService.h"
#include "nsIStreamConverterService.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsHostObjectProtocolHandler.h"
#include "mozilla/Base64.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/EncodingUtils.h"
#include "mozilla/dom/FileReaderBinding.h"
#include "xpcpublic.h"
#include "nsIScriptSecurityManager.h"
#include "nsDOMJSUtils.h"
#include "jsfriendapi.h"
#include "nsITransport.h"
#include "nsIStreamTransportService.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -52,19 +36,19 @@ using namespace mozilla::dom;
#define LOADSTART_STR "loadstart"
#define LOADEND_STR "loadend"
static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileReader)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileReader,
FileIOObject)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFile)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrincipal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader,
FileIOObject)
tmp->mResultArrayBuffer = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFile)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPrincipal)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -76,7 +60,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMFileReader)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsIDOMFileReader)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_END_INHERITING(FileIOObject)
@ -121,14 +104,6 @@ nsDOMFileReader::~nsDOMFileReader()
nsresult
nsDOMFileReader::Init()
{
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
nsCOMPtr<nsIPrincipal> principal;
if (secMan) {
secMan->GetSystemPrincipal(getter_AddRefs(principal));
}
NS_ENSURE_STATE(principal);
mPrincipal.swap(principal);
// Instead of grabbing some random global from the context stack,
// let's use the default one (junk scope) for now.
// We should move away from this Init...
@ -151,15 +126,6 @@ nsDOMFileReader::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
}
fileReader->BindToOwner(owner);
// This object is bound to a |window|,
// so reset the principal.
nsCOMPtr<nsIScriptObjectPrincipal> scriptPrincipal = do_QueryInterface(owner);
if (!scriptPrincipal) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
fileReader->mPrincipal = scriptPrincipal->GetPrincipal();
return fileReader.forget();
}
@ -180,12 +146,11 @@ nsDOMFileReader::GetReadyState(uint16_t *aReadyState)
return NS_OK;
}
JS::Value
nsDOMFileReader::GetResult(JSContext* aCx, ErrorResult& aRv)
void
nsDOMFileReader::GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{
JS::Rooted<JS::Value> result(aCx);
aRv = GetResult(aCx, &result);
return result;
aRv = GetResult(aCx, aResult);
}
NS_IMETHODIMP
@ -270,12 +235,9 @@ nsDOMFileReader::DoAbort(nsAString& aEvent)
// Revert status and result attributes
SetDOMStringToNull(mResult);
mResultArrayBuffer = nullptr;
// Non-null channel indicates a read is currently active
if (mChannel) {
// Cancel request requires an error status
mChannel->Cancel(NS_ERROR_FAILURE);
mChannel = nullptr;
if (mAsyncStream) {
mAsyncStream = nullptr;
}
mFile = nullptr;
@ -309,65 +271,14 @@ ReadFuncBinaryString(nsIInputStream* in,
}
nsresult
nsDOMFileReader::DoOnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount)
nsDOMFileReader::DoOnLoadEnd(nsresult aStatus,
nsAString& aSuccessEvent,
nsAString& aTerminationEvent)
{
if (mDataFormat == FILE_AS_BINARY) {
//Continuously update our binary string as data comes in
NS_ASSERTION(mResult.Length() == aOffset,
"unexpected mResult length");
uint32_t oldLen = mResult.Length();
if (uint64_t(oldLen) + aCount > UINT32_MAX)
return NS_ERROR_OUT_OF_MEMORY;
char16_t *buf = nullptr;
mResult.GetMutableData(&buf, oldLen + aCount, fallible_t());
NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
uint32_t bytesRead = 0;
aInputStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
&bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
uint32_t bytesRead = 0;
aInputStream->Read((char*)JS_GetArrayBufferData(mResultArrayBuffer) + aOffset,
aCount, &bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
else {
//Update memory buffer to reflect the contents of the file
if (aOffset + aCount > UINT32_MAX) {
// PR_Realloc doesn't support over 4GB memory size even if 64-bit OS
return NS_ERROR_OUT_OF_MEMORY;
}
mFileData = (char *)moz_realloc(mFileData, aOffset + aCount);
NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
uint32_t bytesRead = 0;
aInputStream->Read(mFileData + aOffset, aCount, &bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
mDataLen += aCount;
}
return NS_OK;
}
nsresult
nsDOMFileReader::DoOnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatus,
nsAString& aSuccessEvent,
nsAString& aTerminationEvent)
{
// Make sure we drop all the objects that could hold files open now.
nsCOMPtr<nsIChannel> channel;
mChannel.swap(channel);
nsCOMPtr<nsIAsyncInputStream> stream;
mAsyncStream.swap(stream);
nsCOMPtr<nsIDOMBlob> file;
mFile.swap(file);
@ -401,7 +312,7 @@ nsDOMFileReader::DoOnStopRequest(nsIRequest *aRequest,
rv = GetAsDataURL(file, mFileData, mDataLen, mResult);
break;
}
mResult.SetIsVoid(false);
FreeFileData();
@ -409,6 +320,51 @@ nsDOMFileReader::DoOnStopRequest(nsIRequest *aRequest,
return rv;
}
nsresult
nsDOMFileReader::DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount)
{
MOZ_ASSERT(aStream);
if (mDataFormat == FILE_AS_BINARY) {
//Continuously update our binary string as data comes in
uint32_t oldLen = mResult.Length();
NS_ASSERTION(mResult.Length() == mDataLen,
"unexpected mResult length");
if (uint64_t(oldLen) + aCount > UINT32_MAX)
return NS_ERROR_OUT_OF_MEMORY;
char16_t *buf = nullptr;
mResult.GetMutableData(&buf, oldLen + aCount, fallible_t());
NS_ENSURE_TRUE(buf, NS_ERROR_OUT_OF_MEMORY);
uint32_t bytesRead = 0;
aStream->ReadSegments(ReadFuncBinaryString, buf + oldLen, aCount,
&bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
else if (mDataFormat == FILE_AS_ARRAYBUFFER) {
uint32_t bytesRead = 0;
aStream->Read((char*) JS_GetArrayBufferData(mResultArrayBuffer) + mDataLen,
aCount, &bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
else {
//Update memory buffer to reflect the contents of the file
if (mDataLen + aCount > UINT32_MAX) {
// PR_Realloc doesn't support over 4GB memory size even if 64-bit OS
return NS_ERROR_OUT_OF_MEMORY;
}
mFileData = (char *) moz_realloc(mFileData, mDataLen + aCount);
NS_ENSURE_TRUE(mFileData, NS_ERROR_OUT_OF_MEMORY);
uint32_t bytesRead = 0;
aStream->Read(mFileData + mDataLen, aCount, &bytesRead);
NS_ASSERTION(bytesRead == aCount, "failed to read data");
}
mDataLen += aCount;
return NS_OK;
}
// Helper methods
void
@ -433,40 +389,55 @@ nsDOMFileReader::ReadFileContent(JSContext* aCx,
mDataFormat = aDataFormat;
CopyUTF16toUTF8(aCharset, mCharset);
//Establish a channel with our file
{
// Hold the internal URL alive only as long as necessary
// After the channel is created it will own whatever is backing
// the DOMFile.
nsDOMFileInternalUrlHolder urlHolder(mFile, mPrincipal);
nsresult rv;
nsCOMPtr<nsIURI> uri;
aRv = NS_NewURI(getter_AddRefs(uri), urlHolder.mUrl);
NS_ENSURE_SUCCESS_VOID(aRv.ErrorCode());
nsCOMPtr<nsILoadGroup> loadGroup;
if (HasOrHasHadOwner()) {
if (!GetOwner()) {
aRv.Throw(NS_ERROR_FAILURE);
return;
}
nsIDocument* doc = GetOwner()->GetExtantDoc();
if (doc) {
loadGroup = doc->GetDocumentLoadGroup();
}
}
aRv = NS_NewChannel(getter_AddRefs(mChannel), uri, nullptr, loadGroup,
nullptr, nsIRequest::LOAD_BACKGROUND);
NS_ENSURE_SUCCESS_VOID(aRv.ErrorCode());
nsCOMPtr<nsIStreamTransportService> sts =
do_GetService(kStreamTransportServiceCID, &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
//Obtain the total size of the file before reading
nsCOMPtr<nsIInputStream> stream;
rv = mFile->GetInternalStream(getter_AddRefs(stream));
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
nsCOMPtr<nsITransport> transport;
rv = sts->CreateInputTransport(stream,
/* aStartOffset */ 0,
/* aReadLimit */ -1,
/* aCloseWhenDone */ true,
getter_AddRefs(transport));
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
nsCOMPtr<nsIInputStream> wrapper;
rv = transport->OpenInputStream(/* aFlags */ 0,
/* aSegmentSize */ 0,
/* aSegmentCount */ 0,
getter_AddRefs(wrapper));
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
MOZ_ASSERT(!mAsyncStream);
mAsyncStream = do_QueryInterface(wrapper);
MOZ_ASSERT(mAsyncStream);
mTotal = mozilla::dom::kUnknownSize;
mFile->GetSize(&mTotal);
aRv = mChannel->AsyncOpen(this, nullptr);
NS_ENSURE_SUCCESS_VOID(aRv.ErrorCode());
rv = DoAsyncWait(mAsyncStream);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv.Throw(rv);
return;
}
//FileReader should be in loading state here
mReadyState = nsIDOMFileReader::LOADING;

View File

@ -7,24 +7,22 @@
#define nsDOMFileReader_h__
#include "mozilla/Attributes.h"
#include "nsISupportsUtils.h"
#include "nsISupportsUtils.h"
#include "nsString.h"
#include "nsWeakReference.h"
#include "nsIStreamListener.h"
#include "nsIInterfaceRequestor.h"
#include "nsJSUtils.h"
#include "nsTArray.h"
#include "nsIStreamListener.h"
#include "nsIInterfaceRequestor.h"
#include "nsJSUtils.h"
#include "nsTArray.h"
#include "nsIJSNativeInitializer.h"
#include "prtime.h"
#include "nsITimer.h"
#include "prtime.h"
#include "nsITimer.h"
#include "nsIAsyncInputStream.h"
#include "nsIDOMFile.h"
#include "nsIDOMFileReader.h"
#include "nsIDOMFileList.h"
#include "nsIInputStream.h"
#include "nsCOMPtr.h"
#include "nsIStreamLoader.h"
#include "nsIChannel.h"
#include "FileIOObject.h"
@ -50,12 +48,11 @@ public:
// FileIOObject overrides
virtual void DoAbort(nsAString& aEvent) MOZ_OVERRIDE;
NS_IMETHOD DoOnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
nsresult aStatus, nsAString& aSuccessEvent,
nsAString& aTerminationEvent) MOZ_OVERRIDE;
NS_IMETHOD DoOnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
nsIInputStream* aInputStream, uint64_t aOffset,
uint32_t aCount) MOZ_OVERRIDE;
virtual nsresult DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount) MOZ_OVERRIDE;
virtual nsresult DoOnLoadEnd(nsresult aStatus, nsAString& aSuccessEvent,
nsAString& aTerminationEvent) MOZ_OVERRIDE;
nsPIDOMWindow* GetParentObject() const
{
@ -71,11 +68,13 @@ public:
MOZ_ASSERT(aBlob);
ReadFileContent(aCx, aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv);
}
void ReadAsText(nsIDOMBlob* aBlob, const nsAString& aLabel, ErrorResult& aRv)
{
MOZ_ASSERT(aBlob);
ReadFileContent(nullptr, aBlob, aLabel, FILE_AS_TEXT, aRv);
}
void ReadAsDataURL(nsIDOMBlob* aBlob, ErrorResult& aRv)
{
MOZ_ASSERT(aBlob);
@ -86,7 +85,8 @@ public:
// Inherited ReadyState().
JS::Value GetResult(JSContext* aCx, ErrorResult& aRv);
void GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
using FileIOObject::GetError;
@ -126,7 +126,7 @@ protected:
ErrorResult& aRv);
nsresult GetAsText(nsIDOMBlob *aFile, const nsACString &aCharset,
const char *aFileData, uint32_t aDataLen, nsAString &aResult);
nsresult GetAsDataURL(nsIDOMBlob *aFile, const char *aFileData, uint32_t aDataLen, nsAString &aResult);
nsresult GetAsDataURL(nsIDOMBlob *aFile, const char *aFileData, uint32_t aDataLen, nsAString &aResult);
void FreeFileData() {
moz_free(mFileData);
@ -142,8 +142,7 @@ protected:
eDataFormat mDataFormat;
nsString mResult;
nsCOMPtr<nsIPrincipal> mPrincipal;
JS::Heap<JSObject*> mResultArrayBuffer;
};

View File

@ -5767,14 +5767,15 @@ nsDocument::sProcessingStack;
bool
nsDocument::sProcessingBaseElementQueue;
JSObject*
void
nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
const ElementRegistrationOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv)
{
if (!mRegistry) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
return;
}
Registry::DefinitionMap& definitions = mRegistry->mCustomDefinitions;
@ -5795,7 +5796,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
nsCOMPtr<nsIAtom> typeAtom(do_GetAtom(lcType));
if (!nsContentUtils::IsCustomElementName(typeAtom)) {
rv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return nullptr;
return;
}
// If there already exists a definition with the same TYPE, set ERROR to
@ -5804,13 +5805,13 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
CustomElementHashKey duplicateFinder(kNameSpaceID_Unknown, typeAtom);
if (definitions.Get(&duplicateFinder)) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
return;
}
nsIGlobalObject* sgo = GetScopeObject();
if (!sgo) {
rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
return;
}
JS::Rooted<JSObject*> global(aCx, sgo->GetGlobalJSObject());
@ -5820,7 +5821,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
HTMLElementBinding::GetProtoObject(aCx, global));
if (!htmlProto) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
return;
}
int32_t namespaceID = kNameSpaceID_XHTML;
@ -5829,7 +5830,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
protoObject = JS_NewObject(aCx, nullptr, htmlProto, JS::NullPtr());
if (!protoObject) {
rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
return;
}
} else {
// If a prototype is provided, we must check to ensure that it is from the
@ -5837,7 +5838,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
protoObject = aOptions.mPrototype;
if (JS_GetGlobalForObject(aCx, protoObject) != global) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
return;
}
// If PROTOTYPE is already an interface prototype object for any interface
@ -5846,27 +5847,27 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
const js::Class* clasp = js::GetObjectClass(protoObject);
if (IsDOMIfaceAndProtoClass(clasp)) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
return;
}
JS::Rooted<JSPropertyDescriptor> descRoot(aCx);
JS::MutableHandle<JSPropertyDescriptor> desc(&descRoot);
if (!JS_GetPropertyDescriptor(aCx, protoObject, "constructor", desc)) {
rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
return;
}
// Check if non-configurable
if (desc.isPermanent()) {
rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return nullptr;
return;
}
JS::Handle<JSObject*> svgProto(
SVGElementBinding::GetProtoObject(aCx, global));
if (!svgProto) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
return;
}
JS::Rooted<JSObject*> protoProto(aCx, protoObject);
@ -5885,7 +5886,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
if (!JS_GetPrototype(aCx, protoProto, &protoProto)) {
rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
return;
}
}
}
@ -5900,7 +5901,7 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
nsIParserService* ps = nsContentUtils::GetParserService();
if (!ps) {
rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
return;
}
known =
@ -5914,13 +5915,13 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
// If BASE exists, then it cannot be an interface for a custom element.
if (!known) {
rv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return nullptr;
return;
}
} else {
// If NAMESPACE is SVG Namespace, set ERROR to InvalidName and stop.
if (namespaceID == kNameSpaceID_SVG) {
rv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
return;
}
nameAtom = typeAtom;
@ -5929,7 +5930,8 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
nsAutoPtr<LifecycleCallbacks> callbacksHolder(new LifecycleCallbacks());
JS::RootedValue rootedv(aCx, JS::ObjectValue(*protoObject));
if (!callbacksHolder->Init(aCx, rootedv)) {
return nullptr;
rv.Throw(NS_ERROR_FAILURE);
return;
}
// Associate the definition with the custom element.
@ -5988,8 +5990,12 @@ nsDocument::RegisterElement(JSContext* aCx, const nsAString& aType,
JSFunction* constructor = JS_NewFunction(aCx, nsDocument::CustomElementConstructor, 0,
JSFUN_CONSTRUCTOR, JS::NullPtr(),
NS_ConvertUTF16toUTF8(lcType).get());
JSObject* constructorObject = JS_GetFunctionObject(constructor);
return constructorObject;
if (!constructor) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return;
}
aRetval.set(JS_GetFunctionObject(constructor));
}
void

View File

@ -1226,9 +1226,10 @@ public:
// WebIDL bits
virtual mozilla::dom::DOMImplementation*
GetImplementation(mozilla::ErrorResult& rv) MOZ_OVERRIDE;
virtual JSObject*
virtual void
RegisterElement(JSContext* aCx, const nsAString& aName,
const mozilla::dom::ElementRegistrationOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv) MOZ_OVERRIDE;
virtual mozilla::dom::StyleSheetList* StyleSheets() MOZ_OVERRIDE;
virtual void SetSelectedStyleSheetSet(const nsAString& aSheetSet) MOZ_OVERRIDE;

View File

@ -779,33 +779,33 @@ nsINode::SetUserData(const nsAString &aKey, nsIVariant *aData,
return NS_OK;
}
JS::Value
void
nsINode::SetUserData(JSContext* aCx, const nsAString& aKey,
JS::Handle<JS::Value> aData,
nsIDOMUserDataHandler* aHandler, ErrorResult& aError)
nsIDOMUserDataHandler* aHandler,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{
nsCOMPtr<nsIVariant> data;
JS::Rooted<JS::Value> dataVal(aCx, aData);
aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, dataVal, getter_AddRefs(data));
aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, aData, getter_AddRefs(data));
if (aError.Failed()) {
return JS::UndefinedValue();
return;
}
nsCOMPtr<nsIVariant> oldData;
aError = SetUserData(aKey, data, aHandler, getter_AddRefs(oldData));
if (aError.Failed()) {
return JS::UndefinedValue();
return;
}
if (!oldData) {
return JS::NullValue();
aRetval.setNull();
return;
}
JS::Rooted<JS::Value> result(aCx);
JSAutoCompartment ac(aCx, GetWrapper());
aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), oldData,
&result);
return result;
aRetval);
}
nsIVariant*
@ -820,19 +820,19 @@ nsINode::GetUserData(const nsAString& aKey)
return static_cast<nsIVariant*>(GetProperty(DOM_USER_DATA, key));
}
JS::Value
nsINode::GetUserData(JSContext* aCx, const nsAString& aKey, ErrorResult& aError)
void
nsINode::GetUserData(JSContext* aCx, const nsAString& aKey,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
{
nsIVariant* data = GetUserData(aKey);
if (!data) {
return JS::NullValue();
aRetval.setNull();
return;
}
JS::Rooted<JS::Value> result(aCx);
JSAutoCompartment ac(aCx, GetWrapper());
aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), data,
&result);
return result;
aRetval);
}
uint16_t

View File

@ -3204,10 +3204,11 @@ nsObjectLoadingContent::GetContentDocument()
return sub_doc;
}
JS::Value
void
nsObjectLoadingContent::LegacyCall(JSContext* aCx,
JS::Handle<JS::Value> aThisVal,
const Sequence<JS::Value>& aArguments,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv)
{
nsCOMPtr<nsIContent> thisContent =
@ -3221,12 +3222,12 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
// this is not an Xray situation by hand.
if (!JS_WrapObject(aCx, &obj)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return JS::UndefinedValue();
return;
}
if (nsDOMClassInfo::ObjectIsNativeWrapper(aCx, obj)) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return JS::UndefinedValue();
return;
}
obj = thisContent->GetWrapper();
@ -3235,33 +3236,33 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
JS::AutoValueVector args(aCx);
if (!args.append(aArguments.Elements(), aArguments.Length())) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JS::UndefinedValue();
return;
}
for (size_t i = 0; i < args.length(); i++) {
if (!JS_WrapValue(aCx, args[i])) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return JS::UndefinedValue();
return;
}
}
JS::Rooted<JS::Value> thisVal(aCx, aThisVal);
if (!JS_WrapValue(aCx, &thisVal)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return JS::UndefinedValue();
return;
}
nsRefPtr<nsNPAPIPluginInstance> pi;
nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return JS::UndefinedValue();
return;
}
// if there's no plugin around for this object, throw.
if (!pi) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return JS::UndefinedValue();
return;
}
JS::Rooted<JSObject*> pi_obj(aCx);
@ -3270,23 +3271,21 @@ nsObjectLoadingContent::LegacyCall(JSContext* aCx,
rv = GetPluginJSObject(aCx, obj, pi, &pi_obj, &pi_proto);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return JS::UndefinedValue();
return;
}
if (!pi_obj) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return JS::UndefinedValue();
return;
}
JS::Rooted<JS::Value> retval(aCx);
bool ok = JS::Call(aCx, thisVal, pi_obj, args, &retval);
bool ok = JS::Call(aCx, thisVal, pi_obj, args, aRetval);
if (!ok) {
aRv.Throw(NS_ERROR_FAILURE);
return JS::UndefinedValue();
return;
}
Telemetry::Accumulate(Telemetry::PLUGIN_CALLED_DIRECTLY, true);
return retval;
}
void

View File

@ -214,9 +214,10 @@ class nsObjectLoadingContent : public nsImageLoadingContent
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
JS::Value LegacyCall(JSContext* aCx, JS::Handle<JS::Value> aThisVal,
const mozilla::dom::Sequence<JS::Value>& aArguments,
mozilla::ErrorResult& aRv);
void LegacyCall(JSContext* aCx, JS::Handle<JS::Value> aThisVal,
const mozilla::dom::Sequence<JS::Value>& aArguments,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aRv);
protected:
/**

View File

@ -936,12 +936,14 @@ NS_IMETHODIMP
nsXMLHttpRequest::GetResponse(JSContext *aCx, JS::MutableHandle<JS::Value> aResult)
{
ErrorResult rv;
aResult.set(GetResponse(aCx, rv));
GetResponse(aCx, aResult, rv);
return rv.ErrorCode();
}
JS::Value
nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
void
nsXMLHttpRequest::GetResponse(JSContext* aCx,
JS::MutableHandle<JS::Value> aResponse,
ErrorResult& aRv)
{
switch (mResponseType) {
case XML_HTTP_RESPONSE_TYPE_DEFAULT:
@ -951,14 +953,12 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
nsString str;
aRv = GetResponseText(str);
if (aRv.Failed()) {
return JSVAL_NULL;
return;
}
JS::Rooted<JS::Value> result(aCx);
if (!xpc::StringToJsval(aCx, str, &result)) {
if (!xpc::StringToJsval(aCx, str, aResponse)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JSVAL_NULL;
}
return result;
return;
}
case XML_HTTP_RESPONSE_TYPE_ARRAYBUFFER:
@ -968,7 +968,8 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
mState & XML_HTTP_REQUEST_DONE) &&
!(mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_ARRAYBUFFER &&
mInLoadProgressEvent)) {
return JSVAL_NULL;
aResponse.setNull();
return;
}
if (!mResultArrayBuffer) {
@ -977,17 +978,20 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
mResultArrayBuffer = mArrayBufferBuilder.getArrayBuffer(aCx);
if (!mResultArrayBuffer) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JSVAL_NULL;
return;
}
}
return OBJECT_TO_JSVAL(mResultArrayBuffer);
JS::ExposeObjectToActiveJS(mResultArrayBuffer);
aResponse.setObject(*mResultArrayBuffer);
return;
}
case XML_HTTP_RESPONSE_TYPE_BLOB:
case XML_HTTP_RESPONSE_TYPE_MOZ_BLOB:
{
if (!(mState & XML_HTTP_REQUEST_DONE)) {
if (mResponseType != XML_HTTP_RESPONSE_TYPE_MOZ_BLOB) {
return JSVAL_NULL;
aResponse.setNull();
return;
}
if (!mResponseBlob) {
@ -996,30 +1000,31 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
}
if (!mResponseBlob) {
return JSVAL_NULL;
aResponse.setNull();
return;
}
JS::Rooted<JS::Value> result(aCx);
aRv = nsContentUtils::WrapNative(aCx, mResponseBlob, &result);
return result;
aRv = nsContentUtils::WrapNative(aCx, mResponseBlob, aResponse);
return;
}
case XML_HTTP_RESPONSE_TYPE_DOCUMENT:
{
if (!(mState & XML_HTTP_REQUEST_DONE) || !mResponseXML) {
return JSVAL_NULL;
aResponse.setNull();
return;
}
JS::Rooted<JS::Value> result(aCx);
aRv = nsContentUtils::WrapNative(aCx, mResponseXML, &result);
return result;
aRv = nsContentUtils::WrapNative(aCx, mResponseXML, aResponse);
return;
}
case XML_HTTP_RESPONSE_TYPE_JSON:
{
if (!(mState & XML_HTTP_REQUEST_DONE)) {
return JSVAL_NULL;
aResponse.setNull();
return;
}
if (mResultJSON == JSVAL_VOID) {
if (mResultJSON.isUndefined()) {
aRv = CreateResponseParsedJSON(aCx);
mResponseText.Truncate();
if (aRv.Failed()) {
@ -1028,16 +1033,18 @@ nsXMLHttpRequest::GetResponse(JSContext* aCx, ErrorResult& aRv)
// It would be nice to log the error to the console. That's hard to
// do without calling window.onerror as a side effect, though.
JS_ClearPendingException(aCx);
mResultJSON = JSVAL_NULL;
mResultJSON.setNull();
}
}
return mResultJSON;
JS::ExposeValueToActiveJS(mResultJSON);
aResponse.set(mResultJSON);
return;
}
default:
NS_ERROR("Should not happen");
}
return JSVAL_NULL;
aResponse.setNull();
}
bool
@ -3757,10 +3764,12 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
return QueryInterface(aIID, aResult);
}
JS::Value
nsXMLHttpRequest::GetInterface(JSContext* aCx, nsIJSID* aIID, ErrorResult& aRv)
void
nsXMLHttpRequest::GetInterface(JSContext* aCx, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aRv)
{
return dom::GetInterface(aCx, this, aIID, aRv);
dom::GetInterface(aCx, this, aIID, aRetval, aRv);
}
nsXMLHttpRequestUpload*

View File

@ -494,7 +494,8 @@ public:
return XMLHttpRequestResponseType(mResponseType);
}
void SetResponseType(XMLHttpRequestResponseType aType, ErrorResult& aRv);
JS::Value GetResponse(JSContext* aCx, ErrorResult& aRv);
void GetResponse(JSContext* aCx, JS::MutableHandle<JS::Value> aResponse,
ErrorResult& aRv);
void GetResponseText(nsString& aResponseText, ErrorResult& aRv);
nsIDocument* GetResponseXML(ErrorResult& aRv);
@ -510,7 +511,8 @@ public:
}
// We need a GetInterface callable from JS for chrome JS
JS::Value GetInterface(JSContext* aCx, nsIJSID* aIID, ErrorResult& aRv);
void GetInterface(JSContext* aCx, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aRv);
// This creates a trusted readystatechange event, which is not cancelable and
// doesn't bubble.

View File

@ -64,7 +64,11 @@ var asciiFile = createFileWithData(testASCIIData);
var binaryFile = createFileWithData(testBinaryData);
var fileList = document.getElementById('fileList');
SpecialPowers.wrap(fileList).value = "/none/existing/path/fileAPI/testing";
SpecialPowers.Cu.import("resource://gre/modules/FileUtils.jsm", window);
var FU = SpecialPowers.wrap(FileUtils);
var fakeFile = FU.getDir("TmpD", [], false);
fakeFile.append("FileThatDoesntExist.abc");
SpecialPowers.wrap(fileList).value = fakeFile.path;
var nonExistingFile = fileList.files[0];
// Test that plain reading works and fires events as expected, both
@ -356,14 +360,21 @@ expectedTestCount++;
// Test reading from nonexistent files
r = new FileReader();
var didThrow = false;
r.onerror = function (event) {
is(event.target.readyState, FileReader.DONE, "should be DONE while firing onerror");
is(event.target.error.name, "NotFoundError", "error set to NotFoundError for nonexistent files");
is(event.target.result, null, "file data should be null on aborted reads");
testHasRun();
};
try {
r.readAsDataURL(nonExistingFile);
expectedTestCount++;
} catch(ex) {
didThrow = true;
}
// Once this test passes, we should test that onerror gets called and
// that the FileReader object is in the right state during that call.
todo(!didThrow, "shouldn't throw when opening nonexistent file, should fire error instead");
is(didThrow, false, "shouldn't throw when opening nonexistent file, should fire error instead");
function getLoadHandler(expectedResult, expectedLength, testName) {

View File

@ -1267,8 +1267,9 @@ CanvasRenderingContext2D::SetTransform(double m11, double m12,
mTarget->SetTransform(matrix);
}
JSObject*
MatrixToJSObject(JSContext* cx, const Matrix& matrix, ErrorResult& error)
static void
MatrixToJSObject(JSContext* cx, const Matrix& matrix,
JS::MutableHandle<JSObject*> result, ErrorResult& error)
{
double elts[6] = { matrix._11, matrix._12,
matrix._21, matrix._22,
@ -1278,10 +1279,9 @@ MatrixToJSObject(JSContext* cx, const Matrix& matrix, ErrorResult& error)
JS::Rooted<JS::Value> val(cx);
if (!ToJSValue(cx, elts, &val)) {
error.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
} else {
result.set(&val.toObject());
}
return &val.toObject();
}
static bool
@ -1334,11 +1334,13 @@ CanvasRenderingContext2D::SetMozCurrentTransform(JSContext* cx,
}
}
JSObject*
void
CanvasRenderingContext2D::GetMozCurrentTransform(JSContext* cx,
JS::MutableHandle<JSObject*> result,
ErrorResult& error) const
{
return MatrixToJSObject(cx, mTarget ? mTarget->GetTransform() : Matrix(), error);
MatrixToJSObject(cx, mTarget ? mTarget->GetTransform() : Matrix(),
result, error);
}
void
@ -1361,12 +1363,14 @@ CanvasRenderingContext2D::SetMozCurrentTransformInverse(JSContext* cx,
}
}
JSObject*
void
CanvasRenderingContext2D::GetMozCurrentTransformInverse(JSContext* cx,
JS::MutableHandle<JSObject*> result,
ErrorResult& error) const
{
if (!mTarget) {
return MatrixToJSObject(cx, Matrix(), error);
MatrixToJSObject(cx, Matrix(), result, error);
return;
}
Matrix ctm = mTarget->GetTransform();
@ -1376,7 +1380,7 @@ CanvasRenderingContext2D::GetMozCurrentTransformInverse(JSContext* cx,
ctm = Matrix(NaN, NaN, NaN, NaN, NaN, NaN);
}
return MatrixToJSObject(cx, ctm, error);
MatrixToJSObject(cx, ctm, result, error);
}
//
@ -3111,10 +3115,12 @@ CanvasRenderingContext2D::SetMozDash(JSContext* cx,
}
}
JS::Value
CanvasRenderingContext2D::GetMozDash(JSContext* cx, ErrorResult& error)
void
CanvasRenderingContext2D::GetMozDash(JSContext* cx,
JS::MutableHandle<JS::Value> retval,
ErrorResult& error)
{
return DashArrayToJSVal(CurrentState().dash, cx, error);
DashArrayToJSVal(CurrentState().dash, cx, retval, error);
}
void

View File

@ -388,19 +388,22 @@ public:
void Arc(double x, double y, double radius, double startAngle,
double endAngle, bool anticlockwise, mozilla::ErrorResult& error);
JSObject* GetMozCurrentTransform(JSContext* cx,
mozilla::ErrorResult& error) const;
void GetMozCurrentTransform(JSContext* cx,
JS::MutableHandle<JSObject*> result,
mozilla::ErrorResult& error) const;
void SetMozCurrentTransform(JSContext* cx,
JS::Handle<JSObject*> currentTransform,
mozilla::ErrorResult& error);
JSObject* GetMozCurrentTransformInverse(JSContext* cx,
mozilla::ErrorResult& error) const;
void GetMozCurrentTransformInverse(JSContext* cx,
JS::MutableHandle<JSObject*> result,
mozilla::ErrorResult& error) const;
void SetMozCurrentTransformInverse(JSContext* cx,
JS::Handle<JSObject*> currentTransform,
mozilla::ErrorResult& error);
void GetFillRule(nsAString& fillRule);
void SetFillRule(const nsAString& fillRule);
JS::Value GetMozDash(JSContext* cx, mozilla::ErrorResult& error);
void GetMozDash(JSContext* cx, JS::MutableHandle<JS::Value> retval,
mozilla::ErrorResult& error);
void SetMozDash(JSContext* cx, const JS::Value& mozDash,
mozilla::ErrorResult& error);

View File

@ -151,18 +151,20 @@ JSValToDashArray(JSContext* cx, const JS::Value& patternArray,
}
template<typename T>
JS::Value
void
DashArrayToJSVal(FallibleTArray<T>& dashes,
JSContext* cx, mozilla::ErrorResult& rv)
JSContext* cx,
JS::MutableHandle<JS::Value> retval,
mozilla::ErrorResult& rv)
{
if (dashes.IsEmpty()) {
return JS::NullValue();
retval.setNull();
return;
}
JS::Rooted<JS::Value> val(cx);
if (!mozilla::dom::ToJSValue(cx, dashes, &val)) {
if (!mozilla::dom::ToJSValue(cx, dashes, retval)) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
}
return val;
}
}

View File

@ -61,9 +61,9 @@ public:
{
return mHeight;
}
JSObject* Data(JSContext* cx) const
void GetData(JSContext* cx, JS::MutableHandle<JSObject*> aData) const
{
return GetDataObject();
aData.set(GetDataObject());
}
JSObject* GetDataObject() const
{

View File

@ -285,7 +285,9 @@ public:
void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval);
bool IsContextLost() const { return mContextStatus != ContextNotLost; }
void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval);
JSObject* GetExtension(JSContext* cx, const nsAString& aName, ErrorResult& rv);
void GetExtension(JSContext* cx, const nsAString& aName,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv);
void ActiveTexture(GLenum texture);
void AttachShader(WebGLProgram* program, WebGLShader* shader);
void BindAttribLocation(WebGLProgram* program, GLuint location,
@ -357,9 +359,10 @@ public:
dom::Nullable< nsTArray<WebGLShader*> > &retval);
GLint GetAttribLocation(WebGLProgram* prog, const nsAString& name);
JS::Value GetBufferParameter(GLenum target, GLenum pname);
JS::Value GetBufferParameter(JSContext* /* unused */, GLenum target,
GLenum pname) {
return GetBufferParameter(target, pname);
void GetBufferParameter(JSContext* /* unused */, GLenum target,
GLenum pname,
JS::MutableHandle<JS::Value> retval) {
retval.set(GetBufferParameter(target, pname));
}
GLenum GetError();
JS::Value GetFramebufferAttachmentParameter(JSContext* cx,
@ -367,22 +370,34 @@ public:
GLenum attachment,
GLenum pname,
ErrorResult& rv);
void GetFramebufferAttachmentParameter(JSContext* cx,
GLenum target,
GLenum attachment,
GLenum pname,
JS::MutableHandle<JS::Value> retval,
ErrorResult& rv) {
retval.set(GetFramebufferAttachmentParameter(cx, target, attachment,
pname, rv));
}
JS::Value GetProgramParameter(WebGLProgram *prog, GLenum pname);
JS::Value GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog,
GLenum pname) {
return GetProgramParameter(prog, pname);
void GetProgramParameter(JSContext* /* unused */, WebGLProgram *prog,
GLenum pname,
JS::MutableHandle<JS::Value> retval) {
retval.set(GetProgramParameter(prog, pname));
}
void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval);
void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval);
JS::Value GetRenderbufferParameter(GLenum target, GLenum pname);
JS::Value GetRenderbufferParameter(JSContext* /* unused */,
GLenum target, GLenum pname) {
return GetRenderbufferParameter(target, pname);
void GetRenderbufferParameter(JSContext* /* unused */,
GLenum target, GLenum pname,
JS::MutableHandle<JS::Value> retval) {
retval.set(GetRenderbufferParameter(target, pname));
}
JS::Value GetShaderParameter(WebGLShader *shader, GLenum pname);
JS::Value GetShaderParameter(JSContext* /* unused */, WebGLShader *shader,
GLenum pname) {
return GetShaderParameter(shader, pname);
void GetShaderParameter(JSContext* /* unused */, WebGLShader *shader,
GLenum pname,
JS::MutableHandle<JS::Value> retval) {
retval.set(GetShaderParameter(shader, pname));
}
already_AddRefed<WebGLShaderPrecisionFormat>
GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
@ -391,12 +406,18 @@ public:
void GetShaderSource(WebGLShader *shader, nsAString& retval);
void GetShaderTranslatedSource(WebGLShader *shader, nsAString& retval);
JS::Value GetTexParameter(GLenum target, GLenum pname);
JS::Value GetTexParameter(JSContext * /* unused */, GLenum target,
GLenum pname) {
return GetTexParameter(target, pname);
void GetTexParameter(JSContext * /* unused */, GLenum target,
GLenum pname,
JS::MutableHandle<JS::Value> retval) {
retval.set(GetTexParameter(target, pname));
}
JS::Value GetUniform(JSContext* cx, WebGLProgram *prog,
WebGLUniformLocation *location);
void GetUniform(JSContext* cx, WebGLProgram *prog,
WebGLUniformLocation *location,
JS::MutableHandle<JS::Value> retval) {
retval.set(GetUniform(cx, prog, location));
}
already_AddRefed<WebGLUniformLocation>
GetUniformLocation(WebGLProgram *prog, const nsAString& name);
void Hint(GLenum target, GLenum mode);
@ -691,6 +712,10 @@ public:
bool IsQuery(WebGLQuery *query);
already_AddRefed<WebGLQuery> GetQuery(GLenum target, GLenum pname);
JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname);
void GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname,
JS::MutableHandle<JS::Value> retval) {
retval.set(GetQueryObject(cx, query, pname));
}
private:
// ANY_SAMPLES_PASSED(_CONSERVATIVE) slot
@ -740,7 +765,12 @@ public:
void Disable(GLenum cap);
void Enable(GLenum cap);
JS::Value GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv);
JS::Value GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index);
void GetParameter(JSContext* cx, GLenum pname,
JS::MutableHandle<JS::Value> retval, ErrorResult& rv) {
retval.set(GetParameter(cx, pname, rv));
}
void GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
JS::MutableHandle<JS::Value> retval);
bool IsEnabled(GLenum cap);
private:
@ -766,6 +796,11 @@ public:
JS::Value GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
ErrorResult& rv);
void GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
JS::MutableHandle<JS::Value> retval,
ErrorResult& rv) {
retval.set(GetVertexAttrib(cx, index, pname, rv));
}
WebGLsizeiptr GetVertexAttribOffset(GLuint index, GLenum pname);
void VertexAttrib1f(GLuint index, GLfloat x0);

View File

@ -182,11 +182,15 @@ CompareWebGLExtensionName(const nsACString& name, const char *other)
return name.Equals(other, nsCaseInsensitiveCStringComparator());
}
JSObject*
WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& rv)
void
WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv)
{
if (IsContextLost())
return nullptr;
if (IsContextLost()) {
aRetval.set(nullptr);
return;
}
NS_LossyConvertUTF16toASCII name(aName);
@ -235,12 +239,14 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& r
}
if (ext == WebGLExtensionID::Unknown) {
return nullptr;
aRetval.set(nullptr);
return;
}
// step 2: check if the extension is supported
if (!IsExtensionSupported(cx, ext)) {
return nullptr;
aRetval.set(nullptr);
return;
}
// step 3: if the extension hadn't been previously been created, create it now, thus enabling it
@ -248,7 +254,7 @@ WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& r
EnableExtension(ext);
}
return WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv);
aRetval.set(WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv));
}
void

View File

@ -454,11 +454,14 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
return JS::NullValue();
}
JS::Value
WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index)
void
WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index,
JS::MutableHandle<JS::Value> retval)
{
if (IsContextLost())
return JS::NullValue();
if (IsContextLost()) {
retval.setNull();
return;
}
MakeContextCurrent();
@ -467,9 +470,11 @@ WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index)
{
if (index >= mGLMaxTransformFeedbackSeparateAttribs) {
ErrorInvalidValue("getParameterIndexed: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", index);
return JS::NullValue();
retval.setNull();
return;
}
return JS::NullValue(); // See bug 903594
retval.setNull(); // See bug 903594
return;
}
default:
@ -477,7 +482,7 @@ WebGLContext::GetParameterIndexed(JSContext* cx, GLenum pname, GLuint index)
}
ErrorInvalidEnumInfo("getParameterIndexed: parameter", pname);
return JS::NullValue();
retval.setNull();
}
bool

View File

@ -529,7 +529,8 @@ public:
return mAudioCaptured;
}
JSObject* MozGetMetadata(JSContext* aCx, ErrorResult& aRv);
void MozGetMetadata(JSContext* aCx, JS::MutableHandle<JSObject*> aResult,
ErrorResult& aRv);
double MozFragmentEnd();

View File

@ -1673,18 +1673,20 @@ HTMLMediaElement::BuildObjectFromTags(nsCStringHashKey::KeyType aKey,
return PL_DHASH_NEXT;
}
JSObject*
HTMLMediaElement::MozGetMetadata(JSContext* cx, ErrorResult& aRv)
void
HTMLMediaElement::MozGetMetadata(JSContext* cx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
if (mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
return;
}
JS::Rooted<JSObject*> tags(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr()));
if (!tags) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
return;
}
if (mTags) {
MetadataIterCx iter = {cx, tags, false};
@ -1692,19 +1694,19 @@ HTMLMediaElement::MozGetMetadata(JSContext* cx, ErrorResult& aRv)
if (iter.error) {
NS_WARNING("couldn't create metadata object!");
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
return;
}
}
return tags;
aRetval.set(tags);
}
NS_IMETHODIMP
HTMLMediaElement::MozGetMetadata(JSContext* cx, JS::MutableHandle<JS::Value> aValue)
{
ErrorResult rv;
JSObject* obj = MozGetMetadata(cx, rv);
JS::Rooted<JSObject*> obj(cx);
MozGetMetadata(cx, &obj, rv);
if (!rv.Failed()) {
MOZ_ASSERT(obj);
aValue.setObject(*obj);

View File

@ -426,7 +426,8 @@ PropertyNodeList::GetValues(JSContext* aCx, nsTArray<JS::Value >& aResult,
JSAutoCompartment ac(aCx, wrapper);
uint32_t length = mElements.Length();
for (uint32_t i = 0; i < length; ++i) {
JS::Value v = mElements.ElementAt(i)->GetItemValue(aCx, wrapper, aError);
JS::Rooted<JS::Value> v(aCx);
mElements.ElementAt(i)->GetItemValue(aCx, wrapper, &v, aError);
if (aError.Failed()) {
return;
}

View File

@ -3041,33 +3041,31 @@ nsGenericHTMLFormElementWithState::NodeInfoChanged(nsINodeInfo* aOldNodeInfo)
mStateKey.SetIsVoid(true);
}
JS::Value
void
nsGenericHTMLElement::GetItemValue(JSContext* aCx, JSObject* aScope,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{
JS::Rooted<JSObject*> scope(aCx, aScope);
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) {
return JS::NullValue();
aRetval.setNull();
return;
}
if (ItemScope()) {
JS::Rooted<JS::Value> v(aCx);
JSAutoCompartment ac(aCx, scope);
if (!mozilla::dom::WrapObject(aCx, this, &v)) {
if (!mozilla::dom::WrapObject(aCx, this, aRetval)) {
aError.Throw(NS_ERROR_FAILURE);
return JS::UndefinedValue();
}
return v;
return;
}
nsString string;
GetItemValueText(string);
JS::Rooted<JS::Value> v(aCx);
if (!xpc::NonVoidStringToJsval(aCx, string, &v)) {
if (!xpc::NonVoidStringToJsval(aCx, string, aRetval)) {
aError.Throw(NS_ERROR_FAILURE);
return JS::UndefinedValue();
}
return v;
}
NS_IMETHODIMP

View File

@ -124,11 +124,13 @@ public:
return GetTokenList(nsGkAtoms::itemprop);
}
mozilla::dom::HTMLPropertiesCollection* Properties();
JS::Value GetItemValue(JSContext* aCx, JSObject* aScope,
mozilla::ErrorResult& aError);
JS::Value GetItemValue(JSContext* aCx, mozilla::ErrorResult& aError)
void GetItemValue(JSContext* aCx, JSObject* aScope,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
void GetItemValue(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError)
{
return GetItemValue(aCx, GetWrapperPreserveColor(), aError);
GetItemValue(aCx, GetWrapperPreserveColor(), aRetval, aError);
}
void SetItemValue(JSContext* aCx, JS::Value aValue,
mozilla::ErrorResult& aError);

View File

@ -2244,15 +2244,17 @@ nsHTMLDocument::ResolveName(const nsAString& aName, nsWrapperCache **aCache)
return nullptr;
}
JSObject*
void
nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& rv)
{
nsWrapperCache* cache;
nsISupports* supp = ResolveName(aName, &cache);
if (!supp) {
aFound = false;
return nullptr;
aRetval.set(nullptr);
return;
}
JS::Rooted<JS::Value> val(cx);
@ -2260,10 +2262,10 @@ nsHTMLDocument::NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
// here?
if (!dom::WrapObject(cx, supp, cache, nullptr, &val)) {
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
return;
}
aFound = true;
return &val.toObject();
aRetval.set(&val.toObject());
}
bool

View File

@ -174,8 +174,9 @@ public:
void SetDomain(const nsAString& aDomain, mozilla::ErrorResult& rv);
void GetCookie(nsAString& aCookie, mozilla::ErrorResult& rv);
void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv);
JSObject* NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
mozilla::ErrorResult& rv);
void NamedGetter(JSContext* cx, const nsAString& aName, bool& aFound,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& rv);
bool NameIsEnumerable(const nsAString& aName);
void GetSupportedNames(unsigned, nsTArray<nsString>& aNames);
nsGenericHTMLElement *GetBody();

View File

@ -99,8 +99,10 @@ MediaKeyMessageEvent::Constructor(const GlobalObject& aGlobal,
return e.forget();
}
JSObject*
MediaKeyMessageEvent::GetMessage(JSContext* cx, ErrorResult& aRv)
void
MediaKeyMessageEvent::GetMessage(JSContext* cx,
JS::MutableHandle<JSObject*> aMessage,
ErrorResult& aRv)
{
if (!mMessage) {
mMessage = Uint8Array::Create(cx,
@ -109,12 +111,12 @@ MediaKeyMessageEvent::GetMessage(JSContext* cx, ErrorResult& aRv)
mRawMessage.Elements());
if (!mMessage) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
return;
}
mRawMessage.Clear();
}
JS::ExposeObjectToActiveJS(mMessage);
return mMessage;
aMessage.set(mMessage);
}
void

View File

@ -50,7 +50,9 @@ public:
const MediaKeyMessageEventInit& aEventInitDict,
ErrorResult& aRv);
JSObject* GetMessage(JSContext* cx, ErrorResult& aRv);
void GetMessage(JSContext* cx,
JS::MutableHandle<JSObject*> aMessage,
ErrorResult& aRv);
void GetDestinationURL(nsString& aRetVal) const;

View File

@ -94,8 +94,10 @@ MediaKeyNeededEvent::GetInitDataType(nsString& aRetVal) const
aRetVal = mInitDataType;
}
JSObject*
MediaKeyNeededEvent::GetInitData(JSContext* cx, ErrorResult& aRv)
void
MediaKeyNeededEvent::GetInitData(JSContext* cx,
JS::MutableHandle<JSObject*> aData,
ErrorResult& aRv)
{
if (mRawInitData.Length()) {
mInitData = Uint8Array::Create(cx,
@ -104,14 +106,14 @@ MediaKeyNeededEvent::GetInitData(JSContext* cx, ErrorResult& aRv)
mRawInitData.Elements());
if (!mInitData) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
return;
}
mRawInitData.Clear();
}
if (mInitData) {
JS::ExposeObjectToActiveJS(mInitData);
}
return mInitData;
aData.set(mInitData);
}
} // namespace dom

View File

@ -51,7 +51,9 @@ public:
void GetInitDataType(nsString& aRetVal) const;
JSObject* GetInitData(JSContext* cx, ErrorResult& aRv);
void GetInitData(JSContext* cx,
JS::MutableHandle<JSObject*> aData,
ErrorResult& aRv);
private:
nsTArray<uint8_t> mRawInitData;
};

View File

@ -192,21 +192,25 @@ AudioBuffer::SetRawChannelContents(uint32_t aChannel, float* aContents)
PodCopy(JS_GetFloat32ArrayData(mJSChannels[aChannel]), aContents, mLength);
}
JSObject*
void
AudioBuffer::GetChannelData(JSContext* aJSContext, uint32_t aChannel,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
if (aChannel >= NumberOfChannels()) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return nullptr;
return;
}
if (!RestoreJSChannelData(aJSContext)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
return;
}
return mJSChannels[aChannel];
if (mJSChannels[aChannel]) {
JS::ExposeObjectToActiveJS(mJSChannels[aChannel]);
}
aRetval.set(mJSChannels[aChannel]);
}
static already_AddRefed<ThreadSharedFloatArrayBufferList>

View File

@ -74,8 +74,9 @@ public:
* If mSharedChannels is non-null, copies its contents to
* new Float32Arrays in mJSChannels. Returns a Float32Array.
*/
JSObject* GetChannelData(JSContext* aJSContext, uint32_t aChannel,
ErrorResult& aRv);
void GetChannelData(JSContext* aJSContext, uint32_t aChannel,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
void CopyFromChannel(const Float32Array& aDestination, uint32_t aChannelNumber,
uint32_t aStartInChannel, ErrorResult& aRv);

View File

@ -27,9 +27,12 @@ public:
virtual JSObject* WrapObject(JSContext *aCx) MOZ_OVERRIDE;
JSObject* GetCurve(JSContext* aCx) const
void GetCurve(JSContext* aCx, JS::MutableHandle<JSObject*> aRetval) const
{
return mCurve;
if (mCurve) {
JS::ExposeObjectToActiveJS(mCurve);
}
aRetval.set(mCurve);
}
void SetCurve(const Nullable<Float32Array>& aData);

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=4 sw=4 tw=80 et: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -29,6 +29,7 @@
#endif
#include "nsIContent.h"
#include "nsIContentInlines.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
@ -336,6 +337,18 @@ CheckPingURI(nsIURI* uri, nsIContent* content)
typedef void (* ForEachPingCallback)(void *closure, nsIContent *content,
nsIURI *uri, nsIIOService *ios);
static bool
IsElementAnchor(nsIContent* aContent)
{
// Make sure we are dealing with either an <A> or <AREA> element in the HTML
// or XHTML namespace.
if (!aContent->IsHTML()) {
return false;
}
nsIAtom* nameAtom = aContent->Tag();
return nameAtom == nsGkAtoms::a || nameAtom == nsGkAtoms::area;
}
static void
ForEachPing(nsIContent *content, ForEachPingCallback callback, void *closure)
{
@ -346,10 +359,7 @@ ForEachPing(nsIContent *content, ForEachPingCallback callback, void *closure)
// Make sure we are dealing with either an <A> or <AREA> element in the HTML
// or XHTML namespace.
if (!content->IsHTML())
return;
nsIAtom *nameAtom = content->Tag();
if (nameAtom != nsGkAtoms::a && nameAtom != nsGkAtoms::area)
if (!IsElementAnchor(content))
return;
nsCOMPtr<nsIAtom> pingAtom = do_GetAtom("ping");
@ -9080,6 +9090,11 @@ nsDocShell::InternalLoad(nsIURI * aURI,
if (!newDoc || newDoc->IsInitialDocument()) {
isNewWindow = true;
aFlags |= INTERNAL_LOAD_FLAGS_FIRST_LOAD;
// set opener object to null for noreferrer
if (aFlags & INTERNAL_LOAD_FLAGS_NO_OPENER) {
piNewWin->SetOpenerWindow(nullptr, false);
}
}
}
@ -12634,6 +12649,18 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
}
}
uint32_t flags = INTERNAL_LOAD_FLAGS_NONE;
if (IsElementAnchor(aContent)) {
MOZ_ASSERT(aContent->IsHTML());
if (aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::rel,
NS_LITERAL_STRING("noreferrer"),
aContent->IsInHTMLDocument() ?
eIgnoreCase : eCaseMatters)) {
flags |= INTERNAL_LOAD_FLAGS_DONT_SEND_REFERRER |
INTERNAL_LOAD_FLAGS_NO_OPENER;
}
}
// Get the owner document of the link that was clicked, this will be
// the document that the link is in, or the last document that the
// link was in. From that document, we'll get the URI to use as the
@ -12684,7 +12711,7 @@ nsDocShell::OnLinkClickSync(nsIContent *aContent,
referer, // Referer URI
aContent->NodePrincipal(), // Owner is our node's
// principal
INTERNAL_LOAD_FLAGS_NONE,
flags,
target.get(), // Window target
NS_LossyConvertUTF16toASCII(typeHint).get(),
aFileName, // Download as file

View File

@ -114,6 +114,7 @@ interface nsIDocShell : nsIDocShellTreeItem
const long INTERNAL_LOAD_FLAGS_IS_SRCDOC = 0x40;
const long INTERNAL_LOAD_FLAGS_FIXUP_SCHEME_TYPOS = 0x80;
const long INTERNAL_LOAD_FLAGS_NO_OPENER = 0x100;
/**
* Loads the given URI. This method is identical to loadURI(...) except

View File

@ -0,0 +1,20 @@
function handleRequest(request, response) {
response.setHeader("Content-Type", "text/html");
response.setHeader("Cache-Control", "no-cache");
response.write("<body onload='");
if (!request.hasHeader('Referer')) {
response.write("window.parent.onloadCount++;");
}
if (request.queryString == "newwindow") {
response.write("if (window.opener) { window.opener.parent.onloadCount++; window.opener.parent.doNextStep(); }");
response.write("if (!window.opener) window.close();");
response.write("'>");
} else {
response.write("window.parent.doNextStep();'>");
}
response.write(request.method + " " + Date.now());
response.write("</body>");
}

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<body onload="window.parent.onloadCount++">
<a href="bug530396-noref.sjs" rel="noreferrer" id="target1">bug530396-noref.sjs</a>
<a href="bug530396-noref.sjs?newwindow" rel="noreferrer" id="target2" target="newwindow">bug530396-noref.sjs with new window</a>
</body>
</html>

View File

@ -60,6 +60,9 @@ support-files = file_bug511449.html
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug529119-2.html]
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) # b2g-debug(debug-only failure) b2g-desktop(Bug 931116, b2g desktop specific, initial triage)
[test_bug530396.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Timeouts on B2G desktop
support-files = bug530396-noref.sjs bug530396-subframe.html
[test_bug540462.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
[test_bug551225.html]

View File

@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=530396
-->
<head>
<title>Test for Bug 530396</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=530396">Mozilla Bug 530396</a>
<p>
<iframe id="testFrame" src="http://mochi.test:8888/tests/docshell/test/bug530396-subframe.html"></iframe>
<pre id="test">
<script class="testbody" type="text/javascript">
// NOTE: If we ever make subframes do bfcache stuff, this test will need to be
// modified accordingly! It assumes that subframes do NOT get bfcached.
var onloadCount = 0;
var step = 0;
var gTestFrame = document.getElementById('testFrame');
SimpleTest.waitForExplicitFinish();
addLoadEvent(doNextStep);
function doNextStep() {
++step;
switch (step) {
case 1:
is(onloadCount, 1, "Loaded initial page");
sendMouseEvent({type: "click"}, "target2", gTestFrame.contentWindow);
window.setTimeout(doNextStep, 1000);
break;
case 2:
is(onloadCount, 1, "opener must be null");
sendMouseEvent({type: "click"}, "target1", gTestFrame.contentWindow);
break;
case 3:
is(onloadCount, 2, "don't send referrer with rel=referrer");
SimpleTest.finish();
break;
}
}
</script>
</pre>
</html>

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Activity.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsContentUtils.h"
#include "nsDOMClassInfo.h"
#include "nsIConsoleService.h"
@ -67,7 +67,7 @@ Activity::Initialize(nsPIDOMWindow* aWindow,
NS_ENSURE_SUCCESS(rv, rv);
JS::Rooted<JS::Value> optionsValue(aCx);
if (!aOptions.ToObject(aCx, &optionsValue)) {
if (!ToJSValue(aCx, aOptions, &optionsValue)) {
return NS_ERROR_FAILURE;
}

View File

@ -21,7 +21,14 @@ function convertAppsArray(aApps, aWindow) {
let apps = new aWindow.Array();
for (let i = 0; i < aApps.length; i++) {
let app = aApps[i];
apps.push(createApplicationObject(aWindow, app));
// Our application objects are JS-implemented XPCOM objects with DOM_OBJECT
// set in classinfo. These objects are reflector-per-scope, so as soon as we
// pass them to content, we'll end up with a new object in content. But from
// this code, they _appear_ to be chrome objects, and so the Array Xray code
// vetos the attempt to define a chrome-privileged object on a content Array.
// Very carefully waive Xrays so that this can keep working until we convert
// mozApps to WebIDL in bug 899322.
Cu.waiveXrays(apps)[i] = createApplicationObject(aWindow, app);
}
return apps;

View File

@ -697,7 +697,7 @@ Console::ProfileMethod(JSContext* aCx, const nsAString& aAction,
}
JS::Rooted<JS::Value> eventValue(aCx);
if (!event.ToObject(aCx, &eventValue)) {
if (!ToJSValue(aCx, event, &eventValue)) {
return;
}
@ -1111,7 +1111,7 @@ Console::ProcessCallData(ConsoleCallData* aData)
JSAutoCompartment ac2(cx, xpc::GetJunkScope());
JS::Rooted<JS::Value> eventValue(cx);
if (!event.ToObject(cx, &eventValue)) {
if (!ToJSValue(cx, event, &eventValue)) {
return;
}
@ -1485,7 +1485,7 @@ Console::StartTimer(JSContext* aCx, const JS::Value& aName,
RootedDictionary<ConsoleTimerError> error(aCx);
JS::Rooted<JS::Value> value(aCx);
if (!error.ToObject(aCx, &value)) {
if (!ToJSValue(aCx, error, &value)) {
return JS::UndefinedValue();
}
@ -1517,7 +1517,7 @@ Console::StartTimer(JSContext* aCx, const JS::Value& aName,
timer.mStarted = aTimestamp;
JS::Rooted<JS::Value> value(aCx);
if (!timer.ToObject(aCx, &value)) {
if (!ToJSValue(aCx, timer, &value)) {
return JS::UndefinedValue();
}
@ -1551,7 +1551,7 @@ Console::StopTimer(JSContext* aCx, const JS::Value& aName,
timer.mDuration = aTimestamp - entry;
JS::Rooted<JS::Value> value(aCx);
if (!timer.ToObject(aCx, &value)) {
if (!ToJSValue(aCx, timer, &value)) {
return JS::UndefinedValue();
}
@ -1599,7 +1599,7 @@ Console::IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
RootedDictionary<ConsoleCounterError> error(aCx);
JS::Rooted<JS::Value> value(aCx);
if (!error.ToObject(aCx, &value)) {
if (!ToJSValue(aCx, error, &value)) {
return JS::UndefinedValue();
}
@ -1615,7 +1615,7 @@ Console::IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame,
data.mCount = count;
JS::Rooted<JS::Value> value(aCx);
if (!data.ToObject(aCx, &value)) {
if (!ToJSValue(aCx, data, &value)) {
return JS::UndefinedValue();
}

View File

@ -55,8 +55,9 @@ Crypto::WrapObject(JSContext* aCx)
return CryptoBinding::Wrap(aCx, this);
}
JSObject *
void
Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Called on the wrong thread");
@ -76,17 +77,18 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
break;
default:
aRv.Throw(NS_ERROR_DOM_TYPE_MISMATCH_ERR);
return nullptr;
return;
}
aArray.ComputeLengthAndData();
uint32_t dataLen = aArray.Length();
if (dataLen == 0) {
NS_WARNING("ArrayBufferView length is 0, cannot continue");
return view;
aRetval.set(view);
return;
} else if (dataLen > 65536) {
aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
return nullptr;
return;
}
uint8_t* data = aArray.Data();
@ -98,7 +100,7 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
if (!cc->SendGetRandomValues(dataLen, &randomValues) ||
randomValues.Length() == 0) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
return;
}
NS_ASSERTION(dataLen == randomValues.Length(),
"Invalid length returned from parent process!");
@ -108,14 +110,14 @@ Crypto::GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
if (!buf) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
return;
}
memcpy(data, buf, dataLen);
NS_Free(buf);
}
return view;
aRetval.set(view);
}
SubtleCrypto*

View File

@ -41,8 +41,9 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Crypto)
JSObject *
void
GetRandomValues(JSContext* aCx, const ArrayBufferView& aArray,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
SubtleCrypto*

View File

@ -83,7 +83,7 @@ DOMRequest::GetReadyState(nsAString& aReadyState)
NS_IMETHODIMP
DOMRequest::GetResult(JS::MutableHandle<JS::Value> aResult)
{
aResult.set(Result());
GetResult(nullptr, aResult);
return NS_OK;
}

View File

@ -49,11 +49,12 @@ public:
: DOMRequestReadyState::Pending;
}
JS::Value Result(JSContext* = nullptr) const
void GetResult(JSContext*, JS::MutableHandle<JS::Value> aRetval) const
{
NS_ASSERTION(mDone || mResult == JSVAL_VOID,
"Result should be undefined when pending");
return mResult;
"Result should be undefined when pending");
JS::ExposeValueToActiveJS(mResult);
aRetval.set(mResult);
}
DOMError* GetError() const

View File

@ -1,52 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict"
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
this.EXPORTED_SYMBOLS = ["ObjectWrapper"];
// Makes sure that we expose correctly chrome JS objects to content.
const TypedArrayThings = [
"Int8Array",
"Uint8Array",
"Uint8ClampedArray",
"Int16Array",
"Uint16Array",
"Int32Array",
"Uint32Array",
"Float32Array",
"Float64Array",
];
this.ObjectWrapper = {
getObjectKind: function objWrapper_getObjectKind(aObject) {
if (aObject === null || aObject === undefined) {
return "primitive";
} else if (Array.isArray(aObject)) {
return "array";
} else if (aObject instanceof Ci.nsIDOMFile) {
return "file";
} else if (aObject instanceof Ci.nsIDOMBlob) {
return "blob";
} else if (aObject instanceof Date) {
return "date";
} else if (TypedArrayThings.indexOf(aObject.constructor.name) !== -1) {
return aObject.constructor.name;
} else if (typeof aObject == "object") {
return "object";
} else {
return "primitive";
}
},
wrap: function objWrapper_wrap(aObject, aCtxt) {
dump("-*- ObjectWrapper is deprecated. Use Components.utils.cloneInto() instead.\n");
return Cu.cloneInto(aObject, aCtxt, { cloneFunctions: true });
}
}

View File

@ -137,7 +137,6 @@ EXTRA_COMPONENTS += [
EXTRA_JS_MODULES += [
'DOMRequestHelper.jsm',
'IndexedDBHelper.jsm',
'ObjectWrapper.jsm',
]
FAIL_ON_WARNINGS = True

View File

@ -59,6 +59,7 @@
#include "nsCCUncollectableMarker.h"
#include "mozilla/dom/workers/Workers.h"
#include "mozilla/dom/MessagePortList.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsJSPrincipals.h"
#include "mozilla/Attributes.h"
#include "mozilla/Debug.h"
@ -3928,45 +3929,48 @@ nsGlobalWindow::GetRealTop(nsIDOMWindow** aTop)
return GetTopImpl(outer, aTop, /* aScriptable = */ false);
}
JSObject*
nsGlobalWindow::GetContent(JSContext* aCx, ErrorResult& aError)
void
nsGlobalWindow::GetContent(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetContent, (aCx, aError), aError, nullptr);
FORWARD_TO_OUTER_OR_THROW(GetContent, (aCx, aRetval, aError), aError, );
nsCOMPtr<nsIDOMWindow> content = GetContentInternal(aError);
if (aError.Failed()) {
return nullptr;
return;
}
if (content) {
JS::Rooted<JS::Value> val(aCx);
aError = nsContentUtils::WrapNative(aCx, content, &val);
if (aError.Failed()) {
return nullptr;
return;
}
return &val.toObject();
aRetval.set(&val.toObject());
return;
}
if (!nsContentUtils::IsCallerChrome() || !IsChromeWindow()) {
aError.Throw(NS_ERROR_FAILURE);
return nullptr;
return;
}
// Something tries to get .content on a ChromeWindow, try to fetch the CPOW.
nsCOMPtr<nsIDocShellTreeOwner> treeOwner = GetTreeOwner();
if (!treeOwner) {
aError.Throw(NS_ERROR_FAILURE);
return nullptr;
return;
}
JS::Rooted<JS::Value> val(aCx, JS::NullValue());
aError = treeOwner->GetContentWindow(aCx, &val);
if (aError.Failed()) {
return nullptr;
return;
}
return val.toObjectOrNull();
aRetval.set(val.toObjectOrNull());
}
already_AddRefed<nsIDOMWindow>
@ -4034,7 +4038,8 @@ NS_IMETHODIMP
nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
{
ErrorResult rv;
JS::Rooted<JSObject*> content(aCx, GetContent(aCx, rv));
JS::Rooted<JSObject*> content(aCx);
GetContent(aCx, &content, rv);
if (!rv.Failed()) {
aVal.setObjectOrNull(content);
}
@ -4502,17 +4507,17 @@ nsGlobalWindow::GetOpenerWindow(ErrorResult& aError)
return nullptr;
}
JS::Value
nsGlobalWindow::GetOpener(JSContext* aCx, ErrorResult& aError)
void
nsGlobalWindow::GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{
nsCOMPtr<nsIDOMWindow> opener = GetOpenerWindow(aError);
if (aError.Failed() || !opener) {
return JS::NullValue();
aRetval.setNull();
return;
}
JS::Rooted<JS::Value> val(aCx);
aError = nsContentUtils::WrapNative(aCx, opener, &val);
return val;
aError = nsContentUtils::WrapNative(aCx, opener, aRetval);
}
NS_IMETHODIMP
@ -4520,7 +4525,7 @@ nsGlobalWindow::GetScriptableOpener(JSContext* aCx,
JS::MutableHandle<JS::Value> aOpener)
{
ErrorResult rv;
aOpener.set(GetOpener(aCx, rv));
GetOpener(aCx, aOpener, rv);
return rv.ErrorCode();
}
@ -5825,7 +5830,7 @@ nsGlobalWindow::DispatchResizeEvent(const nsIntSize& aSize)
detail.mWidth = aSize.width;
detail.mHeight = aSize.height;
JS::Rooted<JS::Value> detailValue(cx);
if (!detail.ToObject(cx, &detailValue)) {
if (!ToJSValue(cx, detail, &detailValue)) {
return false;
}
@ -9109,10 +9114,11 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aUrl, nsIVariant* aArgument,
return retVal.forget();
}
JS::Value
void
nsGlobalWindow::ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
JS::Handle<JS::Value> aArgument,
const nsAString& aOptions,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{
nsCOMPtr<nsIVariant> args;
@ -9120,23 +9126,22 @@ nsGlobalWindow::ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
aArgument,
getter_AddRefs(args));
if (aError.Failed()) {
return JS::UndefinedValue();
return;
}
nsCOMPtr<nsIVariant> retVal = ShowModalDialog(aUrl, args, aOptions, aError);
if (aError.Failed()) {
return JS::UndefinedValue();
return;
}
JS::Rooted<JS::Value> result(aCx);
if (retVal) {
aError = nsContentUtils::XPConnect()->VariantToJS(aCx,
FastGetGlobalJSObject(),
retVal, &result);
retVal, aRetval);
} else {
result = JS::NullValue();
aRetval.setNull();
}
return result;
}
NS_IMETHODIMP
@ -10584,10 +10589,12 @@ nsGlobalWindow::GetInterface(const nsIID & aIID, void **aSink)
return *aSink ? NS_OK : NS_ERROR_NO_INTERFACE;
}
JS::Value
nsGlobalWindow::GetInterface(JSContext* aCx, nsIJSID* aIID, ErrorResult& aError)
void
nsGlobalWindow::GetInterface(JSContext* aCx, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{
return dom::GetInterface(aCx, this, aIID, aError);
dom::GetInterface(aCx, this, aIID, aRetval, aError);
}
void
@ -12097,7 +12104,8 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
// Hold strong ref to ourselves while we call the callback.
nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
ErrorResult ignored;
callback->Call(me, handler->GetArgs(), ignored);
JS::Rooted<JS::Value> ignoredVal(CycleCollectedJSRuntime::Get()->Runtime());
callback->Call(me, handler->GetArgs(), &ignoredVal, ignored);
}
// We ignore any failures from calling EvaluateString() on the context or
@ -13622,28 +13630,29 @@ NS_IMPL_ADDREF_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
NS_IMPL_RELEASE_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
JS::Value
nsGlobalWindow::GetDialogArguments(JSContext* aCx, ErrorResult& aError)
void
nsGlobalWindow::GetDialogArguments(JSContext* aCx,
JS::MutableHandle<JS::Value> aRetval,
ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetDialogArguments, (aCx, aError), aError,
JS::UndefinedValue());
FORWARD_TO_OUTER_OR_THROW(GetDialogArguments, (aCx, aRetval, aError),
aError, );
MOZ_ASSERT(IsModalContentWindow(),
"This should only be called on modal windows!");
if (!mDialogArguments) {
MOZ_ASSERT(mIsClosed, "This window should be closed!");
return JS::UndefinedValue();
aRetval.setUndefined();
return;
}
// This does an internal origin check, and returns undefined if the subject
// does not subsumes the origin of the arguments.
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
JSAutoCompartment ac(aCx, wrapper);
JS::Rooted<JS::Value> args(aCx);
mDialogArguments->Get(aCx, wrapper, nsContentUtils::SubjectPrincipal(),
&args, aError);
return args;
aRetval, aError);
}
NS_IMETHODIMP
@ -13657,23 +13666,25 @@ nsGlobalModalWindow::GetDialogArguments(nsIVariant **aArguments)
return mDialogArguments->Get(nsContentUtils::SubjectPrincipal(), aArguments);
}
JS::Value
nsGlobalWindow::GetReturnValue(JSContext* aCx, ErrorResult& aError)
void
nsGlobalWindow::GetReturnValue(JSContext* aCx,
JS::MutableHandle<JS::Value> aReturnValue,
ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetReturnValue, (aCx, aError), aError,
JS::UndefinedValue());
FORWARD_TO_OUTER_OR_THROW(GetReturnValue, (aCx, aReturnValue, aError),
aError, );
MOZ_ASSERT(IsModalContentWindow(),
"This should only be called on modal windows!");
JS::Rooted<JS::Value> returnValue(aCx);
if (mReturnValue) {
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
JSAutoCompartment ac(aCx, wrapper);
mReturnValue->Get(aCx, wrapper, nsContentUtils::SubjectPrincipal(),
&returnValue, aError);
aReturnValue, aError);
} else {
aReturnValue.setUndefined();
}
return returnValue;
}
NS_IMETHODIMP

View File

@ -837,7 +837,8 @@ public:
protected:
nsIDOMWindow* GetOpenerWindow(mozilla::ErrorResult& aError);
public:
JS::Value GetOpener(JSContext* aCx, mozilla::ErrorResult& aError);
void GetOpener(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
void SetOpener(JSContext* aCx, JS::Handle<JS::Value> aOpener,
mozilla::ErrorResult& aError);
using nsIDOMWindow::GetParent;
@ -867,7 +868,11 @@ public:
void Prompt(const nsAString& aMessage, const nsAString& aInitial,
nsAString& aReturn, mozilla::ErrorResult& aError);
void Print(mozilla::ErrorResult& aError);
JS::Value ShowModalDialog(JSContext* aCx, const nsAString& aUrl, JS::Handle<JS::Value> aArgument, const nsAString& aOptions, mozilla::ErrorResult& aError);
void ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
JS::Handle<JS::Value> aArgument,
const nsAString& aOptions,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
const nsAString& aTargetOrigin,
const mozilla::dom::Optional<mozilla::dom::Sequence<JS::Value > >& aTransfer,
@ -986,13 +991,17 @@ public:
const nsAString& aOptions,
const mozilla::dom::Sequence<JS::Value>& aExtraArgument,
mozilla::ErrorResult& aError);
JSObject* GetContent(JSContext* aCx, mozilla::ErrorResult& aError);
JSObject* Get_content(JSContext* aCx, mozilla::ErrorResult& aError)
void GetContent(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& aError);
void Get_content(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetval,
mozilla::ErrorResult& aError)
{
if (mDoc) {
mDoc->WarnOnceAbout(nsIDocument::eWindow_Content);
}
return GetContent(aCx, aError);
GetContent(aCx, aRetval, aError);
}
// ChromeWindow bits. Do NOT call these unless your window is in
@ -1017,13 +1026,16 @@ public:
mozilla::dom::Element* aPanel,
mozilla::ErrorResult& aError);
JS::Value GetDialogArguments(JSContext* aCx, mozilla::ErrorResult& aError);
JS::Value GetReturnValue(JSContext* aCx, mozilla::ErrorResult& aError);
void GetDialogArguments(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
void GetReturnValue(JSContext* aCx, JS::MutableHandle<JS::Value> aReturnValue,
mozilla::ErrorResult& aError);
void SetReturnValue(JSContext* aCx, JS::Handle<JS::Value> aReturnValue,
mozilla::ErrorResult& aError);
JS::Value GetInterface(JSContext* aCx, nsIJSID* aIID,
mozilla::ErrorResult& aError);
void GetInterface(JSContext* aCx, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aError);
protected:
// Array of idle observers that are notified of idle events.

View File

@ -96,50 +96,46 @@ nsHistory::GetLength(ErrorResult& aRv) const
return len >= 0 ? len : 0;
}
JS::Value
nsHistory::GetState(JSContext* aCx, ErrorResult& aRv) const
void
nsHistory::GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv) const
{
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
if (!win) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return JS::UndefinedValue();
return;
}
if (!win->HasActiveDocument()) {
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return JS::UndefinedValue();
return;
}
nsCOMPtr<nsIDocument> doc =
do_QueryInterface(win->GetExtantDoc());
if (!doc) {
aRv.Throw(NS_ERROR_NOT_AVAILABLE);
return JS::UndefinedValue();
return;
}
nsCOMPtr<nsIVariant> variant;
doc->GetStateObject(getter_AddRefs(variant));
if (variant) {
JS::Rooted<JS::Value> jsData(aCx);
aRv = variant->GetAsJSVal(&jsData);
aRv = variant->GetAsJSVal(aResult);
if (aRv.Failed()) {
return JS::UndefinedValue();
return;
}
if (!JS_WrapValue(aCx, &jsData)) {
if (!JS_WrapValue(aCx, aResult)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return JS::UndefinedValue();
}
return jsData;
return;
}
return JS::NullValue();
aResult.setNull();
}
void

View File

@ -37,7 +37,8 @@ public:
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
uint32_t GetLength(mozilla::ErrorResult& aRv) const;
JS::Value GetState(JSContext* aCx, mozilla::ErrorResult& aRv) const;
void GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
mozilla::ErrorResult& aRv) const;
void Go(int32_t aDelta, mozilla::ErrorResult& aRv);
void Back(mozilla::ErrorResult& aRv);
void Forward(mozilla::ErrorResult& aRv);

View File

@ -884,25 +884,22 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
return true;
}
JS::Value
void
GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
nsWrapperCache* aCache, nsIJSID* aIID, ErrorResult& aError)
nsWrapperCache* aCache, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
{
const nsID* iid = aIID->GetID();
nsRefPtr<nsISupports> result;
aError = aRequestor->GetInterface(*iid, getter_AddRefs(result));
if (aError.Failed()) {
return JS::NullValue();
return;
}
JS::Rooted<JS::Value> v(aCx, JSVAL_NULL);
if (!WrapObject(aCx, result, iid, &v)) {
if (!WrapObject(aCx, result, iid, aRetval)) {
aError.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
}
return v;
}
bool

View File

@ -1649,15 +1649,17 @@ WantsQueryInterface
}
};
JS::Value
void
GetInterfaceImpl(JSContext* aCx, nsIInterfaceRequestor* aRequestor,
nsWrapperCache* aCache, nsIJSID* aIID, ErrorResult& aError);
nsWrapperCache* aCache, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError);
template<class T>
JS::Value
GetInterface(JSContext* aCx, T* aThis, nsIJSID* aIID, ErrorResult& aError)
void
GetInterface(JSContext* aCx, T* aThis, nsIJSID* aIID,
JS::MutableHandle<JS::Value> aRetval, ErrorResult& aError)
{
return GetInterfaceImpl(aCx, aThis, aThis, aIID, aError);
GetInterfaceImpl(aCx, aThis, aThis, aIID, aRetval, aError);
}
bool

View File

@ -2143,10 +2143,9 @@ class MethodDefiner(PropertyDefiner):
accessor = "genericCrossOriginMethod"
elif self.descriptor.needsSpecialGenericOps():
if m.get("returnsPromise", False):
raise TypeError("%s returns a Promise but needs "
"special generic ops?" %
accessor)
accessor = "genericMethod"
accessor = "genericPromiseReturningMethod"
else:
accessor = "genericMethod"
elif m.get("returnsPromise", False):
accessor = "GenericPromiseReturningBindingMethod"
else:
@ -5444,7 +5443,7 @@ def getWrapTemplateForType(type, descriptorProvider, result, successCode,
False)
if type.isDictionary():
return (wrapAndSetPtr("%s.ToObject(cx, ${jsvalHandle})" % result),
return (wrapAndSetPtr("%s.ToObjectInternal(cx, ${jsvalHandle})" % result),
False)
if type.isDate():
@ -5594,8 +5593,10 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
1) A CGThing for the type of the return value, or None if there is no need
for a return value.
2) A boolean indicating whether the return value is passed as an out
parameter.
2) A value indicating the kind of ourparam to pass the value as. Valid
options are None to not pass as an out param at all, "ref" (to pass a
reference as an out param), and "ptr" (to pass a pointer as an out
param).
3) A CGThing for a tracer for the return value, or None if no tracing is
needed.
@ -5605,23 +5606,23 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
"""
if returnType is None or returnType.isVoid():
# Nothing to declare
return None, False, None, None
return None, None, None, None
if returnType.isPrimitive() and returnType.tag() in builtinNames:
result = CGGeneric(builtinNames[returnType.tag()])
if returnType.nullable():
result = CGTemplatedType("Nullable", result)
return result, False, None, None
return result, None, None, None
if returnType.isDOMString():
if isMember:
return CGGeneric("nsString"), True, None, None
return CGGeneric("DOMString"), True, None, None
return CGGeneric("nsString"), "ref", None, None
return CGGeneric("DOMString"), "ref", None, None
if returnType.isByteString():
return CGGeneric("nsCString"), True, None, None
return CGGeneric("nsCString"), "ref", None, None
if returnType.isEnum():
result = CGGeneric(returnType.unroll().inner.identifier.name)
if returnType.nullable():
result = CGTemplatedType("Nullable", result)
return result, False, None, None
return result, None, None, None
if returnType.isGeckoInterface():
result = CGGeneric(descriptorProvider.getDescriptor(
returnType.unroll().inner.identifier.name).nativeType)
@ -5632,14 +5633,18 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
result = CGTemplatedType("nsRefPtr", result)
else:
result = CGWrapper(result, post="*")
return result, False, None, None
return result, None, None, None
if returnType.isCallback():
name = returnType.unroll().identifier.name
return CGGeneric("nsRefPtr<%s>" % name), False, None, None
return CGGeneric("nsRefPtr<%s>" % name), None, None, None
if returnType.isAny():
return CGGeneric("JS::Value"), False, None, None
if isMember:
return CGGeneric("JS::Value"), None, None, None
return CGGeneric("JS::Rooted<JS::Value>"), "ptr", None, "cx"
if returnType.isObject() or returnType.isSpiderMonkeyInterface():
return CGGeneric("JSObject*"), False, None, None
if isMember:
return CGGeneric("JSObject*"), None, None, None
return CGGeneric("JS::Rooted<JSObject*>"), "ptr", None, "cx"
if returnType.isSequence():
nullable = returnType.nullable()
if nullable:
@ -5659,7 +5664,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
result = CGTemplatedType("nsTArray", result)
if nullable:
result = CGTemplatedType("Nullable", result)
return result, True, rooter, None
return result, "ref", rooter, None
if returnType.isMozMap():
nullable = returnType.nullable()
if nullable:
@ -5679,7 +5684,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
result = CGTemplatedType("MozMap", result)
if nullable:
result = CGTemplatedType("Nullable", result)
return result, True, rooter, None
return result, "ref", rooter, None
if returnType.isDictionary():
nullable = returnType.nullable()
dictName = CGDictionary.makeDictionaryName(returnType.unroll().inner)
@ -5694,7 +5699,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
if nullable:
result = CGTemplatedType("Nullable", result)
resultArgs = None
return result, True, None, resultArgs
return result, "ref", None, resultArgs
if returnType.isUnion():
result = CGGeneric(CGUnionStruct.unionTypeName(returnType.unroll(), True))
if not isMember and typeNeedsRooting(returnType):
@ -5707,12 +5712,12 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
if returnType.nullable():
result = CGTemplatedType("Nullable", result)
resultArgs = None
return result, True, None, resultArgs
return result, "ref", None, resultArgs
if returnType.isDate():
result = CGGeneric("Date")
if returnType.nullable():
result = CGTemplatedType("Nullable", result)
return result, False, None, None
return result, None, None, None
raise TypeError("Don't know how to declare return value for %s" %
returnType)
@ -5801,8 +5806,13 @@ class CGCallGenerator(CGThing):
args.append(arg)
# Return values that go in outparams go here
if resultOutParam:
args.append(CGGeneric("result"))
if resultOutParam is not None:
if resultOutParam is "ref":
args.append(CGGeneric("result"))
else:
assert resultOutParam is "ptr"
args.append(CGGeneric("&result"))
if isFallible:
args.append(CGGeneric("rv"))
args.extend(CGGeneric(arg) for arg in argsPost)
@ -6904,6 +6914,53 @@ class CGGenericMethod(CGAbstractBindingMethod):
return ok;
"""))
class CGGenericPromiseReturningMethod(CGAbstractBindingMethod):
"""
A class for generating the C++ code for an IDL method that returns a Promise.
Does not handle cross-origin this.
"""
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'),
Argument('unsigned', 'argc'),
Argument('JS::Value*', 'vp')]
unwrapFailureCode = dedent("""
ThrowInvalidThis(cx, args, GetInvalidThisErrorForMethod(%%(securityError)s), "%s");\n
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
args.rval());\n""" %
descriptor.interface.identifier.name)
name = "genericPromiseReturningMethod"
customCallArgs = dedent("""
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
// Make sure to save the callee before someone maybe messes with rval().
JS::Rooted<JSObject*> callee(cx, &args.callee());
""")
CGAbstractBindingMethod.__init__(self, descriptor, name,
args,
callArgs=customCallArgs,
unwrapFailureCode=unwrapFailureCode)
def generate_code(self):
return CGGeneric(dedent("""
const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
MOZ_ASSERT(info->type() == JSJitInfo::Method);
JSJitMethodOp method = info->method;
bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
if (ok) {
#ifdef DEBUG
AssertReturnTypeMatchesJitinfo(info, args.rval());
#endif
return true;
}
MOZ_ASSERT(info->returnType() == JSVAL_TYPE_OBJECT);
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
args.rval());
"""))
class CGSpecializedMethod(CGAbstractStaticMethod):
"""
@ -10153,7 +10210,8 @@ class CGDescriptor(CGThing):
# These are set to true if at least one non-static
# method/getter/setter or jsonifier exist on the interface.
(hasMethod, hasGetter, hasLenientGetter, hasSetter, hasJsonifier,
hasLenientSetter) = False, False, False, False, False, False
hasLenientSetter,
hasPromiseReturningMethod) = False, False, False, False, False, False, False
crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set()
for n in descriptor.interface.namedConstructors:
cgThings.append(CGClassConstructor(descriptor, n,
@ -10176,6 +10234,8 @@ class CGDescriptor(CGThing):
specializedMethod = CGSpecializedMethod(descriptor, m)
cgThings.append(specializedMethod)
if m.returnsPromise():
if descriptor.needsSpecialGenericOps():
hasPromiseReturningMethod = True
cgThings.append(CGMethodPromiseWrapper(descriptor, specializedMethod))
cgThings.append(CGMemberJITInfo(descriptor, m))
if m.getExtendedAttribute("CrossOriginCallable"):
@ -10234,6 +10294,8 @@ class CGDescriptor(CGThing):
cgThings.append(CGMemberJITInfo(descriptor, jsonifierMethod))
if hasMethod:
cgThings.append(CGGenericMethod(descriptor))
if hasPromiseReturningMethod:
cgThings.append(CGGenericPromiseReturningMethod(descriptor))
if len(crossOriginMethods):
cgThings.append(CGGenericMethod(descriptor,
allowCrossOriginThis=True))
@ -10600,7 +10662,7 @@ class CGDictionary(CGThing):
return Init(cx, json);
"""))
def toObjectMethod(self):
def toObjectInternalMethod(self):
body = ""
if self.needToInitIds:
body += fill(
@ -10617,7 +10679,7 @@ class CGDictionary(CGThing):
body += fill(
"""
// Per spec, we define the parent's members first
if (!${dictName}::ToObject(cx, rval)) {
if (!${dictName}::ToObjectInternal(cx, rval)) {
return false;
}
JS::Rooted<JSObject*> obj(cx, &rval.toObject());
@ -10640,7 +10702,7 @@ class CGDictionary(CGThing):
for m in self.memberInfo)
body += "\nreturn true;\n"
return ClassMethod("ToObject", "bool", [
return ClassMethod("ToObjectInternal", "bool", [
Argument('JSContext*', 'cx'),
Argument('JS::MutableHandle<JS::Value>', 'rval'),
], const=True, body=body)
@ -10726,11 +10788,11 @@ class CGDictionary(CGThing):
methods.append(self.initMethod())
methods.append(self.initFromJSONMethod())
try:
methods.append(self.toObjectMethod())
methods.append(self.toObjectInternalMethod())
except MethodNotNewObjectError:
# If we can't have a ToObject() because one of our members can only
# be returned from [NewObject] methods, then just skip generating
# ToObject().
# If we can't have a ToObjectInternal() because one of our members
# can only be returned from [NewObject] methods, then just skip
# generating ToObjectInternal().
pass
methods.append(self.traceDictionaryMethod())
@ -11521,15 +11583,26 @@ class CGNativeMember(ClassMethod):
return ("already_AddRefed<%s>" % type.unroll().identifier.name,
"nullptr", "return ${declName}.forget();\n")
if type.isAny():
return "JS::Value", "JS::UndefinedValue()", "return ${declName};\n"
if isMember:
# No need for a third element in the isMember case
return "JS::Value", None, None
# Outparam
return "void", "", "aRetVal.set(${declName});\n"
if type.isObject():
return "JSObject*", "nullptr", "return ${declName};\n"
if isMember:
# No need for a third element in the isMember case
return "JSObject*", None, None
return "void", "", "aRetVal.set(${declName});\n"
if type.isSpiderMonkeyInterface():
if isMember:
# No need for a third element in the isMember case
return "JSObject*", None, None
if type.nullable():
returnCode = "return ${declName}.IsNull() ? nullptr : ${declName}.Value().Obj();\n"
returnCode = "${declName}.IsNull() ? nullptr : ${declName}.Value().Obj();\n"
else:
returnCode = "return ${declName}.Obj();\n"
return "JSObject*", "nullptr", returnCode
returnCode = "${declName}.Obj();\n"
return "void", "", "aRetVal.set(%s);\n" % returnCode
if type.isSequence():
# If we want to handle sequence-of-sequences return values, we're
# going to need to fix example codegen to not produce nsTArray<void>
@ -11619,6 +11692,11 @@ class CGNativeMember(ClassMethod):
args.append(Argument("%s&" %
CGUnionStruct.unionTypeDecl(returnType, True),
"aRetVal"))
elif returnType.isAny():
args.append(Argument("JS::MutableHandle<JS::Value>", "aRetVal"))
elif returnType.isObject() or returnType.isSpiderMonkeyInterface():
args.append(Argument("JS::MutableHandle<JSObject*>", "aRetVal"))
# And the ErrorResult
if 'infallible' not in self.extendedAttrs:
# Use aRv so it won't conflict with local vars named "rv"
@ -11797,6 +11875,9 @@ class CGNativeMember(ClassMethod):
return Argument(decl.define(), arg.identifier.name)
def arguments(self):
return self.member.signatures()[0][1]
class CGExampleMethod(CGNativeMember):
def __init__(self, descriptor, method, signature, isConstructor, breakAfter=True):
@ -13498,14 +13579,16 @@ class CGEventGetter(CGNativeMember):
if (${memberName}) {
JS::ExposeObjectToActiveJS(${memberName});
}
return ${memberName};
aRetVal.set(${memberName});
return;
""",
memberName=memberName)
if type.isAny():
return fill(
"""
JS::ExposeValueToActiveJS(${memberName});
return ${memberName};
aRetVal.set(${memberName});
return;
""",
memberName=memberName)
if type.isUnion():
@ -13562,9 +13645,9 @@ class CGEventMethod(CGNativeMember):
def declare(self, cgClass):
self.args = list(self.originalArgs)
self.args.insert(0, Argument("mozilla::dom::EventTarget*", "aOwner"))
constructorForNativeCaller = CGNativeMember.declare(self, cgClass) + "\n"
constructorForNativeCaller = CGNativeMember.declare(self, cgClass)
self.args = list(self.originalArgs)
if needCx(None, self.descriptorProvider.interface.members, [], True):
if needCx(None, self.arguments(), [], True):
self.args.insert(0, Argument("JSContext*", "aCx"))
self.args.insert(0, Argument("const GlobalObject&", "aGlobal"))
self.args.append(Argument('ErrorResult&', 'aRv'))
@ -13615,7 +13698,7 @@ class CGEventMethod(CGNativeMember):
""",
arg0=self.args[0].name,
arg1=self.args[1].name)
if needCx(None, self.descriptorProvider.interface.members, [], True):
if needCx(None, self.arguments(), [], True):
self.args.insert(0, Argument("JSContext*", "aCx"))
self.args.insert(0, Argument("const GlobalObject&", "aGlobal"))
self.args.append(Argument('ErrorResult&', 'aRv'))

View File

@ -209,7 +209,7 @@ ToJSValue(JSContext* aCx,
const T& aArgument,
JS::MutableHandle<JS::Value> aValue)
{
return aArgument.ToObject(aCx, aValue);
return aArgument.ToObjectInternal(aCx, aValue);
}
// Accept existing JS values (which may not be same-compartment with us

View File

@ -450,7 +450,7 @@ public:
void PassMozMapOfNullableArrayBuffers(const MozMap<Nullable<ArrayBuffer> >&);
void PassVariadicTypedArray(const Sequence<Float32Array>&);
void PassVariadicNullableTypedArray(const Sequence<Nullable<Float32Array> >&);
JSObject* ReceiveUint8Array(JSContext*);
void ReceiveUint8Array(JSContext*, JS::MutableHandle<JSObject*>);
// DOMString types
void PassString(const nsAString&);
@ -523,7 +523,7 @@ public:
void PassOptionalNullableMozMapOfNullableMozMapOfAny(JSContext*, const Optional<Nullable<MozMap<Nullable<MozMap<JS::Value>>>>>&);
void PassOptionalNullableMozMapOfNullableSequenceOfAny(JSContext*, const Optional<Nullable<MozMap<Nullable<Sequence<JS::Value>>>>>&);
void PassOptionalNullableSequenceOfNullableMozMapOfAny(JSContext*, const Optional<Nullable<Sequence<Nullable<MozMap<JS::Value>>>>>&);
JS::Value ReceiveAny(JSContext*);
void ReceiveAny(JSContext*, JS::MutableHandle<JS::Value>);
// object types
void PassObject(JSContext*, JS::Handle<JSObject*>);
@ -539,8 +539,8 @@ public:
void PassOptionalNullableSequenceOfNullableSequenceOfObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&);
void PassOptionalNullableSequenceOfNullableSequenceOfNullableObject(JSContext*, const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*> > > > >&);
void PassMozMapOfObject(JSContext*, const MozMap<JSObject*>&);
JSObject* ReceiveObject(JSContext*);
JSObject* ReceiveNullableObject(JSContext*);
void ReceiveObject(JSContext*, JS::MutableHandle<JSObject*>);
void ReceiveNullableObject(JSContext*, JS::MutableHandle<JSObject*>);
// Union types
void PassUnion(JSContext*, const ObjectOrLong& arg);
@ -767,7 +767,7 @@ public:
TestInterface* PutForwardsAttr();
TestInterface* PutForwardsAttr2();
TestInterface* PutForwardsAttr3();
JS::Value JsonifierShouldSkipThis(JSContext*);
void GetJsonifierShouldSkipThis(JSContext*, JS::MutableHandle<JS::Value>);
void SetJsonifierShouldSkipThis(JSContext*, JS::Rooted<JS::Value>&);
TestParentInterface* JsonifierShouldSkipThis2();
void SetJsonifierShouldSkipThis2(TestParentInterface&);

View File

@ -429,30 +429,34 @@ BluetoothAdapter::StopDiscovery(ErrorResult& aRv)
return StartStopDiscovery(false, aRv);
}
JS::Value
BluetoothAdapter::GetDevices(JSContext* aContext, ErrorResult& aRv)
void
BluetoothAdapter::GetDevices(JSContext* aContext,
JS::MutableHandle<JS::Value> aDevices,
ErrorResult& aRv)
{
if (!mJsDeviceAddresses) {
BT_WARNING("Devices not yet set!\n");
aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
return;
}
JS::ExposeObjectToActiveJS(mJsDeviceAddresses);
return JS::ObjectValue(*mJsDeviceAddresses);
aDevices.setObject(*mJsDeviceAddresses);
}
JS::Value
BluetoothAdapter::GetUuids(JSContext* aContext, ErrorResult& aRv)
void
BluetoothAdapter::GetUuids(JSContext* aContext,
JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv)
{
if (!mJsUuids) {
BT_WARNING("UUIDs not yet set!\n");
aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
return;
}
JS::ExposeObjectToActiveJS(mJsUuids);
return JS::ObjectValue(*mJsUuids);
aUuids.setObject(*mJsUuids);
}
already_AddRefed<DOMRequest>

View File

@ -83,8 +83,10 @@ public:
return mDiscoverableTimeout;
}
JS::Value GetDevices(JSContext* aContext, ErrorResult& aRv);
JS::Value GetUuids(JSContext* aContext, ErrorResult& aRv);
void GetDevices(JSContext* aContext, JS::MutableHandle<JS::Value> aDevices,
ErrorResult& aRv);
void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv);
already_AddRefed<mozilla::dom::DOMRequest>
SetName(const nsAString& aName, ErrorResult& aRv);

View File

@ -206,30 +206,34 @@ BluetoothDevice::Notify(const BluetoothSignal& aData)
}
}
JS::Value
BluetoothDevice::GetUuids(JSContext* aCx, ErrorResult& aRv)
void
BluetoothDevice::GetUuids(JSContext* aContext,
JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv)
{
if (!mJsUuids) {
BT_WARNING("UUIDs not yet set!");
aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
return;
}
JS::ExposeObjectToActiveJS(mJsUuids);
return JS::ObjectValue(*mJsUuids);
aUuids.setObject(*mJsUuids);
}
JS::Value
BluetoothDevice::GetServices(JSContext* aCx, ErrorResult& aRv)
void
BluetoothDevice::GetServices(JSContext* aCx,
JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv)
{
if (!mJsServices) {
BT_WARNING("Services not yet set!");
aRv.Throw(NS_ERROR_FAILURE);
return JS::Value(JSVAL_NULL);
return;
}
JS::ExposeObjectToActiveJS(mJsServices);
return JS::ObjectValue(*mJsServices);
aServices.setObject(*mJsServices);
}
JSObject*

View File

@ -66,8 +66,10 @@ public:
return mConnected;
}
JS::Value GetUuids(JSContext* aContext, ErrorResult& aRv);
JS::Value GetServices(JSContext* aContext, ErrorResult& aRv);
void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv);
void GetServices(JSContext* aContext, JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv);
nsISupports*
ToISupports()

View File

@ -457,30 +457,34 @@ BluetoothAdapter::StopDiscovery(ErrorResult& aRv)
return StartStopDiscovery(false, aRv);
}
JS::Value
BluetoothAdapter::GetDevices(JSContext* aContext, ErrorResult& aRv)
void
BluetoothAdapter::GetDevices(JSContext* aContext,
JS::MutableHandle<JS::Value> aDevices,
ErrorResult& aRv)
{
if (!mJsDeviceAddresses) {
BT_WARNING("Devices not yet set!\n");
aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
return;
}
JS::ExposeObjectToActiveJS(mJsDeviceAddresses);
return JS::ObjectValue(*mJsDeviceAddresses);
aDevices.setObject(*mJsDeviceAddresses);
}
JS::Value
BluetoothAdapter::GetUuids(JSContext* aContext, ErrorResult& aRv)
void
BluetoothAdapter::GetUuids(JSContext* aContext,
JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv)
{
if (!mJsUuids) {
BT_WARNING("UUIDs not yet set!\n");
aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
return;
}
JS::ExposeObjectToActiveJS(mJsUuids);
return JS::ObjectValue(*mJsUuids);
aUuids.setObject(*mJsUuids);
}
already_AddRefed<DOMRequest>

View File

@ -90,8 +90,10 @@ public:
return mDiscoverableTimeout;
}
JS::Value GetDevices(JSContext* aContext, ErrorResult& aRv);
JS::Value GetUuids(JSContext* aContext, ErrorResult& aRv);
void GetDevices(JSContext* aContext, JS::MutableHandle<JS::Value> aDevices,
ErrorResult& aRv);
void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv);
already_AddRefed<mozilla::dom::DOMRequest>
SetName(const nsAString& aName, ErrorResult& aRv);

View File

@ -206,30 +206,34 @@ BluetoothDevice::Notify(const BluetoothSignal& aData)
}
}
JS::Value
BluetoothDevice::GetUuids(JSContext* aCx, ErrorResult& aRv)
void
BluetoothDevice::GetUuids(JSContext* aContext,
JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv)
{
if (!mJsUuids) {
BT_WARNING("UUIDs not yet set!");
aRv.Throw(NS_ERROR_FAILURE);
return JS::NullValue();
return;
}
JS::ExposeObjectToActiveJS(mJsUuids);
return JS::ObjectValue(*mJsUuids);
aUuids.setObject(*mJsUuids);
}
JS::Value
BluetoothDevice::GetServices(JSContext* aCx, ErrorResult& aRv)
void
BluetoothDevice::GetServices(JSContext* aCx,
JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv)
{
if (!mJsServices) {
BT_WARNING("Services not yet set!");
aRv.Throw(NS_ERROR_FAILURE);
return JS::Value(JSVAL_NULL);
return;
}
JS::ExposeObjectToActiveJS(mJsServices);
return JS::ObjectValue(*mJsServices);
aServices.setObject(*mJsServices);
}
JSObject*

View File

@ -66,8 +66,10 @@ public:
return mConnected;
}
JS::Value GetUuids(JSContext* aContext, ErrorResult& aRv);
JS::Value GetServices(JSContext* aContext, ErrorResult& aRv);
void GetUuids(JSContext* aContext, JS::MutableHandle<JS::Value> aUuids,
ErrorResult& aRv);
void GetServices(JSContext* aContext, JS::MutableHandle<JS::Value> aServices,
ErrorResult& aRv);
nsISupports*
ToISupports()

View File

@ -15,6 +15,7 @@
#include "BrowserElementParent.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/dom/HTMLIFrameElement.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsIDOMCustomEvent.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsVariant.h"
@ -160,7 +161,7 @@ BrowserElementParent::DispatchOpenWindowEvent(Element* aOpenerFrameElement,
JS::Rooted<JSObject*> global(cx, sgo->GetGlobalJSObject());
JSAutoCompartment ac(cx, global);
if (!detail.ToObject(cx, &val)) {
if (!ToJSValue(cx, detail, &val)) {
MOZ_CRASH("Failed to convert dictionary to JS::Value due to OOM.");
return BrowserElementParent::OPEN_WINDOW_IGNORED;
}
@ -332,7 +333,7 @@ NS_IMETHODIMP DispatchAsyncScrollEventRunnable::Run()
JSAutoCompartment ac(cx, globalJSObject);
JS::Rooted<JS::Value> val(cx);
if (!detail.ToObject(cx, &val)) {
if (!ToJSValue(cx, detail, &val)) {
MOZ_CRASH("Failed to convert dictionary to JS::Value due to OOM.");
return NS_ERROR_FAILURE;
}

View File

@ -293,10 +293,12 @@ CameraCapabilities::ExposureCompensationStep() const
return mExposureCompensationStep;
}
JS::Value
CameraCapabilities::RecorderProfiles(JSContext* aCx) const
void
CameraCapabilities::GetRecorderProfiles(JSContext* aCx,
JS::MutableHandle<JS::Value> aRetval) const
{
return mRecorderProfiles;
JS::ExposeValueToActiveJS(mRecorderProfiles);
aRetval.set(mRecorderProfiles);
}
void

View File

@ -71,7 +71,7 @@ public:
double MinExposureCompensation() const;
double MaxExposureCompensation() const;
double ExposureCompensationStep() const;
JS::Value RecorderProfiles(JSContext* cx) const;
void GetRecorderProfiles(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval) const;
void GetIsoModes(nsTArray<nsString>& aRetVal) const;
protected:

View File

@ -7,6 +7,7 @@
#ifndef mozilla_dom_RsaKeyAlgorithm_h
#define mozilla_dom_RsaKeyAlgorithm_h
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/KeyAlgorithm.h"
#include "js/TypeDecls.h"
@ -35,10 +36,16 @@ public:
return mModulusLength;
}
JSObject* PublicExponent(JSContext* cx) const
void GetPublicExponent(JSContext* cx, JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aError) const
{
TypedArrayCreator<Uint8Array> creator(mPublicExponent);
return creator.Create(cx);
JSObject* retval = creator.Create(cx);
if (!retval) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
} else {
aRetval.set(retval);
}
}
virtual bool WriteStructuredClone(JSStructuredCloneWriter* aWriter) const MOZ_OVERRIDE;

View File

@ -129,7 +129,8 @@ DataStoreDB::UpgradeSchema()
AutoSafeJSContext cx;
ErrorResult error;
JS::Rooted<JS::Value> result(cx, mRequest->GetResult(error));
JS::Rooted<JS::Value> result(cx);
mRequest->GetResult(&result, error);
if (NS_WARN_IF(error.Failed())) {
return error.ErrorCode();
}
@ -190,7 +191,8 @@ DataStoreDB::DatabaseOpened()
AutoSafeJSContext cx;
ErrorResult error;
JS::Rooted<JS::Value> result(cx, mRequest->GetResult(error));
JS::Rooted<JS::Value> result(cx);
mRequest->GetResult(&result, error);
if (NS_WARN_IF(error.Failed())) {
return error.ErrorCode();
}

View File

@ -10,6 +10,7 @@
#include "DataStoreService.h"
#include "mozilla/dom/DataStoreBinding.h"
#include "mozilla/dom/indexedDB/IDBObjectStore.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsIDOMEvent.h"
namespace mozilla {
@ -57,7 +58,7 @@ DataStoreRevision::AddRevision(JSContext* aCx,
}
JS::Rooted<JS::Value> value(aCx);
if (!data.ToObject(aCx, &value)) {
if (!ToJSValue(aCx, data, &value)) {
return NS_ERROR_FAILURE;
}

View File

@ -587,7 +587,8 @@ public:
AutoSafeJSContext cx;
ErrorResult error;
JS::Rooted<JS::Value> result(cx, mRequest->GetResult(error));
JS::Rooted<JS::Value> result(cx);
mRequest->GetResult(cx, &result, error);
if (NS_WARN_IF(error.Failed())) {
return error.ErrorCode();
}

View File

@ -34,11 +34,12 @@ TextEncoder::Init(const nsAString& aEncoding, ErrorResult& aRv)
mEncoder = EncodingUtils::EncoderForEncoding(mEncoding);
}
JSObject*
void
TextEncoder::Encode(JSContext* aCx,
JS::Handle<JSObject*> aObj,
const nsAString& aString,
const bool aStream,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv)
{
// Run the steps of the encoding algorithm.
@ -48,7 +49,7 @@ TextEncoder::Encode(JSContext* aCx,
nsresult rv = mEncoder->GetMaxLength(data, srcLen, &maxLen);
if (NS_FAILED(rv)) {
aRv.Throw(rv);
return nullptr;
return;
}
// Need a fallible allocator because the caller may be a content
// and the content can specify the length of the string.
@ -56,7 +57,7 @@ TextEncoder::Encode(JSContext* aCx,
nsAutoArrayPtr<char> buf(new (fallible) char[maxLen + 1]);
if (!buf) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
return;
}
int32_t dstLen = maxLen;
@ -80,14 +81,14 @@ TextEncoder::Encode(JSContext* aCx,
reinterpret_cast<uint8_t*>(buf.get()));
if (!outView) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
return;
}
}
if (NS_FAILED(rv)) {
aRv.Throw(rv);
}
return outView;
aRetval.set(outView);
}
void

View File

@ -46,12 +46,13 @@ public:
return TextEncoderBinding::Wrap(aCx, this, aTookOwnership);
}
JSObject* Encode(JSContext* aCx,
JS::Handle<JSObject*> aObj,
const nsAString& aString,
const TextEncodeOptions& aOptions,
ErrorResult& aRv) {
return TextEncoder::Encode(aCx, aObj, aString, aOptions.mStream, aRv);
void Encode(JSContext* aCx,
JS::Handle<JSObject*> aObj,
const nsAString& aString,
const TextEncodeOptions& aOptions,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv) {
TextEncoder::Encode(aCx, aObj, aString, aOptions.mStream, aRetval, aRv);
}
protected:
@ -85,13 +86,15 @@ public:
* If the streaming option is false, then the encoding
* algorithm state will get reset. If set to true then
* the previous encoding is reused/continued.
* @return JSObject* The Uint8Array wrapped in a JS object.
* @return JSObject* The Uint8Array wrapped in a JS object. Returned via
* the aRetval out param.
*/
JSObject* Encode(JSContext* aCx,
JS::Handle<JSObject*> aObj,
const nsAString& aString,
const bool aStream,
ErrorResult& aRv);
void Encode(JSContext* aCx,
JS::Handle<JSObject*> aObj,
const nsAString& aString,
const bool aStream,
JS::MutableHandle<JSObject*> aRetval,
ErrorResult& aRv);
private:
nsCString mEncoding;

View File

@ -640,27 +640,27 @@ DataTransfer::MozGetDataAt(const nsAString& aFormat, uint32_t aIndex,
return NS_OK;
}
JS::Value
void
DataTransfer::MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
uint32_t aIndex, mozilla::ErrorResult& aRv)
uint32_t aIndex,
JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aRv)
{
nsCOMPtr<nsIVariant> data;
aRv = MozGetDataAt(aFormat, aIndex, getter_AddRefs(data));
if (aRv.Failed()) {
return JS::UndefinedValue();
return;
}
if (!data) {
return JS::NullValue();
return;
}
JS::Rooted<JS::Value> result(aCx);
if (!VariantToJsval(aCx, data, &result)) {
if (!VariantToJsval(aCx, data, aRetval)) {
aRv = NS_ERROR_FAILURE;
return JS::UndefinedValue();
return;
}
return result;
}
NS_IMETHODIMP

View File

@ -164,8 +164,9 @@ public:
void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
JS::Handle<JS::Value> aData, uint32_t aIndex,
mozilla::ErrorResult& aRv);
JS::Value MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
uint32_t aIndex, mozilla::ErrorResult& aRv);
void MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval,
mozilla::ErrorResult& aRv);
bool MozUserCancelled()
{
return mUserCancelled;

View File

@ -18,6 +18,7 @@
#include "nsDOMJSUtils.h"
#include "WorkerPrivate.h"
#include "mozilla/ContentEvents.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/HoldDropJSObjects.h"
#include "mozilla/JSEventHandler.h"
#include "mozilla/Likely.h"
@ -155,7 +156,7 @@ JSEventHandler::HandleEvent(nsIDOMEvent* aEvent)
ThreadsafeAutoJSContext cx;
error.Construct(cx);
error.Value() = scriptEvent->Error(cx);
scriptEvent->GetError(cx, &error.Value());
} else {
msgOrEvent.SetAsEvent() = aEvent->InternalDOMEvent();
}
@ -210,8 +211,8 @@ JSEventHandler::HandleEvent(nsIDOMEvent* aEvent)
MOZ_ASSERT(mTypedHandler.Type() == TypedEventHandler::eNormal);
ErrorResult rv;
nsRefPtr<EventHandlerNonNull> handler = mTypedHandler.NormalEventHandler();
JS::Value retval =
handler->Call(mTarget, *(aEvent->InternalDOMEvent()), rv);
JS::Rooted<JS::Value> retval(CycleCollectedJSRuntime::Get()->Runtime());
handler->Call(mTarget, *(aEvent->InternalDOMEvent()), &retval, rv);
if (rv.Failed()) {
return rv.ErrorCode();
}

View File

@ -66,18 +66,19 @@ NS_IMETHODIMP
MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData)
{
ErrorResult rv;
aData.set(GetData(aCx, rv));
GetData(aCx, aData, rv);
return rv.ErrorCode();
}
JS::Value
MessageEvent::GetData(JSContext* aCx, ErrorResult& aRv)
void
MessageEvent::GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
ErrorResult& aRv)
{
JS::Rooted<JS::Value> data(aCx, mData);
if (!JS_WrapValue(aCx, &data)) {
JS::ExposeValueToActiveJS(mData);
aData.set(mData);
if (!JS_WrapValue(aCx, aData)) {
aRv.Throw(NS_ERROR_FAILURE);
}
return data;
}
NS_IMETHODIMP

View File

@ -46,7 +46,8 @@ public:
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
JS::Value GetData(JSContext* aCx, ErrorResult& aRv);
void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
ErrorResult& aRv);
void GetSource(Nullable<OwningWindowProxyOrMessagePort>& aValue) const;

View File

@ -610,14 +610,16 @@ IDBCursor::GetSource(OwningIDBObjectStoreOrIDBIndex& aSource) const
}
}
JS::Value
IDBCursor::GetKey(JSContext* aCx, ErrorResult& aRv)
void
IDBCursor::GetKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mKey.IsUnset() || !mHaveValue);
if (!mHaveValue) {
return JSVAL_VOID;
aResult.setUndefined();
return;
}
if (!mHaveCachedKey) {
@ -627,21 +629,26 @@ IDBCursor::GetKey(JSContext* aCx, ErrorResult& aRv)
}
aRv = mKey.ToJSVal(aCx, mCachedKey);
ENSURE_SUCCESS(aRv, JSVAL_VOID);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
mHaveCachedKey = true;
}
return mCachedKey;
JS::ExposeValueToActiveJS(mCachedKey);
aResult.set(mCachedKey);
}
JS::Value
IDBCursor::GetPrimaryKey(JSContext* aCx, ErrorResult& aRv)
void
IDBCursor::GetPrimaryKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
if (!mHaveValue) {
return JSVAL_VOID;
aResult.setUndefined();
return;
}
if (!mHaveCachedPrimaryKey) {
@ -655,22 +662,27 @@ IDBCursor::GetPrimaryKey(JSContext* aCx, ErrorResult& aRv)
MOZ_ASSERT(!key.IsUnset());
aRv = key.ToJSVal(aCx, mCachedPrimaryKey);
ENSURE_SUCCESS(aRv, JSVAL_VOID);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
mHaveCachedPrimaryKey = true;
}
return mCachedPrimaryKey;
JS::ExposeValueToActiveJS(mCachedPrimaryKey);
aResult.set(mCachedPrimaryKey);
}
JS::Value
IDBCursor::GetValue(JSContext* aCx, ErrorResult& aRv)
void
IDBCursor::GetValue(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mType == OBJECTSTORE || mType == INDEXOBJECT);
if (!mHaveValue) {
return JSVAL_VOID;
aResult.setUndefined();
return;
}
if (!mHaveCachedValue) {
@ -682,7 +694,7 @@ IDBCursor::GetValue(JSContext* aCx, ErrorResult& aRv)
JS::Rooted<JS::Value> val(aCx);
if (!IDBObjectStore::DeserializeValue(aCx, mCloneReadInfo, &val)) {
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
return JSVAL_VOID;
return;
}
mCloneReadInfo.mCloneBuffer.clear();
@ -691,7 +703,8 @@ IDBCursor::GetValue(JSContext* aCx, ErrorResult& aRv)
mHaveCachedValue = true;
}
return mCachedValue;
JS::ExposeValueToActiveJS(mCachedValue);
aResult.set(mCachedValue);
}
void

View File

@ -184,11 +184,13 @@ public:
IDBCursorDirection
GetDirection() const;
JS::Value
GetKey(JSContext* aCx, ErrorResult& aRv);
void
GetKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
JS::Value
GetPrimaryKey(JSContext* aCx, ErrorResult& aRv);
void
GetPrimaryKey(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
already_AddRefed<IDBRequest>
Update(JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv);
@ -202,8 +204,9 @@ public:
already_AddRefed<IDBRequest>
Delete(JSContext* aCx, ErrorResult& aRv);
JS::Value
GetValue(JSContext* aCx, ErrorResult& aRv);
void
GetValue(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
protected:
IDBCursor();

View File

@ -826,24 +826,30 @@ IDBIndex::WrapObject(JSContext* aCx)
return IDBIndexBinding::Wrap(aCx, this);
}
JS::Value
IDBIndex::GetKeyPath(JSContext* aCx, ErrorResult& aRv)
void
IDBIndex::GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!mCachedKeyPath.isUndefined()) {
return mCachedKeyPath;
JS::ExposeValueToActiveJS(mCachedKeyPath);
aResult.set(mCachedKeyPath);
return;
}
aRv = GetKeyPath().ToJSVal(aCx, mCachedKeyPath);
ENSURE_SUCCESS(aRv, JSVAL_VOID);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (mCachedKeyPath.isGCThing()) {
mozilla::HoldJSObjects(this);
mRooted = true;
}
return mCachedKeyPath;
JS::ExposeValueToActiveJS(mCachedKeyPath);
aResult.set(mCachedKeyPath);
}
already_AddRefed<IDBRequest>

View File

@ -176,8 +176,9 @@ public:
return mObjectStore;
}
JS::Value
GetKeyPath(JSContext* aCx, ErrorResult& aRv);
void
GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
bool
MultiEntry() const

View File

@ -164,8 +164,9 @@ IDBKeyRange::WrapObject(JSContext* aCx)
return IDBKeyRangeBinding::Wrap(aCx, this);
}
JS::Value
IDBKeyRange::GetLower(JSContext* aCx, ErrorResult& aRv)
void
IDBKeyRange::GetLower(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -177,17 +178,19 @@ IDBKeyRange::GetLower(JSContext* aCx, ErrorResult& aRv)
aRv = Lower().ToJSVal(aCx, mCachedLowerVal);
if (aRv.Failed()) {
return JS::UndefinedValue();
return;
}
mHaveCachedLowerVal = true;
}
return mCachedLowerVal;
JS::ExposeValueToActiveJS(mCachedLowerVal);
aResult.set(mCachedLowerVal);
}
JS::Value
IDBKeyRange::GetUpper(JSContext* aCx, ErrorResult& aRv)
void
IDBKeyRange::GetUpper(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
@ -199,13 +202,14 @@ IDBKeyRange::GetUpper(JSContext* aCx, ErrorResult& aRv)
aRv = Upper().ToJSVal(aCx, mCachedUpperVal);
if (aRv.Failed()) {
return JS::UndefinedValue();
return;
}
mHaveCachedUpperVal = true;
}
return mCachedUpperVal;
JS::ExposeValueToActiveJS(mCachedUpperVal);
aResult.set(mCachedUpperVal);
}
// static

View File

@ -156,11 +156,13 @@ public:
return mGlobal;
}
JS::Value
GetLower(JSContext* aCx, ErrorResult& aRv);
void
GetLower(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
JS::Value
GetUpper(JSContext* aCx, ErrorResult& aRv);
void
GetUpper(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
bool
LowerOpen() const

View File

@ -2622,24 +2622,30 @@ IDBObjectStore::WrapObject(JSContext* aCx)
return IDBObjectStoreBinding::Wrap(aCx, this);
}
JS::Value
IDBObjectStore::GetKeyPath(JSContext* aCx, ErrorResult& aRv)
void
IDBObjectStore::GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!mCachedKeyPath.isUndefined()) {
return mCachedKeyPath;
JS::ExposeValueToActiveJS(mCachedKeyPath);
aResult.set(mCachedKeyPath);
return;
}
aRv = GetKeyPath().ToJSVal(aCx, mCachedKeyPath);
ENSURE_SUCCESS(aRv, JSVAL_VOID);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (mCachedKeyPath.isGCThing()) {
mozilla::HoldJSObjects(this);
mRooted = true;
}
return mCachedKeyPath;
JS::ExposeValueToActiveJS(mCachedKeyPath);
aResult.set(mCachedKeyPath);
}
already_AddRefed<DOMStringList>

View File

@ -282,8 +282,9 @@ public:
aName.Assign(mName);
}
JS::Value
GetKeyPath(JSContext* aCx, ErrorResult& aRv);
void
GetKeyPath(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv);
already_AddRefed<DOMStringList>
GetIndexNames(ErrorResult& aRv);

View File

@ -326,8 +326,9 @@ IDBRequest::WrapObject(JSContext* aCx)
return IDBRequestBinding::Wrap(aCx, this);
}
JS::Value
IDBRequest::GetResult(mozilla::ErrorResult& aRv) const
void
IDBRequest::GetResult(JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv) const
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -336,7 +337,8 @@ IDBRequest::GetResult(mozilla::ErrorResult& aRv) const
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR);
}
return mResultVal;
JS::ExposeValueToActiveJS(mResultVal);
aResult.set(mResultVal);
}
mozilla::dom::DOMError*

View File

@ -131,13 +131,14 @@ public:
return GetOwner();
}
JS::Value
GetResult(ErrorResult& aRv) const;
void
GetResult(JS::MutableHandle<JS::Value> aResult, ErrorResult& aRv) const;
JS::Value
GetResult(JSContext* aCx, ErrorResult& aRv) const
void
GetResult(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
ErrorResult& aRv) const
{
return GetResult(aRv);
GetResult(aResult, aRv);
}
IDBTransaction*

View File

@ -408,7 +408,8 @@ IndexedDBDatabaseParent::HandleRequestEvent(nsIDOMEvent* aEvent,
AutoSafeJSContext cx;
ErrorResult error;
JS::Rooted<JS::Value> result(cx, mOpenRequest->GetResult(cx, error));
JS::Rooted<JS::Value> result(cx);
mOpenRequest->GetResult(cx, &result, error);
ENSURE_SUCCESS(error, error.ErrorCode());
MOZ_ASSERT(!result.isPrimitive());

View File

@ -10,6 +10,7 @@
#include "mozilla/dom/MozClirModeEvent.h"
#include "mozilla/dom/MozEmergencyCbModeEvent.h"
#include "mozilla/dom/MozOtaStatusEvent.h"
#include "mozilla/dom/ToJSValue.h"
#include "mozilla/dom/USSDReceivedEvent.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
@ -605,7 +606,7 @@ MobileConnection::SetCallForwardingOption(const MozCallForwardingOptions& aOptio
AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx);
if (!aOptions.ToObject(cx, &options)) {
if (!ToJSValue(cx, aOptions, &options)) {
aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr;
}
@ -636,7 +637,7 @@ MobileConnection::GetCallBarringOption(const MozCallBarringOptions& aOptions,
AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx);
if (!aOptions.ToObject(cx, &options)) {
if (!ToJSValue(cx, aOptions, &options)) {
aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr;
}
@ -667,7 +668,7 @@ MobileConnection::SetCallBarringOption(const MozCallBarringOptions& aOptions,
AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx);
if (!aOptions.ToObject(cx, &options)) {
if (!ToJSValue(cx, aOptions, &options)) {
aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr;
}
@ -698,7 +699,7 @@ MobileConnection::ChangeCallBarringPassword(const MozCallBarringOptions& aOption
AutoSafeJSContext cx;
JS::Rooted<JS::Value> options(cx);
if (!aOptions.ToObject(cx, &options)) {
if (!ToJSValue(cx, aOptions, &options)) {
aRv.Throw(NS_ERROR_TYPE_ERR);
return nullptr;
}

View File

@ -60,46 +60,28 @@ public:
return mTnf;
}
JSObject* GetType(JSContext* cx) const
void GetType(JSContext* cx, JS::MutableHandle<JSObject*> retval) const
{
if (mType) {
return GetTypeObject();
} else {
return nullptr;
JS::ExposeObjectToActiveJS(mType);
}
}
JSObject* GetTypeObject() const
{
JS::ExposeObjectToActiveJS(mType);
return mType;
retval.set(mType);
}
JSObject* GetId(JSContext* cx) const
void GetId(JSContext* cx, JS::MutableHandle<JSObject*> retval) const
{
if (mId) {
return GetIdObject();
} else {
return nullptr;
JS::ExposeObjectToActiveJS(mId);
}
}
JSObject* GetIdObject() const
{
JS::ExposeObjectToActiveJS(mId);
return mId;
retval.set(mId);
}
JSObject* GetPayload(JSContext* cx) const
void GetPayload(JSContext* cx, JS::MutableHandle<JSObject*> retval) const
{
if (mPayload) {
return GetPayloadObject();
} else {
return nullptr;
JS::ExposeObjectToActiveJS(mPayload);
}
}
JSObject* GetPayloadObject() const
{
JS::ExposeObjectToActiveJS(mPayload);
return mPayload;
retval.set(mPayload);
}
private:

View File

@ -17,7 +17,6 @@ const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
XPCOMUtils.defineLazyServiceGetter(this,
"appsService",

View File

@ -219,8 +219,8 @@ WrapperPromiseCallback::Call(JSContext* aCx,
// If invoking callback threw an exception, run resolver's reject with the
// thrown exception as argument and the synchronous flag set.
JS::Rooted<JS::Value> retValue(aCx,
mCallback->Call(value, rv, CallbackObject::eRethrowExceptions));
JS::Rooted<JS::Value> retValue(aCx);
mCallback->Call(value, &retValue, rv, CallbackObject::eRethrowExceptions);
rv.WouldReportJSException();

View File

@ -9,7 +9,6 @@ let Ci = Components.interfaces;
let Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
this.EXPORTED_SYMBOLS = ["SettingsDB", "SETTINGSDB_NAME", "SETTINGSSTORE_NAME"];
@ -18,6 +17,18 @@ function debug(s) {
if (DEBUG) dump("-*- SettingsDB: " + s + "\n");
}
const TYPED_ARRAY_THINGS = new Set([
"Int8Array",
"Uint8Array",
"Uint8ClampedArray",
"Int16Array",
"Uint16Array",
"Int32Array",
"Uint32Array",
"Float32Array",
"Float64Array",
]);
this.SETTINGSDB_NAME = "settings";
this.SETTINGSDB_VERSION = 4;
this.SETTINGSSTORE_NAME = "settings";
@ -176,9 +187,29 @@ SettingsDB.prototype = {
return aValue
},
getObjectKind: function(aObject) {
if (aObject === null || aObject === undefined) {
return "primitive";
} else if (Array.isArray(aObject)) {
return "array";
} else if (aObject instanceof Ci.nsIDOMFile) {
return "file";
} else if (aObject instanceof Ci.nsIDOMBlob) {
return "blob";
} else if (aObject.constructor.name == "Date") {
return "date";
} else if (TYPED_ARRAY_THINGS.has(aObject.constructor.name)) {
return aObject.constructor.name;
} else if (typeof aObject == "object") {
return "object";
} else {
return "primitive";
}
},
// Makes sure any property that is a data: uri gets converted to a Blob.
prepareValue: function(aObject) {
let kind = ObjectWrapper.getObjectKind(aObject);
let kind = this.getObjectKind(aObject);
if (kind == "array") {
let res = [];
aObject.forEach(function(aObj) {

View File

@ -17,7 +17,6 @@ Cu.import("resource://gre/modules/SettingsQueue.jsm");
Cu.import("resource://gre/modules/SettingsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
@ -197,6 +196,13 @@ SettingsLock.prototype = {
},
_serializePreservingBinaries: function _serializePreservingBinaries(aObject) {
function needsUUID(aValue) {
if (!aValue || !aValue.constructor) {
return false;
}
return (aValue.constructor.name == "Date") || (aValue instanceof Ci.nsIDOMFile) ||
(aValue instanceof Ci.nsIDOMBlob);
}
// We need to serialize settings objects, otherwise they can change between
// the set() call and the enqueued request being processed. We can't simply
// parse(stringify(obj)) because that breaks things like Blobs, Files and
@ -206,8 +212,7 @@ SettingsLock.prototype = {
let binaries = Object.create(null);
let stringified = JSON.stringify(aObject, function(key, value) {
value = manager._settingsDB.prepareValue(value);
let kind = ObjectWrapper.getObjectKind(value);
if (kind == "file" || kind == "blob" || kind == "date") {
if (needsUUID(value)) {
let uuid = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator)
.generateUUID().toString();
binaries[uuid] = value;

Some files were not shown because too many files have changed in this diff Show More