1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=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 "DOMRequest.h"
8 :
9 : #include "mozilla/Util.h"
10 : #include "nsDOMClassInfo.h"
11 : #include "DOMError.h"
12 : #include "nsEventDispatcher.h"
13 : #include "nsIPrivateDOMEvent.h"
14 : #include "nsDOMEvent.h"
15 :
16 : using mozilla::dom::DOMRequest;
17 : using mozilla::dom::DOMRequestService;
18 :
19 0 : DOMRequest::DOMRequest(nsIDOMWindow* aWindow)
20 : : mDone(false)
21 : , mResult(JSVAL_VOID)
22 0 : , mRooted(false)
23 : {
24 0 : nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
25 0 : BindToOwner(window->IsInnerWindow() ? window.get() :
26 0 : window->GetCurrentInnerWindow());
27 0 : }
28 :
29 : DOMCI_DATA(DOMRequest, DOMRequest)
30 :
31 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(DOMRequest)
32 :
33 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMRequest,
34 : nsDOMEventTargetHelper)
35 0 : NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(success)
36 0 : NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(error)
37 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
38 :
39 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMRequest,
40 : nsDOMEventTargetHelper)
41 0 : tmp->mResult = JSVAL_VOID;
42 0 : tmp->UnrootResultVal();
43 0 : NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(success)
44 0 : NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(error)
45 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
46 :
47 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(DOMRequest,
48 : nsDOMEventTargetHelper)
49 : // Don't need NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER because
50 : // nsDOMEventTargetHelper does it for us.
51 0 : if (JSVAL_IS_GCTHING(tmp->mResult)) {
52 0 : void *gcThing = JSVAL_TO_GCTHING(tmp->mResult);
53 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing, "mResult")
54 : }
55 0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
56 :
57 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMRequest)
58 0 : NS_INTERFACE_MAP_ENTRY(nsIDOMDOMRequest)
59 0 : NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMRequest)
60 0 : NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
61 :
62 0 : NS_IMPL_ADDREF_INHERITED(DOMRequest, nsDOMEventTargetHelper)
63 0 : NS_IMPL_RELEASE_INHERITED(DOMRequest, nsDOMEventTargetHelper)
64 :
65 0 : NS_IMPL_EVENT_HANDLER(DOMRequest, success);
66 0 : NS_IMPL_EVENT_HANDLER(DOMRequest, error);
67 :
68 : NS_IMETHODIMP
69 0 : DOMRequest::GetReadyState(nsAString& aReadyState)
70 : {
71 0 : mDone ? aReadyState.AssignLiteral("done") :
72 0 : aReadyState.AssignLiteral("pending");
73 :
74 0 : return NS_OK;
75 : }
76 :
77 : NS_IMETHODIMP
78 0 : DOMRequest::GetResult(jsval* aResult)
79 : {
80 0 : NS_ASSERTION(mDone || mResult == JSVAL_VOID,
81 : "Result should be undefined when pending");
82 0 : *aResult = mResult;
83 :
84 0 : return NS_OK;
85 : }
86 :
87 : NS_IMETHODIMP
88 0 : DOMRequest::GetError(nsIDOMDOMError** aError)
89 : {
90 0 : NS_ASSERTION(mDone || !mError,
91 : "Error should be null when pending");
92 :
93 0 : NS_IF_ADDREF(*aError = mError);
94 :
95 0 : return NS_OK;
96 : }
97 :
98 : void
99 0 : DOMRequest::FireSuccess(jsval aResult)
100 : {
101 0 : NS_ABORT_IF_FALSE(!mDone, "Already fired success/error");
102 :
103 0 : mDone = true;
104 0 : RootResultVal();
105 0 : mResult = aResult;
106 :
107 0 : FireEvent(NS_LITERAL_STRING("success"));
108 0 : }
109 :
110 : void
111 0 : DOMRequest::FireError(const nsAString& aError)
112 : {
113 0 : NS_ABORT_IF_FALSE(!mDone, "Already fired success/error");
114 :
115 0 : mDone = true;
116 0 : mError = DOMError::CreateWithName(aError);
117 :
118 0 : FireEvent(NS_LITERAL_STRING("error"));
119 0 : }
120 :
121 : void
122 0 : DOMRequest::FireEvent(const nsAString& aType)
123 : {
124 0 : if (NS_FAILED(CheckInnerWindowCorrectness())) {
125 0 : return;
126 : }
127 :
128 0 : nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
129 0 : nsresult rv = event->InitEvent(aType, false, false);
130 0 : if (NS_FAILED(rv)) {
131 : return;
132 : }
133 :
134 0 : rv = event->SetTrusted(PR_TRUE);
135 0 : if (NS_FAILED(rv)) {
136 : return;
137 : }
138 :
139 : bool dummy;
140 0 : DispatchEvent(event, &dummy);
141 : }
142 :
143 0 : NS_IMPL_ISUPPORTS1(DOMRequestService, nsIDOMRequestService)
144 :
145 : NS_IMETHODIMP
146 0 : DOMRequestService::CreateRequest(nsIDOMWindow* aWindow,
147 : nsIDOMDOMRequest** aRequest)
148 : {
149 0 : NS_ADDREF(*aRequest = new DOMRequest(aWindow));
150 :
151 0 : return NS_OK;
152 : }
153 :
154 : NS_IMETHODIMP
155 0 : DOMRequestService::FireSuccess(nsIDOMDOMRequest* aRequest,
156 : const jsval& aResult)
157 : {
158 0 : static_cast<DOMRequest*>(aRequest)->FireSuccess(aResult);
159 :
160 0 : return NS_OK;
161 : }
162 :
163 : NS_IMETHODIMP
164 0 : DOMRequestService::FireError(nsIDOMDOMRequest* aRequest,
165 : const nsAString& aError)
166 : {
167 0 : static_cast<DOMRequest*>(aRequest)->FireError(aError);
168 :
169 0 : return NS_OK;
170 4392 : }
|