1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #include "IDBFileRequest.h"
8
9 #include "IDBFileHandle.h"
10 #include "js/RootingAPI.h"
11 #include "jsapi.h"
12 #include "mozilla/Assertions.h"
13 #include "mozilla/dom/IDBFileRequestBinding.h"
14 #include "mozilla/dom/ProgressEvent.h"
15 #include "mozilla/dom/ScriptSettings.h"
16 #include "mozilla/EventDispatcher.h"
17 #include "nsCOMPtr.h"
18 #include "nsDebug.h"
19 #include "nsError.h"
20 #include "nsLiteralString.h"
21
22 namespace mozilla {
23 namespace dom {
24
25 using namespace mozilla::dom::indexedDB;
26
IDBFileRequest(nsPIDOMWindowInner * aWindow,IDBFileHandle * aFileHandle,bool aWrapAsDOMRequest)27 IDBFileRequest::IDBFileRequest(nsPIDOMWindowInner* aWindow,
28 IDBFileHandle* aFileHandle,
29 bool aWrapAsDOMRequest)
30 : DOMRequest(aWindow)
31 , FileRequestBase(DEBUGONLY(aFileHandle->OwningThread()))
32 , mFileHandle(aFileHandle)
33 , mWrapAsDOMRequest(aWrapAsDOMRequest)
34 {
35 AssertIsOnOwningThread();
36 }
37
~IDBFileRequest()38 IDBFileRequest::~IDBFileRequest()
39 {
40 AssertIsOnOwningThread();
41 }
42
43 // static
44 already_AddRefed<IDBFileRequest>
Create(nsPIDOMWindowInner * aOwner,IDBFileHandle * aFileHandle,bool aWrapAsDOMRequest)45 IDBFileRequest::Create(nsPIDOMWindowInner* aOwner, IDBFileHandle* aFileHandle,
46 bool aWrapAsDOMRequest)
47 {
48 MOZ_ASSERT(aFileHandle);
49 aFileHandle->AssertIsOnOwningThread();
50
51 RefPtr<IDBFileRequest> request =
52 new IDBFileRequest(aOwner, aFileHandle, aWrapAsDOMRequest);
53
54 return request.forget();
55 }
56
NS_IMPL_ADDREF_INHERITED(IDBFileRequest,DOMRequest)57 NS_IMPL_ADDREF_INHERITED(IDBFileRequest, DOMRequest)
58 NS_IMPL_RELEASE_INHERITED(IDBFileRequest, DOMRequest)
59
60 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBFileRequest)
61 NS_INTERFACE_MAP_END_INHERITING(DOMRequest)
62
63 NS_IMPL_CYCLE_COLLECTION_INHERITED(IDBFileRequest, DOMRequest,
64 mFileHandle)
65
66 nsresult
67 IDBFileRequest::PreHandleEvent(EventChainPreVisitor& aVisitor)
68 {
69 AssertIsOnOwningThread();
70
71 aVisitor.mCanHandle = true;
72 aVisitor.mParentTarget = mFileHandle;
73 return NS_OK;
74 }
75
76 // virtual
77 JSObject*
WrapObject(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)78 IDBFileRequest::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
79 {
80 AssertIsOnOwningThread();
81
82 if (mWrapAsDOMRequest) {
83 return DOMRequest::WrapObject(aCx, aGivenProto);
84 }
85 return IDBFileRequestBinding::Wrap(aCx, this, aGivenProto);
86 }
87
88 mozilla::dom::FileHandleBase*
FileHandle() const89 IDBFileRequest::FileHandle() const
90 {
91 AssertIsOnOwningThread();
92
93 return mFileHandle;
94 }
95
96 void
OnProgress(uint64_t aProgress,uint64_t aProgressMax)97 IDBFileRequest::OnProgress(uint64_t aProgress, uint64_t aProgressMax)
98 {
99 AssertIsOnOwningThread();
100
101 FireProgressEvent(aProgress, aProgressMax);
102 }
103
104 void
SetResultCallback(ResultCallback * aCallback)105 IDBFileRequest::SetResultCallback(ResultCallback* aCallback)
106 {
107 AssertIsOnOwningThread();
108 MOZ_ASSERT(aCallback);
109
110 AutoJSAPI autoJS;
111 if (NS_WARN_IF(!autoJS.Init(GetOwner()))) {
112 FireError(NS_ERROR_DOM_FILEHANDLE_UNKNOWN_ERR);
113 return;
114 }
115
116 JSContext* cx = autoJS.cx();
117
118 JS::Rooted<JS::Value> result(cx);
119 nsresult rv = aCallback->GetResult(cx, &result);
120 if (NS_WARN_IF(NS_FAILED(rv))) {
121 FireError(rv);
122 } else {
123 FireSuccess(result);
124 }
125 }
126
127 void
SetError(nsresult aError)128 IDBFileRequest::SetError(nsresult aError)
129 {
130 AssertIsOnOwningThread();
131
132 FireError(aError);
133 }
134
135 void
FireProgressEvent(uint64_t aLoaded,uint64_t aTotal)136 IDBFileRequest::FireProgressEvent(uint64_t aLoaded, uint64_t aTotal)
137 {
138 AssertIsOnOwningThread();
139
140 if (NS_FAILED(CheckInnerWindowCorrectness())) {
141 return;
142 }
143
144 ProgressEventInit init;
145 init.mBubbles = false;
146 init.mCancelable = false;
147 init.mLengthComputable = false;
148 init.mLoaded = aLoaded;
149 init.mTotal = aTotal;
150
151 RefPtr<ProgressEvent> event =
152 ProgressEvent::Constructor(this, NS_LITERAL_STRING("progress"), init);
153 DispatchTrustedEvent(event);
154 }
155
156 } // namespace dom
157 } // namespace mozilla
158