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/. */
7 #include "mozilla/dom/BindingUtils.h"
8 #include "mozilla/dom/Document.h"
9 #include "mozilla/dom/TestFunctions.h"
10 #include "mozilla/dom/TestFunctionsBinding.h"
11 #include "mozilla/dom/WindowBinding.h"
12 #include "mozilla/dom/WrapperCachedNonISupportsTestInterface.h"
13 #include "mozilla/StringBuffer.h"
14 #include "mozITestInterfaceJS.h"
15 #include "nsComponentManagerUtils.h"
16 #include "nsGlobalWindowInner.h"
18 namespace mozilla::dom
{
21 UniquePtr
<TestFunctions
> TestFunctions::Constructor(GlobalObject
& aGlobal
) {
22 return MakeUnique
<TestFunctions
>();
26 void TestFunctions::ThrowUncatchableException(GlobalObject
& aGlobal
,
28 aRv
.ThrowUncatchableException();
32 Promise
* TestFunctions::PassThroughPromise(GlobalObject
& aGlobal
,
38 already_AddRefed
<Promise
> TestFunctions::PassThroughCallbackPromise(
39 GlobalObject
& aGlobal
, PromiseReturner
& aCallback
, ErrorResult
& aRv
) {
40 return aCallback
.Call(aRv
);
43 void TestFunctions::SetStringData(const nsAString
& aString
) {
44 mStringData
= aString
;
47 void TestFunctions::GetStringDataAsAString(nsAString
& aString
) {
48 aString
= mStringData
;
51 void TestFunctions::GetStringDataAsAString(uint32_t aLength
,
53 MOZ_RELEASE_ASSERT(aLength
<= mStringData
.Length(),
54 "Bogus test passing in a too-big length");
55 aString
.Assign(mStringData
.BeginReading(), aLength
);
58 void TestFunctions::GetStringDataAsDOMString(const Optional
<uint32_t>& aLength
,
61 if (aLength
.WasPassed()) {
62 length
= aLength
.Value();
63 MOZ_RELEASE_ASSERT(length
<= mStringData
.Length(),
64 "Bogus test passing in a too-big length");
66 length
= mStringData
.Length();
69 if (StringBuffer
* buf
= mStringData
.GetStringBuffer()) {
70 aString
.SetKnownLiveStringBuffer(buf
, length
);
74 // We better have an empty mStringData; otherwise why did we not have a string
76 MOZ_RELEASE_ASSERT(length
== 0, "Why no stringbuffer?");
77 // No need to do anything here; aString is already empty.
80 void TestFunctions::GetShortLiteralString(nsAString
& aString
) {
81 // JS inline strings can hold 2 * sizeof(void*) chars, which on 32-bit means 8
82 // chars. Return fewer than that.
83 aString
.AssignLiteral(u
"012345");
86 void TestFunctions::GetMediumLiteralString(nsAString
& aString
) {
87 // JS inline strings are at most 2 * sizeof(void*) chars, so at most 16 on
88 // 64-bit. FakeString can hold 63 chars in its inline buffer (plus the null
89 // terminator). Let's return 40 chars; that way if we ever move to 128-bit
90 // void* or something this test will still be valid.
91 aString
.AssignLiteral(u
"0123456789012345678901234567890123456789");
94 void TestFunctions::GetLongLiteralString(nsAString
& aString
) {
95 // Need more than 64 chars.
96 aString
.AssignLiteral(
97 u
"0123456789012345678901234567890123456789" // 40
98 "0123456789012345678901234567890123456789" // 80
102 void TestFunctions::GetStringbufferString(const nsAString
& aInput
,
103 nsAString
& aRetval
) {
104 // We have to be a bit careful: if aRetval is an autostring, if we just assign
105 // it won't cause stringbuffer allocation. So we have to round-trip through
106 // something that definitely causes a stringbuffer allocation.
108 // Can't use operator= here, because if aInput is a literal string then str
109 // would end up the same way.
110 str
.Assign(aInput
.BeginReading(), aInput
.Length());
112 // Now we might end up hitting our external string cache and getting the wrong
113 // sort of external string, so replace the last char by a different value
114 // (replacing, not just appending, to preserve the length). If we have an
115 // empty string, our caller screwed up and there's not much we can do for
117 if (str
.Length() > 1) {
118 char16_t last
= str
[str
.Length() - 1];
119 str
.Truncate(str
.Length() - 1);
127 // Here we use operator= to preserve stringbufferness.
131 StringType
TestFunctions::GetStringType(const nsAString
& aString
) {
132 if (aString
.IsLiteral()) {
133 return StringType::Literal
;
136 if (aString
.GetStringBuffer()) {
137 return StringType::Stringbuffer
;
140 if (aString
.GetDataFlags() & nsAString::DataFlags::INLINE
) {
141 return StringType::Inline
;
144 return StringType::Other
;
147 bool TestFunctions::StringbufferMatchesStored(const nsAString
& aString
) {
148 return aString
.GetStringBuffer() &&
149 aString
.GetStringBuffer() == mStringData
.GetStringBuffer();
152 void TestFunctions::TestThrowNsresult(ErrorResult
& aError
) {
153 nsCOMPtr
<mozITestInterfaceJS
> impl
=
154 do_CreateInstance("@mozilla.org/dom/test-interface-js;1");
155 aError
= impl
->TestThrowNsresult();
158 void TestFunctions::TestThrowNsresultFromNative(ErrorResult
& aError
) {
159 nsCOMPtr
<mozITestInterfaceJS
> impl
=
160 do_CreateInstance("@mozilla.org/dom/test-interface-js;1");
161 aError
= impl
->TestThrowNsresultFromNative();
164 already_AddRefed
<Promise
> TestFunctions::ThrowToRejectPromise(
165 GlobalObject
& aGlobal
, ErrorResult
& aError
) {
166 aError
.Throw(NS_ERROR_DOM_INVALID_STATE_ERR
);
170 int32_t TestFunctions::One() const { return 1; }
172 int32_t TestFunctions::Two() const { return 2; }
174 void TestFunctions::SetClampedNullableOctet(const Nullable
<uint8_t>& aOctet
) {
175 mClampedNullableOctet
= aOctet
;
178 Nullable
<uint8_t> TestFunctions::GetClampedNullableOctet() const {
179 return mClampedNullableOctet
;
182 void TestFunctions::SetEnforcedNullableOctet(const Nullable
<uint8_t>& aOctet
) {
183 mEnforcedNullableOctet
= aOctet
;
186 Nullable
<uint8_t> TestFunctions::GetEnforcedNullableOctet() const {
187 return mEnforcedNullableOctet
;
190 void TestFunctions::SetArrayBufferView(const ArrayBufferView
& aBuffer
) {}
192 void TestFunctions::GetArrayBufferView(JSContext
* aCx
,
193 JS::Handle
<JSObject
*> aObj
,
194 JS::MutableHandle
<JSObject
*> aRetval
,
195 ErrorResult
& aError
) {
196 aError
.Throw(NS_ERROR_NOT_IMPLEMENTED
);
199 void TestFunctions::SetAllowSharedArrayBufferView(
200 const ArrayBufferView
& aBuffer
) {}
202 void TestFunctions::GetAllowSharedArrayBufferView(
203 JSContext
* aCx
, JS::Handle
<JSObject
*> aObj
,
204 JS::MutableHandle
<JSObject
*> aRetval
, ErrorResult
& aError
) {
205 aError
.Throw(NS_ERROR_NOT_IMPLEMENTED
);
208 void TestFunctions::SetSequenceOfArrayBufferView(
209 const Sequence
<ArrayBufferView
>& aBuffers
) {}
211 void TestFunctions::GetSequenceOfArrayBufferView(JSContext
* aCx
,
212 JS::Handle
<JSObject
*> aObj
,
213 nsTArray
<JSObject
*>& aRetval
,
214 ErrorResult
& aError
) {
215 aError
.Throw(NS_ERROR_NOT_IMPLEMENTED
);
218 void TestFunctions::SetSequenceOfAllowSharedArrayBufferView(
219 const Sequence
<ArrayBufferView
>& aBuffers
) {}
221 void TestFunctions::GetSequenceOfAllowSharedArrayBufferView(
222 JSContext
* aCx
, JS::Handle
<JSObject
*> aObj
, nsTArray
<JSObject
*>& aRetval
,
223 ErrorResult
& aError
) {
224 aError
.Throw(NS_ERROR_NOT_IMPLEMENTED
);
227 void TestFunctions::SetArrayBuffer(const ArrayBuffer
& aBuffer
) {}
229 void TestFunctions::GetArrayBuffer(JSContext
* aCx
, JS::Handle
<JSObject
*> aObj
,
230 JS::MutableHandle
<JSObject
*> aRetval
,
231 ErrorResult
& aError
) {
232 aError
.Throw(NS_ERROR_NOT_IMPLEMENTED
);
235 void TestFunctions::SetAllowSharedArrayBuffer(const ArrayBuffer
& aBuffer
) {}
237 void TestFunctions::GetAllowSharedArrayBuffer(
238 JSContext
* aCx
, JS::Handle
<JSObject
*> aObj
,
239 JS::MutableHandle
<JSObject
*> aRetval
, ErrorResult
& aError
) {
240 aError
.Throw(NS_ERROR_NOT_IMPLEMENTED
);
243 void TestFunctions::SetSequenceOfArrayBuffer(
244 const Sequence
<ArrayBuffer
>& aBuffers
) {}
246 void TestFunctions::GetSequenceOfArrayBuffer(JSContext
* aCx
,
247 JS::Handle
<JSObject
*> aObj
,
248 nsTArray
<JSObject
*>& aRetval
,
249 ErrorResult
& aError
) {
250 aError
.Throw(NS_ERROR_NOT_IMPLEMENTED
);
253 void TestFunctions::SetSequenceOfAllowSharedArrayBuffer(
254 const Sequence
<ArrayBuffer
>& aBuffers
) {}
256 void TestFunctions::GetSequenceOfAllowSharedArrayBuffer(
257 JSContext
* aCx
, JS::Handle
<JSObject
*> aObj
, nsTArray
<JSObject
*>& aRetval
,
258 ErrorResult
& aError
) {
259 aError
.Throw(NS_ERROR_NOT_IMPLEMENTED
);
262 void TestFunctions::TestNotAllowShared(const ArrayBufferView
& aBuffer
) {}
264 void TestFunctions::TestNotAllowShared(const ArrayBuffer
& aBuffer
) {}
266 void TestFunctions::TestNotAllowShared(const nsAString
& aBuffer
) {}
268 void TestFunctions::TestAllowShared(const ArrayBufferView
& aBuffer
) {}
270 void TestFunctions::TestAllowShared(const ArrayBuffer
& aBuffer
) {}
272 void TestFunctions::TestDictWithAllowShared(
273 const DictWithAllowSharedBufferSource
& aDict
) {}
275 void TestFunctions::TestUnionOfBuffferSource(
276 const ArrayBufferOrArrayBufferViewOrString
& aUnion
) {}
278 void TestFunctions::TestUnionOfAllowSharedBuffferSource(
279 const MaybeSharedArrayBufferOrMaybeSharedArrayBufferView
& aUnion
) {}
281 bool TestFunctions::ObjectFromAboutBlank(JSContext
* aCx
, JSObject
* aObj
) {
282 // We purposefully don't use WindowOrNull here, because we want to
283 // demonstrate the incorrect behavior we get, not just fail some asserts.
284 RefPtr
<nsGlobalWindowInner
> win
;
285 UNWRAP_MAYBE_CROSS_ORIGIN_OBJECT(Window
, aObj
, win
, aCx
);
290 Document
* doc
= win
->GetDoc();
295 return doc
->GetDocumentURI()->GetSpecOrDefault().EqualsLiteral("about:blank");
298 WrapperCachedNonISupportsTestInterface
*
299 TestFunctions::WrapperCachedNonISupportsObject() {
300 if (!mWrapperCachedNonISupportsTestInterface
) {
301 mWrapperCachedNonISupportsTestInterface
=
302 new WrapperCachedNonISupportsTestInterface();
304 return mWrapperCachedNonISupportsTestInterface
;
307 bool TestFunctions::WrapObject(JSContext
* aCx
,
308 JS::Handle
<JSObject
*> aGivenProto
,
309 JS::MutableHandle
<JSObject
*> aWrapper
) {
310 return TestFunctions_Binding::Wrap(aCx
, this, aGivenProto
, aWrapper
);
313 } // namespace mozilla::dom